pwnable.kr --- blackjack
자신의 서버에 접속한 뒤 nc pwnable.kr 9009로 접속하면 blackjack 문제를 만날 수 있다.
nc pwnable.kr 9009로 접속하면 바로 blackjack 파일이 실행되는 것을 확인할 수 있다.
blackjack에 관한 전체 소스는 아래의 경로로 접속 가능하다.
http://cboard.cprogramming.com/c-programming/114023-simple-blackjack-program.html
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 | void play() //Plays game { int p=0; // holds value of player_total int i=1; // counter for asking user to hold or stay (aka game turns) char choice3; cash = cash; cash_test(); printf("\nCash: $%d\n",cash); //Prints amount of cash user has randcard(); //Generates random card player_total = p + l; //Computes player total p = player_total; printf("\nYour Total is %d\n", p); //Prints player total dealer(); //Computes and prints dealer total betting(); //Prompts user to enter bet amount while(i<=21) //While loop used to keep asking user to hit or stay at most twenty-one times // because there is a chance user can generate twenty-one consecutive 1's { if(p==21) //If user total is 21, win { printf("\nUnbelievable! You Win!\n"); won = won+1; cash = cash+bet; printf("\nYou have %d Wins and %d Losses. Awesome!\n", won, loss); dealer_total=0; askover(); } if(p>21) //If player total is over 21, loss { printf("\nWoah Buddy, You Went WAY over.\n"); loss = loss+1; cash = cash - bet; printf("\nYou have %d Wins and %d Losses. Awesome!\n", won, loss); dealer_total=0; askover(); } if(p<=21) //If player total is less than 21, ask to hit or stay { printf("\n\nWould You Like to Hit or Stay?"); scanf("%c", &choice3); while((choice3!='H') && (choice3!='h') && (choice3!='S') && (choice3!='s')) // If invalid choice entered { printf("\n"); printf("Please Enter H to Hit or S to Stay.\n"); scanf("%c",&choice3); } if((choice3=='H') || (choice3=='h')) // If Hit, continues { randcard(); player_total = p + l; p = player_total; printf("\nYour Total is %d\n", p); dealer(); if(dealer_total==21) //Is dealer total is 21, loss { printf("\nDealer Has the Better Hand. You Lose.\n"); loss = loss+1; cash = cash - bet; printf("\nYou have %d Wins and %d Losses. Awesome!\n", won, loss); dealer_total=0; askover(); } if(dealer_total>21) //If dealer total is over 21, win { printf("\nDealer Has Went Over!. You Win!\n"); won = won+1; cash = cash+bet; printf("\nYou have %d Wins and %d Losses. Awesome!\n", won, loss); dealer_total=0; askover(); } } if((choice3=='S') || (choice3=='s')) // If Stay, does not continue { printf("\nYou Have Chosen to Stay at %d. Wise Decision!\n", player_total); stay(); } } i++; //While player total and dealer total are less than 21, re-do while loop } // End While Loop } // End Function | cs |
play() 함수에서 호출 하는 함수는 아래 4개의 함수이다.
cash_test()
randcard()
dealer()
betting()
위 4개의 함수를 자세히 들여다 보자.
cash_test() function
1 2 3 4 5 6 7 8 9 | void cash_test() //Test for if user has cash remaining in purse { if (cash <= 0) //Once user has zero remaining cash, game ends and prompts user to play again { printf("You Are Bankrupt. Game Over"); cash = 500; askover(); } } // End Function | cs |
유저(게임 참여자)가 betting 할 잔액이 남아 있는지 확인하는 함수이다.
문제가 없음을 확인 할 수 있다.
randcard() function
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 | int randcard() //Generates random card { srand((unsigned) time(NULL)); //Generates random seed for rand() function random_card = rand()%4+1; if(random_card==1) { clubcard(); l=k; } if(random_card==2) { diamondcard(); l=k; } if(random_card==3) { heartcard(); l=k; } if(random_card==4) { spadecard(); l=k; } return l; } // End Function | cs |
srand() 함수에 의해 seed 값이 변경 되기 때문에 rand() 함수를 통한 카드의 종류를 예측할 수 없다.
randcard() 또한 문제가 없음을 확인할 수 있다.
dealer() function
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 | void dealer() //Function to play for dealer AI { int z; if(dealer_total<17) { srand((unsigned) time(NULL) + 1); //Generates random seed for rand() function z=rand()%13+1; if(z<=10) //If random number generated is 10 or less, keep that value { d=z; } if(z>11) //If random number generated is more than 11, change value to 10 { d=10; } if(z==11) //If random number is 11(Ace), change value to 11 or 1 depending on dealer total { if(dealer_total<=10) { d=11; } else { d=1; } } dealer_total = dealer_total + d; } printf("\nThe Dealer Has a Total of %d", dealer_total); //Prints dealer total } // End Function | cs |
dealer의 총 숫자의 합을 구하는 함수이다. srand() 함수를 통해 seed를 초기화하고, 딱히 잘못된 점이 없다.
betting() function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | int betting() //Asks user amount to bet { printf("\n\nEnter Bet: $"); scanf("%d", &bet); if (bet > cash) //If player tries to bet more money than player has { printf("\nYou cannot bet more money than you have."); printf("\nEnter Bet: "); scanf("%d", &bet); return bet; } else return bet; } // End Function | cs |
유저(게임의 참여자)가 betting 할 때 만일 유저가 가지고 있는 cash 보다 더 많은 cash를 betting 하면 다시 입력을 받고 bet를 return 하거나, 정상적으로 입력했을때, betting 값을 return 한다. 하지만 여기서 만일 잘못된 betting(cash보다 더 많은 betting)을 통해 다시 betting 값을 입력받을때, 예외 처리를 하지 않는다.
따라서 두 번째 입력을 받을때 임의의 betting 값 설정이 가능하다.
flag를 얻기 위해서 100만 달러 이상의 부자가 되어야 하니 100만 달러를 betting 후 게임에서 이겨보자.
betting() function 오류를 이용해서 $1000000를 betting 하였다.
dealer와의 게임에서 이기게 된다면, Cash에 $10000000가 추가되고 flag를 얻을 수 있다.
'Wargame > pwnable.kr' 카테고리의 다른 글
[pwnable.kr] lotto 풀이, write-up (0) | 2018.12.27 |
---|---|
[pwnable.kr] blukat 풀이, write-up (0) | 2018.12.24 |
[pwnable.kr] leg 풀이, write-up (0) | 2018.12.24 |
[pwnable.kr] cmd1 풀이, write-up (2) | 2018.11.16 |
[pwnable.kr] mistake 풀이, write-up (0) | 2018.11.15 |