又来审代码了,之前总是倾向于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
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!






