bats3c / shad0w

A post exploitation framework designed to operate covertly on heavily monitored environments
https://blog.dylan.codes/shad0w/
MIT License
2.03k stars 323 forks source link

PS command crashes beacon with `x64/windows/static` payloads #35

Closed bblenard closed 4 years ago

bblenard commented 4 years ago

When issuing the ps command on a x64/windows/static beacon the beacon will immediately crash without returning any data.

bblenard commented 4 years ago

I started working on this earlier today and I think I worked out the issue. This will be quite the bug explanation so bare with me...

Currently the type definition for the ps command in the stdlib code is char* getps(). This type declaration is lost during the compilation and the function is assumed to return an int. I believe this occurs because by default the x86_64-w64-mingw32-gcc compiler applies the gnu89 iso standard to c code during compilation, see here and search for gnu89. Per the c89 standard implicit declarations of functions are treated as int f(); therefore char* getps(); is transformed into int getps();. I couldn't find "official" documentation for this behavior but it is a semi well known thing. I know this behavior from my K.N. King C Programming book but here is a stackoverflow link talking about the same thing. Anyways because the return value is now an int it can only contain 4 bytes of data instead of 8 bytes for a pointer. See this and this for data type sizes from Microsoft's documentation. This all results in the truncation of the return of getps which creates an access violation bug / undefined behavior which typically crashes the beacon. Here is a screenshot showing this behavior occurring on my test vm

integer_truncation

Pointer value pre-truncation nontruncated_breakdown

Pointer value post-truncation truncated_breakdown

Im not 100% sure why this behavior manifests so consistently on this specific beacon... maybe it is how the addressing works within threads on windows however I believe this bug is in every beacon format. A fix could be adding the prototype to the beacons core.h file. If possible it would be good to enforce some compilation checks such as -Wall or a particular C iso standard.

bblenard commented 4 years ago

Wanted to include a better example of the truncation that occurs causing this bug. I couldn't get a pretty screenshot but here is some debug output that nicely shows the bug.

[DEBUG] getps() text return as pointer:               0000025DA43B0C30
[DEBUG] Stdlib() data return from getps() as pointer: FFFFFFFFA43B0C30

As you can see the pointer for the text in getps is truncated and turned into a signed integer when the Stdlib function receives it causing a completely different address to be used in subsequent actions. This results in a access violation.