CTF 스터디

[pwnable.kr] 12번_blackjack 풀이

dalgorithm 2021. 5. 12. 00:16
728x90

포너블 12번 blackjack 문제를 풀어볼 것이다.

 

블랙잭 게임을 이행을 확인하라고 한다.

일단 서버에 접속하여 문제를 확인해보았다.

 

 

서버에 접속하니 총 3가지의 선택지가 있다.

1번은 게임을 시작하고, 2번은 규칙을 볼 수 있으며, 3번은 나가기이다.

우선 규칙을 알아보기 위해 2를 입력하였다.

 

VLAD의 블랙잭 규칙은 다음과 같다.

1. 나는 게임의 확률에 의문을 제기하면 안된다.

S 이 프로그램은 랜덤으로 카드를 생성한다.

D 만약 너가 진다면, 너는 운이 없는 것이다!

 

2. 각 카드에는 가치가 있다.

S 숫자 카드 1부터 10까지는 그 숫자에 해당하는 값을 유지한다.

D J,Q,K 는 10의 값을 갖는다.

C 에이스 카드는 11의 값을 갖는다.

이 게임의 목표는 값의 합이 21에 도달하는 것이다.

 

3. 처음 두 카드를 다룬 후에는, 당신은 반드시 HIT 또는 STAY 중에 결정해야한다.

S 머무르는 것은 당신을 안전하게 하지만, HITTING은 카드를 추가할 것이다.

딜러와 대립하여 경쟁하고 있기때문에, 당신은 그의 손을 이겨야한다.

하지만 조심해야한다!

D 총합이 21 이상이되면, 당신은 지는 것이다. 하지만 게임을 다시 할 수 있기 때문에 세상이 끝난 것은 아니다.

 

SHC 당신의 결과가 프로그램된 채널과 동일한 폴더에 기록되었다.

 

=> 즉, 받은 카드의 숫자 합이 21보다 작지만 최대한 가까운 사람이 이기는 카드게임이다.

링크에 들어가면 소스코드를 볼수있는데 문제에서 백만장자가 되면 플래그를 볼수 있다고 한다.

 

 

blackjack.c 소스코드를 분석해보았다.

소스코드가 굉장히 긴데, betting 함수가 다뤄진 부분을 자세히 보았다.

 

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

 

bet 변수는 함수 안에서만 쓰이기 위해 지역변수가 아닌 전역변수로 설정이 되어있다.

베팅 함수 내에서 cash 변수는 현재 게임참여자가 가지고 잇는 돈의 액수로,  플레이어가 이기면 cash에 베팅한

bet 변수의 금액만큼 더해지는 구조이다. 반대로 지게 되면 cash에 베팅한 금액만큼 차감될 것이다.

 

하지만 이 함수에서 베팅할 금액을 입력 받는데 가지고 있는 돈보다 많은 양을 입력했을 경우 다시 입력하도록 된다.

반복문이 아니기 때문에 그 값이 그대로 넘어가는 것을 볼 수 있다.

또한,  bet 변수가 음수일 경우가 고려되지 않아있다. 만약 음수를 베팅하여 -10000을 베팅하고 지게되면 결과적으로

더해지게 된다.

 

따라서 두 번째 입력을 받을 때 임의의 betting 값 설정이 가능하다.

flag 얻기 위해서는 100만 달러 이상을 가져야하니 100만 달러를 betting 후 게임에서 이기면 된다.

 

flag 값을 확인하였다.

728x90