diff --git a/out/artifacts/sql_sup/sql-sup.jar b/out/artifacts/sql_sup/sql-sup.jar new file mode 100644 index 0000000..d88f91e Binary files /dev/null and b/out/artifacts/sql_sup/sql-sup.jar differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e2d848a --- /dev/null +++ b/pom.xml @@ -0,0 +1,91 @@ + + + + 4.0.0 + + burp + sql-sup + 1.0-SNAPSHOT + + sql-sup + + http://www.example.com + + + UTF-8 + 1.7 + 1.7 + + + + + junit + junit + 4.11 + test + + + + net.portswigger.burp.extender + burp-extender-api + 1.7.22 + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + diff --git a/sql-sup.iml b/sql-sup.iml new file mode 100644 index 0000000..4098198 --- /dev/null +++ b/sql-sup.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java new file mode 100644 index 0000000..6f6042b --- /dev/null +++ b/src/main/java/burp/BurpExtender.java @@ -0,0 +1,33 @@ +package burp; + +import java.io.PrintWriter; + +public class BurpExtender implements IBurpExtender { + + public static IBurpExtenderCallbacks callbacks; + public static IExtensionHelpers helpers; + private String extensionName = "sql-sup(辅助)"; + private String version ="0.1"; + public static PrintWriter out; + + @Override + public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { + this.callbacks = callbacks; + this.helpers = callbacks.getHelpers(); + callbacks.setExtensionName(String.format("%s %s",extensionName,version)); + out = new PrintWriter(callbacks.getStdout(), true); + callbacks.registerContextMenuFactory(new Menu()); + callbacks.registerIntruderPayloadGeneratorFactory(new PayloadGenera()); + out.println(getBanner()); + } + + public String getBanner(){ + String bannerInfo = + "[+] ##############################################\n" + + "[+] " + extensionName + " v" + version +"\n" + + "[+] anthor: S9MF\n" + + "[+] github: https://github.com/S9MF/sql-sup\n" + + "[+] ##############################################"; + return bannerInfo; + } +} diff --git a/src/main/java/burp/Config.java b/src/main/java/burp/Config.java new file mode 100644 index 0000000..49b5ba4 --- /dev/null +++ b/src/main/java/burp/Config.java @@ -0,0 +1,94 @@ +package burp; + +public class Config { + private static Integer params_len = 1; + private static Integer key_len = 1; + private static Integer value_len = 1; + private static Integer number_len = 1; + private static Integer fuzz_number = 1; + private static String filePath; + + public static String getFilePath() { + String val = BurpExtender.callbacks.loadExtensionSetting("filePath"); + try { + return String.valueOf(val); + }catch (Exception e) { + return Config.filePath; + } + } + + public static void setFilePath(String filePath) { + BurpExtender.callbacks.saveExtensionSetting("filePath", String.valueOf(filePath)); + Config.filePath = filePath; + } + + public static Integer getFuzz_number() { + String val = BurpExtender.callbacks.loadExtensionSetting("fuzz_number"); + try { + return Integer.valueOf(val); + }catch (Exception e) { + return Config.fuzz_number; + } + } + + public static void setFuzz_number(Integer fuzz_number) { + BurpExtender.callbacks.saveExtensionSetting("fuzz_number", String.valueOf(fuzz_number)); + Config.fuzz_number = fuzz_number; + } + + public static Integer getParams_len() { + String val = BurpExtender.callbacks.loadExtensionSetting("params_len"); + try { + return Integer.valueOf(val); + }catch (Exception e) { + return Config.params_len; + } + } + + public static void setParams_len(Integer params_len) { + BurpExtender.callbacks.saveExtensionSetting("params_len", String.valueOf(params_len)); + Config.params_len = params_len; + } + + public static Integer getKey_len() { + String val = BurpExtender.callbacks.loadExtensionSetting("key_len"); + try { + return Integer.valueOf(val); + }catch (Exception e) { + return Config.key_len; + } + } + + public static void setKey_len(Integer key_len) { + BurpExtender.callbacks.saveExtensionSetting("key_len", String.valueOf(key_len)); + Config.key_len = key_len; + } + + public static Integer getValue_len() { + String val = BurpExtender.callbacks.loadExtensionSetting("value_len"); + try { + return Integer.valueOf(val); + }catch (Exception e) { + return Config.value_len; + } + } + + public static void setValue_len(Integer value_len) { + BurpExtender.callbacks.saveExtensionSetting("value_len", String.valueOf(value_len)); + Config.value_len = value_len; + } + + public static Integer getNumber_len() { + String val = BurpExtender.callbacks.loadExtensionSetting("number_len"); + try { + return Integer.valueOf(val); + }catch (Exception e) { + return Config.number_len; + } + } + + public static void setNumber_len(Integer number_len) { + BurpExtender.callbacks.saveExtensionSetting("number_len", String.valueOf(number_len)); + Config.number_len = number_len; + } +} diff --git a/src/main/java/burp/ConfigDlg.java b/src/main/java/burp/ConfigDlg.java new file mode 100644 index 0000000..474823e --- /dev/null +++ b/src/main/java/burp/ConfigDlg.java @@ -0,0 +1,158 @@ +package burp; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +public class ConfigDlg extends JDialog { + //定义组件 + private final JPanel mainPanel = new JPanel(); + private final JPanel toPanel = new JPanel(); + private final JPanel centerPanel = new JPanel(); + private final JPanel bottomPanel = new JPanel();; + private final JSpinner spNum = new JSpinner(new SpinnerNumberModel(1,1,200,1)); + private final JSpinner spKey = new JSpinner(new SpinnerNumberModel(1,1,200,1)); + private final JSpinner spValue = new JSpinner(new SpinnerNumberModel(1,1,200,1)); + private final JSpinner spNumber = new JSpinner(new SpinnerNumberModel(1,1,600,1)); + private final JSpinner spFuzzNumber = new JSpinner(new SpinnerNumberModel(1,1,20,1)); + private final JLabel kbText = new JLabel("byte字节"); + private final JLabel filePathText = new JLabel(); + private final JButton btCancel = new JButton("Cancel"); + private final JButton btSave = new JButton("Save"); + private final JButton bCalc = new JButton("Calc"); + private final JButton bSelect = new JButton("浏览"); + + public ConfigDlg() { + initGUI(); + initEvent(); + initValue(); + this.setTitle("SQLSup Config"); + } + //初始化组件 + private void initGUI() { + toPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); + toPanel.add(new JLabel("参数个数:")); + toPanel.add(spNum); + toPanel.add(new JLabel("(1-200)")); + toPanel.add(new JLabel(" key value:")); + toPanel.add(spKey); + toPanel.add(new JLabel("-")); + toPanel.add(spValue); + toPanel.add(new JLabel("(1-200)")); + toPanel.add(new JLabel(" number:")); + toPanel.add(spNumber); + toPanel.add(new JLabel("(1-600)")); + toPanel.add(kbText); + + centerPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); + centerPanel.add(new JLabel("Fuzz个数:")); + centerPanel.add(spFuzzNumber); + centerPanel.add(new JLabel("(1-20)")); + centerPanel.add(bSelect); + centerPanel.add(filePathText); + + + bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); + bottomPanel.add(btSave); + bottomPanel.add(bCalc); + bottomPanel.add(btCancel); + btSave.setToolTipText("Save(保存)配置"); + bCalc.setToolTipText("先Save(保存),再Calc(计算)"); + btCancel.setToolTipText("Cancel(取消)"); + + mainPanel.setLayout(new BorderLayout()); + mainPanel.add(toPanel,BorderLayout.NORTH); + mainPanel.add(centerPanel,BorderLayout.CENTER); + mainPanel.add(bottomPanel,BorderLayout.SOUTH); + + 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()); + } + //组件的事件响应 + private void initEvent() { + //取消按钮 + btCancel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ConfigDlg.this.dispose(); + } + }); + //保存按钮 + btSave.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Integer params_len = (Integer)spNum.getValue(); + Integer key_len = (Integer)spKey.getValue(); + Integer value_len = (Integer)spValue.getValue(); + Integer number_len = (Integer)spNumber.getValue(); + Integer fuzz_number = (Integer) spFuzzNumber.getValue(); + + Config.setParams_len(params_len); + Config.setKey_len(key_len); + Config.setValue_len(value_len); + Config.setNumber_len(number_len); + Config.setFuzz_number(fuzz_number); + + } + }); + //显示kb 先Save然后Calc + bCalc.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + byte[] bytes = Util.getRandomString(Config.getKey_len(), Config.getValue_len(), Config.getNumber_len()).getBytes(); + int kbNum = bytes.length; + String result = kbNum +""; + kbText.setText("(" + result+ "byte)"); + } + }); + //选择按钮 + bSelect.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("文本文件(*.txt)", "txt")); + int result = fileChooser.showOpenDialog(null); + if (result == fileChooser.APPROVE_OPTION) { + String filePath = fileChooser.getSelectedFile().getPath(); + Config.setFilePath(filePath); + } + } + }); + } + //为控件赋值 + public void initValue() { + spNum.setValue(Config.getParams_len()); + spKey.setValue(Config.getKey_len()); + spValue.setValue(Config.getValue_len()); + spNumber.setValue(Config.getNumber_len()); + spFuzzNumber.setValue(Config.getFuzz_number()); + filePathText.setText(Config.getFilePath()); + } +} + + + + + + + + + + + + + + + + diff --git a/src/main/java/burp/Menu.java b/src/main/java/burp/Menu.java new file mode 100644 index 0000000..465032b --- /dev/null +++ b/src/main/java/burp/Menu.java @@ -0,0 +1,90 @@ +package burp; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +public class Menu implements IContextMenuFactory { + @Override + public List createMenuItems(IContextMenuInvocation invocation) { + List menuList = new ArrayList<>(); + + JMenu sqlSupMenu = new JMenu("sql-sup(辅助)"); + JMenuItem paramoVerflowMenu = new JMenuItem("参数溢出"); + JMenuItem garbageDataMenu = new JMenuItem("垃圾数据"); + JMenuItem config = new JMenuItem("设置"); + + sqlSupMenu.add(paramoVerflowMenu); + sqlSupMenu.add(garbageDataMenu); + sqlSupMenu.add(config); + + paramoVerflowMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + IHttpRequestResponse iReqResp = invocation.getSelectedMessages()[0]; + byte[] request = new byte[0]; + try { + request = Util.paramoVerflowAction(iReqResp, Util.getSelect(invocation), Config.getParams_len()); + } catch (UnsupportedEncodingException ex) { + ex.printStackTrace(); + } + if (iReqResp != null) { + iReqResp.setRequest(request); + } + } + }); + + garbageDataMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + IHttpRequestResponse iReqResp = invocation.getSelectedMessages()[0]; + byte[] request = new byte[0]; + try { + request = Util.garbageDataAction(iReqResp, Util.getSelect(invocation)); + } catch (UnsupportedEncodingException ex) { + ex.printStackTrace(); + } + if (iReqResp != null) { + iReqResp.setRequest(request); + } + } + }); + + config.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ConfigDlg dlg = new ConfigDlg(); + BurpExtender.callbacks.customizeUiComponent(dlg); + dlg.setVisible(true); + } + }); + + menuList.add(sqlSupMenu); + return menuList; + } +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/burp/PayloadGenera.java b/src/main/java/burp/PayloadGenera.java new file mode 100644 index 0000000..a362b2b --- /dev/null +++ b/src/main/java/burp/PayloadGenera.java @@ -0,0 +1,60 @@ +package burp; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import static burp.Util.getFileContent; + +public class PayloadGenera implements IIntruderPayloadGeneratorFactory { + public static final byte[][] PAYLOADS = getPayloads(); + @Override + public String getGeneratorName() { + return "parameter fuzz"; + } + + @Override + public IIntruderPayloadGenerator createNewInstance(IIntruderAttack attack) { + return new ParameterFuzz(); + } + + public static byte[][] getPayloads() { + File file = new File(Config.getFilePath()); + if (!file.exists()) { + try { + file = new File("parameter.txt"); + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + List parameterList = getFileContent(file); + List list2 = Util.permutation(parameterList, Config.getFuzz_number()); + byte[][] letter = new byte[list2.size()][]; + for (int i = 0; i < list2.size(); i++) { + letter[i] = list2.get(i).getBytes(); + } + return letter; + } + + + class ParameterFuzz implements IIntruderPayloadGenerator { + int payloadIndex; + @Override + public void reset() { + payloadIndex = 0; + } + + @Override + public boolean hasMorePayloads() { + return payloadIndex < PAYLOADS.length; + } + + @Override + public byte[] getNextPayload(byte[] baseValue) { + byte[] payloads = PAYLOADS[payloadIndex]; + payloadIndex++; + return payloads; + } + } +} diff --git a/src/main/java/burp/Util.java b/src/main/java/burp/Util.java new file mode 100644 index 0000000..23f0045 --- /dev/null +++ b/src/main/java/burp/Util.java @@ -0,0 +1,152 @@ +package burp; + +import java.io.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class Util { + //获取用户选择 + public static String getSelect(IContextMenuInvocation invocation) { + int start = invocation.getSelectionBounds()[0]; + int end = invocation.getSelectionBounds()[1]; + IHttpRequestResponse[] messages =invocation.getSelectedMessages(); + String select = new String(messages[0].getRequest()).substring(start, end); + return select; + } + //参数溢出 + public static byte[] paramoVerflowAction (IHttpRequestResponse requestResponse, String select, int paramslen) throws UnsupportedEncodingException { + //获取body + byte[] request = requestResponse.getRequest(); + IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(request); + int bodyOffset = requestInfo.getBodyOffset(); + int body_length = request.length - bodyOffset; + String body = new String(request, bodyOffset, body_length, "UTF-8"); + //获取header + List headers = BurpExtender.helpers.analyzeRequest(request).getHeaders(); + String oldStr = headers.get(0); + + //处理POST/GET选择 + byte[] bytes = new byte[]{}; + if (requestInfo.getMethod().equals("POST")) { + StringBuffer str = new StringBuffer(); + for (int i = 0; i < paramslen; i++) { + str.append("&"); + str.append(select); + } + //修改body部分 + String newBody = body.replaceFirst(select, select+str); + bytes = BurpExtender.helpers.buildHttpMessage(headers, newBody.getBytes()); + } else if (requestInfo.getMethod().equals("GET")) { + StringBuffer str = new StringBuffer(); + for (int i = 0; i < paramslen; i++) { + str.append("&"); + str.append(select); + } + String newStr = oldStr.replaceFirst(select,select+str); + headers.set(0, newStr); + bytes = BurpExtender.helpers.buildHttpMessage(headers, body.getBytes()); + } + + return bytes; + } + //垃圾数据 + public static byte[] garbageDataAction (IHttpRequestResponse requestResponse, String select) throws UnsupportedEncodingException { + //获取body + byte[] request = requestResponse.getRequest(); + IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(request); + int bodyOffset = requestInfo.getBodyOffset(); + int body_length = request.length - bodyOffset; + String body = new String(request, bodyOffset, body_length, "UTF-8"); + + //获取header + List headers = BurpExtender.helpers.analyzeRequest(request).getHeaders(); + String oldStr = headers.get(0); + + //处理请求 + byte[] bytes = new byte[]{}; + if (requestInfo.getMethod().equals("POST")) { + String newBody = body.replace(select, getRandomString(Config.getKey_len(), Config.getValue_len(), Config.getNumber_len())); + bytes = BurpExtender.helpers.buildHttpMessage(headers, newBody.getBytes()); + } else if (requestInfo.getMethod().equals("GET")) { + String newStr = oldStr.replaceFirst(select, getRandomString(Config.getKey_len(), Config.getValue_len(), Config.getNumber_len())); + headers.set(0, newStr); + bytes = BurpExtender.helpers.buildHttpMessage(headers, body.getBytes()); + } + return bytes; + } + //生成垃圾键值对数据 key参数长度,value数据长度, num键值对数量 + public static String getRandomString(int key, int value, int num){ + String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + Random random=new Random(); + + StringBuffer sb3=new StringBuffer(); + for (int j = 0; j < num; j++) { + + StringBuffer sb=new StringBuffer(); + for(int i=0;i