이번시간엔 Dreamhack 워게임 문제인 Type c-j 에 대하여 작성해보도록 하겠습니다!
1. 취약점 탐색
1. 우선 페이지는 다음과 같이 이루어져 있습니다. ID 와 Password 를 우회하면 flag 가 나오는 형식같습니다. 그러면 소스코드를 한번 훑어보겠습니다!
2. 일단 check.php 의 코드를 살펴보니 $id , $pw 값을 설정해주는 부분이 있습니다. $id 값은 getRandStr()을 통해 난수의 문자열을 받아오고 , $pw 는 1이라는 문자열을 sha1 암호화를 거친 값을 저장해주는것 같습니다. 그러면 일단 $pw 값은 1을 sha1로 암호화만 시키면 얻을수 있으니 패스워드 값은 알아낸 것입니다.
3. 그 바로밑에 있는 코드를 살펴보시면 "입력하는 값은 id는 10글자 , password는 8글자 여야한다"를 보실수 있습니다. 근데 좀 이상한 부분이 있습니다. $input_id , $input_pw 값은 String 형일텐데 (int) 형으로 변환 시켜서 인증절차를 거치고 있습니다. 보통 언어에선 타입이 다르면 비교가 불가능하지만 PHP에선 느슨한 비교연산자 (==)를 사용하면 편의성을 위해 타입이 달라도 자동으로 형변환을 시켜서 비교를 해버리게 됩니다. 만약 이상태로 비교를 한다면 $id 값과 $pw 값에서 숫자가 있는 부분까지만 인식이 되고 뒤에는 짤리게 됩니다.
가령 $pw = "52dlfo32dw4dwaq" 라 한다면 $pw=52 로 들어가게 되고 , $pw ="da523wq5d4h8nbvd" 라 한다면 $pw=0 으로 들어가게 되는것 입니다. 이러한 느슨한 연산자(==) 를 이용한 취약점을 이용한 방법을 타입 저글링 이라는 해킹 기법으로 불립니다. 그러면 이 점을 이용하면 $id 값이 난수이지만 만약 알파벳으로 시작한다면 결국 $id 값은 0으로 귀결 될 것입니다.
[공격 시나리오]
1. ID 값은 10자리의 a을 대입해보자(ID 첫 시작이 알파벳이라 가정)
>> "aaaaaaaaaaa" 를 넣어도 Int 로 인식하게 되면 0 이 되기때문!
2. SHA1 로 "1" 이라는 문자열을 암호화하여 PW를 알아내자
2. 공격 결과
1. 우선 1을 sha1 로 암호환 값을 얻었다. 만약 느슨한 비교연산자로 인해 이 값이 Int 로 치환된다면 356 이라는 값이 $pw 안에 들어갈 것입니다. 그리고 비밀번호 8자리를 지켜야 하니 '356aaaaa' 를 넣게 되면 356으로 들어가되 8자리를 지켜서 인증절차에 충족하게 됩니다.
2. 아이디: aaaaaaaaaaa , PW:356aaaaa 를 넣어주었습니다.
3. flag 값을 무사히 얻었습니다!
긴 글 읽어주셔서 감사합니다!
'워게임 문제풀이 > Dreamhack' 카테고리의 다른 글
[Dreamhack] XSS Filtering Bypass - Write up (0) | 2024.12.07 |
---|