burpsuite插件设置InterceptAction无效的问题
burpsuite从2022.9版本开始引入Montoya API, 从这个版本开始,我使用Python创建的插件不能正常工作,具体的表现为加载多个python插件,如果插件中对请求设置了InterceptAction,只有最后加载的一个插件设置的ACTION有效。
| message.setInterceptAction(IInterceptedProxyMessage.ACTION_DROP)
|
于是我的burpsuite版本一直停留在burpsuite_pro_v2022.7.1, 以为官方会慢慢发现这个问题并进行修复。但一年多过去,这个问题没有被修复。
一个多月前我通过邮件向官方反馈了这个问题,但没有得到回复。
逆向分析
于是我尝试通过逆向的方式找到出问题的原因,以下是反编译的部分代码:
| package burp.api.montoya.proxy;
public enum MessageReceivedAction { CONTINUE, INTERCEPT, DO_NOT_INTERCEPT, DROP }
|
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
| package burp;
public class Zqw3 implements Zbuq, Zq56, Ztn { public int ZI(Z_6q var1, int var2, String var3, InetAddress var4) { String var5 = Zr(); if (this.Zl.isEmpty()) { return var2; } else { List var6 = Z_6r.ZQ(this.Zl); int var7 = var2; Iterator var8 = var6.iterator();
while(var8.hasNext()) { ProxyRequestHandler var9 = (ProxyRequestHandler)var8.next(); Zt4f var10 = new Zt4f(this.ZZ.ZP(var1), new Ztjc(var1.Z_(), var3, var4, (InetAddress)null), this.ZZ.Zw(var1)); ProxyRequestReceivedAction var11 = var9.handleRequestReceived(var10); if (var11 != null) { HttpRequest var12 = var11.request(); this.Zj.Zt(var1, Objects.equals(var12, var10) ? null : var12, var11.annotations()); if (var11.action() != null) { var7 = Zghv.Zn(var11.action()); } }
if (var5 == null) { break; } }
return var7; } } }
|
| package burp.api.montoya.proxy.http;
public interface ProxyRequestHandler { ProxyRequestReceivedAction handleRequestReceived(InterceptedRequest interceptedRequest); ProxyRequestToBeSentAction handleRequestToBeSent(InterceptedRequest interceptedRequest); }
|
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
| package burp;
public class Zem3 implements ProxyRequestHandler, ProxyResponseHandler { private final IProxyListener ZA; private final Set<Znd<Integer, Integer>> Zz; private final Zqdu Zk; private final Zqe8 ZQ;
public Zem3(IProxyListener var1, Zqdu var2, Zqe8 var3) { this.ZA = var1; this.Zk = var2; this.ZQ = var3; this.Zz = new HashSet(); }
public ProxyRequestReceivedAction handleRequestReceived(InterceptedRequest var1) { Zduz var2 = new Zduz(var1, var1.annotations(), this.ZQ); Zqj7 var3 = new Zqj7(var1, new Zos(var2)); this.ZA.processProxyMessage(true, var3); int var4 = var3.getInterceptAction(); if (Zg(var4)) { this.Zz.add(Znd.ZA(var4, var1.messageId())); }
return Zmw.Zx(var2.ZN(), var2.ZD(), Zygo.ZP(var4)); } }
|
Burp会对每个请求依次调用每个插件中的processProxyMessage,但只保存了最后一个插件的返回值,导致前面插件设置的ACTION无效。
我又通过github向PortSwigger提交了这个issue,目前没有任何回复。
本地补丁
通过javassist修改class,对这个方法进行Patch,可以满足我的需求。
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
| { String var5 = Zr(); if (this.Zl.isEmpty()) { return $2; } else { java.util.List var6 = burp.Z_6r.ZQ(this.Zl); int var7 = $2; java.util.Iterator var8 = var6.iterator();
while(var8.hasNext()) { burp.api.montoya.proxy.http.ProxyRequestHandler var9 = (burp.api.montoya.proxy.http.ProxyRequestHandler)var8.next(); burp.Zt4f var10 = new burp.Zt4f(this.ZZ.ZP($1), new burp.Ztjc($1.Z_(), $3, $4, (java.net.InetAddress)null), this.ZZ.Zw($1)); burp.api.montoya.proxy.http.ProxyRequestReceivedAction var11 = var9.handleRequestReceived(var10); if (var11 != null) { burp.api.montoya.http.message.requests.HttpRequest var12 = var11.request(); this.Zj.Zt($1, java.util.Objects.equals(var12, var10) ? null : var12, var11.annotations()); if (var11.action() != null && burp.Zghv.Zn(var11.action())!= $2) { var7 = burp.Zghv.Zn(var11.action()); } }
if (var5 == null) { break; } }
return var7; } }
|
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
| package com.zhighest.agent;
import javassist.*; import java.lang.instrument.Instrumentation; import java.lang.instrument.ClassFileTransformer; import java.security.ProtectionDomain;
public class Agent { public static void premain(String agentArgs, Instrumentation inst) { inst.addTransformer(new ClassFileTransformer() { @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { String targetClassName = "burp/Zqw3"; if (className.equals(targetClassName)) { System.out.println(targetClassName); try { ClassPool pool = ClassPool.getDefault(); CtClass ctClass = pool.get(targetClassName.replace('/', '.'));
CtMethod ctMethod = ctClass.getDeclaredMethod("ZI"); ctMethod.setBody("{\n" + " String var5 = Zr();\n" + " if (this.Zl.isEmpty()) {\n" + " return $2;\n" + " } else {\n" + " java.util.List var6 = burp.Z_6r.ZQ(this.Zl);\n" + " int var7 = $2;\n" + " java.util.Iterator var8 = var6.iterator();\n" + "\n" + " while(var8.hasNext()) {\n" + " burp.api.montoya.proxy.http.ProxyRequestHandler var9 = (burp.api.montoya.proxy.http.ProxyRequestHandler)var8.next();\n" + " burp.Zt4f var10 = new burp.Zt4f(this.ZZ.ZP($1), new burp.Ztjc($1.Z_(), $3, $4, (java.net.InetAddress)null), this.ZZ.Zw($1));\n" + " burp.api.montoya.proxy.http.ProxyRequestReceivedAction var11 = var9.handleRequestReceived(var10);\n" + " if (var11 != null) {\n" + " burp.api.montoya.http.message.requests.HttpRequest var12 = var11.request();\n" + " this.Zj.Zt($1, java.util.Objects.equals(var12, var10) ? null : var12, var11.annotations());\n" + " if (var11.action() != null && burp.Zghv.Zn(var11.action())!= $2) {\n" + " var7 = burp.Zghv.Zn(var11.action());\n" + " }\n" + " }\n" + "\n" + " if (var5 == null) {\n" + " break;\n" + " }\n" + " }\n" + "\n" + " return var7;\n" + " }\n" + " }");
return ctClass.toBytecode(); } catch (Exception e) { e.printStackTrace(); } } return null; } }); } }
|
打包生成jar,执行以下命令运行,达到了预期效果。
| java -javaagent:agent_test.jar -jar burpsuite_community_v2024.6.1.jar
|
链接
https://bbs.kanxue.com/thread-282397.htm
https://portswigger.net/burp/releases/professional-community-2022-9
https://github.com/PortSwigger/burp-extensions-montoya-api/issues/100
https://blog.csdn.net/xifeijian/article/details/79991913