From 7c0b91b7cc0141f57398f1e87280232da96d3a0c Mon Sep 17 00:00:00 2001 From: bit4woo Date: Mon, 1 Feb 2021 16:12:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0SQLMap=E5=92=8CNmap=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E9=80=BB=E8=BE=91=EF=BC=8C2=E7=A7=8D?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E5=8F=AF=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/burp/RobotInput.java | 19 ++- src/burp/TerminalExec.java | 198 +++++++++++++++++++++++++++++++ src/config/ConfigTableModel.java | 1 + src/config/GUI.java | 2 +- src/knife/DoPortScanMenu.java | 70 +++++------ src/knife/RunSQLMapMenu.java | 50 ++++++-- 6 files changed, 285 insertions(+), 55 deletions(-) create mode 100644 src/burp/TerminalExec.java diff --git a/src/burp/RobotInput.java b/src/burp/RobotInput.java index 8e35fa2..e5d721e 100644 --- a/src/burp/RobotInput.java +++ b/src/burp/RobotInput.java @@ -188,7 +188,7 @@ public final String getSelectedString(){ String selectedString = (String)clip.getData(DataFlavor.stringFlavor); System.out.println("复制之前剪切板中的内容:"+selectedString); - + inputWithCtrl(KeyEvent.VK_C); final String result = (String)clip.getData(DataFlavor.stringFlavor); //selectedString = (String)clip.getData(DataFlavor.stringFlavor); @@ -203,10 +203,10 @@ public final String getSelectedString(){ e.printStackTrace(); } return ""; -// 复制之前剪切板中的内容:printStackTrace -// 复制之后剪切板中的内容:null -// 恢复之后剪切板中的内容:printStackTrace -// printStackTrace//最后的值随着剪切板的恢复而改变了,应该是引用传递的原因。所有需要将复制后的值设置为final。 + // 复制之前剪切板中的内容:printStackTrace + // 复制之后剪切板中的内容:null + // 恢复之后剪切板中的内容:printStackTrace + // printStackTrace//最后的值随着剪切板的恢复而改变了,应该是引用传递的原因。所有需要将复制后的值设置为final。 } //单个 按键 @@ -239,4 +239,13 @@ public static void startCmdConsole() { e.printStackTrace(); } } + + /* + * parserPath --- python.exe java.exe .... + * executerPath --- sqlmap.py nmap.exe .... + * parameters ---- -v -A -r xxx.file ..... + */ + public static String genCmd(String parserPath,String executerPath, String parameter) { + return burp.TerminalExec.genCmd(parserPath, executerPath, parameter); + } } \ No newline at end of file diff --git a/src/burp/TerminalExec.java b/src/burp/TerminalExec.java new file mode 100644 index 0000000..a4aee4d --- /dev/null +++ b/src/burp/TerminalExec.java @@ -0,0 +1,198 @@ +package burp; + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; + +import org.apache.commons.io.FileUtils; + +/* + * 在系统terminal中执行命令,实现思路: + * 1、将命令写入bat文件 + * 2、通过执行bat文件执行命令 + */ +public class TerminalExec { + + String workdir; + String cmdContent; + String FullBatchFilePath; + + public String getWorkdir() { + return workdir; + } + + public void setWorkdir(String workdir) { + this.workdir = workdir; + } + + public String getCmdContent() { + return cmdContent; + } + + public void setCmdContent(String cmdContent) { + this.cmdContent = cmdContent; + } + + public String getFullBatchFilePath() { + return FullBatchFilePath; + } + + public void setFullBatchFilePath(String fullBatchFilePath) { + FullBatchFilePath = fullBatchFilePath; + } + + /* + * workdir --the dir of batch file + * + */ + public TerminalExec(String workdir, String batchFileName,String parserPath,String executerPath, String parameter){ + if (workdir == null) { + workdir = (String) System.getProperties().get("java.io.tmpdir"); + } + cmdContent = changeDirCommand(workdir); + cmdContent = cmdContent +genCmd(parserPath,executerPath,parameter); + FullBatchFilePath = genBatchFile(cmdContent,batchFileName); + } + + public void run() { + executeBatchFile(FullBatchFilePath); + } + + /* + * 通知执行bat文件来执行命令 + */ + public static Process executeBatchFile(String batfilepath) { + String command = ""; + if (Utils.isWindows()) { + command="cmd /c start " + batfilepath; + } else { + if (new File("/bin/sh").exists()) { + command="/bin/sh " + batfilepath; + } + else if (new File("/bin/bash").exists()) { + command="/bin/bash " + batfilepath; + } + } + try { + Process process = Runtime.getRuntime().exec(command); + return process; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public String genBatchFile(String cmdContent, String batchFileName) { + try { + //将命令写入剪切板 + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + StringSelection selection = new StringSelection(cmdContent); + clipboard.setContents(selection, null); + + if (batchFileName == null || batchFileName.trim().equals("")) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMdd-HHmmss"); + String timeString = simpleDateFormat.format(new Date()); + batchFileName = timeString+".bat"; + }else if(!batchFileName.endsWith(".bat") && !batchFileName.endsWith(".cmd")) { + batchFileName = batchFileName+".bat"; + } + + File batFile = new File(workdir,batchFileName); + if (!batFile.exists()) { + batFile.createNewFile(); + } + + FileUtils.writeByteArrayToFile(batFile, cmdContent.getBytes()); + return batFile.getAbsolutePath(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + /* + * 切换工作目录 + */ + public String changeDirCommand(String dir){ + //运行命令的工作目录,work path + String command = "cd "+dir+System.lineSeparator(); + + if (Utils.isWindows()) {//如果是windows,还要注意不同磁盘的切换 + String diskString = dir.split(":")[0]; + command =command+ diskString+":"+System.lineSeparator(); + } + return command; + } + + /* + * parserPath --- python.exe java.exe .... + * executerPath --- sqlmap.py nmap.exe .... + * parameters ---- -v -A -r xxx.file ..... + */ + public static String genCmd(String parserPath,String executerPath, String parameter) { + StringBuilder command = new StringBuilder(); + + if ((parserPath != null && new File(parserPath).exists() && new File(parserPath).isFile()) + || isInEnvironmentPath(parserPath)){ + + if (parserPath.contains(" ")) { + parserPath = "\""+parserPath+"\"";//如果路径中包含空格,需要引号 + } + command.append(parserPath); + command.append(" "); + } + + if ((executerPath != null && new File(executerPath).exists() && new File(executerPath).isFile()) + || isInEnvironmentPath(executerPath)){ + + if (executerPath.contains(" ")) { + executerPath = "\""+executerPath+"\"";//如果路径中包含空格,需要引号 + } + + command.append(executerPath); + command.append(" "); + } + + if (parameter != null && !parameter.equals("")) { + command.append(parameter); + } + command.append(System.lineSeparator()); + return command.toString(); + } + + /* + * 判断某个文件是否在环境变量中 + */ + public static boolean isInEnvironmentPath(String filename) { + if (filename == null) { + return false; + } + String pathvalue = System.getenv().get("Path"); +// System.out.println(pathvalue); + String[] items = pathvalue.split(";"); + for (String item:items) { + File tmpPath = new File(item); + if (tmpPath.isDirectory()) { +// System.out.println(Arrays.asList(tmpPath.listFiles())); + File fullpath = new File(item,filename); + if (Arrays.asList(tmpPath.listFiles()).contains(fullpath)) { + return true; + }else { + continue; + } + } + } + return false; + } + + public static void main(String[] args) { + System.out.println(isInEnvironmentPath("nmap.exe")); + TerminalExec xxx = new TerminalExec(null,"nmap-test.bat",null,"nmap.exe","-v -A www.baidu.com"); + xxx.run(); + } +} diff --git a/src/config/ConfigTableModel.java b/src/config/ConfigTableModel.java index 08eff16..255d55e 100644 --- a/src/config/ConfigTableModel.java +++ b/src/config/ConfigTableModel.java @@ -36,6 +36,7 @@ public ConfigTableModel(){ configEntries.add(new ConfigEntry("SQLMap-Options","--risk=3 --level=3",ConfigEntry.Config_Basic_Variable,true,false)); configEntries.add(new ConfigEntry("Nmap-File-Path","D:\\Program Files (x86)\\Nmap\\nmap.exe",ConfigEntry.Config_Basic_Variable,true,false)); + configEntries.add(new ConfigEntry("RunTerminalWithRobotInput","enable",ConfigEntry.Config_Basic_Variable,true,false,"this config effect sqlmap and nmap")); configEntries.add(new ConfigEntry("Chunked-Length", "10",ConfigEntry.Config_Chunked_Variable,true,false)); configEntries.add(new ConfigEntry("Chunked-AutoEnable", "",ConfigEntry.Config_Chunked_Variable,false,false)); diff --git a/src/config/GUI.java b/src/config/GUI.java index e59d964..9d99601 100644 --- a/src/config/GUI.java +++ b/src/config/GUI.java @@ -58,7 +58,7 @@ public class GUI extends JFrame { protected JScrollPane configPanel; private SortOrder sortedMethod; public ConfigTable table;//create in burpextender.java - public ConfigTableModel tableModel;//create in burpextender.java + public static ConfigTableModel tableModel;//create in burpextender.java private JButton RemoveButton; private JButton AddButton; private JSplitPane TargetSplitPane; diff --git a/src/knife/DoPortScanMenu.java b/src/knife/DoPortScanMenu.java index e48493f..cb4e4eb 100644 --- a/src/knife/DoPortScanMenu.java +++ b/src/knife/DoPortScanMenu.java @@ -1,28 +1,20 @@ package knife; -import java.awt.Robot; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.io.File; -import java.io.IOException; import java.io.PrintWriter; import java.util.HashSet; import java.util.Set; import javax.swing.JMenuItem; -import org.apache.commons.io.FileUtils; - import burp.BurpExtender; import burp.IBurpExtenderCallbacks; import burp.IContextMenuInvocation; import burp.IExtensionHelpers; import burp.IHttpRequestResponse; import burp.RobotInput; -import burp.Utils; +import burp.TerminalExec; public class DoPortScanMenu extends JMenuItem { @@ -33,7 +25,7 @@ public class DoPortScanMenu extends JMenuItem { //JMenuItem vs. JMenu public DoPortScanMenu(BurpExtender burp){ - this.setText("^_^ Do Port Scan"); + this.setText("^_^ Run Nmap"); this.addActionListener(new DoPortScan_Action(burp,burp.invocation)); } } @@ -41,7 +33,7 @@ public DoPortScanMenu(BurpExtender burp){ class DoPortScan_Action implements ActionListener{ private IContextMenuInvocation invocation; - public BurpExtender myburp; + public BurpExtender myburp; public IExtensionHelpers helpers; public PrintWriter stdout; public PrintWriter stderr; @@ -51,52 +43,50 @@ class DoPortScan_Action implements ActionListener{ public DoPortScan_Action(BurpExtender burp,IContextMenuInvocation invocation) { this.invocation = invocation; this.burp = burp; - this.helpers = burp.helpers; - this.callbacks = burp.callbacks; - this.stderr = burp.stderr; + this.helpers = burp.helpers; + this.callbacks = burp.callbacks; + this.stderr = burp.stderr; } - + @Override public void actionPerformed(ActionEvent actionEvent) { try{ + boolean useRobot = (BurpExtender.tableModel.getConfigValueByKey("RunTerminalWithRobotInput") != null); + if (useRobot) { + RobotInput.startCmdConsole();//尽早启动减少出错概率 + } + IHttpRequestResponse[] messages = invocation.getSelectedMessages(); Set hosts = new HashSet(); - - for(IHttpRequestResponse message:messages) { - String host = message.getHttpService().getHost(); - hosts.add(host); - } - - RobotInput ri = new RobotInput(); - for(String host:hosts) { - RobotInput.startCmdConsole(); - String command = genNmapCmd(host); - ri.inputString(command); + for(IHttpRequestResponse message:messages) { + String host = message.getHttpService().getHost(); + hosts.add(host); } + String nmapPath = burp.tableModel.getConfigValueByKey("Nmap-File-Path"); + if (nmapPath ==null || nmapPath.trim().equals("")) { + nmapPath = "nmap.exe"; + } + RobotInput ri = new RobotInput(); + for(String host:hosts) { + if (useRobot) { + //RobotInput.startCmdConsole(); + String command = RobotInput.genCmd(null,nmapPath,"-v -A -p 1-65535 "+host.trim()); + ri.inputString(command); + }else { + TerminalExec exec = new TerminalExec(null,"nmap-knife.bat",null,nmapPath,"-v -A -p 1-65535 "+host.trim()); + exec.run(); + } + } } catch (Exception e1) { e1.printStackTrace(BurpExtender.getStderr()); } } - - public String genNmapCmd(String host) { - String nmapPath = burp.tableModel.getConfigValueByKey("Nmap-File-Path"); - if (nmapPath ==null || nmapPath.trim().equals("")) { - nmapPath = "nmap"; - }else if (nmapPath.contains(" ")) {//如果路径中包含空格,需要引号 - nmapPath = "\""+nmapPath+"\""; - } - - String command = nmapPath+" -v -A -p 1-65535 "+host.trim()+System.lineSeparator(); - return command; - } - - public static void main(String[] args){ } } diff --git a/src/knife/RunSQLMapMenu.java b/src/knife/RunSQLMapMenu.java index 84845eb..1996111 100644 --- a/src/knife/RunSQLMapMenu.java +++ b/src/knife/RunSQLMapMenu.java @@ -19,6 +19,7 @@ import burp.IExtensionHelpers; import burp.IHttpRequestResponse; import burp.RobotInput; +import burp.TerminalExec; import burp.Utils; @@ -42,6 +43,7 @@ class RunSQLMap_Action implements ActionListener{ public PrintWriter stderr; public IBurpExtenderCallbacks callbacks; public BurpExtender burp; + public String workdir; public RunSQLMap_Action(BurpExtender burp,IContextMenuInvocation invocation) { this.burp = burp; @@ -50,6 +52,7 @@ public RunSQLMap_Action(BurpExtender burp,IContextMenuInvocation invocation) { this.callbacks = burp.callbacks; this.stderr = burp.stderr; this.stdout = burp.stdout; + workdir = (String) System.getProperties().get("java.io.tmpdir"); } @Override @@ -61,11 +64,41 @@ public void run() { RobotInput ri = new RobotInput(); IHttpRequestResponse[] messages = invocation.getSelectedMessages(); if (messages !=null) { + + boolean useRobot = (BurpExtender.tableModel.getConfigValueByKey("RunTerminalWithRobotInput") != null); + if (useRobot) { + RobotInput.startCmdConsole();//尽早启动减少出错概率 + } + IHttpRequestResponse message = messages[0]; String requestFilePath = RequestToFile(message); - RobotInput.startCmdConsole(); - String sqlmapCmd = genSqlmapCmd(requestFilePath); - ri.inputString(sqlmapCmd); + String pythonPath = burp.tableModel.getConfigValueByKey("SQLMap-Python-Path"); + String sqlmapPath = burp.tableModel.getConfigValueByKey("SQLMap-SQLMap.py-Path"); + String sqlmapOptions = burp.tableModel.getConfigValueByKey("SQLMap-Options"); + + if (pythonPath ==null || pythonPath.trim().equals("")) { + pythonPath = "python.exe"; + } + + if (sqlmapPath ==null || sqlmapPath.trim().equals("")) { + sqlmapPath = "sqlmap.py"; + } + + String paras = " -r "+requestFilePath; + if (sqlmapOptions != null) { + paras = paras+" "+sqlmapOptions; + } + + if (useRobot) { + //方案1:使用模拟输入实现 + //RobotInput.startCmdConsole();//尽早启动减少出错概率 + String sqlmapCmd = RobotInput.genCmd(pythonPath, sqlmapPath, paras); + ri.inputString(sqlmapCmd); + }else { + //方案2:使用bat文件实现 + TerminalExec xxx = new TerminalExec(workdir,"sqlmap-knife.bat",pythonPath, sqlmapPath, paras); + xxx.run(); + } } } catch (Exception e1) @@ -89,13 +122,12 @@ public String RequestToFile(IHttpRequestResponse message) { String timeString = simpleDateFormat.format(new Date()); String filename = host+"."+timeString+".req"; - String basedir = (String) System.getProperties().get("java.io.tmpdir"); String configBasedir = burp.tableModel.getConfigValueByKey("SQLMap-Request-File-Path"); if (configBasedir != null && new File(configBasedir).exists()) { - basedir = configBasedir; + workdir = configBasedir; } - File requestFile = new File(basedir,filename); + File requestFile = new File(workdir,filename); FileUtils.writeByteArrayToFile(requestFile, message.getRequest()); return requestFile.getAbsolutePath(); } catch (IOException e) { @@ -130,9 +162,9 @@ public String genSqlmapCmd(String requestFilePath) { String pythonPath = burp.tableModel.getConfigValueByKey("SQLMap-Python-Path"); String sqlmapPath = burp.tableModel.getConfigValueByKey("SQLMap-SQLMap.py-Path"); StringBuilder command = new StringBuilder(); - + command.append(changeDirCommand()); - + if (pythonPath != null && new File(pythonPath).exists()) { if (new File(pythonPath).isFile()) { command.append(pythonPath); @@ -141,7 +173,7 @@ public String genSqlmapCmd(String requestFilePath) { } command.append(" "); } - + if (sqlmapPath != null && new File(sqlmapPath).exists()) { if (new File(sqlmapPath).isFile()) { command.append(sqlmapPath);