发布于12月5日12月5日 #0x01 虎斑测试 测试版本:tabby v1.2.0-2 2023.02.24,tabby-path-finder-1.1.jar。 ## 1a 工具印象 参考文章:【基于代码属性图的自动化漏洞挖掘实践】(https://paper.seebug.org/2041/)、【利用tabby分析Spring Data MongoDB SpEL漏洞】(https://cn-sec.com/archives/1161260.html)、【尝试利用tabby挖掘CVE-2022-39198虎斑-KingBridge](https://www.cnblogs.com/kingbridge/articles/17020853.html)。 [撞糖](https://tttang.com/?keyword=tabby)共有三篇文章。 |事项|描述|补充| | - | - | - | |解决方案优势|支持分析编译好的War包、Jar包等| - | |工作流程|代码属性图生成阶段,生成带有污染信息的代码属性图|主要由tabby.core 负责| | - |在漏洞发现阶段,查询source-sink语句找到调用链接| neo4j 扩展虎斑路径查找器| Neo4j 扩展虎斑路径查找器 代码属性图生成阶段:如何抽象代码、如何分析代码的执行情况、如何设计图结构等。这些设计细节和实现细节暂时可以忽略,但需要知道该阶段最后生成的代码属性图的结构是什么。 找到代码属性图阶段:先了解Neo4j图数据库再看。 ## 1b 安装并运行 参考文章【Neo4j环境配置V5】(https://github.com/wh1t3p1g/tabby/blob/master/doc/Neo4j%20%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%20%20V5.md),访问官网下载dmg安装包,自动下载Neo4j 5.12.0,分别下载apoc-5.12.0-core.jar和apoc-5.12.0-extended.jar,访问下载[tabby-path-finder-1.0.jar](https://github.com/wh1t3p1g/tabby-path-finder/)(1.1主要适配tabby 2.x版本)。 Neo4j启动时遇到冲突,自动修改端口配置,无需关注: ```` 发现: 5000 → 5001 集群.raft: 7000 → 7001 ```` 配置一个conf文件和三个jar插件: ```` # 允许apoc 扩展 dbms.security.procedures.unrestricted=jwt.security.*,apoc.*,虎斑猫.* ```` 然后启动数据库,查询如下: CALL apoc.help('all') 调用tabby.help('tabby'),成功导入tabby-path-finder-1.1.jar 导入tabby-path-finder-1.0.jar,可以发现导入成功,但是小于1.1程序 提前索引节点: ```` 如果不存在(c:Class),则创建约束c1 要求c.ID 唯一; 如果不存在(c:Class),则创建约束c2 要求c.NAME 是唯一的; 创建约束c3 IF 不存在(m:Method) 要求m.ID 唯一; 创建约束c4 如果不存在(m:Method) 要求m.签名是唯一的; CREATE INDEX index1 IF NOT EXISTS FOR (m:Method) ON (m.NAME); CREATE INDEX index2 IF NOT EXISTS FOR (m:Method) ON (m.CLASSNAME); CREATE INDEX index3 IF NOT EXISTS FOR (m:Method) ON (m.NAME, m.CLASSNAME); CREATE INDEX index4 IF NOT EXISTS FOR (m:Method) ON (m.NAME, m.NAME0); CREATE INDEX index5 IF NOT EXISTS FOR (m:Method) ON (m.SIGNATURE); CREATE INDEX index6 IF NOT EXISTS FOR (m:Method) ON (m.NAME0); CREATE INDEX index7 IF NOT EXISTS FOR (m:Method) ON (m.NAME0, m.CLASSNAME); ```` 分析jar文件,打开config/settings.properties,配置tabby.build.target,然后运行tabby。 ```` java -Xmx8g -jar tabby.jar ```` 操作如图: ## 1c 运行配置 陷阱:我使用小工具分析模式来审核系统。我运行了一整天,直到看到网页分析模式。 参考:【Tabby配置文件介绍.md】(https://github.com/wh1t3p1g/tabby/blob/master/doc/Tabby%20%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E4%BB%8B%E7%BB%8D.md),针对不同场景的config/settings.properties配置: - 建议打开调试模式,以便可以看到tabby的工作内容; - JDK依赖是否参与分析,默认为false - 配置分析目标,不对依赖库进行全量分析,选择web或gadget模式进行分析。 ```` tabby.debug.details=true tabby.build.target=案例/java-sec-code-1.0.0.jar tabby.build.libraries=库 tabby.build.mode=web # 分析类型web 或gadget ```` ## 1d 测试结果 直接分析254MB的Jar包,发现总共有16万个类。首先我们跑了一晚上也没跑完,然后又打开debug模式跑了四个小时也没跑完。 我搜索了相关资料,发现Github地址中有一个trick,但是手动检查哪些功能卡住了,工作量很大,目前还没有找到解决的方法。 其次是扫描31MB的业务源代码,其中不包含lib库。 2w+节课,需要七分钟。 ## 1e 踩坑记录 java -Xmx6g -jar tabby.jar,254MB Jar包,9w+个类,测试发现堆面积不够。 给我8G内存,我跑了三个小时也没跑完。 #0x02 图数据库Neo4j Neo4j的属性图模型由节点和关系组成,Cypher是Neo4j的图查询语言,可以从图中检索数据。 ## 2a 入门 参考官方文档:【使用Cypher查询Neo4j数据库】(https://neo4j.com/docs/getting-started/cypher-intro/)。本节介绍Neo4j是由节点和关系组成的,并介绍三个表示符号()、[]、{}。 节点的主要组成部分: - 描述:是图中的数据实体,用括号来描述节点如(node) - 变量:为变量命名,方便后续引用,如(p)代表person - 标签:可以通过分配节点标签将相似的节点分组在一起 |表示示例|意义| | - | - | | ()|匿名节点可以指向数据库中的任意节点| | (p:人) |使用变量p 和标签Person | | (:科技) |没有变量的技术标签| | (work:公司) |使用可变工作和标签公司| 关系:Cypher 使用箭头-- 或-- 来指示两个节点之间的有向关系,并使用两个破折号-- 来指示无向关系。其他信息放在箭头内的方括号中。 |关系类型|\t描述| | - | - | |[:Likes]\t|只有当节点放在关系的两边时才有意义| |[:Is_Friends_With]\t|只有将节点放在一起才有意义| |[:Works_For]\t|对节点有意义| 节点或关系的属性:属性是名称-值对,提供有关节点和关系的附加详细信息,使用花括号表示。 |事项\t|示例\t|-| | - | - |- | |节点属性|\t(p:Person {name: 'Sally'})\t| |关系属性\t|-[rel:Is_Friends_With {since: 2018}] -| ## 2b 概念指南 参考官方文档:【教程:构建Cypher推荐引擎】(https://neo4j.com/docs/getting-started/appendix/tutorials/guide-build-a-recommendation-engine/)。 根据提示打开neo4j Browser,在左栏找到Neo4j Browser Guides,查看指南概念。 ### 属性图 图数据库可以通过一些基本概念来表示任何类型的数据: |属性图的组成部分\t|描述| | - | - | |Nodes 节点\t|代表域的实体| |labels\t|通过对节点进行分组构建域| |关系\t|连接两个节点| |properties\t|添加命名值作为节点和关系的属性| ### 节点 neo4j 将数据存储到图的节点中。 最简单的图只有一个节点,其中包含一些称为属性的键值。例如,绘制社交图:画一个有节点的圆圈,添加名字Emil,并标记他来自瑞典。 关键信息: - 节点通常表示可以用零个或多个标签进行分类的实体或离散对象 - 数据作为节点的属性存储 - 属性是简单的键值对 ### 标签 用于关联一组节点,例如为创建的Emil节点添加标签Person,并将Person节点标记为红色。 关键信息: - 一个节点可以有零个或多个标签 - 标签用于对节点进行分类 ### 更多节点 Neo4j 是无模式的,没有行和列的概念。 Neo4j 中的数据可以通过添加更多节点来存储,这些节点可以具有许多共同或独特的属性。 ### 关系 Neo4j 真正的魅力在于互联数据。要关联任意两个节点,您可以添加描述这些记录如何关联的关系。 在社交图中,您可以简单地说谁认识谁,使用“知道”作为节点之间的关系。 ### 关系属性 存储两个节点共享的信息。 在属性图中,关系还可以包含描述关系的属性,例如自2001 年以来的已知属性。 ## 2c 密码指南 Cypher 是Neo4j 的图查询语言,专为查询图数据而设计。 - 使用模式来描述图形数据 - 类似SQL的语句 - 声明式,描述要查询什么数据,而不是如何查询数据 |事项\t|声明\t|补充| | - | - |- | |创建节点|\tCREATE (ee:Person {name: 'Emil', from: 'Sweden', kloutScore: 99})\t|ee 为临时别名,图中节点显示属性值| |查找节点|\tMATCH (ee:Person) WHERE ee.name='Emil' RETURN ee; |\tee 如果替换为| 则具有相同的效果 |创建节点和关系|\tMatch Create (), (), (ee)-[:KNOWS {since: 2001}]-(js),\t|此处Macth 查询Emil 以向其添加关系。该关系也是使用Create 创建的。这里的关系是已知且没有命名别名| |某种类型的查询节点|\tmatch (any:Person) 返回any\t|所有Person组的查询节点| ### 2d 尝试查询代码属性图 ####查看图数据库信息 您可以看到有250,000 个节点、370,000 个属性、700,000 个关系和12 种关系类型。 #### 查看关系类型等 尝试:match [any:relationship Type ID] return any;查询会报错,只能查询到该节点。 搜索资料,找到文章:【neo4j图数据库,如何cypher查询标签/类型/属性等信息? ](https://newsn.net/say/neo4j-schema-2.html)。 |事项\t|声明\t|补充| | - | - |- | |可视化查看图表\t|调用db.schema.visualization\t|使用call调用内置命令查看信息| |获取所有标签|\tmatch (n) return labels(n) match (n) return unique(labels(n)) call db.labels\t| unique 关键字,用于重复数据删除| |获取所有关系类型|\tmatch (n)-[r]-(m) 返回不同类型(r) 调用db.relationshipTypes|\teg 知道/喜欢| |获取所有节点属性\t|\tmatch (n) 展开键(n),因为allkeys 返回不同的allkeys\t|-| #### 查看Java对象和方法 如图所示,有3个节点标签和5种关系类型。 #0x03 tabby-某赛通测试 使用网页模式扫描发现有3万个类别。速度应该很快,最终用了20分钟。 ## 3a 如何检查 参考文章:【如何高效挖掘Java反序列化利用链? -wh1t3p1g](https://blog.0kami.cn/blog/2021/how_to_find_gadget_chains/)。 为了构建图查询语言,文章提供了一个模板。 PS:指导后完善查询语句。 procedure中使用apoc时需要使用ALIAS|CALL,使用tabby-path-finder时需要使用-。 (使用- 关系的查询速度更快) ```` match(source:Method) //添加where语句限制源函数 match(sink:Method {IS_SINK:true}) //添加where语句限制sink函数 call apoc.algo.allSimplePaths(m1, source, \'ALIAS|CALL\', 12) Yield Path //查找具体路径,12代表深度,可以修改 匹配(来源:方法) 返回* 限制20 ```` 查询:java文件导入声明是类名,如import javax.servlet.http.HttpServletRequest。 |查询事项|\t查询语句\t |效果| | - | - |- | |查询Tomcat的请求|\tmatch(source:Class {NAME:\'javax.servlet.http.HttpServletRequest\'}) return source\t |单节点| |查询FileOutputStream\t |Match (sink:Class {NAME:\'java.io.FileOutputStream\'}) return sink\t |发现属性和值区分大小写| |查询链接\t |见下文\t |发现CALL和Alias只有方法-方法| 查询链接 ```` 匹配(source:Method {NAME:\'getParameter\'}) Match (sink:Method {NAME:\'FileOutputStream\'})-[:CALL]-(m1:Method) 调用apoc.algo.allSimplePaths(m1, source, \'ALIAS|CALL\', 12) 生成路径 返回* 限制20 ```` ## 3b 静态分析的技术问题 问:Tabby 好像没有污点流分析? request.getParameter() 和request.getInputStream() 都无法跟踪并确认是否发现危险函数。 tabby首先对类/方法等节点进行建模,然后构建调用图时生成的调用边会添加pollution_positions来保存污染信息(方法和关系的属性)。 PS:我感觉除了调用图之外,其他大部分信息都是存储在属性中的,需要慢慢摸索它的功能。 ## 3c端点识别 ### 文章示例 参考文章:像专业人士一样进行tabby java 代码审查第三部分[KCon2022].pdf 像专业人士一样查找Java Web 漏洞。 Tabby 默认内置以下端点标识: - 支柱类型 - Servlet 类型 - JSP类型 - 注释类型 查询语句模板: ```` 匹配(source:方法{IS_ENDPOINT:true}) 以collect(source)作为来源 ```` 示例: ```` 匹配(source:Method {NAME:\'doAction\'}) -[:HAS]-(c:Class)-[:接口|扩展*] -(c1:Class {NAME:\'nc.bs.framework.adaptor.IHttpServletAdaptor\'}) 以collect(source)作为来源 匹配(sink:Method {IS_SINK: true,VUL:\'FILE_WRITE\'
创建帐户或登录后发表意见