0x00 前言
最近没搞白嫖版而是用的社区版的Burp,很多功能用不上,而且之前的Burp插件都是基于Python来写的,现在就换Java来写下插件吧,就拿CSRF PoC生成器来练练手。
项目地址:BurpExtender-CSRFPoCGenerator
0x01 Burp插件开发基础
主要参考Her0in大佬系列文章:
BurpSuite插件开发指南之 API 上篇 – Her0in
BurpSuite插件开发指南之 API 下篇 – Her0in
BurpSuite插件开发指南之 Java 篇 – Her0in
BurpSuite插件开发指南之 Python 篇 – Her0in
当然,官方也给出了一些插件实例供参考学习:https://portswigger.net/burp/extender/
将Burp提供的扩展接口和使用方式大致了解之后就能入手了。
0x02 插件开发——CSRF PoC生成器
Burp的Extender标签下,有个APIs子标签,其中展示了有哪些扩展接口及其功能。这里点击Save Interface files下载下来:
下载下来是个burp文件夹,其中都是Burp插件相关接口的java文件。
使用IDEA打开,将burp包放入src目录中,在burp包下新建名为“BurpExtender”的类:
直接看代码吧。
这里BurpExtender类实现了IBurpExtender接口和IContextMenuFactory接口,其中定义了三个BurpExtender类成员变量,并在registerExtenderCallbacks()函数中完成初始化,然后设置插件名和注册上下文菜单工厂:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class BurpExtender implements IBurpExtender, IContextMenuFactory {
public IBurpExtenderCallbacks callbacks; public IExtensionHelpers helpers; public PrintWriter stdout;
@Override public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { this.callbacks = callbacks; this.helpers = callbacks.getHelpers(); this.stdout = new PrintWriter(callbacks.getStdout(), true); callbacks.setExtensionName("Mi1k7ea"); callbacks.registerContextMenuFactory(this); }
|
Burp所有插件必须实现IBurpExtender接口且命名必须为“BurpExtender”,且必须实现其registerExtenderCallbacks()函数。当插件被加载时,Burp会调用registerExtenderCallbacks()函数并传递一个IBurpExtenderCallbacks类对象,插件可以通过这个对象来调用很多扩展Burp功能必需的方法,比如这里的getHelpers()、getStdout()、setExtensionName()、registerContextMenuFactory()等方法。
- getHelpers()函数:用于获取IExtensionHelpers接口类对象,在后续用到了该类的analyzeRequest()函数来解析请求报文;
- getStdout()函数:用于获取标准输出流,在Extender->Extensions->Output窗口中输出内容;
- setExtensionName()函数:用于设置插件名;
- registerContextMenuFactory()函数:用于注册自定义上下文菜单项的工厂。当用户在Burp中的任何地方调用一个上下文菜单时就会触发这个工厂函数,根据菜单调用的细节,提供应该被显示在上下文菜单中的任何自定义上下文菜单项;
接着,是实现IContextMenuFactory接口类的createMenuItems()函数,先看外围部分代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Override public List<JMenuItem> createMenuItems(IContextMenuInvocation invocation) { List<JMenuItem> jMenuItemList = new ArrayList<>(); JMenu jMenu = new JMenu("Mi1k7ea's Extender"); JMenuItem jMenuItem = new JMenuItem("Generate CSRF PoC"); jMenu.add(jMenuItem); jMenuItemList.add(jMenu);
jMenuItem.addActionListener(e -> { ... });
return jMenuItemList; }
|
这里其实涉及到的就是Java Swing编程,具体看网上资料即可。主要是创建自己的上下文菜单项然后设置监听事件,当点击时触发addActionListener()函数里面的代码逻辑。
其中监听触发的代码,直接看注释就行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| JFrame frame = new JFrame("CSRF PoC"); JPanel codePanel = new JPanel(new GridLayout());
IHttpRequestResponse iHttpRequestResponse = invocation.getSelectedMessages()[0]; IRequestInfo iRequestInfo = this.helpers.analyzeRequest(iHttpRequestResponse);
URL url = iRequestInfo.getUrl(); String method = iRequestInfo.getMethod(); String http_method = ""; String request_url = ""; String params = "";
try { List<IParameter> iParameters = iRequestInfo.getParameters(); for (IParameter iParameter : iParameters) { if (method.equals("POST")) { request_url = url.toString(); http_method = " method=\"POST\""; if (iParameter.getType() == IParameter.PARAM_BODY) { params += " <input type=\"hidden\" name=\"" + EncodeSpecialChars(iParameter.getName()) + "\" value=\"" + EncodeSpecialChars(iParameter.getValue()) + "\" />\n"; } } else if (method.equals("GET")) { request_url = url.toString().split("\\?")[0]; http_method = " method=\"GET\""; if (iParameter.getType() == IParameter.PARAM_URL) { params += " <input type=\"hidden\" name=\"" + EncodeSpecialChars(iParameter.getName()) + "\" value=\"" + EncodeSpecialChars(iParameter.getValue()) + "\" />\n"; } } } } catch (Exception exception) { exception.printStackTrace(); }
final String PoC = "<html>\n" + " <body>\n" + " <form action=\"" + request_url + "\"" + http_method + ">\n" + params + " <input type=\"submit\" value=\"Submit request\" />\n" + " </form>\n" + " </body>\n" + " <script>\n" + " var m = document.getElementsByTagName('form')[0];\n" + " m.submit();\n" + " </script>\n" + "</html>";;
JTextArea jt = new JTextArea(PoC); JScrollPane scrollPane = new JScrollPane(jt); jt.setEditable(false);
frame.add(codePanel, BorderLayout.CENTER); codePanel.add(scrollPane);
JPanel buttonPanel = new JPanel(new FlowLayout()); JButton button = new JButton("Copy"); buttonPanel.add(button); frame.add(buttonPanel, BorderLayout.PAGE_END); button.addActionListener(e1 -> { Toolkit toolkit = Toolkit.getDefaultToolkit(); Clipboard clipboard = toolkit.getSystemClipboard(); StringSelection CSRFCodeToCopy = new StringSelection(PoC); clipboard.setContents(CSRFCodeToCopy, CSRFCodeToCopy); });
frame.setSize(600,500); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
其中EncodeSpecialChars()函数用于处理一些PoC的input标签中特殊字符和解码问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public static String EncodeSpecialChars(String content) throws Exception { content = URLDecoder.decode(content, "UTF-8"); String special_word = "<>\"'"; for (int i = 0; i < special_word.length(); i++) { char word = special_word.charAt(i); String w = Character.toString(word); if (content.contains(w)) { String ascii_word = Integer.toString(word); String html_word = "&#" + ascii_word + ";"; System.out.println(html_word); content = content.replace(w, html_word); } } return content; }
|
OK,最后来看下效果吧。
将项目打包成jar包后,然后加载进来:
对任意报文,右键就能看到插件,点击就能加载生成CSRF PoC:
OK,更多的插件后面再写。