본문으로 바로가기

BlackJack 취약점 찾기

category 시스템해킹 2020. 5. 22. 15:26
728x90
  • 코드

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

 

Simple Blackjack Program

Replies: 10 Last Post: 09-09-2004, 05:48 AM

cboard.cprogramming.com

 

  • C언어로 코딩된 블랙잭 게임 프로그램이다.
  • 우리는 이 블랙잭 게임에서 부자가 되는 방법을 찾을 것이다.

취약점-1

 

- 우리의 목적은 부자가 되는 것, 그렇다면 우선 코드를 볼때 배팅하는 부분을 분석해보는 것이 좋을 것이다.

int betting() //배팅 금액을 물어보는 함수
{
	printf("\n\nEnter Bet: $");
 	scanf("%d", &bet);
 
 if (bet > cash) // 만약에 배팅금액이 보유금액보다 클경우, 금액 검사를 하는 부분
 {
        printf("\nYou cannot bet more money than you have.");
        printf("\nEnter Bet: ");
        scanf("%d", &bet);
        return bet;
 } else return bet;
} // 배팅함수 종료

이 함수를 보아하니 배팅금액을 보유금액(cash)보다 많이 책정한 경우에 금액을 재 입력하도록 하는 것이다.

그런데 자세히 보니 금액에 대한 검사가 단일검사이다 (반복해서 검사하지 않는다)

그렇다면 한번 실행을 해보자

 

윈도우에서는 컴파일러를 통해서 실행하면 된다.

리눅스는 -> nc pwnable.kr 9009로 접속해서 게임을 진행하면 된다.

 

현재 보유한 cash는 $500이지만 베팅을 $9999달러를 해보았다.

You cannot bet more money than you have.라는 문구가 뜨며 다시 입력을 요청하는데 

무시하고 다시 $9999를 넣어보았다.

다시 $9999를 입력하였을 때는 정상정으로 값이 들어간걸로 표현되어 게임이 진행되었다.

게임에서 승리하고 보유 cash가 내가 베팅한 금액인 9999만큼 증가한것을 알수 있다.

 

취약점-2

 

두번째 부자가 되는 방법이 있다. 이 취약점은 단순히 범위에 관련되어있는데

우선, C언어의 정수 int의 범위가 어떻게 될까?

우리는 베팅하는 값을 정수로 입력하게 된다. 그렇다면 이건은 음수와 양수를 모두 포함하는가?

직접 해보면 알수 있다.

그리고 우리는 음수도 포함되는 signed int라는 것을 알아내었다.(각자 해보세요)

 

그렇다면 signed int의 범위와 무엇을 중점적으로 볼지 알아보겠다.

 

1. signed int 의 범위는 -2,147,483,648 ~ 2,147,483,647  이다

2. 이 범위는 양수의 범위를 벗어나면 음수로, 음수의 범위를 벗어나면 양수로 바뀌어 원형으로 반복되는 범위다.

3. 블랙잭 게임을 보면 플레이어가 선, 딜러가 후 이기때문에 확률상 딜러가 이길 확률이 높다.

 

--> 이것을 보고 알수 있는것은 우리는 저 정수의 범위내에서 딜러에게 지면서 얻어가는게 있어야 하는것이다.

 

파란색 : 양수의 범위 (0 ~ 2,147,483,647)

빨간색 : 음수의 범위 (-2,147,483,648 ~ 0)

 

양수가 0에서 시작해 최대값에 도달하게 되면, 음수의 최대 값부터 다시 0까지 진행하고 다시 음수가 0에 도달하면,

양수가 시작되는 무한 연결고리가 생긴다.

 

그렇다면 가장 빠르게 부자가 되는 방법은 뭐가있을까?

 

블랙잭을 베팅한다 -> 진다 -> 총보유 금액 - 베팅금액

그렇다면?

양의 최대값에서 현 보유 cash를 뺀 값을 음수로 베팅하면 (-양의 최대값 - cash) = 양의 최대 값 결과가 나온다.

즉 -2147483147 정수형의 범위의 최대 값을 넣게 되면....

바로 우리는 stay를 통해 패배를 만든다.

다음게임을 진행하려고 했더니 짜잔!

signed int의 양의 최대 값에 해당하는돈을 얻게 된다!

 

이렇게 두가지의 방법으로 우리는 블랙잭에서 부자가되었다!

728x90