持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第十一天,点击查看活动详情
首先分析目录结构
admin -> 管理员后台
css -> 样式表
files -> 功能函数
images -> 图片
inc -> 配置文件
install -> 安装文件
seacmsseditor -> 编辑器
template -> 模板文件
upload -> 上传
index.php和admin/index.php存在文件包含
使用addslashes()函数对r传进来的参数进行转义,但是对于文件包含来说这个函数是没有用的
$action=$file==''?'index':$file;
这里的意思是如果r传入的为空的话就载入index.php,反之则载入r传入的值 文件包含一般配合文件上传使用,如果可以上传php文件的情况的话,直接传参就可以,但是这里限制后缀为.php,可以使用截断来绕过这个后缀限制 这里我们假设已经上传好了一个文件1.php
%00、#、?截断绕过
需要设置magic_quotes_gpc=Off,php版本5.3以下
http://192.168.31.82/?r=../upload/1.jpg%00
文件名溢出截断
linux需要4096,Windows需要256
http://192.168.31.82/?r=../upload/123.jpg………………………………………………………………………………………………………………………………………………………………………………………………………………
zip绕过
将1.php压缩为1.zip,然后访问
http://192.168.31.82/?r=../upload/1.zip/1
admin/login.php存在SQL注入
未经过滤就将$user的值传入了SQL语句中,很容易就想到了万能密码登录,但是根据代码逻辑可以看出先判断user是否再数据库中存在,再进行password的比较
可以利用报错注入得到用户名和密码
user=123' or extractvalue(1,concat((select concat(0x7e,password) from manage)))#&password=&login=yes
要注意的点就是这边只显示了31位,可以进行两次注入
user=123' or extractvalue(1,concat((select concat(0x7e,password) from manage)))#&password=&login=yes
user=123' or extractvalue(1,concat((select concat(password,0x7e) from manage)))#&password=&login=yes
后台疑似SQL注入,admin/files/adset.php
但是这里使用了addslashes()函数进行过滤,会在预定义字符前添加反斜杠进行转义
单引号(')
双引号(")
反斜杠(\)
NULL
那么使用单引号也就无法逃逸出来,按照其他绕过该函数的方式,有base、url编码,但源代码中并未有这些解码,所以该方法不使用,另外就是宽字节注入,改源码使用的为utf8编码,那么也就不存在了宽字节注入。
后台SQL注入,admin/files/columnlist.php
未对$delete的值进行过滤而直接带入数据库进行删除操作
2' and 1=(updatexml(1,concat(0x7e,(select+database())),1))#
这里要注意的是因为是get请求,所以需要进行一次url编码
inc/checklogin.php存在越权
通过adset.php追踪到checklogin.php
cookie中user值不为空即可登录
登录状态抓包,可以看到cookie中user=admin,将user=1111,发现仍然可以登录
admin/files/commentlist.php&linklist.php存在SQL注入
未对delete语句进行过滤
admin/files/editcolumn.php存在SQL注入
使用burp抓包,使type=1,之后传id的值
?r=editcolumn&type=1&id=2'+and+1%3d(updatexml(1,concat(0x7e,(select%2bdatabase())),1))%23
update这里也是同样方法
admin/files/editlink.php&editsoft.php&editwz.php存在SQL注入
均为未对传入数据进行严格过滤而带入数据库进行查询
files/downloads.php任意文件读取
发现fopen函数
$fp = fopen("$sourceFile", "rb");
追踪$sourceFile,可以得到$sourceFile = $fileadd; 那么继续搜索$fileadd,$fileadd=down['softadd'];继续追踪softadd,\softadd=_POST['softadd'];,可以看到写入了download表中  整个流程为fopen("\sourceFile", "rb"); -> $sourceFile = $fileadd; -> $fileadd=$down['softadd']; -> $softadd=$_POST['softadd']; -> UPDATE download SET softadd='$softadd'; 那么我们就可以在POST传参的时候将softadd值换成我们要读取的文件 #contact.php/download.php/list.php存在反射型xss
contact.php
$page=addslashes($_GET['page']);
<a>第 <?php echo $page?> - <?php echo $Totalpage?> 页 共 <?php echo $Total?> 条</a>
list.php
$yemas=$_GET['page'];
<title><?php echo $navs['name']?><?php echo $yema ?> - <?php echo $info['name']?></title>
虽然使用了addslashes函数进行过滤,但是对于xss来说用处不大,这里写个demo
<?php
$content = addslashes($_GET["a"]);
print $content;
?>
files/content.php/concat.php存在存储型xss
需要注意的是
<textarea name="content" cols="" rows=""></textarea>
textarea里的内容在浏览器里会自动编码成实体字符
<textarea><script>alert(1)</script></textarea>
那么就可以在name、mail、url处进行xss攻击
留言提交给submit.php进行判断,如果评论中没有中文则提示再说点别的,再把语句插入到数据库中
存储型xss和反射型xss的区别(代码角度)
反射型xss:
<?php
$name = $_GET["name"];
?>
<input type="text" value="<?php echo \$name?>">
?>
存储型xss:
<?php
error_reporting(0);
$name = $_GET["name"];
//连接服务器
$conn = mysql_connect("localhost","root","");
//打开数据库
mysql_select_db("test",\$conn);
$sql_insert = "insert into pay(id,name) values('\$id','\$name')";
$result = mysql_query(\$sql_insert,\$conn);
$sql_select = "select * from pay";
$results = mysql_fetch_array(mysql_query(\$sql_select));
echo \$results[content];
?>
不同点在于存储型xss将数据传入数据库中
总结
这个小型cms存在了很多的SQL注入和xss,主要练习的审计的思路,在这次审计中我主要是先利用源码搭建网站后查看每个功能点后再通过源码进行审计,首先查看的index.php,然后跳到包含的文件,按照代码逻辑依次进行审计。也可以根据敏感函数进行审计,file_get_contents()、file_put_contents()、fopen()看是否能进行文件读写,shell_exec()和exec()看是否能进行命令执行,require、require_once()、include和include_once()看是否有文件包含,数据库的话查询mysql_query()、mysql_fetch_row()函数,查询完这次可能会造成漏洞的函数再去查询$_GET、$_POST、$_COOKIE、$_SERVER,这些搜索到的结果一般是很多的。