Write-up/Web

 

초보 개발자의 일기 (Web)


Created by ch4n3 | You can get 150point!


진짜 초보같은 개발자가 DB를 이용해서 일기를 만들었다고 한다.
CSS하고 DB를 보니까 진짜 초보인가 보다. 

http://chaneyoon.dothome.co.kr/h3x0r.php



위 URL로 들어가면 "초보개발자의 하루"라는 일기 형식의 웹이 나온다.


일기를 보려면 일을 입력해달라고 나오는데... 1~31까지 입력하면 그날의 일기가 나온다. (참고로 하나하나 보면 꽤 재미가 쏠쏠하다 ㄷㄷ)


먼저 소스보기를 통해 소스를 보았다.




<!DOCTYPE html>

<html>

<head>

    <meta charset="UTF-8">

    <title>초보 개발자의 일기</title>

    <script src="./javascript.js"></script>

    <link rel="stylesheet" type="text/css" href="./style.css">

</head>

<body>

<div class="container" align="center">

    <div class="header">

        <br><br><br><br><br>

        <p align="right" style="font-family: 'Noto Sans KR', sans-serif; color: darkgrey;"  class="title">made by ch4n3</p>

        <h1 align="right" style="font-family: 'Noto Sans KR', sans-serif;"  class="title">

            <a href="./index.php" class="title">초보 개발자의 하루</a>

        </h1>

    </div>

    <p>히힛 오늘은 개발 배우기 시작한지 딱 한달되는 날이다! 정말 기분 좋다ㅎㅎ</p>

    <p>개발할 때 마다 일기를 쓰고 있는데 정말 재밌는 것 같다.</p>

    <textarea id="daily" rows="1"></textarea>

    <button type="button" id="submit" value="일기 보기" class="button5">일기보기</button>

    <p>일기를 보려면 일(日)을 입력해주세용~~ (ex. 1)</p><br><br><br>

    <div id="daily_note" class="daily">

        <!-- Vmtkb2NHTXhPWEJqTVRsMVlqTlNabGxXT1VkVVJVWkk= -->

    </div>

</div>

</body>

</html> 



먼저 위의 초록색  <!-- Vmtkb2NHTXhPWEJqTVRsMVlqTlNabGxXT1VkVVJVWkk= --> 이 부분이 눈에 띈다.

base64로 인코딩이 여러번 씌워져있어서 디코딩을 여러번 수행해보았다. 


그 결과 아래와 같은 것이 나왔다.


This_is_not_a_FLAG


... ㅂㄷㅂㄷ


다른것을 살펴보도록하자... 초보 개발자라고 하니 (사실 필자보다 훨 낫긴하지만 ㅠ)


/javascript.js /style.css 가 눈에 띄어서 살펴보았다.


먼저 style.css 에는 크게 특별한게 없었다... 굳이 특별한게 있다고 치면 아래내용?

/* Nice try.. but flag is not in this css file.. */

ㅋㅋㅋㅋㅋ 또 한방먹었다.


이제 javascript.js 를 살펴보면



var isEmpty = function(value){

    if( value == "" || value == null || value == undefined || ( value != null && typeof value == "object" && !Object.keys(value).length ) ){

        return true

    }else{

        return false

    }

};




function daily(e) {

    var daily = document.getElementById("daily").value;

    var query = 'daily=' + daily;

    var http = new XMLHttpRequest();

    var url = "./json.php";

    var params = "daily=" + daily;

    http.open("POST", url, true);

    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");


    http.onreadystatechange = function() {//Call a function when the state changes.

        if(http.readyState == 4 && http.status == 200) {

            var res = http.responseText;

            res = JSON.parse(res);

            if(isEmpty(res[0].daily)) {

                var element = "<br>2016년 1월 " + daily + "일의 일기가 없음 T.T";

            } else {

                var element = "<br>2016년 1월 " + daily + "일" + "<br><br><br>" + res[0].daily;

            }


            document.getElementById("daily_note").innerHTML = element + "<br><br>";

        }

    }

    http.send(params);


}


window.onload = function() {

    document.getElementById("submit").onclick = daily;

};



 



날짜값을 얻어 일기를 띄워주는것 같다.


여기서 다른것은 잘 모르겠고... 사실 잘모른다 ㅠ;


./json.php에 무언가 있을거같아서 들어가 보았다.


아니다 다를까;


[{"daily":null},{"V20xNGFGcDNQVDA9":"Vm0wd2QyUXlVWGxXYTJoV1YwZG9WVll3Wkc5alJsWjBUVl .... "}


많이 생략하였지만 무언가 들어있다.(생략은 필자가 했다.)


daily가 null일 경우 출력해주는 것같다.


하지만 위 isEmpty 함수에 의해 null값이 들어가면 "일기가 없음 T.T"  가 뜨게 되어있으므로 flag값은 아마 일기의 일이 null일때에 숨겨뒀음을 알수 있다.


base64로 다시 풀어보면 아래와 같이 나온다.


flag : heh3_Th4t_w45_f4ke!_Im_sorry


'Write-up > Web' 카테고리의 다른 글

[ch4n3] Strcmp (Web)  (1) 2017.03.08

[ch4n3] Strcmp (Web)

2017. 3. 8. 23:46

Strcmp (Web)


Created by 해커지망생 | You can get 100point!


 



이 문제는 PHP 에서 strcmp 취약점을 이용한 인증 우회 기법을 이용한 문제다.


근데 아니... 저거 404 NOT FOUND뜸 ;; 일단 패스


문제오류가 수정되었다!


  1. No...
  2. <?php
  3. require_once("./flag.php");
  4. $password = mt_rand();
  5. $password2 = $_GET['password2'];
  6. if(@strcmp($password2, $password)==0){
  7. echo "Gooooooooooood! flag is ".$flag;
  8.  
  9. }
  10. else{
  11. echo "No...";
  12. }
  13. show_source("strcmp.php");
  14. ?>


이게 본 문제의 소스다. 들어가면 바로 저 소스가 보인다.


flag를 얻기 위해서는 password와 password2를 strcmp로 비교하여 같다면 flag를 출력하게 되어있고

아니라면 No...를 출력하게 되어있다.


일단 밑과 같이 동작한다.


http://respect.dothome.co.kr/strcmp.php?password2=123

=> No...



여기서 password 파라미터를 GET방식으로 얻는데 (POST로 얻어도 상관없다.)


strcmp 함수의 내용을 살펴보면 아래와 같다.



Description ¶

int strcmp ( string $str1 , string $str2 )


Return Values ¶

Returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal.


strcmp($str1, $str2)에서 $str1이 $str2보다 작으면 음수, 반대로 더 크면 양수, 같으면 0이 반환된다.


문제에서 우리가 password의 값과 같은 값을 password2에 넣으면 0이 반환된다. 하지만 rand함수로.. 랜덤으로 나오겠지;;


그래서 password 값을 모르면서 저 값을 0으로 우회할 방법이 필요하다.


구글에 (Google : strcmp() expects parameter 2 to be string, array given in ) 검색하면 


PHP 버전 5.2, 5.3에서 strcmp에 대한 취약점을 찾을수 있다.


PHP 버전 5.2에서 strcmp(String, Array())을 실행하면 1 or -1을 반환한다. (5.2에서는 Array()를 "Array"라는 문자열로 변환하여 비교한다...)

PHP 버전 5.3에서는 strcmp(String, Array())을 실행하면 NULL 을 반환한다.


예제를 하나 들면


  1. <?php
  2.  
  3. $str1 = 'rand';
  4. $str2 = Array("test");
  5.  
  6. if (strcmp($a, $b) == 0)
  7. echo "good !";
  8. else
  9. echo "bad ....";
  10.  
  11. ?>
  12.  


이 코드를 실행하면 결과는 "good !"이 나온다.


이는 PHP 5.3 버전에서 strcmp 함수 인자값에 문자열이 들어오지 않을 경우 NULL을 반환하는 것에서


발생한 취약점으로 인해 if( NULL==0 ) 에서 NULL==0은 TRUE가 되어 if문이 실행되는것이다. 


여기서 우리는 미리 결과를 봤기 때문에 NULL == 0 의 결과가 TRUE라는 것을 알지만


그러면 결과적으로 NULL은 0 인 것인가 하면... 밑의 비교표를 보면 알 수 있다.



"==" 으로 느슨한 비교를 한 결과


"===" 으로 엄격한 비교를 한 결과


위 두 표를에서 나오듯 느슨한 비교를 할 시에는 NULL이 숫자 0과 같기 때문에 0 == NULL 이 TRUE를 반환하지만 

NULL이 0과 같은 타입이 아니기 때문에 0 === NULL 시에는 FALSE를 얻게 된다.



그러므로 위 취약점이 있는 PHP 버전에서 위 같은 취약점이 생기길 원하지 않을 경우 엄격한 비교인 ===을 사용하거나


비교대상이 Array가 아닌지 확인을 통해 취약점을 해결할수 있다. ( 참고로 PHP 5.5버전도 통한다... 어디까지 되는거여 ㄷㄷ)




어쨋든 .. 그러므로 다시 문제로 돌아와서


password2의 값에 array값을 넣어주면 답이 출력된다.


http://respect.dothome.co.kr/strcmp.php?password2[]


Gooooooooooood! flag is {are_y0u_kn0w_strcmp_bo9?} 

<?php
require_once("./flag.php");
$password mt_rand();
$password2 $_GET['password2'];
if(@
strcmp($password2$password)==0){
  echo 
"Gooooooooooood! flag is ".$flag;

}
else{
  echo 
"No...";
}
show_source("strcmp.php");
?>




flag is {are_y0u_kn0w_strcmp_bo9?}

'Write-up > Web' 카테고리의 다른 글

[ch4n3] 초보 개발자의 일기 (Web)  (0) 2017.03.08

+ Recent posts