Exploitation: randy (100)
We were given an address to connect to and an executable:

It turned out it was a 32 bit ELF executable. Running the executable resulted into "guessing" some input:

I used retdec to get some juicy info about the source:
int main(int argc, char ** argv) {
char * mem = malloc(46); // 0x80485ae
int32_t v1 = (int32_t)mem; // 0x80485bc
strcpy(mem, "Welcome to Randy's TinyPoker! DebugInfo: AAAA\n");
srand(time(NULL));
uint32_t v2 = rand(); // 0x80485f6
char * v3 = (char *)(v1 + 41); // 0x8048601_0
*v3 = (char)((int32_t)*v3 + v2 / 0x1000000);
char * v4 = (char *)(v1 + 42); // 0x804861e_0
*v4 = (char)((int32_t)*v4 + v2 / 0x10000);
char * v5 = (char *)(v1 + 43); // 0x804863b_0
*v5 = (char)((int32_t)*v5 + v2 / 256);
char * v6 = (char *)(v1 + 44); // 0x8048658_0
*v6 = (char)((int32_t)*v6 + v2);
printf(mem);
printf("We've dealt you your hand face down, please enter it:\n");
int32_t str;
memset((char *)&str, 0, 5);
int32_t stream = g1;
fgets((char *)&str, 5, (struct struct__IO_FILE *)&stream);
if (str == v2) {
printf("You guessed that hand perfectly! Here's your prize: flag-here\n");
} else {
printf("Sorry, wrong hand, try again!\n");
}
return 0;
}
So basically v1
points to a string in memory Welcome to Randy's TinyPoker! DebugInfo: AAAA\n
, v2
is some random number and v3
, v4
, v5
, v6
all point to the debug info part (AAAA initially).
Then it proceeds to add a part of the random number to each of v3
, v4
, v5
, v6
by dividing v2 first:
*v3 = (char)((int32_t)*v3 + v2 / 0x1000000); // v3 = v3 + (v2 / 2^24)
*v4 = (char)((int32_t)*v4 + v2 / 0x10000); // v4 = v4 + (v4 / 2^16)
*v5 = (char)((int32_t)*v5 + v2 / 256); // v5 = v5 + (v5 / 2^8)
*v6 = (char)((int32_t)*v6 + v2);
At the end, it compares our input with the random generated value str == v2
. So in order to guess correctly we need to get the debug info and substract A
from each character, pack it and send it!
#!/usr/bin/python3
# Make sure to install pexpect (linux only) - pip install pexpect
import pexpect
import struct
import os
# Spawn the program
child = pexpect.spawn('./randy_noflag')
child.expect('Welcome to Randy\'s TinyPoker! DebugInfo: (.{4})')
debug = child.match.group(1)
payload = ""
print(debug)
for char in debug:
byte = char - 0x41 # Substract "A"
byte %= 256 # Prevent out of range errors
payload += "{:02x}".format(byte) # Convert to hex and append
payload = bytes.fromhex(payload)[::-1] # convert to bytes and reverse
# Own it
child.sendline(payload)
child.interact()

This local script was handy since the remote server was down some of the times.
The flag: sun{c4rds_in_th3_tr4p}
.