lotto

References

Question

Mommy! I made a lotto program for my homework.
do you want to play?

ssh [email protected] -p2222 (pw:guest)

Source Code

#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;
}

Writeup

  • 題目是玩樂透,我們輸入6個字元,會與電腦產生的做比較,當完全符合時則得到flag,但由於迴圈判斷式有問題,變成使用者輸入的每個字元會與電腦輸入的每個字元都去做比較,這大大提高了符合的次數,只要剛好滿足6次,就能取得flag。
    // 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++;
                    }
            }
    }
    
  • 題目限制了電腦random的字元,是介於ASCII的1~45,但由於前面0~31是控制符,所以我們只能輸入32~45 (http://www.ascii-code.com/)
  • 測試看看電腦產生的亂數,發現確實有不可見的符號,另外這邊只是測試用,所以會看見除了1~45以外的ASCII
    ngC♠►▒lotto@ubuntu:~$ cat /dev/urandom | head -c 6
    ▒▒lotto@ubuntu:~$ cat /dev/urandom | head -c 6
    ▒-▒♠*lotto@ubuntu:~$ cat /dev/urandom | head -c 6
    7▒▒B▒▒lotto@ubuntu:~$ cat /dev/urandom | head -c 6
    ▒U▒lotto@ubuntu:~$ cat /dev/urandom | head -c 6
    ǿ▒ޑlotto@ubuntu:~$ cat /dev/urandom | head -c 6
    ▒▒H&3lotto@ubuntu:~$ cat /dev/urandom | head -c 6
    ▒ާ▒▒lotto@ubuntu:~$ cat /dev/urandom | head -c 6
    
  • 所以我們只要輸入相同六個字元,當電腦剛好產生一個與我們相同的字元,就能取得flag了 (結果試了14次才成功-_-)
    Submit your 6 lotto bytes : !!!!!!
    Lotto Start!
    bad luck...
    - Select Menu -
    1. Play Lotto
    2. Help
    3. Exit
    1
    Submit your 6 lotto bytes : !!!!!!
    Lotto Start!
    sorry mom... I FORGOT to check duplicate numbers... :(
    

results matching ""

    No results matching ""