又来审代码了,之前总是倾向于RCE或者文件上传getshell一类的洞,都没怎么看过SQL注入,这回就来看看吧…
前台SQL注入
根据更新特地指出的说明,确定引起前台SQL注入的为p
函数,全局搜索P
函数,定位到function/common.php
,暂时先不看,由于是前台SQL诸如点,所以需要先找到漏洞点,index文件夹当中存储的都是前台可以访问的页面即调用的方法
反向搜索调用了p函数的文件,定位到c/index/TagsAction.class.php
在调用p函数对$data
进行赋值之后,会调用string
类中的delHtml
方法对$data['name']
进行去除html
根据前面传入的参数,这里的data
值通过$_GET
进行传参,$pe和$sql
都为1
,$mysql
默认为false
,按照1为true
,会调用filter_sql
方法对$data进行处理;之后对$data是否为数组进行判断,这里可控,由于$pe=1
,接着会调用addslashes
方法对传入的值进行转义,然后返回值;下面来看一下
首先对$data中的值是否为数组进行判断,当然没有任何影响,如果是数组就会进行循环调用filter_sql方法罢了;之后会转换大小写并检测是否有黑名单中的关键词,有的话就直接报错
回到最开始的构造方法,在url解码之后,会调用tagsModel类中的getNameData方法,跟进
这里会调用父类的oneModel
方法对$param
进行处理,继续跟进
调用父类的oneDB方法,继续跟进
这里调用了类中的where方法对前面传递过来的$param进行处理,一开始的name就是可控的,所以这里的$We="name=xxx"
,这里是进行了字符串的拼接,所以在执行时候会造成SQL
注入,这里才是最后的注入点
而触发点在最开始类中的index方法,这里会对结果进行打印输出
index
方法中调用到的parse
类中的tags
方法这里就不深究了,感兴趣可以自己去看看
poc
需要进行两次URL编码来进行绕过,浏览器默认解析一次
union联合查询:
SELECT * FROM lmx_tags WHERE name = '-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3,4,5,6,7,8,9,10,11,12#
一开始本来是想用union注入来打的,但是后面发现缺少相应的文件,没办法跳转,就拿不到回显,SQLMAP也是因为这个判断不了是否注入成果而跑不出结果,恰巧这里有报错信息,这里就是上面提到的tags方法中的内容,因为会到数据库里进行相应的查询操作,所以这里改为报错注入
报错注入
' and (updatexml(1,concat(0x7e,(database()),0x7e),1)) and '1'='1
要用sqlmap也是可以的,就是需要指定以下tamper脚本,两次URL最方便,实际上前面关键词WAF的绕过不止一种方法,像是用<>来进行绕过也是可以的
sqlmap.py -r 'burp数据包路径' --technique=E -v3 --tamper=chardoubleencode -p name --dbs
任意文件删除
漏洞点位于后台首页->图片管理,选择一张图片进行删除,Burp抓包
根据请求路径,定位到代码
c/admin/FileAction.class.php
public function delete(){
if(!$_POST['fid']) rewrite::js_back('请选择要删除的文件');
$this->fileModel->delete($_POST);
addlog('删除文件、图片');
rewrite::succ('删除成功');
}
先判断$fid参数是否进行传参,之后调用delete
方法进行了传入的数据处理,跟进,发现调用到了FileModel
类中的delete
方法
m/FileModel.class.php
传入的$data是一个数组,存有POST
传递的三个参数,根据POST
包中的数据,$data['type']=
0,接着会循环遍历$data,键值指定为$fid
,之后会调用explode方法对$v值进行分割处理,$fileInfo[1]
才是我们指定想要删除的文件的真实路径,并且在传递之前会去除首尾的/
;后面调用implode函数将一维数组转换为字符串重新赋值给$fid
;下面的if始终满足为true,之后就会调用unLink方法进行文件删除了。
经过测试,可以进行目录穿越,也就可以进行任意文件删除操作
poc
type=0&fid%5B%5D=1#####/filepath
任意文件读取
定位到代码位置
c/admin/TemplateAction.class.php#81
直接通过GET
传参传入文件的路径,由于这里没有POST
传入的几个参数,所以直接跳过if判断,直接到下面将文件的路径进行赋值,调用file
类的getcon
方法
该方法直接读取了文件内容, 并且会检查文件的权限问题;之后调用string类中的html_char方法转换html实体并去除空格
这里就可以利用路径穿越来读取任意文件了
写在后面
SQL注入还是审计的少了,在打POC那里卡了好久,愣是没想到用报错注入可以直接打出结果,后面在大哥的提醒下还是顺利解决了,后面的两个漏洞属于鸡肋了,毕竟需要后台权限,没什么作用。
ps:漏洞已经在新版本修复了~
- 本文作者: joker
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/955
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!