Stackstrings, type 2
Update 1: Added disassembler output.
When I teach FOR610: Reverse-Engineering Malware: Malware Analysis Tools and Techniques, one of the things we talk about is stackstrings. This is a technique that is used to 'hide' strings from the malware analyst (well, from normal use of the Linux strings
command) by placing a string onto the stack 1 character (byte) at a time, usually by allocating a chunk of memory and then using MOV instructions to place the string into the allocated chunk of memory. I'll call this Type 1 Stackstrings, since this is the standard stackstring most folks think of when discussing them. We also mention a couple of tools that can be used to find these. However, in my examination of shellcode, I've discovered what I'm calling Type 2 Stackstrings that these tools don't usually find, though when looking at the ASCII strings they are sort of visible. I'm sure other malware analysts have seen this, but I've never seen it explicitly documented, so I figured I'd take a little time and explain what I'm seeing (and ask if anyone has tools that pull these kind of strings, I've just opened an issue/feature request for FLOSS on Github to add this). These type 2 stackstrings are pushed onto the stack 4 bytes at a time using the actual PUSH instruction rather than MOVs. I don't usually see this type of stackstring in ordinary malware, I most often see it in shellcode, though I understand that it also gets used by Metasploit. It turns out that in x86 assembly one of the opcodes for the PUSH instruction is opcode 0x68 which when converted to ASCII is the lowercase h
character, so, you'll see h<4 ASCII chars>
followed by another h<4 ASCII chars>
, etc. to push the string onto the stack 4 bytes at a time. That is probably a bit more efficient than the allocate space then move 1 character at a time.
As I said above, if you just look at ASCII strings you can sort of see these stackstrings as noted in the 2 samples below
You can see it in the raw data
But, if I throw this is a disassembler, those strings still aren't obvious.
You can see the pieces since they get pushed in (sort of) reverse order. In the first example you can see the string wininet
being pushed, in the second there are a bunch of them (ExitProc
, URLDownloadToFile
, urlmon.dll
, and LoadLibraryA
). Hopefully, my "feature request" in FLOSS will get implemented soon, but does anyone else have tools that pull these type 2 stackstrings? Any other thoughts? I welcome your comments either here, or via our contact page, or email.
---------------
Jim Clausing, GIAC GSE #26
jclausing --at-- isc [dot] sans (dot) edu
LINUX Incident Response and Threat Hunting | Online | US Eastern | Jan 29th - Feb 3rd 2025 |
Comments