【Writeup】pwnable.kr--lotto
1. 题目概述Mommy! I made a lotto program for my homework.do you want to play?ssh lottopwnable.kr -p2222 (pw:guest)2. 解题思路查看详细信息运行程序ls -llottoubuntu:~$ ./lotto - Select Menu - 1. Play Lotto 2. Help 3. Exit 1 Submit your 6 lotto bytes : 123456 Lotto Start! bad luck... - Select Menu - 1. Play Lotto 2. Help 3. Exit 3 bye程序运行后有3种选项3退出2打印提示信息1进入游戏输入猜的6个数字全部正确得到flag反之就显示bad luck...接下来看源代码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(i0; i6; i){ lotto[i] (lotto[i] % 45) 1; // 1 ~ 45 } close(fd); // calculate lotto score int match 0, j 0; for(i0; i6; i){ for(j0; j6; j){ if(lotto[i] submit[j]){ match; } } } // win! if(match 6){ setregid(getegid(), getegid()); system(/bin/cat flag); } else{ printf(bad luck...\n); } }程序运行后输入1进入play()函数。首先从键盘读6字节输入存入submit[]然后系统利用/dev/urandom随机生成6个数字存入lotto[]。接着把随机数取余使其大小范围在1-45。查询ASCII码表前32个是控制字符32-45是可见字符。接下来是for双层嵌套循环也是问题所在。对于lotto[]中每一个字节把submit[]对比一遍一旦submit[]中都是同样的数字恰巧lotto[i]与之相同那么在lotto[i]这个循环中进行了j次match也就无需猜中每一个数字。例如lotto[]{1,2,3,33,4,5}submit[]{33,33,33,33,33,33}在循环到i3时match增加到了6。所以输入6个“!”十进制33运行几次后就会出现flag。lottoubuntu:~$ ./lotto - Select Menu - 1. Play Lotto 2. Help 3. Exit 1 Submit your 6 lotto bytes : !!!!!! Lotto Start!