Wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 img recovery 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번에는 생각해보면 간단한 문제이면서, 관련 프로그램을 이용하여 풀어야 하더군요.

문제를 풀어보도록 하겠습니다.




 

 문제 이해


문제는 다음과 같습니다.

PNG 파일인가, 스테가노그래피, 포렌식 도전 이라고 나오는데...

일단 스테가노그래피의 일종이라는 것은 알 것 같습니다.


아래의 그림을 보면 코드를 찾으라고 나오는데, 


아무래도 배경이 수상합니다.

마치 QR 코드 같이 생겼습니다.

소스에서 보면 같은 디렉토리 위치에 pattern.png라는 파일이 있는 것을 확인할 수 있습니다.


혹은 개발자도구로도 다음과 같이 확인할 수 있습니다.

이제 문제를 풀어보도록 하겠습니다.




 

 문제 풀이


Hex Editor로 열어보면 맨 아래에 tExtSoftware.Japng 라고 나와있습니다.

이 프로그램을 다운로드 받아 열어보면 다음과 같이 두 개의 PNG 파일이 나오게 됩니다.


이제 이 파일을 Export 해서 사용해보도록 합시다~


위의 두 그림을 PPT로 옮겨서 투명도를 조작한 후 온전한 QR코드로 만들어보았습니다.


하는 방법은 다음과 같습니다.


[정사각형 도형 그리기] -> [채우기] -> [그림 또는 질감 채우기] -> [파일 선택 후 PNG 파일 선택] -> [투명도 하나만 50%하여 겹치기]

그냥 끌어다가 투명도를 조절하려고 하지 마세요. 안 돼요 ㅠㅠ


QR 코드를 읽으면 WHAT!@#$? 라는 값이 나오게 됩니다.


이 코드를 입력하면 플래그가 나오게 됩니다.



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와 비슷한 형태를 보여준다고 합니다.




wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 tmitter 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번에는 생각해보면 간단한 문제인데, 저는 삽질로 풀었습니다.

사실 답을 알고나서 하하하 했습니다 ㅋㅋㅋㅋ



 

 문제 이해


문제는 다음과 같습니다.


위의 문제에서 tmitter_user에 대한 테이블 정보가 있었네요.

그거도 모르고 헛짓을 하고 있었네요.


두 가지나.. ㅎㅎ


먼저 사용자 계정 정보가 id 32글자, pw 32글자로 이루어져 있습니다.

이를 이용한 취약점이 존재하지만, 저는 다른 방법으로 먼저 풀이를 진행하도록 하겠습니다.



저는 먼저 계정을 만들어 들어갔습니다.


간단하게 하나 만들고 Sign in을 하고 들어갔더니 다음과 같이 입력창이 나타나 있었습니다.


여기에 값을 입력하거나 다른 사람이 값을 입력한 것이 들어가 있는 것을 볼 수 있었습니다.

그래서 그냥 단순히 우리가 입력한 값이 Insert SQL 문일 것이라고 판단했습니다.




 

 문제 풀이 - insert 문 이용



그러면 어디에 어떻게 입력된 것인지 Insert 문에 몇 개의 요소로 몇 가지가 있을 것인지 추측하기 위해 별 걸 다 넣어봤습니다.


결론은 다음과 같은 값을 넣었을 때 값이 들어가지는 것을 볼 수 있었습니다.


your text', 'some string')# 

위의 값을 넣었을 때 아마 다음과 같은 결과가 나타났을 것 같습니다.


insert into table_name values(idx, 'id value', 'your input value', 'something value')# some values)


그렇다면 저 뒤에 값을 더 넣어서, admin으로 계정 정보를 바꾼다면 어떻게 될까 살펴봤습니다.


다음과 같은 값을 넣으니 admin으로 값이 입력된 것처럼 바꼈습니다.


tmeet=1','2'),(0,'admin','I am admin!! hahaahahahahahaha','4');#



제 아이디로 들어간 값이 tmeet=1 이라는 문자열이 들어가고,

idx에 0이라는 값을 대충 입력하고, id value 쪽에는 admin을 입력하고, 값을 입력하니,

마치 admin이 입력한 값인 것처럼 입력되었습니다.


아마 계정 이름이 admin이면 admin인 것으로 그림이 바뀌는 것 같습니다.


이제 여기를 이용해서 schema 이름 가져오고, table 이름 가져오고, column 이름을 가져왔습니다.


 

 schema 이름 가져오기


tmeet=1','2'),(0,'admin',(select table_schema from information_schema.tables where table_name='tmitter_tmeets'),'4');#

결과 : tmitter



 

 table 이름 가져오기


tmeet=1','2'),(0,'admin',(select table_name from information_schema.columns where column_name='ps'),'4');#

결과 : tmitter_user



 

 column 이름 가져오기

tmeet=1','2'),(0,'admin',(select column_name from information_schema.columns where table_name='tmitter_user' limit 0,1),'4');#

tmeet=1','2'),(0,'admin',(select column_name from information_schema.columns where table_name='tmitter_user' limit 1,1),'4');#

tmeet=1','2'),(0,'admin',(select column_name from information_schema.columns where table_name='tmitter_user' limit 2,1),'4');#

결과 : 각각 idx, id, ps



 

 admin 아이디의 비밀번호 알아내기


tmeet=1','2'),(0,'admin',(select ps from tmitter.tmitter_user where id='admin'),'4');#

결과 : iD0nTkn0wpassw0rd..!!



저는 위의 비밀번호로 이걸로 로그인해서 들어갔습니다.





 

 문제 풀이 - 정석


admin으로 로그인하려는데, 이미 회원가입이 되어 있다고 합니다.

일단 테스트로 계정을 하나 만들어서 비밀번호를 바꿔봤더니, join에서 비밀번호가 특정 방법을 통해 변하는 것을 확인했습니다.


방법은 다음과 같습니다.


admin의 경우 회원가입 페이지에 32글자가 넘어가게 되면 php에서는 admin과 다른 글자로 알아먹지만,

mysql은 32글자만 받아들여, admin으로 인식하게 됩니다.


이로 인해 join 페이지를 통해 admin의 비밀번호를 바꿀 수 있게 되고,

여기서 admin의 비밀번호를 7글자 1234567로 변하게 됩니다.


바뀐 비밀번호를 통해 로그인하게 되면 정답이 나타나게 됩니다.


wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 md5_compare 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번에는 생각해보면 간단한 문제이면서, 생각만으로는 어려운 문제입니다.

즉, 어려운 이유는 기존에 알려진 취약점을 알아야 하기 때문입니다.


그래도 만약 md5에 대한 취약점을 안다면, 큰 어려움은 없으니 풀어보도록 합시다.



 

 문제 이해


문제는 다음과 같습니다.


위의 문제에서는 단순히 값을 비교를 한다고 합니다.


문제로 들어가 소스를 확인해보았습니다.

<?php
    if (isset($_GET['view-source'])) {
         show_source(__FILE__);
         exit();
    }

    if (isset($_GET['v1']) && isset($_GET['v2'])) {
        sleep(3); // anti brute force

        $chk = true;
        $v1 = $_GET['v1'];
        $v2 = $_GET['v2'];

        if (!ctype_alpha($v1)) {$chk = false;}
        if (!is_numeric($v2) ) {$chk = false;}
        if (md5($v1) != md5($v2)) {$chk = false;}

        if ($chk){
            include("../lib.php");
            echo "Congratulations! FLAG is : ".auth_code("md5_compare");
        } else {
            echo "Wrong...";
        }
    }
?>
<br />
<form method="GET">
    VALUE 1 : <input type="text" name="v1" /><br />
    VALUE 2 : <input type="text" name="v2" /><br />
    <input type="submit" value="chk" />
</form>
<br />
<a href="?view-source">view-source</a>


14, 15번 라인을 보게되면, 문자인지 숫자인지 확인합니다.


14번 라인은 문자열이면 참을 반환하는 ctype_alpha() 함수를 이용하여 문자열인지 비교하고, 

15번 라인은 숫자값이면 참을 반환하는 is_numeric() 함수를 이용하여 숫자값인지 비교합니다.


그리고 문자열과 숫자값이 적절하게 들어간 두 값을 각각 md5() 함수로 암호화를하여 비교합니다.

만약 비교가 정상적이라면 Flag를 토해냅니다.


이제 문제를 풀어보도록 합시다.




 

 문제 풀이


일단 이번 문제를 풀기 앞서 md5의 취약점을 보도록 합시다.


 

 md5 취약점(md5에서 나타날 수 있는 취약점)


PHP의 md5함수는 다음과 같은 취약점을 가지고 있습니다.


만약 md5 함수를 이용하여 나온 해쉬값이 0e로 시작하여 뒤의 값이 모두 숫자인 경우, 다음과 같은 결과값으로 바뀌게 됩니다.


0e462097431906509019562988736854 ==> 0.0 ==> 0


이렇게 되면 숫자 0으로 인식하게 됩니다.


이러한 해쉬를 매직해쉬라고도 하는데, md5는 잘 알려진 매직해쉬가 2개가 있습니다.


문자열로만 이루어진 매직해쉬 : QNKCDZO

숫자로만 이루어진 매직해쉬 : 240610708


이 두 값을 비교하여 검사를 해보면 다음과 같습니다.

그렇다면 이제 이 값들을 이용하여 문제를 풀어보도록 합시다.


앙!




wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 strcmp 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번 문제도 어려움이 많았습니다. 이번 문제는 SQL 뿐만 아니라 PHP와 웹에 대한 이해가 필요합니다.


마음을 다잡고 문제를 풀어보도록 합시다.



 

 문제 이해


문제는 다음과 같습니다.


문제에서는 strcmp 함수의 취약점을 이용하여 우회 후, 플래그를 가져가라는 메시지가 작성되어 있습니다.

앙, 문제를 풀면서 strcmp 취약점에 대해 찾아봐야겠습니다.


문제로 들어가 소스를 확인해보았습니다.

<?php
    require("../lib.php"); // for auth_code function

    $password = sha1(md5(rand().file_get_contents("/var/lib/dummy_file")).rand());

    if (isset($_GET['view-source'])) {
        show_source(__FILE__);
        exit();
    }else if(isset($_POST['password'])){
        sleep(1); // do not brute force!
        if (strcmp($_POST['password'], $password) == 0) {
            echo "Congratulations! Flag is <b>" . auth_code("strcmp") ."</b>";
            exit();
        } else {
            echo "Wrong password..";
        }
    }

?>
<br />
<br />
<form method="POST">
    password : <input type="text" name="password" /> <input type="submit" value="chk">
</form>
<br />
<a href="?view-source">view-source</a>


4번 라인에서는 $password 값에 엄청나게 반복적으로 암호화를 수행한 것이 보입니다.

이렇게 해놓은 것으로 보아 password에 특정한 값을 넣어 때려맞추는 것은 불가능할 것 같습니다.


11번 라인에서는 strcmp 함수를 통해 비교한 값의 결과가 0이 리턴될 때 문제가 풀리도록 되어 있습니다.


이제 문제를 풀어봐야겠습니다.




 

 문제 풀이


일단 이번 문제를 풀기 앞서 strcmp에 대한 취약점을 찾아보도록 합시다.


 

 PHP strcmp 취약점


먼저 strcmp에 대한 이해가 먼저일 것 같습니다.


strcmp 함수는 두 개의 문자열을 비교하여 값을 리턴하는 구조입니다.


예시 : strcmp($a, $b);

(1) 만약 두 문자열의 값이 일치하면 0을 반환

(2) 만약 $a 값이 크면 양수를 반환

(3) 만약 $b 값이 크면 음수를 반환


그러나 PHP의 strcmp 함수는 문자열 두 개 중 하나가 배열일 경우 무조건 0을 반환한다는 취약점을 가지고 있습니다.


다음과 같은 테스트코드를 통해 시험을 해보실 수 있으실 것입니다.

<?php

$a = Array("a");
$b = "pass";

if(strcmp($a, $b)==0)
  echo "Strings are same !";
else
  echo "Strings are different!!";
?>


여기서 결과는 다음과 같습니다.


WARNING strcmp() expects parameter 1 to be string, array given on line number 6

Strings are same ! 


그렇다면 이제 POST 혹은 GET 방식으로 배열을 넘겨주게 되면 취약점으로 인해 우회가 가능할 것으로 보입니다.




 

 위의 기법을 응용한 문제풀이


위의 기법을 응요하기 위해서는 POST와 GET 방식으로 어떻게 배열을 보낼 수 있는지 알아봐야 합니다.

배열 값을 보내기 위해서는 다음과 같은 방법으로 보낼 수 있습니다.


GET : http://example.com/?value1[]='something'&value2[]='something'

POST : value1[]='something'&value2[]='something'


이제 값을 넘겨주도록 합시다.






wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 db_is_really_good 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번 문제는 DB에 대한 이해와 파일 다운로드 취약성이 있는 곳을 찾아볼 수 있어야 합니다.

DB에 어떤 값을 넣어야 터지는지에 대한 학습을 쭈욱 하고, 따라오시는 것을 추천합니다.



 

 문제 이해


문제는 다음과 같습니다.


문제에서는 어떤 데이터베이스 종류인지, 물어보기도 합니다.

여기서 user name과 database 내에서 값을 얻을 수 있다고 힌트를 주고 있습니다.


이제 한 번 문제로 들어가보도록 합시다.



문제에는 user라는 입력란과, 로그인 버튼이 있습니다.

힌트에서 user라는 곳에서 답을 얻을 수 있다고 했으니 별의 별 걸 다 넣어봤습니다.


일단 admin은 안 되네요.


일단 aa를 입력하고 로그인이 되어 들어가보았습니다.

위에는 입력창이 있고 write와 logout 버튼이 있습니다.

각각 입력, 로그아웃 버튼입니다.


아래의 그림을 보아하니 누가 또 열심히 때려밖아본 흔적이 보입니다.


별의 별 걸 다 입력해보았는데, 변하는 것이 없었습니다.



 

 문제 풀이


이번 문제는 역시나 user 영역에서 답을 구할 수 있었습니다.


SQL Injection은 아니었습니다. 다만, 다른 방향의 Injection입니다.

이는 일종의 개발자의 설계 실수가 있었다는 가정하에 만든 문제 같았습니다.



 

 특별한 결과가 돌아오는 값들


이번 문제에서 . 과 /를 넣었을 때의 결과가 달랐습니다.


만약 .을 넣게 되면 _로 바뀌게 되고, /를 넣게 되면 Fatal Error가 발생했습니다.

일단 .을 넣게 됐을 때의 반응은 별다른 의미는 없어보이고, Fatal Error에서 좋은 힌트를 얻을 수 있었습니다.


위와 같은 Fatal Error가 있습니다.


에러 내용을 쭉 살펴보니, open() 함수에서 에러가 발생한 것을 볼 수 있습니다.

우리가 입력한 값이 /이기 때문에 /가 들어간 곳이 어디인지 살펴보면 wkrm_ 와 .db 사이에 /가 부자연스럽게 들어가 있는 것을 볼 수 있습니다.

아마 wkrm_.db 파일이겠구나 싶어 다운로드를 해봅니다.


다운로드를 마치고 SQLite Expert Personal 프로그램으로 내용을 살펴보니 별 거 없었습니다.


아 링크, http://www.sqliteexpert.com/


그리고, /db 디렉토리가 디렉토리 리스팅 취약점으로 인해 모두 보이는 것을 확인할 수 있었습니다.



보아하니, wkrm_ + '우리가 입력한 값' + .db로 파일이 생성되는 것이며, 그 db에 값이 입력되는 것이라고 볼 수 있을 것 같습니다.

그렇다면, 우리가 입력하지 못했던 값이 admin입니다.


admin을 뒤에 붙인 파일을 찾아 다운로드 해보도록 합시다.



잡았다 요놈..




wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 md5_password 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번 문제에서는 모르면 못 푸는 문제가 아닌가 싶습니다. ㅎㅎ...


그래도 큰 어려움은 없으니 풀어보도록 합시다.



 

 문제 이해


문제는 다음과 같습니다.

문제에서 md5('value', true)라고 나옵니다.

PHP의 md5 함수에서는 뒤에 boolean 옵션이 있습니다. 이 옵션은 기본적으로 false가 되어 있는데, 어째서인지 문제에서는 true로 작성해두었습니다.


문제로 들어가 소스를 확인해보았습니다.

<?php
 if (isset($_GET['view-source'])) {
  show_source(__FILE__);
  exit();
 }

 if(isset($_POST['ps'])){
  sleep(1);
  mysql_connect("localhost","md5_password","md5_password_pz");
  mysql_select_db("md5_password");
  mysql_query("set names utf8");
  /*
  
  create table admin_password(
   password char(64) unique
  );
  
  */

  include "../lib.php"; // include for auth_code function.
  $key=auth_code("md5 password");
  $ps = mysql_real_escape_string($_POST['ps']);
  $row=@mysql_fetch_array(mysql_query("select * from admin_password where password='".md5($ps,true)."'"));
  if(isset($row[0])){
   echo "hello admin!"."<br />";
   echo "Password : ".$key;
  }else{
   echo "wrong..";
  }
 }
?>
<style>
 input[type=text] {width:200px;}
</style>
<br />
<br />
<form method="post" action="./index.php">
password : <input type="text" name="ps" /><input type="submit" value="login" />
</form>
<div><a href='?view-source'>get source</a></div>


22번 라인에서는 싱글쿼터 우회를 방지하기 위해 real_escape가 걸려 있는 것을 볼 수 있습니다.

단, 23번 라인에서 우리가 입력한 값이 md5 함수에 들어가고 옵션이 true가 되어 있는 것을 볼 수 있습니다.

이 문제를 풀기 앞서 이 문제는 2010년에 플로리다 대학교에서 열린 Leet More CTF2010의 문제 중 하나입니다.


해당 참고 링크입니다.


http://cvk.posthaven.com/sql-injection-with-raw-md5-hashes




 

 문제 풀이


일단 이번 문제를 풀기 앞서 md5함수의 이해와 MySQL의 우회 방법에 대해 이해해야 합니다.


 

 md5('value', true) 이해


PHP의 md5함수의 bool 옵션은 기본적으로 false가 되어 있으나, true로 바뀔 경우 다음과 같은 변화가 있습니다.


md5('abcd', false) ==> e2fc714c4727ee9395f324cd2e7f331f

md5('abcd', true) ==> ��qLG'�$�.3


원래는 false의 경우처럼 hex로 된 값을 string으로 변환하여 반환해주는데, true 옵션을 넣어주게 되면, e2fc714c4727ee9395f324cd2e7f331f  hex값이 그대로 binary 형태로 보이게 됩니다. 


이해를 돕기 위해 다음과 같이 설명드리겠습니다.



 

 MySQL 우회


MySQL에서는 정상적인 조건문을 넣게 되면 당연하게도 정상적이게 실행됩니다.

select * from testtable where pw='abcd';


그러나 MySQL에서 만약 다음과 같이 조건문이 들어가게 되면 어떻게 되는지 알아보도록 하겠습니다.

select * from testtable where pw='abcd'='qwer';


이렇게 실행하게 되면 마치 아래의 쿼리와 같은 행동을 하게 됩니다.

select * from testtable where pw=0;


이는 'abcd'='qwer'이 거짓이기 때문에 0을 반환하게 되는 원리를 이용한 것입니다.


이해가 안 된다면 select 'abcd'='qwer'; 을 실행해보도록 합니다.



혹은 등호 말고도 or를 이용할 수도 있습니다.

select * from testtable where pw='abcd'or'1';


단 or 뒤에는 숫자가 나와야 합니다!!


이해가 되지 않는다면,

select 'adcd'or'1';

select 'abcd'or'a'; 

select 'abcd'or'1a';

select 'abcd'or'a1';

 각각 입력해보면 어떤 경우에 참인지 거짓인지 알 수 있습니다.




 

 위의 기법을 응용한 문제풀이


이제 위의 기법을 응용하여 문제를 풀어보도록 하겠습니다.

만약, md5() 해쉬로 나온 값에서 273d27 라는 값을 중간에 품고 있다면?


즉, 0x273d27 라는 값은 '=' 값입니다.


위의 값이 hash 중간에 들어가 있다면, binary를 그대로 출력해줄 때 ~~1~'='~~2~ 의 형태가 되게 됩니다.


그 말은 즉, select * from admin_password where password='~~1~'='~~2~' 의 형태로 쿼리가 만들어지게 되고, MySQL 우회 기법과 마찬가지로 문제가 풀리게 된다는 의미입니다.


이에 해당하는 값은 사실 브루트포싱을 통해 알아내야 합니다.


그런데 알아내는데 시간이 너무 오래걸립니다... ㅠㅠ


그래서 일단 저는 기존의 풀이대로 129581926211651571912466741651878684928 를 값으로 입력하였습니다.   


wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 fly_to_the_moon 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번 문제에서는 앞서 소개드렸던 문제들보다 보다 추가적인 이해가 요구됩니다.


그래도 큰 어려움은 없으니 차근차근 설명해보도록 하겠습니다.



 

 문제 이해


문제는 다음과 같습니다.


문제에서는 javascript game이며, clear를 하거나 우회를하여 클리어하라고 말합니다.

저는 시간이 남아돌아서 게임좀 해보려는데 겁나 어렵더군요....


게임을 하다보면, 아래의 스코어와 재시작 버튼이 있는 것을 알 수 있습니다.

31337 스코어까지 어떻게 올리지... 하지 말고 fiddler를 켜서 문제를 살펴보도록 합시다.



 

 문제 풀이


문제에서 POST 데이터로 token과 score를 보내는 것을 볼 수 있습니다.

token은 주기적으로 바뀌는 인증데이터로 보이고, score는 우리가 조작해야 하는 값입니다.


그러나 아래와 같이 유효하지 않은 token을 가지고 score를 전송하면 토큰 에러를 뱉어냅니다.


토큰은 주기적으로 GET 메소드 형태로 응답이 돌아오게 됩니다.


때문에 토큰이 도착했다! 싶으면 바로 거기에 맞춰서 POST 형태의 데이터를 조작하여 보내주도록 합니다.



이로 인해 문제가 풀리게 됩니다.



wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 WTF_CODE 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


근데, 문제 풀이의 이해는 딱히 없는 것 같고, 풀이만 있을 것 같습니다.


이 문제는 그냥 패킷 캡처 툴 혹은 프록시 툴을 다룰줄 아느냐에 대한 문제 같습니다.


 

 문제 이해


문제는 다음과 같습니다.


문제에서는 이것은 새로운 형태의 프로그래밍 언어라며, 이 코드를 읽을 수 있는지에 대해 물어보고 있습니다.

대체 무슨 코드길래...


문제 사이트에 들어가 source_code.ws를 다운받으니 다음과 같은 코드가 보입니다.


이를 보아하니 난독화 기법으로 작성된 코드의 일종으로 보입니다.


ws 확장자가 뭔지 알아봐야겠습니다.



 

 문제 풀이


ws 확장자는 따로 없는 것 같고, 아마 whitespace 의 약자가 아닌가 싶습니다.

구글링을 통해 whitespace 언어 혹은 whitespace code decoder 라고 작성해보았습니다.

해당 페이지에 들어가 코드를 붙여넣고 [Run]을 해보니 문제가 풀렸습니다.




+ Recent posts