Dreamhack/Dreamhack Wargame (Challenge)

[94] IT 비전공자 [dreamhack]wargame.kr type confusion문제 풀기

imaginefuture-1 2024. 12. 12. 08:48

 

 

 

 

타입 혼란..?

 

 

헤엥

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

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

<html>
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
        <script src="./util.js"></script>
    </head>
    <body>
        <form onsubmit="return submit_check(this);">
            <input type="text" name="key" />
            <input type="submit" value="check" />
        </form>
        <a href="./?view-source">view-source</a>
    </body>
</html>

 

 

소스코드를 확인해 본 결과 사용자로부터 json이라는 이름의 파라미터(Parameter)를 전달 받아서, 그 json 데이터의 'key'라는 데이터가 서버에서의 key 데이터와 동일한 경우 플래그(Flag)를 반환하는 것을 알 수 있습니다.
따라서 사용자가 입력한 데이터가 JSON 형식으로 서버에 전달이 되는 것으로 이해할 수 있을 것입니다.
출처:https://ndb796.tistory.com/337
[안경잡이개발자:티스토리]

 

json 파일을 찾았다. util.js 파일이다

 

개발자도구로 util.js를 보면 submit()으로 서버에서 데이터를 전송하는 방식을 확인할 수 있다.
 
특히, {key: key} 형태인 객체를 JSON.stringify으로 {"key":"key"} 와 같은 문자열 형태로 변환하고 서버에 전송한다.
 
서버에 데이터가 전송될 때, {"key":"true"}로 전송하면 어떨까?
 
json_decode에 의해 {"key":"true"} 에서 {key:true} 으로 바뀐다. 이때 type confusion이 발생하고 true는 더 이상 문자열 type이 아닌 boolean type이 된다.
 
이런 식으로 type confusion을 트리거하여 문제를 해결할 수 있다.

출처ㅣ https://keyme2003.tistory.com/entry/wargamekr-type-confusion

 

원래 코드에서 ==를 확인하자 

if ($json->key == $key) {
        $ret = ["code" => true, "flag" => $FLAG];
    } else {
        $ret = ["code" => false];
    }

https://imaginefuture-1.tistory.com/109

 

[68] IT 비전공자 [dreamhack][wargame.kr] strcmp문제 풀기

" . $FLAG .""; exit(); } else { echo "Wrong password.."; } }?> password : view-source do not brute force! 브루트포스는 막혔다.   `strcmp` 함수는 두 문자열을 비교하는 함수로, 두 문자열이 동일한지 여부를 비

imaginefuture-1.tistory.com

느슨한 비교다, 저번에 문제 풀었던 것이다. 즉 같은 값이 아니더라도, true값이 나오는 경우다

 

"=="로 비교하는 경우에는 값이 같지 않더라도 결과가 true로 인식이 되는 경우가 있다.
[true == 문자열] 인 경우도 "=="로 비교할 경우에는 결과가 true가 된다.
 
즉, json→key로 true를 보낼 수만 있다면 if문 조건을 참으로 만들 수 있다.


출처ㅣ 
https://keyme2003.tistory.com/entry/wargamekr-type-confusion

 

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;
}

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;
	});
}

 

여기 소스코드에서 function submit(key)코드에서

data : {json:JSON.stringify({key: key})}

요걸 아래로 바꿔줄꺼다

data : {json:JSON.stringify({key: true})}

 

1) util.js의 submit 함수를 조작해서 서버로 전송하는 데이터(key의 value)를 true로 바꾼다. 

2) {"key":"true"} 를 서버로 전송하면 {"key":"true"}는 디코딩되고 {key:true}로 바뀐다. 이때, true는 type confusion이 발생하여 문자열이 아닌 boolean으로 취급된다. 

3) if문에서 "=="로 느슨한 비교를 하고 있으므로 true == "문자열" 형태를 조건이 완성되면서 참이된다.

출처 ㅣ https://keyme2003.tistory.com/entry/wargamekr-type-confusion

 

 

 

 

 

 

플래그가 나왔다!!