Wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.
이번 포스트에서는 type_confusion 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.
이번에는 생각해보면 간단한 문제이면서, 생각만으로는 어려운 문제입니다.
여기서는 JSON의 타입 오류를 이용하여 풀어야 합니다.
|
문제 이해 |
문제는 다음과 같습니다.
문제를 보면, 단순 비교하는 문제라고 나타나 있습니다.
문제를 들어가면 view-source가 나오고, 입력창이 있습니다.
일단 view-source를 보도록 합시다.
<?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; } ?> <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>
위의 소스에서 php 영역보다는 html 영역 먼저 살펴보도록 해야 합니다.
일단 submit을 했을 경우 submit_check() 함수를 onsubmit()함수로 실행하는 것을 볼 수 있습니다.
submit_check() 함수를 찾아보려는데, 위의 소스에는 없는 것 같습니다.
잘 보면 29번 라인에 같은 디렉토리에 util.js 파일이 있는 것을 볼 수 있습니다.
해당 파일을 살펴보면 다음과 같습니다.
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; }); }
위의 소스에서 submit_check() 함수와 submit() 함수가 있는 것을 볼 수 있습니다.
분석해보니, 우리가 입력받은 값(정확히는 POST로 전송받은 값)을 submit_check의 변수인 f로 받게 되고,
이 값이 존재하는지 먼저 체크하고, 존재한다면 submit 함수로 보내게 됩니다.
그리고 submit 함수에서는 우리가 입력받은 값을 json으로 인코딩하여,
{key: 입력받은 값}과 같은 형태로 처음 우리가 열었던 index.php 파일로 전송하게 됩니다.
값을 전달받은 index.php 파일은 우리가 입력한 값과 임의로 생성한 문자열 값이 동일한지 확인하게 됩니다.
sha1으로 해쉬화하여 전송하기 때문에 같은지 다른지 알 길이 없지요...
그렇다면 우리가 입력한 값이 무엇이든 문자열과 비교하게 된다는 것을 알 수 있습니다.
이 부분은 타입 에러에서 살펴보도록 해야 할 것 같습니다.
|
문제 풀이 |
여러 타입과 관련하여 PHP에서는 위와 같은 리턴 값을 가지고 있습니다.
우리는 문자열과 비교하여 어떤 값이 참을 내뱉는지 살펴보도록 해야 할 것 같습니다.
위의 표에서 문자열은 "php"라고 써두었습니다.
"php"와 true, 0, 그리고 동일한 문자열일 경우에는 참을 리턴하는군요.
그렇다면 이제 참을 리턴할 수 있도록 값을 전송하도록 합시다.
입력 창에서 true를 입력하면, "true" 라는 문자열이 전송되기 때문에 저는 fiddler로 값을 따로 입력해주었습니다.
0 값도 시도해보았으나 true를 뱉지 않더라구요..
phptester.net에서 그냥 테스트를 해봤는데, true일 경우는 문자열과 일치하는 결과를 보여주지만, 0일 경우에는 일치하지 않는다는 결과를 보여주는군요. 저 표가 잘못된 건 아니지만, 0과 hash 값을 비교했을 때는 어째서인지 false를 뱉어냅니다.
|
phptester에서 알아낸 내용 |
no를 뱉어내는 문자열
9b38360c57ba1a4688527cd4d9f58e3deaacccb6
7363e885238bb05b960a6f02c8bf464f7f413502
yes를 뱉어내는 문자열
e8cea42b73ba481a854368ad4827ec577c783059
beee587d9273f7570541e1ef2769a4d56cec4027
위의 두 종류의 해쉬는 문자열로 먼저 시작했는지, 숫자로 먼저 시작했는지에 따라 0과 비교했을 때 true 혹은 false로 나뉘어지는 것 같습니다.
제아무리 문자열이라고 하더라도 숫자로 먼저 시작할 경우에는 0과 비교할 때 false인 것 같습니다.
이는 atoi와 비슷한 형태를 보여준다고 합니다.
'WARGAMES > wargame.kr' 카테고리의 다른 글
[Wargame.kr] Level 16 - web_chatting (0) | 2019.05.16 |
---|---|
[Wargame.kr] Level 15 - easy_crackme(IDA) (0) | 2019.05.15 |
[Wargame.kr] Level 14 - php? c? (0) | 2019.05.15 |
[Wargame.kr] Level 13 - img recovery (2) | 2019.05.01 |
[Wargame.kr] Level 11 - tmitter (0) | 2019.04.30 |
[Wargame.kr] Level 10 - md5_compare (0) | 2019.04.10 |
[Wargame.kr] Level 09 - strcmp (0) | 2019.04.10 |
[Wargame.kr] Level 08 - db_is_really_good (0) | 2019.04.09 |