오랜만에 모의해킹에 관심이 생겨 웹해킹 공부도 할겸 문제를 하나 풀어보기로 했다.

일단 사이트를 들어가서 문제를 보면 해당 페이지가 나오는데...

 

아무것도 없으니 일단 페이지 소스를 보기로 했다. 

<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 26</title>
<style type="text/css">
body { background:black; color:white; font-size:10pt; }    
a { color:lightgreen; }
</style>
</head>
<body>
<?php
  if(preg_match("/admin/",$_GET['id'])) { echo"no!"; exit(); }
  $_GET['id'] = urldecode($_GET['id']);
  if($_GET['id'] == "admin"){
    solve(26);
  }
?>
<br><br>
<a href=?view_source=1>view-source</a>
</body>
</html>

 

해당 소스를 분석을 해보면 중요한 부분을 볼 수 있는데 아래의 부분 인 것 같다. 

<?php
  if(preg_match("/admin/",$_GET['id'])) { echo"no!"; exit(); }
  $_GET['id'] = urldecode($_GET['id']);
  if($_GET['id'] == "admin"){
    solve(26);
  }

 

사실 PHP를 제대로 공부해본 적이 없어서 구글링을 통해 함수들을 검색해서 찾아보았다, 

 

찾아본 바에 의하면 대략 Preg_match  라는 함수는 현재 정규표현식을 사용해서 문자열을 찾는 함수라고 한다

그렇다면 아래의 코드를 해석해볼 수 있다,

if(preg_match("/admin/",$_GET['id'])) { echo"no!"; exit(); }

 

보면은 서버에서 GET 방식으로 Id를 받아오는데 Id 값이 admin과 일치하게 된다면 no를 출력하고 종료되는것 같다,

그래서 url을 입력해보았다. 

 

 

예상대로 해당 구문이 실행되어서 no를 출력하고 종료되는 것을 볼 수 있다, 

그럼 만약에 id 값이 admin이 아니게 된다면 어떨지 궁금해졌다. 

아래의 코드를 보면 어떻게 동작하는지 알 수 있을거 같다.

$_GET['id'] = urldecode($_GET['id']);
  if($_GET['id'] == "admin"){
    solve(26);

 

현재 GET으로 받아온 id를 urldecode 함수를 통해서 저장을 하는데..

urldecode가 무엇인지 잘 몰라서 구글링을 통해 찾아보니 url 인코딩 된 값을 디코딩을 하는 함수라고 한다.

그럼 해석을 해보자면,  인코딩된 id 값을 디코딩 하는데 여기서 인코딩 된 값이 admin이라면??

urldecode에서 디코딩한 결과가 admin이 될것이고 그럼  $GET[ 'id' ] 값이 admin이 될 것이다.

 

그렇다는 말은 solve함수를 실행한다는 말이 된다. 그래서 한번 admin을 인코딩한 값을 넣어보았다.

61%64%6D%69%6E -> url 인코딩 표를 보고 인코딩 하였다.

 

 

???? 같은 화면이 나온다...??

admin을 인코딩한 값인 %61%64%6D%69%6E를 넣었음에도 불구하고 URL이 admin으로 id 값이 들어가 있다. 

그렇다는 말은 preg_match 구문이 실행되고 바로 종료되었다는 이야기가 된다.

 

PHP는 GET 방식과 REQUEST 방식은 서버측에서 값을 전달받을때, 자동으로 한번 디코딩이 된다고 한다.

그말인 즉슨  %61%64%6D%69%6E이 값을 한번 자체적으로 한번 디코딩을 했다는 말이 된다,

그래서 preg_match 함수가 실행되고 종료된것 같다. 

 

그럼 이것을 어떻게 해결할 수 있을끼..?

자동적으로 디코딩을 한번 했다고 하니 그럼 인코딩을 2번 하게 된다면?

자동적으로 한번 디코딩을 하고 난 뒤 urldecode 함수가 실행되어 한번 더 디코딩이 될것이다.

그렇게 되면 아래의 코드를 실행 시킬 수 있을 것이다.

if($_GET['id'] == "admin"){
    solve(26);
  }

 

만약 생각한대로 실행이 된다면 뭔가 값을 찾을 수 있지 않을까 생각해본다.

따라서 한번더 url 인코딩을 해보았다. 

%2561%2564%256D%2569%256E

 

 

문제가 해결되었다. 

확실히 웹해킹 문제들은 PHP의 취약점을 찾는 문제들이 많이 나오는 것 같다.

웹 언어는 제대로 공부를 해본적이 많이 없어서 개념을 많이 몰라서 시간이 오래걸렸던 것 같다. 

PHP 공부를 해봐야 할 것 같다. 그럼 쉬워지지 않을려나 

 

그럼 20000~~~~

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - strcmp  (0) 2021.02.26
Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11

 

 

패스워드 입력창이 나오는데 소스를 보기로 했다.

 

<?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>

 

여기서 중요하게 살펴볼것은 

 

if (strcmp($_POST['password'], $password) == 0) {
            echo "Congratulations! Flag is <b>" . auth_code("strcmp") ."</b>";

 

password 값과 일치 하면 congratulations 라는 말과 함께 플래그를 넘겨준다.

 

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

 

$password값은 랜덤함수 돌린 값을 md5 해쉬암호화를 한 후, sha1 해쉬 암호화를 더 한다.

이 암호를 맞추는 것은 사실상 불가능하며 strcmp 우회를 해야 한다.

php stcmp 문자열 비교 함수는 strcmp($a, $b)에서 두 값이 같으면 0을 반환하며, $a가 작으면 음수값을, 크면 양수값을 반환한다

 

여기서 핵심은 두 문자열이 같을 때 0을 반환한다.

하지만 strcmp 함수는 문자열과 배열을 비교했을때도 NULL을 반환한다.

그리고 문자열과 배열을 비교하게되면 무조건 0을 반환한다. 

그럼 배열형태로 바꿔주면 되지  않을까?

 

/var/lib/dummy_file에서 password를 랜덤으로 가져오는데 입력값이 password와 같아야 한다. => 0을 반환하면 됨

 

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

 

여기서 password를 배열형태로 바꿔주었다.

 

 password : <input type="text" name="password[]" /> <input type="submit" value="chk">

 

아무값이나 입력해줘도 이미 password는 배열로 선언을 해주었기 때문에 항상 0을 반환할것이다.

그러면 플래그 값이 나올것이다.

 

Congratulations! Flag is ace988be45c213cd4575884d30007cd25370010b

 

성공

'CTF > WebHacking' 카테고리의 다른 글

WebHacking.kr old-26  (0) 2024.01.28
Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11

 

javascript game 이라고 한다.

그럼 여기서 개발자 도구에서 무언가가 있음을 예측할 수 있다.

 

 

게임이 나오는데 게임을 실행해보면 아래와 같은 화면이 나오는데

 

 

31337을 넘으면 키값을 준다고 한다. 

게임으로는 절대 못넘을거 같으니 일단 개발자도구를 실행해보자 

 

<script>
eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('76 58=["\\89\\66\\68\\68\\154\\68\\67\\92\\59\\71","\\70\\74\\59\\70\\89\\136\\66\\86\\59","\\81\\59\\63\\118\\70\\61\\71\\59","\\124\\66\\64\\70\\118\\70\\61\\71\\59","\\69\\74\\71\\66\\64\\89\\98\\78\\64\\64\\59\\68","\\97\\66\\84\\63\\74\\98\\78\\64\\64\\59\\68","\\61\\104\\148\\59\\70\\63","\\159\\61\\90\\70\\74\\59\\67\\63\\66\\64\\81\\155\\90\\66\\86\\90\\92\\61\\78\\90\\70\\67\\64","\\97\\67\\71\\64","\\61\\86\\86\\69\\59\\63\\136\\59\\86\\63","\\63\\78\\64\\64\\59\\68","\\81\\59\\63\\170\\68\\59\\85\\59\\64\\63\\124\\92\\142\\84","\\63\\61\\77","","\\77\\112","\\70\\69\\69","\\84\\66\\69\\77\\68\\67\\92","\\104\\68\\61\\70\\89","\\59\\67\\70\\74","\\66\\85\\81\\107\\68\\59\\86\\63\\111\\97\\67\\68\\68","\\66\\85\\81\\107\\71\\66\\81\\74\\63\\111\\97\\67\\68\\68","\\91\\74\\66\\81\\74\\111\\69\\70\\61\\71\\59\\69","\\71\\59\\85\\61\\103\\59","\\63\\67\\104\\68\\59","\\64\\61\\64\\59","\\84\\66\\103\\91\\69\\70\\61\\71\\59\\111\\63\\67\\104\\68\\59","\\70\\68\\66\\70\\89","\\63\\59\\112\\63","\\69\\77\\67\\64\\91\\69\\70\\61\\71\\59","\\68\\59\\86\\63","\\66\\85\\81\\91\\69\\74\\66\\77","\\69\\68\\61\\97","\\86\\67\\84\\59\\142\\64","\\104\\67\\70\\89\\81\\71\\61\\78\\64\\84\\149\\77\\61\\69\\66\\63\\66\\61\\64","\\168\\167\\164\\90","\\84\\66\\103\\91\\63\\78\\64\\64\\59\\68","\\71\\67\\64\\84\\61\\85","\\86\\68\\61\\61\\71","\\78\\77\\84\\67\\63\\59\\98\\78\\64\\64\\59\\68\\143\\150","\\86\\67\\84\\59\\151\\78\\63","\\154\\151\\118\\98","\\74\\66\\81\\74\\149\\69\\70\\61\\71\\59\\69\\107\\77\\74\\77","\\63\\61\\89\\59\\64\\146","\\169\\69\\70\\61\\71\\59\\146","\\67\\148\\67\\112","\\74\\63\\85\\68","\\77\\91\\97\\59\\68\\70\\61\\85\\59","\\78\\77\\84\\67\\63\\59\\98\\61\\89\\59\\64\\143\\150","\\63\\74\\112\\155\\90\\152\\74\\71\\66\\69\\63\\66\\67\\64\\90\\145\\61\\64\\63\\61\\92\\67","\\85\\61\\78\\69\\59\\61\\103\\59\\71","\\91\\70\\74\\71\\66\\69\\63\\66\\67\\64","\\85\\61\\78\\69\\59\\61\\78\\63","\\71\\59\\67\\84\\92","\\152\\74\\71\\66\\69\\63\\66\\67\\64\\90\\145\\61\\64\\63\\61\\92\\67","\\77\\67\\81\\59\\175","\\85\\61\\78\\69\\59\\85\\61\\103\\59","\\63\\61\\89\\59\\64\\107\\77\\74\\77","\\81\\59\\63"];62 119(){76 174=73;76 108=93;62 141(){108=173;79 93};62 130(){79 108};73[58[0]]=62(){141();79 93};73[58[1]]=62(){79 130()};76 116=0;62 131(){79 116};62 133(){72(108){116++};79 93};73[58[2]]=62(){79 131()};73[58[3]]=62(){133();79 93};76 123=161;62 138(){123-=20;79 93};62 144(){79 123};73[58[4]]=62(){138();79 93};73[58[5]]=62(){79 144()}};76 95=0;76 110=0;76 134=125;76 75=117;76 94=117;76 101=0;76 102=0;76 99=0;76 96=0;82=106 127(20);88=106 127(20);62 153(){87=106 119();72(58[6]==135 105){105[58[8]](58[7])};110=121[58[11]](58[10])[58[9]];134+=110;65=0;122(65=0;65<20;65++){82[65]=80;88[65]=137};$(58[19])[58[18]](62(83){65=83*25;$(73)[58[15]](58[12],58[13]+65+58[14]);$(73)[58[15]](58[16],58[17])});$(58[20])[58[18]](62(83){65=83*25;$(73)[58[15]](58[12],58[13]+65+58[14]);$(73)[58[15]](58[16],58[17])});$(58[25])[58[26]](62(){$(58[23])[58[22]](58[21]);$(58[25])[58[15]](58[16],58[24]);132();114()})};62 132(){87=106 119();72(58[6]==135 105){105[58[8]](58[7])};75=117;101=0;102=0;99=0;$(58[28])[58[27]](58[13]+0);$(58[30])[58[15]](58[29],75+58[14]);65=0;122(65=0;65<20;65++){82[65]=80;88[65]=137};$(58[30])[58[32]](58[31]);$(58[19])[58[18]](62(83){65=83*25;$(73)[58[15]](58[12],58[13]+65+58[14]);$(73)[58[15]](58[16],58[17])});$(58[20])[58[18]](62(83){65=83*25;$(73)[58[15]](58[12],58[13]+65+58[14]);$(73)[58[15]](58[16],58[17])})};62 114(){95=95+2;72(95>20){95=0};$(58[35])[58[15]](58[33],58[34]+95+58[14]);72(75+32<125){72(75+46<94){75+=4}109{72(75+16<94){75+=2}}};72(75>0){72(75-14>94){75-=4}109{72(75+16>94){75-=2}}};$(58[30])[58[15]](58[29],75+58[14]);102++;72(102>60){102=0;96=126[58[37]](126[58[36]]()*2)};72(82[0]<10){96=1}109{72(88[0]>166){96=0}};65=0;122(65=20;65>0;65--){82[65]=82[65-1];88[65]=88[65-1]};72(96==0){82[0]-=3};72(96==1){82[0]+=3};88[0]=82[0]+87[58[5]]();$(58[19])[58[18]](62(83){$(73)[58[15]](58[29],58[13]+82[83]+58[14])});$(58[20])[58[18]](62(83){$(73)[58[15]](58[29],58[13]+88[83]+58[14])});72(87[58[5]]()>=120){99++;72(99>100){99=0;87[58[4]]();82[0]+=10}};101++;72(101>20){101=0;87.165();$(58[28])[58[27]](58[13]+87[58[2]]())};72(75<=82[18]+20||75+32>=88[18]){87[58[0]]()};72(87[58[1]]()){158(58[38],10)}109{$(58[30])[58[39]](58[31]);$(58[19])[58[15]](58[16],58[24]);$(58[20])[58[15]](58[16],58[24]);$[58[44]]({171:58[40],156:58[41],162:58[42]+115+58[43]+87[58[2]](),157:62(113){147(113)}})}};62 160(){79};62 147(113){$(58[25])[58[45]](113);$(58[25])[58[15]](58[16],58[17])};$(121)[58[52]](62(){$(58[46])[58[15]](58[16],58[17]);140();163(58[47],172);$(58[46])[58[26]](62(){$(58[46])[58[15]](58[16],58[24]);153();114()});$(58[50])[58[49]](62(){$(73)[58[45]](58[48])});$(58[50])[58[51]](62(){$(73)[58[45]](139)})});76 139=58[53];$(121)[58[55]](62(129){94=129[58[54]]-110});76 115=58[13];62 140(){$[58[57]](58[56],62(128){115=128})};',10,176,'||||||||||||||||||||||||||||||||||||||||||||||||||||||||||_0x32bb|x65||x6F|function|x74|x6E|y|x69|x61|x6C|x73|x63|x72|if|this|x68|ship_x|var|x70|x75|return||x67|left_wall|_0x8618x16|x64|x6D|x66|BTunnelGame|right_wall|x6B|x20|x23|x79|true|pos_x|bg_val|t_state|x77|x54|c_w||c_s|c_r|x76|x62|console|new|x2E|_0x8618x3|else|rail_left|x5F|x78|_0x8618x19|updateTunnel|token|_0x8618x6|234|x53|secureGame||document|for|_0x8618x9|x42|500|Math|Array|_0x8618x20|_0x8618x1d|_0x8618x5|_0x8618x7|restartTunnel|_0x8618x8|rail_right|typeof|x4C|400|_0x8618xa|temp|updateToken|_0x8618x4|x49|x28|_0x8618xb|x4D|x3D|showHighScores|x6A|x2D|x29|x4F|x43|initTunnel|x50|x2C|url|success|setTimeout|x44|scoreUpdate|320|data|setInterval|x25|BincScore|470|x30|x35|x26|x45|type|10000|false|_0x8618x2|x58'.split('|'),0,{}))
</script>
  

 

javascript 난독화 코드인것 같다.

beautifier.io/ -> 난독화 코드를 정상적인 코드로 해독해서 보여준다고 한다.

그래서 들어가서 코드를 분석 해보았다.

 

function secureGame() {
    var _0x8618x2 = this;
    var _0x8618x3 = true;

    function _0x8618x4() {
        _0x8618x3 = false;
        return true
    };

    function _0x8618x5() {
        return _0x8618x3
    };
    this['killPlayer'] = function() {
        _0x8618x4();
        return true
    };
    this['checkLife'] = function() {
        return _0x8618x5()
    };
    var _0x8618x6 = 0;

    function _0x8618x7() {
        return _0x8618x6
    };

    function _0x8618x8() {
        if (_0x8618x3) {
            _0x8618x6++
        };
        return true
    };
    this['getScore'] = function() {
        return _0x8618x7()
    };
    this['BincScore'] = function() {
        _0x8618x8();
        return true
    };
    var _0x8618x9 = 320;

    function _0x8618xa() {
        _0x8618x9 -= 20;
        return true
    };

    function _0x8618xb() {
        return _0x8618x9
    };
    this['shrinkTunnel'] = function() {
        _0x8618xa();
        return true
    };
    this['widthTunnel'] = function() {
        return _0x8618xb()
    }
};
var bg_val = 0;
var rail_left = 0;
var rail_right = 500;
var ship_x = 234;
var pos_x = 234;
var c_s = 0;
var c_r = 0;
var c_w = 0;
var t_state = 0;
left_wall = new Array(20);
right_wall = new Array(20);

function initTunnel() {
    BTunnelGame = new secureGame();
    if ('object' == typeof console) {
        console['warn']('Do cheating, if you can')
    };
    rail_left = document['getElementById']('tunnel')['offsetLeft'];
    rail_right += rail_left;
    y = 0;
    for (y = 0; y < 20; y++) {
        left_wall[y] = 80;
        right_wall[y] = 400
    };
    $('img.left_wall')['each'](function(_0x8618x16) {
        y = _0x8618x16 * 25;
        $(this)['css']('top', '' + y + 'px');
        $(this)['css']('display', 'block')
    });
    $('img.right_wall')['each'](function(_0x8618x16) {
        y = _0x8618x16 * 25;
        $(this)['css']('top', '' + y + 'px');
        $(this)['css']('display', 'block')
    });
    $('div#score_table')['click'](function() {
        $('table')['remove']('#high_scores');
        $('div#score_table')['css']('display', 'none');
        restartTunnel();
        updateTunnel()
    })
};

function restartTunnel() {
    BTunnelGame = new secureGame();
    if ('object' == typeof console) {
        console['warn']('Do cheating, if you can')
    };
    ship_x = 234;
    c_s = 0;
    c_r = 0;
    c_w = 0;
    $('span#score')['text']('' + 0);
    $('img#ship')['css']('left', ship_x + 'px');
    y = 0;
    for (y = 0; y < 20; y++) {
        left_wall[y] = 80;
        right_wall[y] = 400
    };
    $('img#ship')['fadeIn']('slow');
    $('img.left_wall')['each'](function(_0x8618x16) {
        y = _0x8618x16 * 25;
        $(this)['css']('top', '' + y + 'px');
        $(this)['css']('display', 'block')
    });
    $('img.right_wall')['each'](function(_0x8618x16) {
        y = _0x8618x16 * 25;
        $(this)['css']('top', '' + y + 'px');
        $(this)['css']('display', 'block')
    })
};

function updateTunnel() {
    bg_val = bg_val + 2;
    if (bg_val > 20) {
        bg_val = 0
    };
    $('div#tunnel')['css']('background-position', '50% ' + bg_val + 'px');
    if (ship_x + 32 < 500) {
        if (ship_x + 46 < pos_x) {
            ship_x += 4
        } else {
            if (ship_x + 16 < pos_x) {
                ship_x += 2
            }
        }
    };
    if (ship_x > 0) {
        if (ship_x - 14 > pos_x) {
            ship_x -= 4
        } else {
            if (ship_x + 16 > pos_x) {
                ship_x -= 2
            }
        }
    };
    $('img#ship')['css']('left', ship_x + 'px');
    c_r++;
    if (c_r > 60) {
        c_r = 0;
        t_state = Math['floor'](Math['random']() * 2)
    };
    if (left_wall[0] < 10) {
        t_state = 1
    } else {
        if (right_wall[0] > 470) {
            t_state = 0
        }
    };
    y = 0;
    for (y = 20; y > 0; y--) {
        left_wall[y] = left_wall[y - 1];
        right_wall[y] = right_wall[y - 1]
    };
    if (t_state == 0) {
        left_wall[0] -= 3
    };
    if (t_state == 1) {
        left_wall[0] += 3
    };
    right_wall[0] = left_wall[0] + BTunnelGame['widthTunnel']();
    $('img.left_wall')['each'](function(_0x8618x16) {
        $(this)['css']('left', '' + left_wall[_0x8618x16] + 'px')
    });
    $('img.right_wall')['each'](function(_0x8618x16) {
        $(this)['css']('left', '' + right_wall[_0x8618x16] + 'px')
    });
    if (BTunnelGame['widthTunnel']() >= 120) {
        c_w++;
        if (c_w > 100) {
            c_w = 0;
            BTunnelGame['shrinkTunnel']();
            left_wall[0] += 10
        }
    };
    c_s++;
    if (c_s > 20) {
        c_s = 0;
        BTunnelGame.BincScore();
        $('span#score')['text']('' + BTunnelGame['getScore']())
    };
    if (ship_x <= left_wall[18] + 20 || ship_x + 32 >= right_wall[18]) {
        BTunnelGame['killPlayer']()
    };
    if (BTunnelGame['checkLife']()) {
        setTimeout('updateTunnel()', 10)
    } else {
        $('img#ship')['fadeOut']('slow');
        $('img.left_wall')['css']('display', 'none');
        $('img.right_wall')['css']('display', 'none');
        $['ajax']({
            type: 'POST',
            url: 'high-scores.php',
            data: 'token=' + token + '&score=' + BTunnelGame['getScore'](),
            success: function(_0x8618x19) {
                showHighScores(_0x8618x19)
            }
        })
    }
};

function scoreUpdate() {
    return
};

function showHighScores(_0x8618x19) {
    $('div#score_table')['html'](_0x8618x19);
    $('div#score_table')['css']('display', 'block')
};
$(document)['ready'](function() {
    $('p#welcome')['css']('display', 'block');
    updateToken();
    setInterval('updateToken()', 10000);
    $('p#welcome')['click'](function() {
        $('p#welcome')['css']('display', 'none');
        initTunnel();
        updateTunnel()
    });
    $('#christian')['mouseover'](function() {
        $(this)['html']('thx, Christian Montoya')
    });
    $('#christian')['mouseout'](function() {
        $(this)['html'](temp)
    })
});
var temp = 'Christian Montoya';
$(document)['mousemove'](function(_0x8618x1d) {
    pos_x = _0x8618x1d['pageX'] - rail_left
});
var token = '';

function updateToken() {
    $['get']('token.php', function(_0x8618x20) {
        token = _0x8618x20
    })
};

 

여기서 알아보야야 할게 이부분인데 

 

this['checkLife'] = function() {
        return _0x8618x5()
    };
    var _0x8618x6 = 0;

    function _0x8618x7() {
        return _0x8618x6
    };

    function _0x8618x8() {
        if (_0x8618x3) {
            _0x8618x6++
        };
        return true
    };
    this['getScore'] = function() {
        return _0x8618x7()
    };
    this['BincScore'] = function() {
        _0x8618x8();
        return true
    };
    var _0x8618x9 = 320;

 

이것을 복사해서 콘솔창에다가 실행을 시켜보면 덮어쓰기를 해서 실행이 될것이다.

 

this['checkLife'] = function() {
        return _0x8618x5()
    };
    var _0x8618x6 = 40000;

    function _0x8618x7() {
        return _0x8618x6
    };

 

여기서 31337보다 높으면 key가 나오니까 40000으로 하고 콘솔에서 실행을 해봤다.

 

 

성공

'CTF > WebHacking' 카테고리의 다른 글

WebHacking.kr old-26  (0) 2024.01.28
Wargame.kr - strcmp  (0) 2021.02.26
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11

 

소스코드를 읽을 수 있는가??

실행을 시켜 보았다. 

 

 

소스코드 파일이 보여서 다운로드를 해서 보기로 했다.

아무것도 안보여서 확인 해보니 공백으로 구분되어있다.

 

 

???? -> 일단 확장자가 ws라서 = 처음보는 확장자 

그래서 확장자명으로 어떤 프로그램인지 찾아보기로 하고 구글링을 했더니

 

 

Whitespace Programming Language라고한다. 

아마도 이것의 줄임말로 확장자를 ws라고 하지 않았을까

블로그를 들어가보니 온라인으로 컴파일이 가능한곳이 있다고 한다.

ideone.com/

 

Ideone.com

Ideone is something more than a pastebin; it's an online compiler and debugging tool which allows to compile and run code online in more than 40 programming languages.

ideone.com

 

여기서 아까 봤었던 공백문자 == ws 파일을 컴파일 해보면??

 

wow key is 31b25937d25e(생략)e 

 

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - strcmp  (0) 2021.02.26
Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11
Wargame.kr - flee button  (0) 2021.02.11

 

by-pass를 하는 문제인것 같은데 우회하라는 뜻인가?

일단 들어가보았다.

 

 

아무런 표시 없이 로그인 창이 나오게 되는데

ID 와 PW를 알아보기 위해서 get_source를 들어가서 페이지 소스를 보았다.

 

 

소스파일을 볼 수 있는데 여기서 봐야될것이 몇가지 있다.

 

you have blocked accounts.

guest / guest
blueh4g / blueh4g1234ps

 

block이 되어있는 것 같지만 한번 로그인을 시도해봤다.

 

 

예상했지만 block되었다고 메세지를 표시해준다.

그럼 소스코드를 다시 살펴보자 

 

 <?php

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

/*
create table user(
 idx int auto_increment primary key,
 id char(32),
 ps char(32)
);
*/

 if(isset($_POST['id']) && isset($_POST['ps'])){
  include("../lib.php"); # include for auth_code function.

  mysql_connect("localhost","login_filtering","login_filtering_pz");
  mysql_select_db ("login_filtering");
  mysql_query("set names utf8");

  $key = auth_code("login filtering");

  $id = mysql_real_escape_string(trim($_POST['id']));
  $ps = mysql_real_escape_string(trim($_POST['ps']));

  $row=mysql_fetch_array(mysql_query("select * from user where id='$id' and ps=md5('$ps')"));

  if(isset($row['id'])){
   if($id=='guest' || $id=='blueh4g'){
    echo "your account is blocked";
   }else{
    echo "login ok"."<br />";
    echo "Password : ".$key;
   }
  }else{
   echo "wrong..";
  }
 }
?>
<!DOCTYPE html>
<style>
 * {margin:0; padding:0;}
 body {background-color:#ddd;}
 #mdiv {width:200px; text-align:center; margin:50px auto;}
 input[type=text],input[type=[password] {width:100px;}
 td {text-align:center;}
</style>
<body>
<form method="post" action="./">
<div id="mdiv">
<table>
<tr><td>ID</td><td><input type="text" name="id" /></td></tr>
<tr><td>PW</td><td><input type="password" name="ps" /></td></tr>
<tr><td colspan="2"><input type="submit" value="login" /></td></tr>
</table>
 <div><a href='?view-source'>get source</a></div>
</form>
</div>
</body>
<!--

you have blocked accounts.

guest / guest
blueh4g / blueh4g1234ps

 

mysql구문을 이야기하는것 같다. (mysql은 한번도 공부해본적이 없어서 잘은 모른다.)

 

1. POST 방식으로 입력받은 id ,ps 값이 존재하는지 확인

2. mysql_real_escape_string_trim 함수를 이용해서 공백문자와 특수문자를 제외하여 SQL injection을 방지한다.

3. id 값을 확인하고 guest or blue4g이면 block 

4. id 값이 3이 아니면 OK를 출력하고 MD5으로 인코딩된 FLAG를 보여준다.  

5. id 값이 아무것도 없으면 Worng을 출력 

 

guest / guest
blueh4g / blueh4g1234ps

 

 

분명히 else문을 이용해서 다른 값을 입력했는데도 wrong이 출력된다.

그럼 소스코드안의 if문의 필터링을 우회해보기로 했다.

$key를 사용해서 로그인 필터링으로 값을 구분했던것 같다.

 

if($id=='guest' || $id=='blueh4g'){                   /* id 값이 guest or blueh4g 이면 블락된 상태 */
    echo "your account is blocked";
 }else{
    echo "login ok"."<br />";                               /* id 값이 guest or blueh4g 만 아니면 성공 */
    echo "Password : ".$key;
 }

 

 

쿼리 자체는 대소문자를 구별하지 않는다.

그래서 Guest로 로그인을 해보았다. -> 나중에 알았지만 PHP는 대소문자를 구분하지 않는다고 한다.

 

 

필터링은 php에서 하고있다. 

그래서 Guest를 입력하고 pw = guest를 입력하면 쿼리에서는 대소문자를 구분하지 않기 때문에

서로 같은 값이라고 인식을 하여 key를 내어준다.

 

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11
Wargame.kr - flee button  (0) 2021.02.11
Wargame.kr - already got  (0) 2021.02.11

접속을 해보니 QR코드가 나왔다.

어떠한 정보를 담고 있는듯 한데 하나 하나 맟추는것도 방법이겠다. (어느세월에...???)

개발자도구를 사용해서 소스코드를 분석 해보았다.

보통 웹에서 어떠한 동작이나 이벤트들은 자바스크립트로 작성된 경우가 많다고 한다.

 

/*<![CDATA[*/
 $(function(){ $('#join_img').attr('src',unescape('.%2f%69%6d%67%2f%71%72%2e%70%6e%67'));
  $('#join_img').jqPuzzle({rows:6,cols:6,shuffle:true,numbers:false,control:false,style:{overlap:false}});
  hide_pz();});
 function hide_pz(){
  var pz=$('#join_img div'); if(pz[pz.length-2]){$(pz[1]).remove();$(pz[pz.length-2]).remove();}else{setTimeout("hide_pz()",5);}
 }
/*]]>*/

 

이미지의 id 값을 src로 사용을 하는것 처럼 보이는데 unescape가 뭔지 모르겠다 .

구글링을 하는것도 방법이겠지만 직접 콘솔에 입력을 해보았다.

 

$unescape('.%2f%69%6d%67%2f%71%72%2e%70%6e%67');
"./img/qr.png"

 

이미지를 사용하는것을 확인 할 수 있다.

unescape를 이용해서 QR코드의 정보를 해독하는것 같다.

 

QR 코드(영어: QR code, Quick Response code)은 흑백 격자무늬 패턴으로 정보를 나타내는 매트릭스 형식의 이차원 코드이다. 비슷한 용도로 먼저 사용된 이 차원 코드로는 바코드가 있다. 바코드는 이름 그대로 단순한 막대기 모양의 바를 이차원으로 나열한 것이다 - Wiki pedia

 

Url에 해당 이미지를 입력하면 온전한 QR코드가 나오지 않을까? 

 

 

정상적으로 나오는데 이 QR코드의 내용을 확인 할 수 있다면??

휴대폰으로 찍어도 되지 않을까 -> 사실 이 방법도 있긴한데 안해봤다.

 

온라인 디코더를 이용해서 QR코드를 확인을 했다.

 

 

해당 URL 주소로 이동을 해보니 플래그가 나왔다.

 

성공!!

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - flee button  (0) 2021.02.11
Wargame.kr - already got  (0) 2021.02.11

flee button = 도망가는 버튼??

일단 시작을 해보았다.

 

 

버튼을 클릭하기위해서 마우스를 움직여보면 버튼도 같이 움직인다 

결국 클릭을 못하게 해두었다는건데 그래서 개발자도구를 켜서 안의 소스코드를 확인해 보았다.

 

 

버튼의 클릭과 관련된 소스코드를 찾았다.

그래서 이걸 콘솔에서 실행을 시켜주면???

 

window.location='?key=7263';

 

성공

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11
Wargame.kr - already got  (0) 2021.02.11

 

Start 버튼을 클릭해서 시작을 해보니 

 

 

이미 키를 받았다고 한다. (????)

개발자 도구를 사용하기로 했다.

 

 

플래그를 쉽게 확인할 수 있었다.

 

 

성공

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11
Wargame.kr - flee button  (0) 2021.02.11

+ Recent posts