power-girl0-0

[pwnable] blackjack 풀이 본문

War game/pwnable.kr

[pwnable] blackjack 풀이

power-girl0-0 2022. 3. 16. 02:56
728x90

 

안녕하세요~~ (ノ◕ヮ◕)ノ*:・゚✧


1. 문제

문제에는 nc접속 주소와 blackjack게임의 소스코드가 존재하는 웹주소가 주어진다.

( https://cboard.cprogramming.com/c-programming/114023-simple-blackjack-program.html )

또한 문제 지문에서 백만 달러가 되면, flag를 얻을 수 있는 것을 확인할 수 있다.

 

2. 코드 분석

코드 중 play함수를 중점으로 살펴봐야 한다.

함수 이름 그대로, 게임 실행에 중점이 되는 함수가 play함수이다.

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(); // 딜러의 수를 구해오는 함수.
     betting(); // cash 베팅.
       
     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

play함수를 큰 범위로 정리하면, 아래와 같다.


  1. 함수 호출 : cash_test( ), randcard( ), dealer( ), betting( )

      ① cash_test() : 파산인지 확인하는 함수.
      ② randcard() : 랜덤한 값으로 player total값을 구해오는 함수.
      ③ dealer() :  랜덤한 값으로 dealer total값을 구해오는 함수.
      ④ betting() : 사용자가 게임에 베팅할 돈을 입력하는 함수.

  2. 호출 외 코드 : 크게는 win, loss, Hit, Stay관련 소스코드이다.

호출하는 함수 중 betting코드를 살펴보면, 이상한 부분을 확인할 수 있다.

int betting() -
{
 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

코드에서 cash는 현재 갖고 있는 돈의 값을 저장하고 있는 변수이다.

여기서 이상한 부분은 처음 입력받아온 bet이 cash보다 큰지 확인하는 조건문은 있지만, 

다시 입력받아온 bet에 해당되는 조건문은 존재하지 않는 것이다.

 

즉, 처음에는 bet값이 cash보다 크면 조건문에 걸리지만

다시 한 번 입력받아온 값은 cash보다 커도 조건문이 존재하지 않기 때문에 문제가 발생하지 않는다. 

 

3. 풀이

문제 지문에 적혀있듯이, flag는 백만 달러가 되면 얻을 수 있다.

그렇기 때문에 betting함수의 결함을 이용해서, 1000000 이상의 값을 두 번 입력하면 flag획득이 가능하다.

 

4. flag 획득.


Bye~~ (* ̄3 ̄)╭

728x90

'War game > pwnable.kr' 카테고리의 다른 글

[pwnable] uaf 풀이  (1) 2022.03.21
[pwnable] lotto 풀이  (0) 2022.03.17
[pwnable] coin1 풀이  (0) 2022.03.11
[pwnable] cmd2 풀이  (0) 2022.02.21
[pwnable] cmd1 풀이  (0) 2022.02.20
Comments