Pwnable.kr - lotto

1 minute read

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... :(