-
Notifications
You must be signed in to change notification settings - Fork 14.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nodejs v8 debugger eval exploit #8931
Conversation
print_error("Got unexpected response: #{buf}") | ||
end | ||
|
||
handler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't be necessary to call handler
explicitly here.
return Exploit::CheckCode::Appears | ||
end | ||
|
||
return Exploit::CheckCode::Unknown |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can drop the explicit return
here if you'd like.
escaped_payload = payload.encoded.gsub(/"/, '\\"') | ||
msg_body = MESSAGE_TEMPLATE % {:payload => escaped_payload} | ||
msg_header = MESSAGE_HEADER_TEMPLATE % {:length => msg_body.length} | ||
return msg_header + msg_body |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
end | ||
|
||
def make_eval_message | ||
escaped_payload = payload.encoded.gsub(/"/, '\\"') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your indentation is off here.
Clean first submission. :) |
escaped_payload = payload.encoded.gsub(/"/, '\\"') | ||
msg_body = MESSAGE_TEMPLATE % {:payload => escaped_payload} | ||
msg_header = MESSAGE_HEADER_TEMPLATE % {:length => msg_body.length} | ||
return msg_header + msg_body |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more return
. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it too late to complain about Ruby's implicit returns? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kind of hate it, tbqh. Same with unless
and the lack of parens for method definitions and calls. You can do what you want. :P
@wvu-r7 One thing I couldn't figure out was what target specification to provide that wouldn't include the generic payloads, since they're not applicable here. Only nodejs code is valid as a drop-in payload, so I wouldn't want the default to be a generic that won't work:
Thoughts? |
# 'Arch' => [ ARCH_NODEJS ], | ||
'Targets' => | ||
[ | ||
['NodeJS', { 'Platform' => 'nodejs', 'Arch' => 'nodejs' } ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you want this to be ARCH_NODEJS
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That might be the answer to the question above. Wasn't clear to me from looking at other modules which was the preferred way of specifying. Let me know if you've got a suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I usually go by the compatible payloads.
|
Nope, my mistake. generic payloads work fine.
I was remembering that from when I had my target spec goofed up. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat, thanks, adding to test queue.
@@ -28,8 +28,6 @@ def initialize(info={}) | |||
[ 'URL', 'https://github.com/buggerjs/bugger-v8-client/blob/master/PROTOCOL.md' ], | |||
[ 'URL', 'https://github.com/nodejs/node/pull/8106' ] | |||
], | |||
# 'Platform' => ['node'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While these aren't necessary, since you already have them in the target, the info
command won't show platform if it's not top-level. I found this the other day working on the Struts exploit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'll fix this in the library.
PR #8825 was recently merged, so the comment in "Verification" no longer applies; this exploit will now work using master branch. |
Yup, thanks to @jmartin-r7 for that. I'll get this landed shortly. |
Release NotesThe NodeJS Debugger Command Injection module has been added to the framework. |
This module uses the "evaluate" request type of the NodeJS V8
debugger protocol (version 1) to evaluate arbitrary JS resulting
in RCE.
(This is my first exploit PR; any feedback welcome)
Target Setup
Current and historical versions of node (or any JS env based on the V8 JS engine) have this functionality and could be exploitable if configured to expose the JS port on an untrusted interface. In particular, versions of Node released between April 2014 and Aug 2016 incorrectly bound this in default configurations.
Install a version of node using any of the normal methods:
sudo apt-get install nodejs
Alternately, use standard node docker containers as targets:
(Others at https://hub.docker.com/_/node/)
Tested on Node 7.x, 6.x, 4.x
Verification
Important: Exploiting modern node relies on a (submitted but not yet merged)
bugfix for the nodejs/shell_reverse_tcp payload: #8825
Make sure you have that patch applied before testing against node >= 5.3.0.
(If using docker hosts as targets for testing, ensure that LHOST addr is accessible to the container)
Note that in older Node versions (notably 4.8.4), the debugger will not immediately process the incoming eval message. As soon as there is some kind of activity (such as a step or continue in the debugger, or just hitting enter), the payload will execute and the handler session will start.
Example Run
Node 7.x
Victim:
Attacker: