前言
整理下平时Java代码审计中常见的一些漏洞学习总结以及一些审计思路,后续会不断补充。
工具
以下为常用的工具清单
1 | 一、代码编辑器: |
常见漏洞
SQL注入
审计的注意点
- 是否使用预编译技术,预编译是否完整。
- 定位SQL语句上下文,查看是否有参数直接拼接,是否有对模糊查询关键字的过滤。
- Mybatis框架则搜索${},四种情况无法预编译:like模糊查询、order by排序、范围查询in、动态表名/列名,只能拼接,所以还是需要手工防注入,此时可查看相关逻辑是否正确。
- JPA搜索
JpaSort.unsafe()
,查看是否用实体之外的字段对查询结果排序,进行了SQL的拼接。以及查看EntityManager
的使用,也可能存在拼接SQL的情况。
关键函数或字符串查找
1 | Statement |
XSS
审计的注意点
- 定位用户的输入输出,梳理数据交互以及前端展示的过程
- 找到一条完整的利用链之后,就是结合现有的安全措施(输出编码、过滤器等)进行判断,例如是否存在绕过的可能,或者是没有任何安全防护可直接造成攻击。
- 扫描所有的 HttpServletRequest 查看相关的上下文环境。
关键函数或字符串查找
1 | request.getParamter |
XXE
审计的注意点
XML 解析一般在导入配置、数据传输接口等场景可能会用到,涉及到 XML 文件处理的场景可留意下 XML 解析器是否禁用外部实体,从而判断是否存在 XXE。
XML解析涉及的业务功能点: WebServices接口、RESTful接口、Excel文件解析、Soap协议等。
计XML解析器是否设置了相关的安全属性,禁用DTDs或者禁止使用外部实体。还有是否使用了不安全的漏洞组件。
关键函数或字符串查找
1 | javax.xml.parsers.DocumentBuilder |
部分XML解析器的正确禁用方式,参考:https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#Java
1 | XMLInputFactory (a StAX parser) |
反序列化
审计的注意点
- 反序列化操作的功能位置:导入模版文件、网络通信、数据传输、日志格式化存储、对象数据落磁盘或DB存储等业务场景。
- 可以通过对网络抓包寻找序列化数据:java序列化的数据一般会以标记(ac ed 00 05)开头,base64编码后的特征为rO0AB。
- 查看反序列化触发点的参数是否由用户可控。
- 全局查找implements Serializable 的所有内部类。
- 程序中存在一条可以产生安全问题的利用链,如远程代码执行,并找到一个可以触发利用链的点。
关键函数或字符串查找
1 | ObjectInputStream.readObject |
命令执行
审计的注意点
- 重点关注能执行命令的一些功能及函数
关键函数或字符串查找
1 | Runtime.getRuntime().exec() |
SSRF
审计的注意点
- SSRF 漏洞出现的场景有很多,如在线翻译、转码服务、图片收藏/下载、信息采集、邮件系统或者从远程服务器请求资源等。通常我们可 以通过浏览器查看源代码查找是否在本地进行了请求,也可以使用 DNSLog 等工具进行测试网页是否被访问。
- 重点关注HTTP请求操作函数。
- 想要支持所有的协议,只能使用URLConnection、URL。
关键函数或字符串查找
1 | HttpClient.execute() |
除了建立HTTP协议连接,还可能直接通过 Socket建立连接
1 | AsynchronousServerSocketChannel.accept/bind |
文件上传
审计的注意点
- 关注文件后缀验证,是使用白名单还是黑名单。
- 最好使用
lastIndexOf()
方法获取文件后缀,如果使用IndexOf()
可能被绕过。 - 如果是白名单验证时,使用
toLowerCase()
处理再进行对比,或使用equalsIgnoreCase()
,避免被大小写绕过。 - 是否校验了文件的大小。
- 是否校验了文件类型
getContentType()
。 - 对于使用Hutool的FileTypeUtil的
getType()
或ImageIO.read()
通过读取文件流中前N个byte值来判断文件类型的,也可以使用类似图片马的方式进行绕过。 - 尝试”%00”截断能否绕过。
- QP编码特性能否绕过。
javax.mail.internet.MimeUtility.encodeWord()
方法。 - 有一些安全校验的顺序有问题,先将文件保存,再进行安全检测,如果不通过检测则进行删除,此时可以在文件保存后触发报错终止流程,导致不删除文件。
关键函数或字符串查找
1 | FileUpload |
任意文件读/写/删除/复制/移动/遍历
审计的注意点
- 首先关注包含这些功能的类和函数
- 对传入的路径未做严格的校验,导致攻击者可以自定义路径
关键函数或字符串查找
1 | sun.nio.ch.FileChannelImpl |
URL跳转
审计的注意点
- 用户登录、统一身份认证处,认证完了会通过url=的形式跳转到类似操作的页面。
- 用户分享、收藏内容后跳转。
- 跨域认证授权后进行跳转。
- 对于URL跳转漏洞在黑盒测试时主要的关注点为:注意URL中是否带有return、redirect、url、jump、goto、target、link等 参数值,并注意观察后跟的URL地址的具体格式,再构造相应的payload尝试跳转。在白盒审计中我们则会重点关注可以进行URL跳转的相关方法。
- 定位可能存在redirect业务的代码段,审计跳转的URL是否来自于前端参数,是否具有校验和限制。
关键函数或字符串查找
1 | sendRedirect |
敏感信息泄露
审计的注意点
- 重点审计系统使用的框架、组件,根据经验查看配置,配置是否有误、是否将调试功能正式上线到生产环境中等。
- 由于配置不当或使用有误,将可能导致泄露服务器的敏感信息。
例如:swagger 接口文档、Hystrix 监控面板、DWR 框架、Actuator、druid监控平台等等。
关键函数或字符串查找
1 | SwaggerConfig |
代码执行/表达式执行
审计的注意点
- 重点审计具有加载类、反序列化类、对类字节码进行操作的功能和代码
关键函数或字符串查找
1 | eval |
Zip文件提取
审计的注意点
- 重点主要关注应用是否存在ZIP解压缩功能
关键函数或字符串查找
1 | FileInputStream |
业务逻辑漏洞
1 | 1. 用户登陆、用户注册、找回密码等功能中密码信息未采用加密算法。 |
硬编码
审计的注意点
- 审计源代码中是否有硬编码敏感信息。
关键函数或字符串查找
1 | password |
不安全的反射
审计的注意点
- 查看开发人员是否对反射调用方法、反射创建类实例进行了封装,并是否在对外的接口中进行了相关的调用。
关键函数或字符串查找
1 | Class.forName |
使用了不安全的组件
1 | 组件例如 fastjson、jackson、xstream、shiro、xxl-job,框架例如 struts2、spring 等等,都要注意使用的版本问题。 |
模板注入
- 内建函数的利用:虽然FreeMarker中预制了大量的内建函数,极大地增强和拓展了模板的语言功能,但也可能引发一些危险操作。若研发人员不加以限制, 则很可能产生安全隐患。
- new函数的利用:new函数可以创建一个继承自freemarker.template.TemplateModel 类的实例,查阅源码会发现freemarker.template.utility.Execute#exec可以执行 任意代码,因此可以通过new函数实例化一个Execute对象并执行exec() 方法造成任意代码被执行。
1 | ObjectConstructor:<#assign value="freemarker.template.utility.ObjectConstructor"?new()>${value("Java.lang. ProcessBuilder","calc.exe").start()} |
- api函数的利用:api函数可以用来访问Java API,使用方法为value?api.someJavaMethod(),相当于value.someJavaMethod()。因此可以利用api函数通过 getClassLoader来获取一个类加载器,进而加载恶意类。也可以通过getResource来读取服务器上的资源文件。
1 | <#assign classLoader=object?api.class.getClassLoader()> |
CSRF
审计的注意点
- 一些增删改查方法,是否进行
Referer头检验
、token检验
无法构造的随机数参数
、验证码密码
关键函数或字符串查找
1 | session["token"] |
越权
审计的注意点
- 在每个
request.getParameter("userid");
之后查看是否有检验当前用户与要进行增删改查的用户。
关键函数或字符串查找
1 | request.getParameter("userid") |
文件包含
审计的注意点
- 关注jsp是否存在文件包含的方法
关键函数或字符串查找
1 | 本地文件包含: |
XMLDecoder反序列化
审计注意点
- 观察传入XMLDecoder()的参数是否可控
关键函数或字符串查找
1 | XMLDecoder decoder = new XMLDecoder(ins); |
BeanShell RCE
审计注意点
- 查找参数是否可控
关键函数或字符串查找
1 | Interpreter interpreter = new Interpreter(); |
SnakeYaml反序列化
审计注意点
- 直接定位
yaml.load()
,然后进行回溯,查看下参数是否可控
关键函数或字符串查找
1 | Yaml yaml = new Yaml() |
未授权访问/权限绕过
审计注意点
- 查看权限校验的过滤器,观察是否存在校验不严格的路由,或者是否存在检验绕过的情况
- 找出全部的请求路由
关键函数或字符串查找
1 | @(.*?)Mapping( |
参考
https://su18.org/post/code-audit/
https://github.com/Cryin/JavaID
https://shu1l.github.io/2021/01/27/java-dai-ma-shen-ji-zhi-chang-jian-lou-dong-xue-xi/
《网络安全JAVA代码审计实战》
《JAVA代码审计入门篇》