Pwnable.kr - lotto
Challenge description:
Mommy! I made a lotto program for my homework. do you want to play?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
unsigned char submit[6];
void play(){
int i;
printf("Submit your 6 lotto bytes : ");
fflush(stdout);
int r;
r = read(0, submit, 6);
printf("Lotto Start!\n");
//sleep(1);
// generate lotto numbers
int fd = open("/dev/urandom", O_RDONLY);
if(fd==-1){
printf("error. tell admin\n");
exit(-1);
}
unsigned char lotto[6];
if(read(fd, lotto, 6) != 6){
printf("error2. tell admin\n");
exit(-1);
}
for(i=0; i<6; i++){
lotto[i] = (lotto[i] % 45) + 1; // 1 ~ 45
}
close(fd);
// calculate lotto score
int match = 0, j = 0;
for(i=0; i<6; i++){
for(j=0; j<6; j++){
if(lotto[i] == submit[j]){
match++;
}
}
}
// win!
if(match == 6){
system("/bin/cat flag");
}
else{
printf("bad luck...\n");
}
}
// The rest of the code is not important
The game asks for 6 bytes and compares them with 6 random bytes in the range [1-45], if the number of matches is 6 we win the game.
The observation here is that it compares each random byte to all the 6 input bytes, so if there is only one match, we win :)
So we will enter 6 of the same character (in the range [1-45]) and hope there is a match.
Solution:
# solve.py
from pwn import *
sh = ssh('lotto', 'pwnable.kr', password='guest', port=2222)
p = sh.process('./lotto')
for i in range(1000):
p.recv()
p.sendline('1')
p.recv()
p.sendline('------')
_ , ans = p.recvlines(2)
if "bad" not in ans:
print(ans)
break
$ python solve.py
[+] Connecting to pwnable.kr on port 2222: Done
[+] Starting remote process './lotto' on pwnable.kr: pid 102926
sorry mom... I FORGOT to check duplicate numbers... :(
Flag: sorry mom... I FORGOT to check duplicate numbers... :(