[tctt2022] pwnable 06
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.txtLet’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.
0x63is99in 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)
breakThat is it for the pwnable challenge for Thailand Cyber Top Talent 2022.
I hope you enjoy this blog series :)
Part 1:
![[picoCTF] PIE TIME — Easy](https://miro.medium.com/v2/resize:fit:1358/format:webp/1*rtDXECnJ5MrXPCulhVbjxA.png)
![[ROPEmporium] ret2win](https://miro.medium.com/v2/resize:fit:1358/format:webp/1*w1tZZhLSwhw1wKMJmAqDpw.png)
![[CTT2023] hello flutter — 100 pts](https://miro.medium.com/v2/resize:fit:1358/format:webp/1*QiyQTKnYHb24TxsTQijQXA.png)
![[CTT2023] Hflag — 200 pts](https://miro.medium.com/v2/resize:fit:1358/format:webp/1*HJRyhBj0sasQ8OtnYTbLwQ.png)


