[pwnable.kr] lotto(2 pts) :: Write-Up
두비니
·2020. 7. 14. 01:20
Mommy! I made a lotto program for my homework.
do you want to play?
ssh lotto@pwnable.kr -p2222 (pw: guest)
lotto@pwnable:~$ nl lotto.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <fcntl.h>
5 unsigned char submit[6];
6 void play(){
7
8 int i;
9 printf("Submit your 6 lotto bytes : ");
10 fflush(stdout);
11 int r;
12 r = read(0, submit, 6);
13 printf("Lotto Start!\n");
14 //sleep(1);
15 // generate lotto numbers
16 int fd = open("/dev/urandom", O_RDONLY);
17 if(fd==-1){
18 printf("error. tell admin\n");
19 exit(-1);
20 }
21 unsigned char lotto[6];
22 if(read(fd, lotto, 6) != 6){
23 printf("error2. tell admin\n");
24 exit(-1);
25 }
26 for(i=0; i<6; i++){
27 lotto[i] = (lotto[i] % 45) + 1; // 1 ~ 45
28 }
29 close(fd);
30
31 // calculate lotto score
32 int match = 0, j = 0;
33 for(i=0; i<6; i++){
34 for(j=0; j<6; j++){
35 if(lotto[i] == submit[j]){
36 match++;
37 }
38 }
39 }
40 // win!
41 if(match == 6){
42 system("/bin/cat flag");
43 }
44 else{
45 printf("bad luck...\n");
46 }
47 }
48 void help(){
49 printf("- nLotto Rule -\n");
50 printf("nlotto is consisted with 6 random natural numbers less than 46\n");
51 printf("your goal is to match lotto numbers as many as you can\n");
52 printf("if you win lottery for *1st place*, you will get reward\n");
53 printf("for more details, follow the link below\n");
54 printf("http://www.nlotto.co.kr/counsel.do?method=playerGuide#buying_guide01\n\n");
55 printf("mathematical chance to win this game is known to be 1/8145060.\n");
56 }
57 int main(int argc, char* argv[]){
58 // menu
59 unsigned int menu;
60 while(1){
61 printf("- Select Menu -\n");
62 printf("1. Play Lotto\n");
63 printf("2. Help\n");
64 printf("3. Exit\n");
65 scanf("%d", &menu);
66 switch(menu){
67 case 1:
68 play();
69 break;
70 case 2:
71 help();
72 break;
73 case 3:
74 printf("bye\n");
75 return 0;
76 default:
77 printf("invalid menu\n");
78 break;
79 }
80 }
81 return 0;
82 }
일단 코드의 전문이다. 보아하니 help와 main문 자체에서는 딱히 취약점이 없어서 play함수를 다시보자.
6 void play(){
7
8 int i;
9 printf("Submit your 6 lotto bytes : ");
10 fflush(stdout);
우선 나의 로또 6숫자를 입력받고, output stream을 비웁니다.
11 int r;
12 r = read(0, submit, 6);
13 printf("Lotto Start!\n");
14 //sleep(1);
15 // generate lotto numbers
16 int fd = open("/dev/urandom", O_RDONLY);
17 if(fd==-1){
18 printf("error. tell admin\n");
19 exit(-1);
20 }
그 다음 로또 번호를 랜덤생성해주고,
21 unsigned char lotto[6];
22 if(read(fd, lotto, 6) != 6){
23 printf("error2. tell admin\n");
24 exit(-1);
25 }
26 for(i=0; i<6; i++){
27 lotto[i] = (lotto[i] % 45) + 1; // 1 ~ 45
28 }
29 close(fd);
30
랜덤생성한 숫자를 45로 나눕니다. 범위가 1~45이기 때문이죠.
31 // calculate lotto score
32 int match = 0, j = 0;
33 for(i=0; i<6; i++){
34 for(j=0; j<6; j++){
35 if(lotto[i] == submit[j]){ //vuln
36 match++;
37 }
38 }
39 }
40 // win!
41 if(match == 6){
42 system("/bin/cat flag");
43 }
44 else{
45 printf("bad luck...\n");
46 }
47 }
근데 여기서 취약점이 발생하게 됩니다. if문을 확인할때 무조건 앞에서부터 끝까지 무조건 확인합니다.
즉, 로또번호를 중복확인하지 않습니다.
예를들어 로또당첨번호가 123456이라면, 제가 222222를 입력해도 당첨이 된다는 것이죠.
그러면 그냥 1~45사이의 아스키값을 가지는 문자를 입력하면 되겠네요. 저는 !(느낌표) 사용하였고, 아스키 코드표 참고해서 되는값 아무거나해도 상관없습니다.
아무래도 random함수를 돌리다보니까 몇번 해야되네요
'War Games > pwnable.kr' 카테고리의 다른 글
[pwnable.kr] cmd2(9 pts) :: Write-Up (0) | 2020.07.19 |
---|---|
[pwnable.kr] cmd1(1 pts) :: Write-Up (0) | 2020.07.18 |
[pwnable.kr] blackjack(1 pts) :: Write-Up (0) | 2020.07.13 |
[pwnable.kr] coin1(6 pts) :: Write-Up (0) | 2020.07.12 |
[pwnable.kr] shellshock(1 pts) :: Write-Up (0) | 2020.07.09 |