2.21.3 urldecode
urldecode()
urldecode()函数使用参考
http://www.php.net/manual/zh/function.urldecode.php
<?php
if(eregi("hackerDJ",$_GET[id])) {
echo("
not allowed!
");
exit();
}
$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ")
{
echo "
Access granted!
";
echo "
flag
";
}
?>
tips:
eregi — 不区分大小写的正则表达式匹配
int eregi( string $pattern, string $string[, array &$regs] )
本函数和 ereg() 完全相同,只除了在匹配字母字符时忽略大小写的区别。
ereg()函数
int ereg ( string $pattern , string $string [, array &$regs ] )
以区分大小写的方式在 string 中寻找与给定的正则表达式 pattern 所匹配的子串。
如果找到与 pattern 中圆括号内的子模式相匹配的子串并且函数调用给出了第三个参数 regs,则匹配项将被存入 regs 数组中。$regs[1] 包含第一个左圆括号开始的子串,$regs[2] 包含第二个子串,以此类推。$regs[0] 包含整个匹配的字符串。
如果在 string 中找到 pattern 模式的匹配则返回所匹配字符串的长度,如果没有找到匹配或出错则返回 FALSE。如果没有传递入可选参数 regs 或者所匹配的字符串长度为 0,则本函数返回 1。
代码审计需要满足两个条件:1. id里面不能包含字符串“hackerDJ”
2. id经过urldecode()之后等于字符串“hackerDJ”
利用浏览器默认对提交的数据进行一次url解码
所以对“hackerDJ”二次编码
payload:
二次urldecode注入
示例代码:
<?php
$a = addslashes($_GET['p']);
$b = urldecode($a);
echo '$a= '.$a;
echo '<br / >';
echo '$b= '.$b;
?>
以此代码为例,本来使用了魔术引号的方法,直接提交将会出现单引号

但因为进行了urldecode解码就导致了二次注入问题

成功绕过..
DocCms漏洞分析
代码分析
在/content/search/index.php中,首先对参数keyword进行非法字符检测,
<?php
//首页搜索,站内关键字搜索
function index()
{
global $db;
global $request;
global $params;
global $tag; // 标签数组
!checkSqlStr($request['keyword'])? $request['keyword'] = $request['keyword'] : exit('非法字符');
$keyword = urldecode($request['keyword']);
if(empty($keyword))
{
echo '<script>alert("请输入您要查询的内容!");window.history.go(-1);</script>';
}
进一步追溯checkSqlStr函数,看代码如何过滤,在/inc/function.php中
function checkSqlStr($string)
{
$string = strtolower($string);
return preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|_user/i', $string);
}
checkSqlStr函数对传入的字符串进行正则匹配,检测是否函数非法字符。
继续看在/content/search/index.php中的get_search_result函数:
function get_search_result($modelName)
{
global $db,$request;
!checkSqlStr($request['keyword'])? $request['keyword'] = $request['keyword'] : exit('非法字符');
$keyword = urldecode($request['keyword']);
switch($modelName)
{
case 'article':
$sql = "SELECT * FROM ".TB_PREFIX."article WHERE title LIKE '%".$keyword."%' OR content LIKE '%".$keyword."%' ORDER BY id DESC";
break;
case 'list':
$sql="SELECT * FROM ".TB_PREFIX."list WHERE title LIKE '%".$keyword."%' OR content LIKE '%".$keyword."%' ORDER BY id DESC";
break;
case 'product':
$sql="SELECT * FROM ".TB_PREFIX."product WHERE title LIKE '%".$keyword."%' OR content LIKE '%".$keyword."%' ORDER BY id DESC";
break;
case 'download':
$sql="SELECT * FROM ".TB_PREFIX."download WHERE title LIKE '%".$keyword."%' OR content LIKE '%".$keyword."%' ORDER BY id DESC";
break;
case 'picture':
$sql="SELECT * FROM ".TB_PREFIX."picture WHERE title LIKE '%".$keyword."%' OR description LIKE '%".$keyword."%' ORDER BY id DESC";
break;
case 'video':
$sql="SELECT * FROM ".TB_PREFIX."video WHERE title LIKE '%".$keyword."%' OR description LIKE '%".$keyword."%' ORDER BY id DESC";
break;
case 'jobs':
$sql="SELECT * FROM ".TB_PREFIX."jobs WHERE lastTime>='".date('Y-m-d')."' AND (title LIKE '%".$keyword."%' OR content LIKE '%".$keyword."%') ORDER BY id DESC";
break;
case 'poll':
$sql="SELECT * FROM ".TB_PREFIX."poll_category WHERE title LIKE '%".$keyword."%' ORDER BY id DESC";
break;
default: break;
}
return $db->get_results($sql);
}
参数keyword进行非法字符检测后,进行url解码,然后拼接到SQL语句中执行。
如果我们传入双重url编码的字符串,将绕过非法字符检测,然后经urldecode解码,带入数据库中执行,导致SQL注入漏洞存在。
此时就可以使用sqlmap的chardoubleencode.py进行双重编码进行注入了
Last updated
Was this helpful?