PortSwigger / burp-extensions-montoya-api

Burp Extensions Api
Other
140 stars 5 forks source link

The value of the InterceptAction is always overwritten by the last extension #100

Open xjohjrdy opened 4 months ago

xjohjrdy commented 4 months ago

I have two legacy extensions written in Python named extension-a.py and extension-b.py.

The difference between these two extensions lies in their extension names and URL matching rules.

Here is the source code for the two extensions:

# extension-a.py
from burp import IBurpExtender
from burp import IHttpListener
from burp import IProxyListener

class BurpExtender(IBurpExtender, IProxyListener, IHttpListener):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        callbacks.setExtensionName('extension-a')
        callbacks.registerProxyListener(self)

    def processProxyMessage(self, messageIsRequest, message):
        messageInfo = message.getMessageInfo()
        url = self._helpers.analyzeRequest(messageInfo).getUrl().toString()
        if messageIsRequest:
            if 'aaa' in url:
                print('Dropping url:',  url)
                message.setInterceptAction(message.ACTION_DROP)
# extension-b.py
from burp import IBurpExtender
from burp import IHttpListener
from burp import IProxyListener

class BurpExtender(IBurpExtender, IProxyListener, IHttpListener):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        callbacks.setExtensionName('extension-b')
        callbacks.registerProxyListener(self)

    def processProxyMessage(self, messageIsRequest, message):
        messageInfo = message.getMessageInfo()
        url = self._helpers.analyzeRequest(messageInfo).getUrl().toString()
        if messageIsRequest:
            if 'bbb' in url:
                print('Dropping url:',  url)
                message.setInterceptAction(message.ACTION_DROP)

Since the release of the Montoya API, these two extensions cannot work properly at the same time.

Each extension works fine when used alone. However, when both extensions are loaded simultaneously, one of them does not function properly.

Here is my test command and some output text:

➜  ~ curl -x 127.0.0.1:8080 http://httpbin.org/aaa
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>

➜  ~ curl -x 127.0.0.1:8080 http://httpbin.org/bbb
<html><head><title>Burp Suite Community Edition</title>
<style type="text/css">
body { background: #dedede; font-family: Arial, sans-serif; color: #404042; -webkit-font-smoothing: antialiased; }
#container { padding: 0 15px; margin: 10px auto; background-color: #ffffff; }
a { word-wrap: break-word; }
a:link, a:visited { color: #e06228; text-decoration: none; }
a:hover, a:active { color: #404042; text-decoration: underline; }
h1 { font-size: 1.6em; line-height: 1.2em; font-weight: normal; color: #404042; }
h2 { font-size: 1.3em; line-height: 1.2em; padding: 0; margin: 0.8em 0 0.3em 0; font-weight: normal; color: #404042;}
.title, .navbar { color: #ffffff; background: #e06228; padding: 10px 15px; margin: 0 -15px 10px -15px; overflow: hidden; }
.title h1 { color: #ffffff; padding: 0; margin: 0; font-size: 1.8em; }
div.navbar {position: absolute; top: 18px; right: 25px;}
div.navbar ul {list-style-type: none; margin: 0; padding: 0;}
div.navbar li {display: inline; margin-left: 20px;}
div.navbar a {color: white; padding: 10px}
div.navbar a:hover, div.navbar a:active {text-decoration: none; background: #404042;}
</style>
</head>
<body>
<div id="container">
<div class="title"><h1>Burp Suite Community Edition</h1></div>
<h1>Error</h1><p>Request&#32;was&#32;dropped&#32;by&#32;Burp&#32;extension&#46;</p>
<p>&nbsp;</p>
</div>
</body>
</html>

I sent the above information to support#portswigger.net via email, but I did not receive a response.

So, I tried debugging the burpsuite to find the cause of the issue, and I believe I have identified the root cause.

As shown in the code snippet below, burpsuite calls each plugin, but the return value is overwritten by the last plugin.

package burp;

public class Zqw3 implements Zy9r, Zqqz, Zo96 {
    //.........
    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()); // var7,the return value
                    }
                }

                if (var5 == null) {
                    break;
                }
            }

            return var7;
        }
    }

    //.........
}
Hannah-PortSwigger commented 4 months ago

Hi

Unfortunately, I can't seem to find your email in our system.

Thanks to your detailed replication steps, I've replicated this issue and will look into this further.

We'll get back to you with some further feedback shortly.

Hannah-PortSwigger commented 4 months ago

Hi

Thank you for your patience. This issue seems to have been introduced with the Montoya API. For this example, it may be best to combine these extensions into one so that the appropriate requests are dropped.

For an unaffected version, you would need to go back to v2022.8.5, prior to the Montoya API's introduction.

We'll get a bug report raised for this behavior.

If there's anything else we can help with, then please let us know.