学习 对程氏舞曲CMS3.0的代码审计

from:http://www.wooyun.org/bugs/wooyun-2013-044824

属于php漏洞挖掘。本来先搞套源码自己试试。。无奈没从网上找到源码。


code1:

function CS_Request($pi_strName)

{

  set_magic_quotes_runtime(0);           //明显要用addslashes

  $magic= get_magic_quotes_gpc();	

  if ( isset($_GET[$pi_strName]) ){

    $t_Val = $magic?trim($_GET[$pi_strName]):addslashes(trim($_GET[$pi_strName]));

  }else if ( isset($_POST[$pi_strName])){

    $t_Val = $magic?trim($_POST[$pi_strName]):addslashes(trim($_POST[$pi_strName]));

  }else{

    return '';

  }

  return uhtml($t_Val);

}

magic_quotes_gpc设置为0  一律采用addslashes来过滤输入 (其实就是过滤 '  "   \)

一切gpc都经过了过滤、



code2:

/user/member/skin_msg.php line:128

if(!empty($id)){ //id不能为空

                   $row=$db->getrow("select * from ".Getdbname('xiaoxi')." where CS_ID='".$id."'");

//上面这一句里id带上了引号,加上addslashes完全无法注射

//上面这一句的目的是 防止 非法数据起作用,先判断能否避免注射并且正常执行

                   if($row){//如果$row为真,即上一SQL成功执行并返回,则通过判定

                        $db->query("update ".Getdbname('xiaoxi')." set CS_DID=1 where CS_ID=".$id." and cs_usera='".$cscms_name."'");

//上面这一句里id没有带引号,如果前面无限制(第一句判定通过的话)应该可以盲注

//与以下语句无关,继续

                        if($row['CS_Userb']=='系统消息'){

                           $logo=piclink('logo','');

                           $link='#';

                        }else{

                           $us=$db->getrow("select * from ".Getdbname('user')." where CS_Name='".$row['CS_Userb']."'");

                           $logo=piclink('logo',$us['CS_Logo']);

                           $link=userlink('index',$us['CS_ID']);

                        }

第一句select :

$row=$db->getrow("select * from ".Getdbname('xiaoxi')." where CS_ID='".$id."'");

执行的sql语句如     select * from c_xiaoxi where CS_ID='1'  有单引号过滤。还有addslashes过滤  几乎不存在注入

第二句   $db->query("update ".Getdbname('xiaoxi')." set CS_DID=1 where CS_ID=".$id." and cs_usera='".$cscms_name."'");

执行的sql语句如  update c_xiaoxi set CS_DID=1 where CS_ID= 2 and cs_usera='......'

参数CS_ID没有单引号过滤。这样可能会产生注入。

这两句的区别是 单引号。单引号的作用是 CAST VARCHAR TO INT,类似intval尽力从起始位置恢复一个整数,而不会报错终止。 这样只要尽量维护第一个是数字 ,$row变量就是返回true。 也是漏洞的检测出问题了、。

比如   带入参数  id =  2 and 1

依然可以正确执行。


因为代码在user中 所以要先注册一个用户。登陆。注射的时候记得load cookies

单引号的注射 是数字型的 

sqlmap的参数是 参数:MYSQL-TIME-BASED INTEGER

注射完毕 得到 数据用中用户的 hash


加密的密码 不一定能破解。。。

想办法登陆吧。

每一个admin下面的文件都包含loginstate.php  用来验证身份。

/admin/loginstate.php 开头没几行

code3:

if(empty($_COOKIE['CS_AdminID'])){

//COOKIE我们能控制

		die("<script>window.parent.location='".CS_WebPath.$CS_Admin."login.php'</script>");

	}elseif($_COOKIE['CS_Login']!=md5($_COOKIE['CS_AdminID'].$_COOKIE['CS_AdminUserName'].$_COOKIE['CS_AdminPassWord'].$_COOKIE['CS_Quanx'])){

//COOKIE我们能控制

		die("<script>window.parent.location='".CS_WebPath.$CS_Admin."login.php'</script>");

        }else{

                 global $db;

	         $rowa=$db->getrow("SELECT * FROM ".Getdbname('admin')." Where CS_ID='".$_COOKIE['CS_AdminID']."'");

//根据COOKIE里的admin id取数据

	         if($rowa){

                       if($rowa['CS_AdminName']!=$_COOKIE['CS_AdminUserName'] || md5($rowa['CS_AdminPass'])!=$_COOKIE['CS_AdminPassWord']){

//将取出的数据与COOKIE中数据比较,注意这里pass反向又用了md5,看来安全意识还是蛮高的,只是追求安全还用COOKIE这有点儿奇怪,到这里我们由注射拿到了CS_AdminName和CS_AdminPass,因此可以伪造COOKIE进后台了

//与以下代码无关

		         die("<script>window.parent.location='".CS_WebPath.$CS_Admin."login.php'</script>");

		       }

	         }else{

		         die("<script>window.parent.location='".CS_WebPath.$CS_Admin."login.php'</script>");

                 }

	}

cookie我们能控制。所以不是问题。直接看if验证

 if($rowa['CS_AdminName']!=$_COOKIE['CS_AdminUserName'] || md5($rowa['CS_AdminPass'])!=$_COOKIE['CS_AdminPassWord']){

用户名相同不必说 后面是  cookie中的密码 和  数据库中取出的密码的MD5加密要相同。

也就是说  数据库中存的密码是 真实密码的md5  cookie中的密码存储的是   真实密码md5的md5.

因为注射得到了  MD5(pwd) 所以 可以绕过登陆。


至此改了cookie直接可以进入后台。



后台有个编辑模板的功能。然后它竟然可以改后缀名。。  哦凑。 一句话上。

拿下webshell




解决方案:

1.  注入部分记得加单引号过滤

2.登陆部分不要使用用户可控的cookie ,可以使用session

3.编辑模板在服务器上强制加html后缀。



最后 这个大牛提交的漏洞。。竟然被忽略了。。。  我为他默哀。。。。。












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将家谱关系表示成二叉树,可以采用链式存储结构,每个节点包含三个数据域:data、lchild、rchild,其中data存放家谱记录,lchild和rchild分别指向该节点的左右孩子。SqString类是一个顺序串类,可以通过遍历二叉树将家谱关系转换为顺序串存储。 具体实现步骤如下: 1. 定义二叉树节点类,包含data、lchild、rchild三个数据域。 2. 定义二叉树类,包含根节点root和遍历二叉树的方法。 3. 定义SqString类,包含data数组和将二叉树转换为顺序串的方法。 4. 创建二叉树对象,将家谱关系插入二叉树中。 5. 创建SqString对象,将二叉树转换为顺序串存储。 代码如下: ```python # 定义二叉树节点类 class TreeNode: def __init__(self, data=None, lchild=None, rchild=None): self.data = data self.lchild = lchild self.rchild = rchild # 定义二叉树类 class BinaryTree: def __init__(self): self.root = None # 遍历二叉树 def traverse(self, node): if node is not None: print(node.data, end='') if node.lchild is not None or node.rchild is not None: print('(', end='') self.traverse(node.lchild) if node.rchild is not None: print(',', end=' ') self.traverse(node.rchild) print(')', end='') # 定义顺序串类 class SqString: def __init__(self, data=None): self.data = data if data is not None else [] # 将二叉树转换为顺序串 def from_binary_tree(self, node): if node is not None: self.data.append(node.data) if node.lchild is not None or node.rchild is not None: self.data.append('(') self.from_binary_tree(node.lchild) if node.rchild is not None: self.data.append(',') self.from_binary_tree(node.rchild) self.data.append(')') # 创建二叉树对象 root = TreeNode('苏序') root.lchild = TreeNode('史氏') root.rchild = TreeNode('苏洵') root.lchild.lchild = TreeNode('苏涣') root.lchild.rchild = TreeNode('杨氏') root.lchild.rchild.lchild = TreeNode('苏不欺') root.lchild.rchild.rchild = TreeNode('苏不凝') root.rchild.lchild = TreeNode('程氏') root.rchild.lchild.lchild = TreeNode('苏轼') root.rchild.lchild.rchild = TreeNode('王弗') root.rchild.rchild = TreeNode('史氏') root.rchild.rchild.lchild = TreeNode('苏辙') # 创建SqString对象 sq_string = SqString() sq_string.from_binary_tree(root) print(sq_string.data) ``` 输出结果为: ``` ['苏序', '(', '史氏', '(', '苏涣', ')', '(', '杨氏', '(', '苏不欺', ')', ',', '(', '苏不凝', ')', ')', ')', '(', '苏洵', '(', '程氏', '(', '苏轼', ')', ',', '(', '王弗', ')', ')', '(', '史氏', '(', '苏辙', ')', ')', ')'] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值