cgy12306
[pwnable.kr] lotto 본문
[lotto]
#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");
}
}
void help(){
printf("- nLotto Rule -\n");
printf("nlotto is consisted with 6 random natural numbers less than 46\n");
printf("your goal is to match lotto numbers as many as you can\n");
printf("if you win lottery for *1st place*, you will get reward\n");
printf("for more details, follow the link below\n");
printf("http://www.nlotto.co.kr/counsel.do?method=playerGuide#buying_guide01\n\n");
printf("mathematical chance to win this game is known to be 1/8145060.\n");
}
int main(int argc, char* argv[]){
// menu
unsigned int menu;
while(1){
printf("- Select Menu -\n");
printf("1. Play Lotto\n");
printf("2. Help\n");
printf("3. Exit\n");
scanf("%d", &menu);
switch(menu){
case 1:
play();
break;
case 2:
help();
break;
case 3:
printf("bye\n");
return 0;
default:
printf("invalid menu\n");
break;
}
}
return 0;
}
로또 문제이다.
맨 처음 인풋이 2번을 입력하면 도움말, 3번을 입력하면 종료를 하게 된다.
1번을 입력하면 게임을 시작하는데 /dev/urandom에서 6byte만큼 값을 읽어와서 lotto 변수에 넣는다.
그리고 6byte만큼 submit 변수에 입력을 한다.
여기서 내가 입력한 값과 랜덤으로 뽑은 값을 비교할 때 한 byte씩 비교를 하게 된다.
lotto 1 2 3 4 5 6
submit 5 6 7 8 9 10
이렇게 입력을 했다면 1을 submit에 있는 값을 하나씩 비교해서 같으면 match 값을 +1해주게 된다.
이러면 총 6 * 6 = 36번을 비교하게 된다는 말이다.
submit 변수에 값을 입력할 때 중복검사를 하지 않는다.
같은 값 6개를 입력을 하고, lotto에서 내가 입력한 값 하나가 나오게 되면 5개는 같지 않아서 match 값이 0이었다가 같은 값 하나를 검증할 때 match 값이 6이 돼버린다.
즉, 6/45 확률에 거는 것이다.운빨
그리고 값을 입력할 때 아스키 값으로 비교하기 때문에 아스키코드 표에서 1~45에 해당하는 값 하나를 선택해서 6번 입력하고, 당첨 될때까지 무한 반복하면 된다.
'Wargame > pwnable.kr' 카테고리의 다른 글
[pwnable.kr] cmd2 (0) | 2020.01.27 |
---|---|
[pwnable.kr] cmd1 (0) | 2020.01.27 |
[pwnable.kr] blackjack (0) | 2020.01.27 |
[pwnable.kr ] coin1 (0) | 2020.01.26 |
[pwnable.kr] input (0) | 2020.01.26 |
Comments