Bootstrap

xhcms代码审计

将代码相关文件放入自动审计工具中

这里使用了RIPS

cms搭建好后的样子

审计过程初阶段

目录了解

admin#后台管理文件

css#cs起源(bushi)css文件栏

files#这是页面文件

images#名如其名放图片

inc#配置文件文件夹

install#安装用的

seacmseditor#编辑器文件

template#模板文件夹

upload#上传

index#首页

看看有啥特别的

随便点几个

发现在我点击的页面的交互之间是由r为介赋值后进而转到对应页面

也就是GET传参r

这个页面的url&cid带数字调用,然后是一个评论区,是不是可以有sql注入或者xss?

后面试试

这个时候看看自动化工具怎么说

漏洞很多——对照着下面给的数据看看能不能验证出来漏洞

(话说实战真的弄得到源文件吗......)

审计过程正式阶段

文件包含漏洞

就像钓鱼一样,知道水里有鱼了,但是要想办法钓个鱼上来看看才知道是不是真有鱼的阶段

$file = addslashes($_GET['r']);//输入转义防了sql这是前面填了个\可以绕过
$action = 'index' : $file;
include include ('files/' . $action . '.php');//action可以通过修改来访问其他文件

get一个值r进去用addslashes函数过滤

转义后赋值给$file构建文件路径并且判断是否为空来传递给action

包含action
但是get传参文件名到$action变量,然后在include进行files文件夹下的文件包含,来进行网页跳转的过程中,变量是没有任何过滤的,所以明显文件名可以进行目录穿越

这是file下

传入?r=download可以访问到界面

后台文件包含

创建一个php文件在file路径下

内容:

<?php phpinfo();?>
前台文件包含

payload:?r=phpinfo

出现界面

将文件移到根目录中

payload:?r=../phpinfo

界面如下

验证了这个文件包含漏洞

垂直提权

进登录界面我直接用burp开了

这里cookie没有用户user的参数

尝试将修改cookie

放包后成功登录了

同原理另尝试
cookie editor

通过源码看看逻辑

inc/checklogin.php路径中的登录验证

<?php
$user = $_COOKIE['user'];
if ($user == ""){
    header("Location: ?r=login");
    exit;   
}
?>

从 Cookie 中获取名为 'user' 的值,并将其赋给变量 $user

检查 $user 是否为空字符串

如果 $user 为空,即 Cookie 中不存在 'user'

header重新定到r=login页面重新登录

后面发现只要user有值给他就可以通过了

sqlmap

--dbs爆库名

--tables爆表名

--columns爆列

--dump显数据

可以进后台

XSS

自动化工具是节选代码

参考目录files/contact.php

$page=addslashes($_GET['page']);    
}
$startnum = ($page-1)*$perpagenum;  
if($page>1)   
$per=$page-1;   
else  
$per=1;   
if($Total%$perpagenum==0)   
$Totalpage=$Total/$perpagenum;   
else  
$Totalpage=(integer)($Total/$perpagenum)+1;   
$next=$page+1;   
if($next>=$Totalpage)   
 $next=$Totalpage;   
 
$query=mysql_query("SELECT * FROM interaction WHERE (xs=1 AND cid=0 AND type=2) ORDER BY id DESC limit $startnum,$perpagenum ") ;
$i=$perpagenum*($page-1)+1; 
?>
<div id="plbt"><span><a>所有留言</a></span>留言列表 - [ <?php echo $Total?> ]</div>
<?php
while($pinglun = mysql_fetch_array($query)){  
?>
<!--评论内容-->
<div id="plcontent">
<ul>
<div class="userinfo">
<div class="lou">#<?php echo $pinglun['id']?> 楼</div>
<?php if ($pinglun['url']<>""){?> 
<a href="<?php echo $pinglun['url']?>" target="_blank" ><img src="upload/portrait/<?php echo $pinglun['touxiang']?>.jpg"></a>
<?php }else{?>
<img src="upload/portrait/<?php echo $pinglun['touxiang']?>.jpg">
<?php }?>
<strong><a href="<?php echo $pinglun['url']?>" target="_blank"><?php echo $pinglun['name']?></a><span>Lv 1</span></strong>
<li>位置:<a><?php echo $pinglun['ip']?></a></li>
<li>时间:<a><?php echo tranTime(strtotime($pinglun['date']))?></a></li>
<li>来自:<a><?php echo $pinglun['shebei']?></a></li>
</div>
<div class="content">
<?php echo $pinglun['content']?>
</div>
</ul>
<?php if ($pinglun['rcontent']<>""){?>
<div class="manageinfo">
<ul>
<div class="lou">回复 #<?php echo $pinglun['id']?> 楼</div>
<?php 
$query2 = "SELECT * FROM manage";
$resul2 = mysql_query($query2) or die('SQL语句有误:'.mysql_error());
$manage2 = mysql_fetch_array($resul2);
if ($manage2['img']==""){
$touxiang="images/manage.jpg";
} else{
$touxiang=$manage2['img'];		
}
?>
<img src="<?php echo $touxiang?>">
<strong><?php echo $manage2['name']?><span>认证站长</span></strong>
<li>位置:<a><?php echo $pinglun['rip']?></a></li>
<li>时间:<a><?php echo tranTime(strtotime($pinglun['rdate']))?></a></li>
<li>来自:<a><?php echo $pinglun['rshebei']?></a></li>
</ul>
</div>
<div class="content2">
<?php echo $pinglun['rcontent']?>
</div>
<?php }?>
<div id="qcfd"></div>
</div>
<!--评论内容end-->
<?php }?>


<div class="pagecode">
<span>
<a href="?<?php echo $pageyema?>">首页</a> -
<a href="<?php echo "?$pageyema&page=$per" ?>">上一页</a> -
<a href="<?php echo "?$pageyema&page=$next" ?>">下一页</a> -
<a href="<?php echo "?$pageyema&page=$Totalpage" ?>">尾页</a>
</span>

<a>第 <?php echo $page?> - <?php echo $Totalpage?> 页 共 <?php echo $Total?> 条</a>

这里实现了一个关于留言列表页面的功能

分页显示留言:

通过 $_GET['page'] 获取用户传递的分页参数

使用 $page 计算起始位置,执行 SQL 查询获取指定页的留言信息

展示留言内容:

通过数据库查询获取留言数据,并在页面中循环显示每一条留言的相关信息,包括留言者的信息、留言内容、留言时间等

展示回复内容:

如果留言有回复内容,则显示回复的相关信息,包括回复者的信息、回复时间等

分页链接:

显示分页链接,包括首页、上一页、下一页、尾页等,提供用户导航到不同页数的留言

处理用户输入的页面参数:

使用 addslashes 处理用户通过 GET 请求传递的页面参数,防范 SQL 注入

关键内容:

这里对用户的输入和留言内容输出都没有好好过滤

$page = addslashes($_GET['page']);//过滤输入少了
<?php echo $page?>//处理输出是直接将变量输出到页面

构造payload:<img src=1 οnerrοr=alert(/xss/)>

将page值设置为<img src=1 οnerrοr=alert(/xss/)>

并使onerror出发警告框实现xss

因为过滤缺少还可以弄出很多xss

目录/content.php相似代码

payload:?r=contact&page=<script>alert(1)</script>

$page=addslashes($_GET['page']);
if ($page<>""){
if ($page<>1){
$pages="第".$page."页 - ";
}
    
 <?php echo $pages.$info['name']?>

SQL注入

admin/files/editlink.php路径中

$id=$_GET['id'];
$type=$_GET['type'];
if ($type==1){
$query = "SELECT * FROM nav WHERE id='$id'";
$resul = mysql_query($query) or die('SQL语句有误:'.mysql_error());
$nav = mysql_fetch_array($resul);
}

分析:

这里GET输入id和type后

type和1进行比较,匹配后会进行sql语句执行这里有一个单引号闭合漏洞

在参数前构造一个闭合单引号就可以成功执行后面要输进去反应的sql语句

r=editcolumn&type=1&id=1'%20or%20updatexml(1,concat(0x7e,database()),1)%23

但是返回结果是正与否

所以可以进行报错注入

login没有过滤

die函数可以输出mysql错误信息

当然上面关于sql注入的内容用sqlmap一把梭了

关于过滤函数的后谈

有一些地方用了addslashes函数来进行放sql注入

加了反斜杠使得无法正常单引号闭合

这个函数真的这么狠?

类似见sqllab32

可以用宽字节注入进行绕过

;