当前位置: 首页 > news >正文

Codeql复现CVE-2018-11776学习笔记

基本使用

1、首先下载struts2漏洞版本源码:
https://codeload.github.com/apache/struts/zip/refs/tags/STRUTS_2_3_20
2、构建codeql数据库(构建失败文末有解决办法):

codeql database create ~/CodeQL/databases/struts2-2.3.20-database  --language="java"  --command="mvn clean install --file pom.xml" --source-root=~/CodeQL/struts-STRUTS_2_3_20/xwork-core

QL代码编写

source的建模

以S2-032 ( CVE-2016-3081 )、S2-033 ( CVE-2016-3687 ) 和S2-037 ( CVE-2016-4438 )为例,这三个漏洞都是与调用ognlUtil.getValue有关,比如下列代码:

String methodName = proxy.getMethod();    //<--- untrusted source, but where from?
LOG.debug("Executing action method = {}", methodName);
String timerKey = "invokeAction: " + proxy.getActionName();
try {UtilTimerStack.push(timerKey);Object methodResult;try {methodResult = ognlUtil.getValue(methodName + "()", getStack().getContext(), action); //<--- RCE

上面的代码中使用了proxy.getMethod()方法来获取不受信任的数据源,最终导致了调用ognlUtil.getValue造成了RCE,但除此之外还有各种方法,例如getActionName()和getNamespace(),所以可以编写如下QL代码,对这些不受信任的源进行建模:

class ActionProxyGetMethod extends Method {ActionProxyGetMethod() {getDeclaringType().getASupertype*().hasQualifiedName("com.opensymphony.xwork2", "ActionProxy") and(hasName("getMethod") orhasName("getNamespace") orhasName("getActionName"))}
}predicate isActionProxySource(DataFlow::Node source) {source.asExpr().(MethodAccess).getMethod() instanceof ActionProxyGetMethod
}

因为proxy是com.opensymphony.xwork2.ActionProxy类型,所以getDeclaringType().getASupertype*().hasQualifiedName(“com.opensymphony.xwork2”, “ActionProxy”),其中*号代表递归

sink的建模

S2-032、S2-033和S2-037使用了 OgnlUtil::getValue(),然而在漏洞 S2-045(CVE-2017-5638)中,使用了 TextParseUtil::translateVariables(),所以推测一下OgnlUtil::compileAndExecute() 和 OgnlUtil::compileAndExecuteMethod() 也可能存在漏洞,所以对传入compileAndExecute、和compileAndExecute的sink进行建模:

predicate isOgnlSink(DataFlow::Node sink) {exists(MethodAccess ma | ma.getMethod().hasName("compileAndExecute") or ma.getMethod().hasName("compileAndExecuteMethod") | ma.getMethod().getDeclaringType().getName().matches("OgnlUtil") and sink.asExpr() = ma.getArgument(0))
}

MethodAccess表示方法访问,即当调用xxx.compileAndExecute或者xxx.compileAndExecuteMethod
ma.getMethod().getDeclaringType().getName().matches(“OgnlUtil”)表示该方法所在的类为OgnlUtil。

进行污点追踪

之前已经定义好了sink和source,所以直接将这两个套进去,这里重写了一个isAdditionalFlowStep,用来衔接一些没匹配到的参数。

class OgnlTaintTrackingCfg extends DataFlow::Configuration {OgnlTaintTrackingCfg() {this = "mapping"}override predicate isSource(DataFlow::Node source) {isActionProxySource(source)}override predicate isSink(DataFlow::Node sink) {isOgnlSink(sink)}override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {TaintTracking::localTaintStep(node1, node2) orexists(Field f, RefType t | node1.asExpr() = f.getAnAssignedValue() and node2.asExpr() = f.getAnAccess() andnode1.asExpr().getEnclosingCallable().getDeclaringType() = t andnode2.asExpr().getEnclosingCallable().getDeclaringType() = t)}
}from OgnlTaintTrackingCfg cfg, DataFlow::Node source, DataFlow::Node sink
where cfg.hasFlow(source, sink)
select source, sink

isAdditionalFlowStep用于衔接一些没匹配上的数据流,简单来说可能有如下情况,在调用bar()时没有提前调用foo(),导致数据流并不认为foo到bar是连通的所以默认DataFlow::Configuration是不包括这个流步骤的,因为也不能确定bar()中对this.field的访问总是被污染的,但是在漏洞挖掘中,包含这种形式的调用是非常有意义的。

public void foo(String taint) {this.field = taint;
}public void bar() {String x = this.field; //x is tainted because field is assigned to tainted value in `foo`
}

对isAdditionalFlowStep进行逐步分析:
TaintTracking::localTaintStep(node1, node2) 测试node1到node2的连通性。
Field 表示字段,RefType表示除了原始类型(int、float等)、null、数组的任何类型
f.getAnAssignedValue()表示获取被赋值给该字段的表达式。例如有一个字段int a,其中a = 10+20,那么表达式为10+20
f.getAnAccess()表示该字段的访问。例如int y = x;//访问字段x
node1.asExpr() = f.getAnAssignedValue() and node2.asExpr() = f.getAnAccess()这段连起来:表示有一个获取被赋值给字段的表达式node1,node2表达式对该字段进行了访问。
node1.asExpr().getEnclosingCallable().getDeclaringType() = t and node2.asExpr().getEnclosingCallable().getDeclaringType() = t表示node1和node2都是同一个类

初版代码

import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTrackingclass ActionProxyGetMethod extends Method{ActionProxyGetMethod(){getDeclaringType().getASupertype*().hasQualifiedName("com.opensymphony.xwork2", "ActionProxy") and(hasName("getMethod") orhasName("getActionName") orhasName("getNamespace"))}
}predicate isActionProxySource(DataFlow::Node source) {source.asExpr().(MethodAccess).getMethod() instanceof ActionProxyGetMethod}predicate isOgnlSink(DataFlow::Node sink) {exists(MethodAccess ma | ma.getMethod().hasName("compileAndExecute") or ma.getMethod().hasName("compileAndExecuteMethod") | ma.getMethod().getDeclaringType().getName().matches("OgnlUtil") and sink.asExpr() = ma.getArgument(0))
}class OgnlTaintTrackingCfg extends DataFlow::Configuration {OgnlTaintTrackingCfg() {this = "mapping"}override predicate isSource(DataFlow::Node source) {isActionProxySource(source)}override predicate isSink(DataFlow::Node sink) {isOgnlSink(sink)}override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {TaintTracking::localTaintStep(node1, node2) orexists(Field f, RefType t | node1.asExpr() = f.getAnAssignedValue() and node2.asExpr() = f.getAnAccess() andnode1.asExpr().getEnclosingCallable().getDeclaringType() = t andnode2.asExpr().getEnclosingCallable().getDeclaringType() = t)}}from OgnlTaintTrackingCfg cfg, DataFlow::Node source, DataFlow::Node sinkwhere cfg.hasFlow(source, sink)select source, sink

改进isBarrier

查看数据流步骤:
在这里插入图片描述

在数据流经过几步之后,调用getActionName()返回的值流入到了对pkg.getActionConfigs()返回的对象上调用get()的一个参数中:

String chainedTo = actionName + nameSeparator + resultCode; //actionName comes from `getActionName` somewhere
ActionConfig chainedToConfig = pkg.getActionConfigs().get(chainedTo); //chainedTo contains `actionName` and ended up in the `get` method.

点进入ValueStackShadowMap::get()函数内部,代码类似如下:

public Object get(Object key) {Object value = super.get(key);  //<--- key gets tainted?if ((value == null) && key instanceof String) {value = valueStack.findValue((String) key);  //<--- findValue ended up evaluating `key`}return value;
}

通过查看数据流步骤发现,因为pkg.getActionConfigs()返回一个Map,而ValueStackShadowMap实现了Map接口,理论上,pkg.getActionConfigs()返回的值可能是ValueStackShadowMap的一个实例。因此,CodeQL DataFlow库显示了从变量chainedTo到ValueStackShadowMap类中get()实现的这一潜在流动。

但实际上,ValueStackShadowMap类属于jasperreports插件,且该类的实例只在几个地方创建,其中没有任何一个是通过pkg.getActionConfigs()返回的。所以ValueStackShadowMap::get()可能是个误报,不太可能被触发。

定义一个isBarrier,如果污点数据流入ValueStackShadowMap的get()或containsKey()方法,则不继续跟踪它。

override predicate isBarrier(DataFlow::Node node) {exists(Method m | (m.hasName("get") or m.hasName("containsKey")) andm.getDeclaringType().hasName("ValueStackShadowMap") andnode.getEnclosingCallable() = m)
}

最终代码:
https://github.com/Semmle/SecurityQueries/blob/master/semmle-security-java/queries/struts/cve_2018_11776/initial.ql

坑点

1、构建数据库失败
~/CodeQL/struts-STRUTS_2_3_20/xwork-core/target/surefire-reports

-------------------------------------------------------------------------------
Test set: TestSuite
-------------------------------------------------------------------------------
Tests run: 741, Failures: 5, Errors: 0, Skipped: 0, Time elapsed: 13.404 sec <<< FAILURE!
testSetPropertiesDate(com.opensymphony.xwork2.ognl.OgnlUtilTest)  Time elapsed: 0.011 sec  <<< FAILURE!
junit.framework.AssertionFailedError: expected:<Fri Feb 12 00:00:00 CST 1982> but was:<null>at junit.framework.Assert.fail(Assert.java:47)at junit.framework.Assert.failNotEquals(Assert.java:283)at junit.framework.Assert.assertEquals(Assert.java:64)at junit.framework.Assert.assertEquals(Assert.java:71)at com.opensymphony.xwork2.ognl.OgnlUtilTest.testSetPropertiesDate(OgnlUtilTest.java:351)testRangeValidation(com.opensymphony.xwork2.validator.DateRangeValidatorTest)  Time elapsed: 0.028 sec  <<< FAILURE!
junit.framework.AssertionFailedError: Expected date range validation error message.at junit.framework.Assert.fail(Assert.java:47)at junit.framework.Assert.assertTrue(Assert.java:20)at junit.framework.Assert.assertNotNull(Assert.java:214)at com.opensymphony.xwork2.validator.DateRangeValidatorTest.testRangeValidation(DateRangeValidatorTest.java:60)testVisitorChildConversionValidation(com.opensymphony.xwork2.validator.VisitorFieldValidatorTest)  Time elapsed: 0.015 sec  <<< FAILURE!
junit.framework.AssertionFailedError: expected:<6> but was:<4>at junit.framework.Assert.fail(Assert.java:47)at junit.framework.Assert.failNotEquals(Assert.java:283)at junit.framework.Assert.assertEquals(Assert.java:64)at junit.framework.Assert.assertEquals(Assert.java:195)at junit.framework.Assert.assertEquals(Assert.java:201)at com.opensymphony.xwork2.validator.VisitorFieldValidatorTest.testVisitorChildConversionValidation(VisitorFieldValidatorTest.java:189)testVisitorChildValidation(com.opensymphony.xwork2.validator.VisitorFieldValidatorTest)  Time elapsed: 0.015 sec  <<< FAILURE!
junit.framework.AssertionFailedError: expected:<5> but was:<3>at junit.framework.Assert.fail(Assert.java:47)at junit.framework.Assert.failNotEquals(Assert.java:283)at junit.framework.Assert.assertEquals(Assert.java:64)at junit.framework.Assert.assertEquals(Assert.java:195)at junit.framework.Assert.assertEquals(Assert.java:201)at com.opensymphony.xwork2.validator.VisitorFieldValidatorTest.testVisitorChildValidation(VisitorFieldValidatorTest.java:167)testContextIsPropagated(com.opensymphony.xwork2.validator.VisitorFieldValidatorTest)  Time elapsed: 0.008 sec  <<< FAILURE!
junit.framework.AssertionFailedError: expected:<3> but was:<2>at junit.framework.Assert.fail(Assert.java:47)at junit.framework.Assert.failNotEquals(Assert.java:283)at junit.framework.Assert.assertEquals(Assert.java:64)at junit.framework.Assert.assertEquals(Assert.java:195)at junit.framework.Assert.assertEquals(Assert.java:201)at com.opensymphony.xwork2.validator.VisitorFieldValidatorTest.testContextIsPropagated(VisitorFieldValidatorTest.java:153)

报错的都是一些测试方法,解决方法:删除测试目录,即:
~/CodeQL/struts-STRUTS_2_3_20/xwork-core/src/test

参考链接

https://www.freebuf.com/articles/web/283795.html (入门推荐)
https://securitylab.github.com/research/apache-struts-CVE-2018-11776/

相关文章:

Codeql复现CVE-2018-11776学习笔记

基本使用 1、首先下载struts2漏洞版本源码&#xff1a; https://codeload.github.com/apache/struts/zip/refs/tags/STRUTS_2_3_20 2、构建codeql数据库&#xff08;构建失败文末有解决办法&#xff09;&#xff1a; codeql database create ~/CodeQL/databases/struts2-2.3.…...

CVE-2024-27199 JetBrains TeamCity 身份验证绕过漏洞2

漏洞简介 TeamCity Web 服务器中发现了第二个身份验证绕过漏洞。这种身份验证旁路允许在没有身份验证的情况下访问有限数量的经过身份验证的端点。未经身份验证的攻击者可以利用此漏洞修改服务器上有限数量的系统设置&#xff0c;并泄露服务器上有限数量的敏感信息。 项目官网…...

ms office学习记录12:Excel学习记录㈥

数据工具 分列的其他运用&#xff1a;身份证号中“出生日期”切片&#xff1a;分列→固定宽度→下一步→切割出三列→下一步→不导入第一列→导入第二列且转换成日期→不导入第三列→完成 删除重复值&#xff1a;定位到要“数据”选项卡→删除重复项→取消全选再勾选要删除的…...

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的条形码二维码检测系统(深度学习+UI界面+训练数据集+Python代码)

摘要&#xff1a;在物流和制造业中&#xff0c;开发一套高效的条形码与二维码识别系统显得尤为关键。本博文深入探讨了如何利用深度学习技术打造出一套先进的条形码及二维码检测系统&#xff0c;并且提供了一套完整的实施方案。该系统搭载了性能卓越的YOLOv8算法&#xff0c;并…...

npm yarn 一起使用报错

项目记录&#xff0c;具有独特性&#xff0c;仅供参考 项目好好的运行&#xff0c;前一天装个测试工具包&#xff0c; 突然就不行了&#xff0c;卸载重装也不行&#xff0c;所有的项目都安装失败&#xff0c;新起一个项目也不行&#xff0c;有时候某个单独安装一个包可以&…...

基于springboot实现驾校信息管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现驾校信息管理系统演示 摘要 随着人们生活水平的不断提高&#xff0c;出行方式多样化&#xff0c;也以私家车为主&#xff0c;那么既然私家车的需求不断增长&#xff0c;那么基于驾校的考核管理也就不断增强&#xff0c;那么业务系统也就慢慢的随之加大。信息…...

DXP软件界面显示“No Hard Devices”【简单的操作问题】加【软件下载】

目录 一&#xff0c;DXP软件界面显示“No Hard Devices” 二&#xff0c;软件下载的百度网盘资源 一&#xff0c;DXP软件界面显示“No Hard Devices” Protel DXP是2004是澳大利亚Altium公司于2002年推出的一款电子设计自动化软件。它的主要功能包括&#xff1a;原理图编辑、印…...

通过Spring Boot 实现页面配置生成动态接口?

流程介绍 在Spring Boot中实现页面配置生成动态接口通常涉及几个关键步骤: 设计页面配置:首先,你需要设计一个用户界面(UI),允许用户通过此界面来配置接口的各种参数,例如HTTP方法(GET、POST等)、URL路径、请求参数、响应数据格式等。保存配置信息:当用户通过页面配置…...

【数据结构与算法】:插入排序与希尔排序

&#x1f525;个人主页&#xff1a; Quitecoder &#x1f525;专栏: 数据结构与算法 欢迎大家来到初阶数据结构的最后一小节&#xff1a;排序 目录 1.排序的基本概念与分类1.1什么是排序的稳定性&#xff1f;1.2内排序与外排序内排序外排序 2.插入排序2.1实现插入排序2.3稳定性…...

前端性能优化——javascript

优化处理&#xff1a; 讲javascript脚本文件放到body标记的后面 减少页面当中所包含的script标记的数量 课堂练习&#xff1a; 脚本优化处理 使用原生JavaScript完成操作过程。 document.querySelector document.querySelectorAll classList以及类的操作API Element.class…...

Docker容器化技术(使用Docker搭建论坛)

第一步&#xff1a;删除容器镜像文件 [rootlocalhost ~]# docker rm -f docker ps -aq b09ee6438986 e0fe8ebf3ba1第二步&#xff1a;使用docker拉取数据库 [rootlocalhost ~]# docker run -d --name db mysql:5.7 02a4e5bfffdc81cb6403985fe4cd6acb0c5fab0b19edf9f5b8274783…...

C# ListView 控件使用

1.基本设置 listView1.Columns.Add("序号", 60); //向 listView1控件中添加1列 同时设置列名称和宽度listView1.Columns.Add("温度", 100); //下同listView1.Columns.Add("偏移", 100);listView1.Columns.Add("分割", 50);listView1…...

【string一些函数用法的补充】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 string类对象的修改操作 我们来看 c_str 返回c格式的字符串的操作&#xff1a; 我们来看 rfind 和 substr 的操作&#xff1a; string类非成员函数 我们来看 r…...

【Go】令牌桶限流算法

1. 限流 限流&#xff0c;顾名思义&#xff0c;限制用户请求流量&#xff0c;避免大规模并发导致系统宕机。 2. 令牌桶算法 令牌管理员以恒定的速率向令牌桶里放置一个令牌。如果桶满&#xff0c;就丢弃令牌。 请求到达时&#xff0c;都要先去令牌桶里取一个令牌&#xff0c…...

go的slice学习

并发访问slice 线上出现一粒多协程并发append全局slice的情况&#xff0c;导致内存不断翻倍&#xff0c;因此对slice的使用需要重新考虑。 并发读写的情况下&#xff0c; 可以利用锁、channel等避免竞态 问题 func TestDemo32(t *testing.T) {var wg sync.WaitGroupvar n 1…...

软件设计师17--磁盘管理

软件设计师17--磁盘管理 考点1&#xff1a;存储管理 - 磁盘管理调度算法磁盘调度 - FCFS磁盘调度 - SSTF例题&#xff1a; 考点1&#xff1a;存储管理 - 磁盘管理 存取时间寻道时间等待时间&#xff0c;训导时间是指磁头移动到磁道所需的时间&#xff1b;等待时间为等待读写的扇…...

学点Java打小工——Day2Day3一点作业

1 猜数字&#xff08;10次机会&#xff09; 随机生成[1,1000]的一个数&#xff0c;输入你猜的数程序会给出反馈&#xff0c;直到猜对或次数用尽(10次)。 //猜数字 10次机会Testpublic void guessNumber() {Random random new Random();// [0, 1000) 1// [1, 1000]int num ra…...

【话题】2024年AI辅助研发趋势,有那些应用领域

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读文章&#xff01; 此篇是【话题达人】系列文章&#xff0c;这一次的话题是《2024年AI辅助研发趋势》 目录 背景概念实践医药领域汽车设计领域展望未来文章推荐 背景 随着人工智能技术的持续发展与突破&#xff0c;2024年AI辅…...

蓝桥杯——数组切分

数组切分 题目分析 这里要搞清楚一个点就是满足区间内数字是连续数字的区间有什么样的特点&#xff0c;既然数字连续重新排列后的数字为n,n1,n2,n3,n4,…nlen&#xff0c;则最大数字和最小数字之差恰好是区间长度减1&#xff0c;即nlen-nlen&#xff0c;同样因为下标也是连续…...

【机器学习】进阶学习:详细解析Sklearn中的MinMaxScaler---原理、应用、源码与注意事项

【机器学习】进阶学习&#xff1a;详细解析Sklearn中的MinMaxScaler—原理、应用、源码与注意事项 这篇文章的质量分达到了97分&#xff0c;虽然满分是100分&#xff0c;但已经相当接近完美了。请您耐心阅读&#xff0c;我相信您一定能从中获得不少宝贵的收获和启发~ &#x1f…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...