본문 바로가기
[ ★ ]Study/War Game

[Toddler's Bottle] pwnable.kr lotto 풀이

by nroses-taek 2017. 9. 15.
반응형

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#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;
}
 
cs
 
소스코드는 상당히 길어보이지만 정말 볼게 없습니다.
main이랑 help 심심풀이로 읽어보시고, 핵심은 play
소스도 하나씩 천천히 따라 읽다가 이상한 점을 바로 발견했습니다.
1
2
3
4
5
6
7
for(i=0; i<6; i++){
    for(j=0; j<6; j++){
        if(lotto[i] == submit[j]){
            match++;
        }
    }
}
cs
바로 부분인데, 번째로 6개를 비교하면 되는데 36번이나 roop 돌리는거지? 라고 생각이 바로 들었으며, 내부 for문을 보니 lotto[i] == submuit[j] 보고 ! 했습니다. 여러분도 그러셨겠죠 …
, 핵심은 lotto[0] == submit[0~5] 맞추면 됩니다.
, lotto 번호 1개만 유추해내면 된다는 겁니다. 그리고 한가지 값으로 저희는 대입만 하면 match 6 것입니다.
 
하나, 무엇을 입력할지 고민도 해봐야 되는데, lotto int 배열이 아닌 char 배열입니다. 문자이므로, 이를 10진수 계산해본다면

45까지 키보드로 입력이 가능한 부분입니다. 하나를 골라서 계속 대입해봅시다.

 
19번만에 성공했습니다.


반응형

댓글