Sitemap
Fnnnr

Fnnnr

Currently a penetration tester. Interested in binary exploit and RE.

[tctt2022] pwnable 06

3 min readOct 1, 2022

The last part of the series

The binary for this challenge is simply asking the user to guess a number. If it is not correct, the binary will reveal the correct number:

./challenge               
[*] ============================
[*] Hello!, guess a lucky number
>> 20
[*] GUESS: is 20
[*] LUCKY: is 77
[-] NO-gratulation!!!

Using rabin2 , we can see that the flag will be read using system() :

rabin2 -zzz ./challenge
026 0x00002093 0x00002093 14 15 (.rodata) ascii cat SECRET.txt

Let’s decompile the binary:

void main(void)
{
undefined4 uVar1;
int32_t iVar2;
int32_t var_14h;
time_t *timer;
uint64_t var_4h;

uVar1 = time(&timer);
srand(uVar1);
iVar2 = rand();
var_4h._0_4_ = _LOWER + iVar2 % ((_UPPER - _LOWER) + 1);
var_14h = -1;
puts("[*] ============================ ");
puts("[*] Hello!, guess a lucky number ");
printf(0x2052);
__isoc99_scanf(0x2056, &var_14h);
putchar(10);
printf("[*] GUESS: is %d\n", var_14h);
printf("[*] LUCKY: is %d\n", (int32_t)var_4h);
putchar(10);
if ((int32_t)var_4h == var_14h) {
puts("[+] Congratulation!!!");
system("cat SECRET.txt");
} else {
puts("[-] NO-gratulation!!!");
}
return;
}

where:

[0x000011a9]> px @ obj.LOWER
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x00004058 0000 0000 0000 0000 ffff ffff ffff ffff ................
[0x000011a9]> px @ obj.UPPER
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x00004050 6300 0000 0000 0000 0000 0000 0000 0000 c...............

It basically uses current time as the seed and random within range of 0–99.

0x63 is 99 in case you are wondering

Note that the time() will return a time in seconds.

Get Fnnnr’s stories in your inbox

Join Medium for free to get updates from this writer.

So, if we try over and over again within the same second, it will stays the same.
This can be done multiple ways:

  • use the same number but try over and over
  • iterate from 0–99 within the second
  • guess incorrectly once and use the revealed answer as the next answer

I will shows the second and third options.

Iterate from 0–99 within the second

This can easily be done using bash script:

for i in {0..99}; do echo $i|./challenge; done;

The result:

...
[*] ============================
[*] Hello!, guess a lucky number
>>
[*] GUESS: is 3
[*] LUCKY: is 5
[-] NO-gratulation!!!
[*] ============================
[*] Hello!, guess a lucky number
>>
[*] GUESS: is 4
[*] LUCKY: is 5
[-] NO-gratulation!!!
[*] ============================
[*] Hello!, guess a lucky number
>>
[*] GUESS: is 5
[*] LUCKY: is 5
[+] Congratulation!!!
tctt2022{REDACTED}

Guess incorrectly once and use the revealed answer as the next answer

I am not sure why when I run this locally it stuck at the receiving input but it works with remote exploit

The code I use is:

from pwn import *
import re
context.log_level = 'debug'
i = 0
payload = str(i)
while True:
io = process('./challenge')
io.recvuntil(b">>")
io.sendline(payload)
mesg = io.recvall()
lucky = re.search('LUCKY:\s+is\s+(\d+)',mesg.decode())
if lucky:
print("lucky "+ str(lucky[1]))
payload = str(lucky[1])
if "[+]" in mesg.decode():
print(mesg)
break

That is it for the pwnable challenge for Thailand Cyber Top Talent 2022.

I hope you enjoy this blog series :)

Part 1:

--

--

Fnnnr
Fnnnr

Written by Fnnnr

Currently a penetration tester. Interested in binary exploit and RE.