JavaWeb代码审计CheckList
2022-06-16 23:30:37 # Java安全

前言

整理下平时Java代码审计中常见的一些漏洞学习总结以及一些审计思路,后续会不断补充。

工具

以下为常用的工具清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
一、代码编辑器:
1.Jetbrains IDEA(IDE)
2.Sublime text(文本编辑器)
3.Eclipse
二、测试工具:
1.Burp Suite:是渗透测试工作者必备的一款工具,同时对于代码审计者和安全研究人员来说,这也是一款比较重要的测试工具,其跨平台、便捷、强大的功能以及丰富的插件,深受信息安全从业者的喜爱。
2.SwitchyOmega:SwitchyOmega 是一款代理管理插件,支持Firefox和Chrome浏览器,并支持HTTP、HTTPS、socket4和socket5协议。
3.Max HackerBar:HackBar是Firefox的一个插件,也是信息安全从业者常用的经典工具。
4.Postman:Postman是一款功能强大的网页调试工具,能够为用户提供强大的Web API & HTTP请求调试功能。
5.Ysoserial:是一款开源的Java反序列化测试工具,内部集成有多种利用链,可以快速生成用于攻击的代码,也可以将新公开的反序列化漏洞利用方式自行加入Ysoserial中。
6.Marshalsec:是一款开源的Java反序列化测试工具,不仅可以生成各类反序列化利用链,还可以快速启动恶意的RMI服务等。
7.MySQL Monitor:是Web版本的SQL记录实时监控工具。
8.Beyond Compare:是一款文件比较工具,主要对比两个文件夹或者文件,并以颜色标示差异,比较范围包括目录、文档内容等。使用该工具可以方便代码审计人员快速地比对两个版本代码的差别。
三、反编译工具
1.JD-GUI:是一款具有UI界面的反编译工具,界面简洁大方,使用简单方便。
2.Fernflower:功能比JD-GUI更强大,虽然没有UI界面,但可以配合系统指令完成批量反编译的工作。
3.CFR:功能强大的反编译工具,支持主流Java特性——Java 8 lambda表达式,以及Java 7字符串切换。在某些JD-GUI无法反编译的情况下,CFR仍然能完美地进行反编译,也可以像FernFlower那样配合系统指令进行批量反编译。
4.IntelliJ IDEA:具能够自动解包已添加依赖的Jar包,并对其内容进行反编译。该工具拥有强大的动态调试和字符串匹配和搜索功能,为审计和调试漏洞的工作提供了极大便利。
5.CodeReviewTools:是一款可以快速搜索代码中的关键点,一键对jar进行批量反编译,也支持直接对war包进行操作。
四、Java代码静态扫描工具
1.Fortify SCA:获得业界认可的静态代码检查工具,但它是收费的。Fortify SCA的核心在于规则库,用户可以自定义规则库,减少误报。
2.VCG:基于 VB 开发的一款Windows下的白盒审计工具。VCG 支持多种语言,例如C/C++、Java、C#、VB、PL/SQL、PHP。VCG会根据代码中的变量名等信息动态生成针对该代码的漏洞规则,通过正则检查是否有和漏洞规则所匹配的代码。
3.FindBugs与FindSecBugs插件:FindBugs是一款Bug扫描插件,在IDEA和Eclipse中都可进行安装。FindBugs可以帮助开发人员发现代码缺陷,减少Bug,但其本身并不具备发现安全漏洞的能力,需要安装FindSecBugs拓展发现安全漏洞的能力。
4.SpotBugs:是FindBugs的继任者,所以二者用法基本一样,可以独立使用,也可以作为插件使用。
5.CheckMark:白盒代码审计解决方案,主要通过采用独特的词汇分析技术和CxQL专利查询技术对应用程序源码进行静态分析检查。
6.Snyk插件:修复项目中的安全漏洞、基础架构错误配置和代码质量问题。
7.Sensei插件:可在键入时扫描和修复易受攻击的代码 - 具有数百个可下载的安全编码配方(规则)以及内置的自行制作能力。
8.Reshift Security插件:可以快速发现漏洞,提供多个代码修复片段,以及丰富的文档,涵盖了每个漏洞的检测、修复和测试。
9.MurphySec Code Scan插件:可以快速识别您的项目中使用了哪些存在安全缺陷的开源组件,并帮助您一键修复问题。
10.Momo Code Sec Inspector插件:重于在编码过程中发现项目潜在的安全风险,并提供一键修复能力。
11.dependence-check:可用于检查已发布安全漏洞的项目依赖项。
12.wJa:一款结合DAST、SAST、IAST的综合性应用程序安全分析工具,支持对java web程序的安全性进行分析,含有反编译,代码审计,调试jar包,代理追踪等用于分析软件安全的功能。
13.tabby:是一款针对Java语言的静态代码分析工具,它使用静态分析框架 Soot 作为语义提取工具,将JAR/WAR/CLASS文件转化为代码属性图,并使用 Neo4j 图数据库来存储生成的代码属性图CPG。
14.SpringInspector:Java自动代码审计工具,尤其针对Spring框架,提供一个SpringBoot的Jar包即可进行自动代码审计,底层技术基于字节码分析。
15.gadgetinspector:反序列化漏洞利用链、漏洞检测工具。

常见漏洞

SQL注入

审计的注意点

  • 是否使用预编译技术,预编译是否完整。
  • 定位SQL语句上下文,查看是否有参数直接拼接,是否有对模糊查询关键字的过滤。
  • Mybatis框架则搜索${},四种情况无法预编译:like模糊查询、order by排序、范围查询in、动态表名/列名,只能拼接,所以还是需要手工防注入,此时可查看相关逻辑是否正确。
  • JPA搜索JpaSort.unsafe(),查看是否用实体之外的字段对查询结果排序,进行了SQL的拼接。以及查看EntityManager的使用,也可能存在拼接SQL的情况。

关键函数或字符串查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Statement
createStatement
PrepareStatement
like '%${
in(${
in (${
select
update
insert
delete
${
setObject(
setInt(
setString(
setSQLXML(
createQuery(
createSQLQuery(
createNativeQuery(

XSS

审计的注意点

  • 定位用户的输入输出,梳理数据交互以及前端展示的过程
  • 找到一条完整的利用链之后,就是结合现有的安全措施(输出编码、过滤器等)进行判断,例如是否存在绕过的可能,或者是没有任何安全防护可直接造成攻击。
  • 扫描所有的 HttpServletRequest 查看相关的上下文环境。

关键函数或字符串查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
request.getParamter
<%=
param
${
<c:out
<c:if
<c:forEach
ModelAndView
ModeMap
Model
request.setAttribute
response.getWrite().print(
response.getWrite().writer(
XssFilter
org.springframework.web.util.HtmlUtils
org.apache.commons.lang3.StringEscapeUtils
ESAPI.encoder().encodeForHTML

XXE

审计的注意点

  • XML 解析一般在导入配置、数据传输接口等场景可能会用到,涉及到 XML 文件处理的场景可留意下 XML 解析器是否禁用外部实体,从而判断是否存在 XXE。

  • XML解析涉及的业务功能点: WebServices接口、RESTful接口、Excel文件解析、Soap协议等。

  • 计XML解析器是否设置了相关的安全属性,禁用DTDs或者禁止使用外部实体。还有是否使用了不安全的漏洞组件。

关键函数或字符串查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
javax.xml.parsers.DocumentBuilder
javax.xml.parsers.DocumentBuilderFactory
javax.xml.stream.XMLStreamReader
javax.xml.stream.XMLInputFactory
org.jdom.input.SAXBuilder
org.jdom2.input.SAXBuilder
org.jdom.output.XMLOutputter
oracle.xml.parser.v2.XMLParser
javax.xml.parsers.SAXParser
org.dom4j.io.SAXReader
org.dom4j.DocumentHelper
org.xml.sax.XMLReader
javax.xml.transform.sax.SAXSource
javax.xml.transform.TransformerFactory
javax.xml.transform.sax.SAXTransformerFactory
javax.xml.validation.SchemaFactory
javax.xml.validation.Validator
javax.xml.bind.Unmarshaller
javax.xml.xpath.XPathExpression
java.beans.XMLDecoder

部分XML解析器的正确禁用方式,参考:https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
XMLInputFactory (a StAX parser)
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); // This disables DTDs entirely for that
factory
xmlInputFactory.setProperty("javax.xml.stream.isSupportingExternalEntities", false); // disable external entities

TransformerFactory
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

Validator
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
Validator validator = schema.newValidator();
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");

SchemaFactory
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
Schema schema = factory.newSchema(Source);

SAXTransformerFactory
SAXTransformerFactory sf = SAXTransformerFactory.newInstance();
sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
sf.newXMLFilter(Source);
//Note: Use of the following XMLConstants requires JAXP 1.5, which was added to Java in 7u40 and Java 8:
javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD
javax.xml.XMLConstants.ACCESS_EXTERNAL_SCHEMA
javax.xml.XMLConstants.ACCESS_EXTERNAL_STYLESHEET

XMLReader
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); // This may
not be strictly required as DTDs shouldn't be allowed at all, per previous line.
15 / 28
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

SAXReader
saxReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
saxReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
//Based on testing, if you are missing one of these, you can still be vulnerable to an XXE attack.

SAXBuilder
SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
builder.setFeature("http://xml.org/sax/features/external-general-entities", false);
builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
Document doc = builder.build(new File(fileName));

Unmarshaller
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(), new InputSource(new StringReader(xml)));
JAXBContext jc = JAXBContext.newInstance(Object.class);
Unmarshaller um = jc.createUnmarshaller();
um.unmarshal(xmlSource);

XPathExpression
DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
df.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
df.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
DocumentBuilder builder = df.newDocumentBuilder();
String result = new XPathExpression().evaluate( builder.parse(new
ByteArrayInputStream(xml.getBytes())) );

反序列化

审计的注意点

  • 反序列化操作的功能位置:导入模版文件、网络通信、数据传输、日志格式化存储、对象数据落磁盘或DB存储等业务场景。
  • 可以通过对网络抓包寻找序列化数据:java序列化的数据一般会以标记(ac ed 00 05)开头,base64编码后的特征为rO0AB。
  • 查看反序列化触发点的参数是否由用户可控。
  • 全局查找implements Serializable 的所有内部类。
  • 程序中存在一条可以产生安全问题的利用链,如远程代码执行,并找到一个可以触发利用链的点。

关键函数或字符串查找

1
2
3
4
5
6
7
ObjectInputStream.readObject
ObjectInputStream.readUnshared
XMLDecoder.readObject
Yaml.load
XStream.fromXML
ObjectMapper.readValue
JSON.parseObject

命令执行

审计的注意点

  • 重点关注能执行命令的一些功能及函数

关键函数或字符串查找

1
2
3
4
5
6
7
8
9
Runtime.getRuntime().exec()
Process
UNIXProcess
ProcessImpl
ProcessBuilder.start()
GroovyShell.evaluate()
由java后端模板引擎注入导致的 RCE 漏洞,常见的如:Freemarker、Velocity、Thymeleaf等
由java一些脚本语言引起的 RCE 漏洞,常见的如:Groovy、JavascriptEngine等
由第三方开源组件引起的 RCE 漏洞,常见的如:Fastjson、Shiro、Xstream、Struts2、weblogic等

SSRF

审计的注意点

  • SSRF 漏洞出现的场景有很多,如在线翻译、转码服务、图片收藏/下载、信息采集、邮件系统或者从远程服务器请求资源等。通常我们可 以通过浏览器查看源代码查找是否在本地进行了请求,也可以使用 DNSLog 等工具进行测试网页是否被访问。
  • 重点关注HTTP请求操作函数。
  • 想要支持所有的协议,只能使用URLConnection、URL。

关键函数或字符串查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
HttpClient.execute()
HttpClient.executeMethod()
HttpURLConnection.connect()
HttpURLConnection.getInputStream()
URL.openStream()
HttpServletRequest()
BasicHttpEntityEnclosingRequest()
DefaultBHttpClientConnection()
BasicHttpRequest()
ImageIO.read()
Request.Get.execute
Request.Post.execute
OkHttpClient.newCall.execute
com.alibaba.druid.util.HttpClientUtils
javax.servlet.http.HttpServletRequest
java.net.URI
java.net.URL
java.net.URLConnection
com.bea.uddiexplorer.Search
org.apache.commons.httpclient.HttpMethodBase
org.apache.http.client.methods.HttpRequestBase

除了建立HTTP协议连接,还可能直接通过 Socket建立连接

1
2
3
4
5
6
7
8
AsynchronousServerSocketChannel.accept/bind
AsynchronousSocketChannel.write/read/bind/connect
ServerSocketChannel.bind
ServerSocket.accept/bind
Socket.bind/connect
Socket.getInputStream().read
Socket.getOutputStream().write
SocketChannel.bind/read/write/connect

文件上传

审计的注意点

  • 关注文件后缀验证,是使用白名单还是黑名单。
  • 最好使用lastIndexOf()方法获取文件后缀,如果使用IndexOf()可能被绕过。
  • 如果是白名单验证时,使用toLowerCase()处理再进行对比,或使用equalsIgnoreCase(),避免被大小写绕过。
  • 是否校验了文件的大小。
  • 是否校验了文件类型getContentType()
  • 对于使用Hutool的FileTypeUtil的getType()ImageIO.read()通过读取文件流中前N个byte值来判断文件类型的,也可以使用类似图片马的方式进行绕过。
  • 尝试”%00”截断能否绕过。
  • QP编码特性能否绕过。javax.mail.internet.MimeUtility.encodeWord()方法。
  • 有一些安全校验的顺序有问题,先将文件保存,再进行安全检测,如果不通过检测则进行删除,此时可以在文件保存后触发报错终止流程,导致不删除文件。

关键函数或字符串查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
FileUpload
FileUploadBase
FileItemIteratorImpl
FileItemStreamImpl
FileUtils
UploadHandleServlet
FileLoadServlet
FileOutputStream
DiskFileItemFactory
MultipartRequestEntity
MultipartFile
com.oreilly.servlet.MultipartRequest
java.io.File
MultipartMethod
MultipartHttpServletRequest
CommonsMutipartResolver
upload
fileNmae
filePath
lastIndexOf
indexOf
FileUpload
getRealPath
getServletPath
getPathInfo
getContentType
equalsIgnoreCase
FileUtils
UploadHandleServlet
FileLoadServlet
getInputStream
DiskFileItemFactory
file.getInputStream()
new ServletFileUpload(factory)
handleFileUpload(@RequestParam("file") MultipartFile file)

任意文件读/写/删除/复制/移动/遍历

审计的注意点

  • 首先关注包含这些功能的类和函数
  • 对传入的路径未做严格的校验,导致攻击者可以自定义路径

关键函数或字符串查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sun.nio.ch.FileChannelImpl
java.io.File.list/listFiles
java.io.FileInputStream
java.io.FileOutputStream
java.io.FileSystem/Win32FileSystem/WinNTFileSystem/UnixFileSystem
sun.nio.fs.UnixFileSystemProvider/WindowsFileSystemProvider
java.io.RandomAccessFile
sun.nio.fs.CopyFile
sun.nio.fs.UnixChannelFactory
sun.nio.fs.WindowsChannelFactory
java.nio.channels.AsynchronousFileChannel
FileUtil/IOUtil
filePath/download/deleteFile/move/getFile
fileName/filePath

URL跳转

审计的注意点

  • 用户登录、统一身份认证处,认证完了会通过url=的形式跳转到类似操作的页面。
  • 用户分享、收藏内容后跳转。
  • 跨域认证授权后进行跳转。
  • 对于URL跳转漏洞在黑盒测试时主要的关注点为:注意URL中是否带有return、redirect、url、jump、goto、target、link等 参数值,并注意观察后跟的URL地址的具体格式,再构造相应的payload尝试跳转。在白盒审计中我们则会重点关注可以进行URL跳转的相关方法。
  • 定位可能存在redirect业务的代码段,审计跳转的URL是否来自于前端参数,是否具有校验和限制。

关键函数或字符串查找

1
2
3
4
5
6
7
8
9
sendRedirect
setHeader
forward
redirect:
<c:redirect
self.location.href
location.href
windows.location.href
redirect、redirect_do、redirect_url、url、jump、jump_to、target、to、link、domain

敏感信息泄露

审计的注意点

  • 重点审计系统使用的框架、组件,根据经验查看配置,配置是否有误、是否将调试功能正式上线到生产环境中等。
  • 由于配置不当或使用有误,将可能导致泄露服务器的敏感信息。
    例如:swagger 接口文档、Hystrix 监控面板、DWR 框架、Actuator、druid监控平台等等。

关键函数或字符串查找

1
2
3
4
5
6
7
8
9
10
11
12
13
SwaggerConfig 
Swagger2Config
@EnableSwaggerBootstrapUI
@EnableSwagger2
application.properties或者application.yml:swagger.production=true或swagger.basic.enable=true
Hystrix
spring.datasource.druid.stat-view-servlet.enabled=falsefalse禁用,true开启)
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.login-username=
spring.datasource.druid.stat-view-servlet.login-password=
endpoints.enabled = false
endpoints:
management:

代码执行/表达式执行

审计的注意点

  • 重点审计具有加载类、反序列化类、对类字节码进行操作的功能和代码

关键函数或字符串查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
eval
classLoader
$$BCEL$$
ServiceLoader
ToolProvider.getSystemJavaCompiler()
getSystemClassLoader
JavaFileObject
JdbcRowSetImpl
TemplatesImpl
TransformerFactoryImpl
resolveClass
loadClass
javax.el.ELProcessor
SpelExpressionParser
org.springframework.expression.spel.standard
parseExpression
expression.getValue()
expression.setValue()

Zip文件提取

审计的注意点

  • 重点主要关注应用是否存在ZIP解压缩功能

关键函数或字符串查找

1
2
3
4
FileInputStream
ZipInputStream
getSize()
ZipEntry

业务逻辑漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1. 用户登陆、用户注册、找回密码等功能中密码信息未采用加密算法。
2. 用户登陆、用户注册、找回密码等功能中`未采用验证码`或`验证码未做安全刷新`(未刷新Session中验证码的值)导致的撞库、密码爆破漏洞。
3. 找回密码逻辑问题(如:可直接跳过验证逻辑直接发包修改)。
4. 手机、邮箱验证、找回密码等涉及到动态验证码`未限制验证码失败次数`、`验证码有效期`、`验证码长度过短`导致的验证码爆破问题。
5. 充值、付款等功能调用了第三方支付系统未正确校验接口(与第三方的交互、与客户的交互,主要查看逻辑问题)。
6. 后端采用了`ORM框架`更新操作时因处理不当导致可以更新用户表任意字段(如:用户注册、用户个人资料修改时可以`直接创建管理员账号`或其他越权修改操作)。
7. 后端采用了`ORM框架`查询数据时因处理不当导致可以接收任何参数导致的越权查询、敏感信息查询等安全问题。
8. 用户中心转账、修改个人资料、密码、退出登陆等功能未采用验证码或`Token机制`导致存在`CSRF漏洞`。
9. 后端服务过于信任前端,重要的参数和业务逻辑只做了前端验证(如:文件上传功能的文件类型只在JS中验证、后端不从Session中获取用户ID、用户名而是直接接收客户端请求的参数导致的`越权问题`)。
10. 用户身份信息认证逻辑问题(如:后台系统自动登陆时直接读取Cookie中的用户名、用户权限不做验证)。
11. 重要接口采用`ID自增、ID可预测并且云端未验证参数有效性`导致的越权访问、信息泄漏问题(如:任意用户订单越权访问)。
12. `条件竞争问题`,某些关键业务(如:用户转账)不支持并发、分布式部署时不支持锁的操作等。
13. 重要接口`未限制请求频率`,导致短信、邮件、电话、私信等信息轰炸。
14. 敏感信息未保护,如`Cookie中直接存储用户密码等重要信息`,跟踪cookie中的变量最终到了哪。
15. 弱加密算法、弱密钥,如勿把Base64当成数据加密方式、重要算法密钥采用弱口令如`123456`。
16. 后端无异常处理机制、未自定义50X错误页面,服务器异常导致敏感信息泄漏(如:数据库信息、网站绝对路径等)。
17. 使用`DWR框架`开发时前后端不分漏洞(如:DWR直接调用数据库信息把用户登陆逻辑直接放到了前端来做)。

硬编码

审计的注意点

  • 审计源代码中是否有硬编码敏感信息。

关键函数或字符串查找

1
2
3
4
5
password
pass
jdbc
auth
key

不安全的反射

审计的注意点

  • 查看开发人员是否对反射调用方法、反射创建类实例进行了封装,并是否在对外的接口中进行了相关的调用。

关键函数或字符串查找

1
2
3
4
Class.forName
Method.invoke
newInstance
Worker/Invoker

使用了不安全的组件

1
组件例如 fastjson、jackson、xstream、shiro、xxl-job,框架例如 struts2、spring 等等,都要注意使用的版本问题。

模板注入

  1. 内建函数的利用:虽然FreeMarker中预制了大量的内建函数,极大地增强和拓展了模板的语言功能,但也可能引发一些危险操作。若研发人员不加以限制, 则很可能产生安全隐患。
  2. new函数的利用:new函数可以创建一个继承自freemarker.template.TemplateModel 类的实例,查阅源码会发现freemarker.template.utility.Execute#exec可以执行 任意代码,因此可以通过new函数实例化一个Execute对象并执行exec() 方法造成任意代码被执行。
1
2
3
4
5
ObjectConstructor:<#assign value="freemarker.template.utility.ObjectConstructor"?new()>${value("Java.lang. ProcessBuilder","calc.exe").start()}

JythonRuntime:<#assign value="freemarker.template.utility.JythonRuntime"?new()><@value>import os;os. system("calc.exe")</@value>

Execute:<#assign value="freemarker.template.utility.Execute"?new()>${value("calc.exe")}
  1. api函数的利用:api函数可以用来访问Java API,使用方法为value?api.someJavaMethod(),相当于value.someJavaMethod()。因此可以利用api函数通过 getClassLoader来获取一个类加载器,进而加载恶意类。也可以通过getResource来读取服务器上的资源文件。
1
2
<#assign classLoader=object?api.class.getClassLoader()>
${classLoader.loadClass("Evil.class")}

CSRF

审计的注意点

  • 一些增删改查方法,是否进行Referer头检验token检验 无法构造的随机数参数验证码密码

关键函数或字符串查找

1
session["token"]

越权

审计的注意点

  • 在每个request.getParameter("userid");之后查看是否有检验当前用户与要进行增删改查的用户。

关键函数或字符串查找

1
request.getParameter("userid")

文件包含

审计的注意点

  • 关注jsp是否存在文件包含的方法

关键函数或字符串查找

1
2
3
4
5
6
本地文件包含:
<jsp:include page="<%=file%>"></jsp:include>
<jsp:include page ="<%=file%>"/>
%@include file="test.jsp"%
远程文件包含:
<c:import url="<%= url%>"></c:import>

XMLDecoder反序列化

审计注意点

  • 观察传入XMLDecoder()的参数是否可控

关键函数或字符串查找

1
2
XMLDecoder decoder = new XMLDecoder(ins);
deocder.readObject()

BeanShell RCE

审计注意点

  • 查找参数是否可控

关键函数或字符串查找

1
2
Interpreter interpreter = new Interpreter();
Interpreter.eval(evalString)

SnakeYaml反序列化

审计注意点

  • 直接定位yaml.load(),然后进行回溯,查看下参数是否可控

关键函数或字符串查找

1
2
Yaml yaml = new Yaml()
yaml.load()

未授权访问/权限绕过

审计注意点

  • 查看权限校验的过滤器,观察是否存在校验不严格的路由,或者是否存在检验绕过的情况
  • 找出全部的请求路由

关键函数或字符串查找

1
2
3
@(.*?)Mapping(
request.getRequestURL()
request.getRequestURI()

参考

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代码审计入门篇》