본문 바로가기

보안공부/XCZ 풀이

xcz.kr 18번 문제 풀이 - 보내고 받고

XCZ.KR PROB 18 풀이

[ 보내고 받고 ]


오늘은 XCZ.KR의 18번 문제를 풀어보자.

매우 친절하게도 이 페이지의 소스를 볼 수 있게 해두었다.

그래서 열어보면 다음과 같이 나온다.

위의 코드는 다음과 같다.

<html> 
<head> 
<link rel="shortcut icon" href="../images/favicon.ico" type="image/x-icon"> 
<title>Prob18</title> 
</head> 
<body style="background-image:url('../images/content-tail.gif');"> 
<b>Title</b></br> 
<i>Comming Soon</i></br></br> 
<b>Description</b></br> 
<font size="2px"> 
View source</br> 
<? 
$key = "Congratulations!</br>Key is ??????????????????"; 
$liillillilliliili = @$_COOKIE['c']; 
$liillillliiiliili = @$_GET['g']; 
$lilllillliiiliili = @$_POST['p']; 
if(empty($liillillilliliili) || empty($liillillliiiliili) || empty($lilllillliiiliili)){exit ('wrong T.T');} 
$lililillliiiliili = $liillillliiiliili . $liillillilliliili; 
$lilililliiiiliill = $lilllillliiiliili; 

function test($a){ 
$b = ''; 
    for($i=0; $i < strlen($a); $i++){ 
        $b = $b . ' - ' . ord(substr($a,$i,1)); 
    } 
    return $b; 
} 
if(test($lililillliiiliili)==" - 103 - 105 - 118 - 101 - 109 - 101 - 112 - 97 - 115 - 115 - 119 - 111 - 114 - 100" || test($lilililliiiiliill) == " - 107 - 101 - 121 - 112 - 108 - 122 - 33"){ 
    echo $key; 
} 
else{ 
    echo 'wrong T.T'; 
} 
?>
</font> 
</body> 
</html>


이 코드의 변수명을 보면 절로 한숨이 나온다.


그러니 이 변수명을 다른 이름으로 대입하고 실질적으로 사이트가 돌아가는 백엔드인 PHP부분만 떼면 다음과 같다.

<? 
    $key = "Congratulations!</br>Key is ??????????????????"; 
    $A = @$_COOKIE['c'];
    $B = @$_GET['g']; 
    $C = @$_POST['p'];
    if(empty($A) || empty($B) || empty($C)){exit ('wrong T.T');}
    $D = $B . $A;
    $E = $C;
    function test($a){ 
        $b = ''; 
        for($i=0; $i < strlen($a); $i++){ 
            $b = $b . ' - ' . ord(substr($a,$i,1)); 
        } 
        return $b; 
    }
    if(test($D)==" - 103 - 105 - 118 - 101 - 109 - 101 - 112 - 97 - 115 - 115 - 119 - 111 - 114 - 100" || test($E) == " - 107 - 101 - 121 - 112 - 108 - 122 - 33"){ 
        echo $key; 
    } 
    else{ 
        echo 'wrong T.T'; 
    }
?>

그럼 이제 이 코드를 한줄한줄 분석해보자.


c라는 쿠키의 값을 받아와 $A에 대입해준다.

$A = @$_COOKIE['c']; 

GET 메소드를 통해 받은 g값을 $B에 대입해준다.

$B = @$_GET['g']; 

POST 메소드를 통해 받은 p값을 $C에 대입해준다.

$C = @$_POST['p'];

만약 $A, $B, $C 세 값중 하나라도 비어있으면 wrong T.T 를 띄워주며 코드 실행을 멈춘다.

if(empty($A) || empty($B) || empty($C)){exit ('wrong T.T');}

$B와 $A의 문자열을 합친값을 $D에 대입해준다.

$D = $B . $A;

$C값을 $E값으로 대입해준다.

$E = $C;

문자열을 넣으면 1글자 단위로 잘라 아스키코드로 만들고 ' - '로 이어붙혀 리턴해주는 함수를 선언해준다.

function test($a){ 
    $b = ''; 
    for($i=0; $i < strlen($a); $i++){ 
        $b = $b . ' - ' . ord(substr($a,$i,1)); 
} return $b; }

test함수를 거친 $D 값이 - 103 - 105 - 118 - 101 - 109 - 101 - 112 - 97 - 115 - 115 - 119 - 111 - 114 - 100이고, $E 값이 - 107 - 101 - 121 - 112 - 108 - 122 - 33라면 플래그를 출력

if(test($D)==" - 103 - 105 - 118 - 101 - 109 - 101 - 112 - 97 - 115 - 115 - 119 - 111 - 114 - 100" || test($E) == " - 107 - 101 - 121 - 112 - 108 - 122 - 33"){ 
    echo $key; 
}

위 조건문이 성립하지 않으면 wrong T.T를 출력

else{ 
    echo 'wrong T.T'; 
}


$D값이 아스키로 - 103 - 105 - 118 - 101 - 109 - 101 - 112 - 97 - 115 - 115 - 119 - 111 - 114 - 100 (givemepassword), $E값이 - 107 - 101 - 121 - 112 - 108 - 122 - 33 (keyplz!) 가 되어야 한다.


$D값은 $B와 $A의 문자열을 합친것이기 때문에, $B의 값 바로 다음에 $A를 이어 붙혔을 때 $D와 같은 값이 나온다면 성립한다.

따라서 $D를 두조각 내어 $B와 $A에 각각 넣을때 어디서 자를지는 본인이 결정하면 된다.


나는 단어 단위로 두조각 내어 문제를 해결해보겠다.


플래그값을 얻기 위해서는

$_GET['g'] = 'giveme';

$_COOKIE['c'] = 'password';

$_POST['p'] = 'keyplz!';

가 되어야 한다.


GET 메소드로 g값을 전송하자.

우리가 자주 봤고, 알다시피 get을 사용하는법은 매우 간단하다.

해당 링크 주소 뒤에 ?변수명=값의 형태로 사용할 수 있다.


따라서 우리는 이 문제의 링크 뒤에 ?g=giveme를 추가한다.


쿠키 c를 만들어주자.

크롬에는 EditThisCookie라는 확장프로그램이 있는데, 이 확장프로그램을 이용하여 넣어주면 편하다.

이 확장프로그램을 이요하여 c값을 넣어주면 다음과 같다.


POST 메소드로 p를 전송하자.

이 페이지에는 따로 form이 없으니 js를 통해 폼을 만들어 전송하자.


우선 F12를 눌러 개발자 도구를 열고, Console 탭에 들어가자.


구글링을 하던 도중, POST 과정을 쉽게 해주는 함수를 발견했다.

function post_to_url(path, params, method) {
    method = method || "post"; // Set method to post by default, if not specified.
    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);
    for(var key in params) {
        var hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", key);
        hiddenField.setAttribute("value", params[key]);
        form.appendChild(hiddenField);
    }
    document.body.appendChild(form);
    form.submit();
}

이제 위 코드를 이용하여 쿼리를 전송하자.

post_to_url('http://xcz.kr/START/prob/prob18.php?g=giveme', {'p':'keyplz!'});

이제 이 쿼리를 전송해주면 플래그가 나오게 된다.



XCZ.KR 18번 문제 클리어!