1. 코드 분석
일단 해당 문제의 코드를 보면 DB나 별도의 저장을 하지 않고 if문의 비교만 뚫으면 매우 쉬운 문제이다.
다른 파일은 상관없고 가장 유심히 봐야 할 파일은 check.php 파일이다.
php 파일 부분을 보게 되면, 일단 index.php에서 입력받은 id와 password 를 받아서
POST를 사용하여 check.php로 전송하도록 되어있다.
그리고 check.php 에서는 데이터를 받아서 if문으로 비교하여 만약 통과 된다면 flag.php파일에서 참조하여 가져온 flag를 출력하도록 되어 있다.
2. id 값 알아내기
일단 이 if문을 어떻게 뚫을지 보면, 각각 id와 password를 비교하여 원하는 값과 일치하면 되는 것인데
일단 id를 확인하는 if문이 password if 문을 감싸고 있기에 먼저 id부터 구해보아야 한다.
일단 가져온 id 값을 getRandStr() 함수를 실행하여 값을 넣는데,
해당 함수를 살펴보면 숫자, 영어소문자, 영어대문자를 섞어
숫자가 들어있는 length라는 변수만큼 생성을 한다. (length 가 3이라면 3자리의 문자를 생성함)
하지만 해당 함수 실행 시 length를 정의하는 코드가 없기 때문에 기본값인 10이 들어가서 10자리의 랜덤 문자가 생성된다.
그리고 if 문에서도 id를 10자리가 아니면 걸러내기 때문에 공통점은 있다.
하지만 이 문자열을 알 수 있는 방법은.. 사실 없다. 아예 알 수 있는 코드가 없기 때문에 불가능한 것이다.
하지만 if문에 특이한 게 하나 있다.
(int)?? 이게 붙어 있다.
처음에는 나도 몰랐지만 대충 감으로 $input_id(입력한 id값)을 int(숫자) 형으로 바꿔주는 거라고 생각했다.
하지만 이게 결정적인 취약점이었다.
입력한 값인 $input_id 뿐만 아니라 getRandStr() 함수로 만들어진 문자열이 들어간 $id 값도 int로 비교한다는 것이었다.
이때 (int) 특성이 문자열이면 모든 걸 0으로 처리하고 숫자라면 그대로 숫자를 두는 것이다.
이것을 활용하면 결국 id 값은 0000000000(0*10) 인 것이다.
엄청 쉽게 풀려버렸다.
3. password 값 알아내기
이제 passwrod 코드를 보면 if문에서 $input_pw(입력한 password)가 $pw와 같아야 하고 8 자리인지 검사를 한다.
그리고 $pw의 값은 sha1("1"); 이런 식으로 SHA-1로 숫자 1을 해싱한 문자열을 저장한다.
그렇다면 $pw는 대충 Google에서 'SHA-1 hashing tool'이라고 검색하면 나오는 사이트에서 1을 해싱한 문자열을 가져오면 된다.
그러면 356 a192 b7913 b04 c54574 d18 c28 d46 e6395428 ab라는 값을 얻을 수 있는데,
8자리로 제한해 두었기 때문에, pw는 356a192b 가 된다.
4. flag 알아내기
웹사이트에 적용하게 된다면 이런 식으로 나올 것이다.
id: 0000000000
password: 356a192b
즉, 해당 문제는 if문에서 쓰인 (int)만 잘 인식하고 있으면 매우 쉬운 문제!!
flag는 DH {} 형식이기에
flag는 DH{33f2cac27f2cd193c31ac34b1b8bc99e2fbb731bd8a94c512c17d13dbf80794a} 가 된다.
※ 답을 복사하지 말고 위 글을 이해하여 직접 풀어보세요.