From 4e4741d80e5ebd8b799629ccdb9c080f87a8fcf5 Mon Sep 17 00:00:00 2001 From: retnullyu <1902008285@qq.com> Date: Wed, 1 Dec 2021 17:27:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 7 ++ README.md | 14 +++ pom.xml | 45 ++++++++ src/main/java/burp/BurpExtender.java | 22 ++++ src/main/java/burp/Config.java | 99 ++++++++++++++++ src/main/java/burp/ConfigDlg.java | 138 +++++++++++++++++++++++ src/main/java/burp/DirsearchStarter.java | 84 ++++++++++++++ src/main/java/burp/GBC.java | 57 ++++++++++ src/main/java/burp/Menu.java | 49 ++++++++ src/main/java/burp/Util.java | 99 ++++++++++++++++ 10 files changed, 614 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/burp/BurpExtender.java create mode 100644 src/main/java/burp/Config.java create mode 100644 src/main/java/burp/ConfigDlg.java create mode 100644 src/main/java/burp/DirsearchStarter.java create mode 100644 src/main/java/burp/GBC.java create mode 100644 src/main/java/burp/Menu.java create mode 100644 src/main/java/burp/Util.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3ecd0c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/out +/.idea +*.class +src/META-INF/* +.DS_Store +target/ +*.iml% diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee7f66d --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# burp加载dirsearch +## 项目介绍 +项目改自[sqlmap4burp++](https://github.com/c0ny1/sqlmap4burp-plus-plus),其实本质都是一样,调用python启动本地[dirsearch](https://github.com/maurosoria/dirsearch),sqlmap读取request数据改为--raw即可 + +## 插件编译 + +``` +mvn clean package +``` + +## 参考项目 +* https://github.com/blueroutecn/Burpsuite4Extender +* https://github.com/difcareer/sqlmap4burp +* https://github.com/c0ny1/sqlmap4burp-plus-plus diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9ab4f3b --- /dev/null +++ b/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + retnull.top + burp2dirsearch + 0.1 + + + + + net.portswigger.burp.extender + burp-extender-api + 1.7.22 + + + + 1.6 + 1.6 + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + + + jar-with-dependencies + + + + + + diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java new file mode 100644 index 0000000..4a4420e --- /dev/null +++ b/src/main/java/burp/BurpExtender.java @@ -0,0 +1,22 @@ +package burp; + +import java.io.PrintWriter; + +public class BurpExtender implements IBurpExtender { + public static IExtensionHelpers helpers; + public static IBurpExtenderCallbacks callbacks; + public static PrintWriter stdout; + public static PrintWriter stderr; + + @Override + public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) { + this.helpers = callbacks.getHelpers(); + this.callbacks = callbacks; + this.stdout = new PrintWriter(callbacks.getStdout(),true); + this.stderr = new PrintWriter(callbacks.getStderr(),true); + + callbacks.registerContextMenuFactory(new Menu()); + callbacks.setExtensionName(String.format("%s %s",Config.getExtenderName(),Config.getExtenderVersion())); + stdout.println(Util.getBanner()); + } +} diff --git a/src/main/java/burp/Config.java b/src/main/java/burp/Config.java new file mode 100644 index 0000000..5c95515 --- /dev/null +++ b/src/main/java/burp/Config.java @@ -0,0 +1,99 @@ +package burp; + +public class Config { + private static final String EXTENDER_NAME = "burp2dirsearch"; + private static final String EXTENDER_VERSION = "0.1"; + private static String PYTHON_NAME = "python3"; + private static String DIRSEARCH_PATH = "dirsearch"; + private static String REQUST_FILE_PATH = ""; + private static String DIRSEARCH_OPTIONS_COMMAND = ""; + private static String OS_TYPE; + private static boolean IS_INJECT = false; + + + public static String getExtenderName() { + return EXTENDER_NAME; + } + + public static String getExtenderVersion() { + return EXTENDER_VERSION; + } + + public static String getPythonName() { + try { + String val = BurpExtender.callbacks.loadExtensionSetting("PYTHON_NAME"); + if(val == null){ + return Config.PYTHON_NAME; + }else{ + return val; + } + }catch(Exception e){ + return Config.PYTHON_NAME; + } + } + + public static void setPythonName(String pythonName) { + BurpExtender.callbacks.saveExtensionSetting("PYTHON_NAME", String.valueOf(pythonName)); + Config.DIRSEARCH_PATH = pythonName; + } + + public static String getDirsearch() { + try { + String val = BurpExtender.callbacks.loadExtensionSetting("DIRSEARCH_PATH"); + if(val == null){ + return Config.DIRSEARCH_PATH; + }else{ + return val; + } + }catch(Exception e){ + return Config.DIRSEARCH_PATH; + } + } + + public static void setDirsearchPath(String dirsearch) { + BurpExtender.callbacks.saveExtensionSetting("DIRSEARCH_PATH", String.valueOf(dirsearch)); + Config.DIRSEARCH_PATH = dirsearch; + } + + public static String getRequstFilePath() { + return REQUST_FILE_PATH; + } + + public static void setRequstFilePath(String requstFilePath) { + REQUST_FILE_PATH = requstFilePath; + } + + public static String getDirsearchOptionsCommand() { + try { + String val = BurpExtender.callbacks.loadExtensionSetting("DIRSEARCH_OPTIONS_COMMAND"); + if(val == null){ + return Config.DIRSEARCH_OPTIONS_COMMAND; + }else{ + return val; + } + }catch(Exception e){ + return Config.DIRSEARCH_OPTIONS_COMMAND; + } + } + + public static void setDirsearchOptionsCommand(String dirsearchOptionsCommand) { + BurpExtender.callbacks.saveExtensionSetting("DIRSEARCH_OPTIONS_COMMAND", String.valueOf(dirsearchOptionsCommand)); + Config.DIRSEARCH_OPTIONS_COMMAND = dirsearchOptionsCommand; + } + + public static String getOsType() { + return OS_TYPE; + } + + public static void setOsType(String osType) { + OS_TYPE = osType; + } + + public static boolean isIsInject() { + return IS_INJECT; + } + + public static void setIsInject(boolean isInject) { + IS_INJECT = isInject; + } +} diff --git a/src/main/java/burp/ConfigDlg.java b/src/main/java/burp/ConfigDlg.java new file mode 100644 index 0000000..23aac9f --- /dev/null +++ b/src/main/java/burp/ConfigDlg.java @@ -0,0 +1,138 @@ +package burp; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +/** + * 配置窗口类,负责显示配置窗口,处理窗口消息 + */ +public class ConfigDlg extends JDialog { + private final JPanel mainPanel = new JPanel(); + + private final JLabel lbPythonName = new JLabel("Python name:"); + private final JTextField tfPythonName = new JTextField(30); + private final JLabel lbDirsearchPath = new JLabel("dirsearch path:"); + private final JTextField tfDirsearchPath = new JTextField(30); + private final JButton btnBrowse = new JButton("Browse"); + private final JLabel lbDirsearchOption = new JLabel("dirsearch option:"); + private final JTextField tfDirsearchOption = new JTextField(30); + private final JLabel lbPrompt = new JLabel("Prompt:"); + + private final JButton btnOK = new JButton("OK"); + private final JButton btnCancel = new JButton("Cancel"); + + + public ConfigDlg(){ + initGUI(); + initEvent(); + initValue(); + this.setTitle("burp2dirsearch config"); + } + + + /** + * 初始化UI + */ + private void initGUI(){ + JLabel lbPythonNameHelp = new JLabel("?"); + lbPythonNameHelp.setToolTipText("eg: python,python2,python3,py2,py3,..."); + JLabel lbDirsearchOptionHelp = new JLabel("?"); + lbDirsearchOptionHelp.setToolTipText("eg: --skip-on-status/size,-t..."); + + mainPanel.setLayout(new GridBagLayout()); + mainPanel.add(lbPythonName,new GBC(0,0,2,1).setFill(GBC.BOTH).setInsets(10,10,2,0)); + mainPanel.add(tfPythonName, new GBC(2,0,3,1).setFill(GBC.BOTH).setInsets(10,0,2,10)); + mainPanel.add(lbPythonNameHelp,new GBC(5,0,6,1).setFill(GBC.BOTH).setInsets(10,0,2,10)); + mainPanel.add(lbDirsearchPath,new GBC(0,1,2,1).setFill(GBC.BOTH).setInsets(10,10,2,0)); + mainPanel.add(tfDirsearchPath,new GBC(2,1,3,1).setFill(GBC.BOTH).setInsets(10,0,2,10)); + mainPanel.add(btnBrowse,new GBC(5,1,1,1).setFill(GBC.BOTH).setInsets(10,0,2,10)); + mainPanel.add(lbDirsearchOption,new GBC(0,2,2,1).setFill(GBC.BOTH).setInsets(10,10,2,0)); + mainPanel.add(tfDirsearchOption,new GBC(2,2,3,1).setFill(GBC.BOTH).setInsets(10,0,2,10)); + mainPanel.add(lbDirsearchOptionHelp,new GBC(5,2,1,1).setFill(GBC.BOTH).setInsets(10,0,2,10)); + mainPanel.add(btnOK,new GBC(0,3,1,1).setFill(GBC.BOTH).setInsets(10,10,10,0)); + mainPanel.add(btnCancel,new GBC(1,3,1,1).setFill(GBC.BOTH).setInsets(10,0,10,10)); + + if(Util.getOSType() == Util.OS_LINUX){ + lbPrompt.setText("Notice: The command will be copied to the clipboard. Paste it into Terminal!"); + mainPanel.add(lbPrompt,new GBC(2,3,1,1).setFill(GBC.BOTH).setInsets(10,0,2,10)); + }else if(Util.getOSType() == Util.OS_MAC){ + lbPrompt.setText("Notice: Please ensure that Terminal is in running state!"); + mainPanel.add(lbPrompt,new GBC(2,3,1,1).setFill(GBC.BOTH).setInsets(10,0,2,10)); + } + lbPrompt.setForeground(new Color(0,0,255)); + + this.setModal(true); + this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + this.add(mainPanel); + //使配置窗口自动适应控件大小,防止部分控件无法显示 + this.pack(); + //居中显示配置窗口 + Dimension screensize=Toolkit.getDefaultToolkit().getScreenSize(); + this.setBounds(screensize.width/2-this.getWidth()/2,screensize.height/2-this.getHeight()/2,this.getWidth(),this.getHeight()); + BurpExtender.callbacks.customizeUiComponent(this); + } + + + /** + * 初始化事件 + */ + private void initEvent(){ + + btnBrowse.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JFileChooser chooser = new JFileChooser(); + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);//设置只能选择目录 + int returnVal = chooser.showOpenDialog(ConfigDlg.this); + if(returnVal == JFileChooser.APPROVE_OPTION) { + String selectPath =chooser.getSelectedFile().getPath() ; + tfDirsearchPath.setText(selectPath); + chooser.hide(); + } + } + }); + + + btnOK.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Config.setIsInject(true); + Config.setPythonName(tfPythonName.getText().trim()); + Config.setDirsearchPath(tfDirsearchPath.getText().trim()); + Config.setDirsearchOptionsCommand(tfDirsearchOption.getText().trim()); + ConfigDlg.this.dispose(); + } + }); + + btnCancel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Config.setIsInject(false); + ConfigDlg.this.dispose(); + } + }); + + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + super.windowClosing(e); + Config.setIsInject(false); + } + }); + + } + + + /** + * 为控件赋值 + */ + public void initValue(){ + tfPythonName.setText(Config.getPythonName()); + //BurpExtender.stderr.println("Python name:"+Config.getPythonName()); + tfDirsearchPath.setText(Config.getDirsearch()); + tfDirsearchOption.setText(Config.getDirsearchOptionsCommand()); + } +} \ No newline at end of file diff --git a/src/main/java/burp/DirsearchStarter.java b/src/main/java/burp/DirsearchStarter.java new file mode 100644 index 0000000..eb71766 --- /dev/null +++ b/src/main/java/burp/DirsearchStarter.java @@ -0,0 +1,84 @@ +package burp; + +import javax.swing.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +/** + * @program: burp2dirsearch + * @description: start dirsearch + * @author: luoyu + * @create: 2021-12-01 16:27 + **/ + +public class DirsearchStarter implements Runnable { + @Override + public void run() { + try { + String command = String.format("%s \"%s\" --raw \"%s\" %s",Config.getPythonName(),Config.getDirsearch(),Config.getRequstFilePath(),Config.getDirsearchOptionsCommand()); + List cmds = new ArrayList(); + int osType = Util.getOSType(); + if(osType == Util.OS_WIN){ + cmds.add("cmd.exe"); + cmds.add("/c"); + cmds.add("start"); + String batFilePath = Util.makeBatFile("burp2dirsearch.bat",command); + if(!batFilePath.equals("Fail")){ + cmds.add(batFilePath); + }else{ + String eMsg = "make burp2dirsearch.bat fail!"; + JOptionPane.showMessageDialog(null,eMsg,"burp2dirsearch++ alert",JOptionPane.ERROR_MESSAGE); + return; + } + }else if(osType == Util.OS_MAC){ + String optionCommand = Config.getDirsearchOptionsCommand(); + //将参数数中的"转译为\" + optionCommand = optionCommand.replace("\"","\\\""); + command = String.format("%s \\\"%s\\\" --raw \\\"%s\\\" %s",Config.getPythonName(),Config.getDirsearch(),Config.getRequstFilePath(),optionCommand); + cmds.add("osascript"); + cmds.add("-e"); + String cmd = "tell application \"Terminal\" \n" + + " activate\n" + + " do script \"%s\"\n" + + "end tell"; + cmds.add(String.format(cmd,command)); + //BurpExtender.stdout.println(String.format(cmd,command)); + }else if(osType == Util.OS_LINUX){ + cmds.add("/bin/sh"); + cmds.add("-c"); + cmds.add("gnome-terminal"); + Util.setSysClipboardText(command); + JOptionPane.showMessageDialog(null,"The command has been copied to the clipboard. Please paste it into Terminal for execution","burp2dirsearch++ alert",JOptionPane.OK_OPTION); + }else{ + cmds.add("/bin/bash"); + cmds.add("-c"); + cmds.add(command); + } + + ProcessBuilder processBuilder = new ProcessBuilder(cmds); + Process process = processBuilder.start(); + InputStreamReader ir = new InputStreamReader(process.getInputStream()); + BufferedReader input = new BufferedReader (ir); + String line; + while ((line = input.readLine()) != null) { + BurpExtender.stdout.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + BurpExtender.stderr.println("[*]" + e.getMessage()); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public static void main(String[] args) { +// new Thread(new SqlmapStarter()).start(); + Properties properties = System.getProperties(); + System.out.println(properties.get("java.io.tmpdir")); + } +} diff --git a/src/main/java/burp/GBC.java b/src/main/java/burp/GBC.java new file mode 100644 index 0000000..f821459 --- /dev/null +++ b/src/main/java/burp/GBC.java @@ -0,0 +1,57 @@ +package burp; + +import java.awt.*; + +public class GBC extends GridBagConstraints { + // 初始化左上角位置 + public GBC(int gridx, int gridy) { + this.gridx = gridx; + this.gridy = gridy; + } + + // 初始化左上角位置和所占行数和列数 + public GBC(int gridx, int gridy, int gridwidth, int gridheight) { + this.gridx = gridx; + this.gridy = gridy; + this.gridwidth = gridwidth; + this.gridheight = gridheight; + } + + // 对齐方式 + public GBC setAnchor(int anchor) { + this.anchor = anchor; + return this; + } + + // 是否拉伸及拉伸方向 + public GBC setFill(int fill) { + this.fill = fill; + return this; + } + + // x和y方向上的增量 + public GBC setWeight(double weightx, double weighty) { + this.weightx = weightx; + this.weighty = weighty; + return this; + } + + // 外部填充 + public GBC setInsets(int distance) { + this.insets = new Insets(distance, distance, distance, distance); + return this; + } + + // 外填充 + public GBC setInsets(int top, int left, int bottom, int right) { + this.insets = new Insets(top, left, bottom, right); + return this; + } + + // 内填充 + public GBC setIpad(int ipadx, int ipady) { + this.ipadx = ipadx; + this.ipady = ipady; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/burp/Menu.java b/src/main/java/burp/Menu.java new file mode 100644 index 0000000..dd4de8c --- /dev/null +++ b/src/main/java/burp/Menu.java @@ -0,0 +1,49 @@ +package burp; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + + +public class Menu implements IContextMenuFactory { + + @Override + public List createMenuItems(final IContextMenuInvocation invocation) { + List list = new ArrayList(); + +// if(invocation.getInvocationContext() != IContextMenuInvocation.CONTEXT_MESSAGE_EDITOR_REQUEST){ +// return list; +// } + + JMenuItem jMenuItem = new JMenuItem("Send to dirsearch"); + list.add(jMenuItem); + jMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ConfigDlg cfd = new ConfigDlg(); + cfd.show(); + + if(Config.isIsInject()) { + IHttpRequestResponse[] messages = invocation.getSelectedMessages(); + byte[] req = messages[0].getRequest(); + IHttpService httpService = messages[0].getHttpService(); + String host = httpService.getHost().replace(".", "_"); + int port = httpService.getPort(); + + SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); + String data = df.format(new Date()); + String requstFilename = String.format("%s_%s_%s.req", host, port, data); + String reqFilePath = Util.getTempReqName(requstFilename); + Util.writeFile(req, reqFilePath); + new Thread(new DirsearchStarter()).start(); + Config.setIsInject(false); + } + } + }); + return list; + } +} diff --git a/src/main/java/burp/Util.java b/src/main/java/burp/Util.java new file mode 100644 index 0000000..7591866 --- /dev/null +++ b/src/main/java/burp/Util.java @@ -0,0 +1,99 @@ +package burp; + + +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.util.Properties; + +public class Util { + public static final int OS_WIN = 1; + public static final int OS_MAC = 2; + public static final int OS_LINUX = 3; + public static final int OS_UNKOWN = 4; + + public static String getOSName(){ + return System.getProperties().getProperty("os.name").toUpperCase(); + } + + + public static int getOSType(){ + String OS_NAME = getOSName(); + if(OS_NAME.contains("WINDOW")){ + return OS_WIN; + }else if(OS_NAME.contains("MAC")){ + return OS_MAC; + }else if(OS_NAME.contains("LINUX")){ + return OS_LINUX; + }else { + return OS_UNKOWN; + } + } + + + public static void writeFile(byte[] bytes,String filepath){ + try { + //writePath 为最终文件路径名 如:D://test.txt + FileOutputStream fos = new FileOutputStream(filepath); + fos.write(bytes); + fos.close(); + } catch (Exception e) { + //e.printStackTrace(); + BurpExtender.stderr.println("[*] " + e.getMessage()); + } + } + + + public static String getTempReqName(String filename) { + Properties properties = System.getProperties(); + String tempDir = (String) properties.get("java.io.tmpdir"); + Config.setRequstFilePath(tempDir + File.separator + filename); + return Config.getRequstFilePath(); + } + + + public static String makeBatFile(String filename,String content){ + Properties properties = System.getProperties(); + String tempDir = (String) properties.get("java.io.tmpdir"); + String batFile = (tempDir + File.separator + filename); + String sysEncoding = System.getProperty("file.encoding"); + try { + OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(batFile),sysEncoding); + BufferedWriter writer=new BufferedWriter(write); + writer.write(content); + writer.close(); + return batFile; + } catch (Exception e) { + BurpExtender.stderr.println("[*] "+e.getMessage()); + return "Fail"; + } + } + + + public static String getBanner(){ + String bannerInfo = + "[+] " + Config.getExtenderName() + " is loaded\n" + + "[+] " + Config.getExtenderName() + " v" + Config.getExtenderVersion() +"\n" + + "[+] anthor: retnull\n" + + "[+] email: xiaoluoyu110@gmail\n" + + "[+] github: retnullyu\n" + + "[+] blog: retnull.top\n" + + "[+] I won't admit bugs and do not add requirements,good luck to you"; + + + return bannerInfo; + } + + + public static void setSysClipboardText(String str) { + Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); + Transferable tText = new StringSelection(str); + clip.setContents(tText, null); + } +} +