{"id":3507,"date":"2024-07-30T14:16:18","date_gmt":"2024-07-30T12:16:18","guid":{"rendered":"https:\/\/security.humanativaspa.it\/?p=3507"},"modified":"2025-12-10T09:00:05","modified_gmt":"2025-12-10T09:00:05","slug":"extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6","status":"publish","type":"post","link":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/","title":{"rendered":"Extending Burp Suite for fun and profit &#8211; The Montoya way &#8211; Part 6"},"content":{"rendered":"<ol>\n<li><a href=\"https:\/\/hnsecurity.it\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-1\">Setting up the environment + Hello World<\/a><\/li>\n<li><a href=\"https:\/\/hnsecurity.it\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-2\">Inspecting and tampering HTTP requests and responses<\/a><\/li>\n<li><a href=\"https:\/\/hnsecurity.it\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3\">Inspecting and tampering WebSocket messages<\/a><\/li>\n<li><a href=\"https:\/\/hnsecurity.it\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-4\">Creating new tabs for processing HTTP requests and responses<\/a><\/li>\n<li><a href=\"https:\/\/hnsecurity.it\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-5\/\">Adding new functionalities to the context menu (accessible by right-clicking)<\/a><\/li>\n<li><strong>-&gt; Adding new checks to Burp Suite Active and Passive Scanner<\/strong><\/li>\n<li><a href=\"https:\/\/hnsecurity.it\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-7\/\">Using the Collaborator in Burp Suite plugins<\/a><\/li>\n<li><a href=\"https:\/\/hnsecurity.it\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-8\/\">BChecks &#8211; A quick way to extend Burp Suite Active and Passive Scanner<\/a><\/li>\n<li><a href=\"https:\/\/hnsecurity.it\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-9\/\">Custom scan checks &#8211; An improved quick way to extend Burp Suite Active and Passive Scanner<\/a><\/li>\n<li>&#8230; and much more!<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>Hi there!<\/p>\n<p>Today we will see how to develop an extension that will <strong>add custom active and passive checks to Burp Scanner<\/strong>, following the configurations with which the scanner itself has been run.<\/p>\n<p>In this article, we will look at how to extend the scanner using the &#8220;classic method&#8221;, that is, by <strong>writing a plugin that uses the Montoya API<\/strong>. This method gives us the most possibilities, as we can write arbitrary Java code to implement our checks. On the other hand, it is also the most complex way to add a check to the scanner, since Burp Suite has recently integrated a new method that allows to add checks via text files with a format similar to YAML, called <strong>BCheck<\/strong>. The Burp Suite team is continuing to develop this new method to allow for checking for more and more issues, but it is still good to know how to develop a complete extension as it obviously allows for more articulated checks. Maybe we will also see in one of the upcoming articles how to extend the scanner using the BCheck method.<\/p>\n<p>As usual, let&#8217;s start from a <strong>real scenario<\/strong>. This time we will use a Java application that I developed some time ago as a test case for developing an extension aimed at identifying Java deserialization issues, named <a href=\"https:\/\/github.com\/federicodotta\/Java-Deserialization-Scanner\">Java Deserialization Scanner<\/a>. The test application, in WAR format, simply deserializes objects received in different ways and with different encodings, and it is easy to add vulnerable libraries to its package.<\/p>\n<p>In order to <strong>exploit a Java serialization issue to achieve RCE<\/strong>, it is not sufficient to merely find an endpoint that deserializes user input. It is also necessary to find a serializable object known to the backend that, during deserialization, allows the execution of arbitrary commands or Java code. Such objects are not super easy to find and known ones are mainly offered by outdated external Java libraries. To delve deeper into this topic, I recommend the <a href=\"https:\/\/foxglovesecurity.com\/2015\/11\/06\/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability\/\">article that demonstrated the actual potential of this type of issue<\/a> by exploiting most Java application servers (Foxglove Security) and the <a href=\"https:\/\/www.slideshare.net\/slideshow\/appseccali-2015-marshalling-pickles\/44009258\">original slides by the researchers who discovered the vulnerability<\/a>\u00a0(Gabriel Lawrence and Chris Frohoff).<\/p>\n<p>Our target will therefore be a <strong>Java application that deserializes the input sent to it<\/strong>, packaged with a vulnerable version of the Apache Commons Collections 3 libraries, which offer one of these serializable objects that allow for the execution of arbitrary Java code once deserialized. The target application can be downloaded from <a href=\"https:\/\/github.com\/federicodotta\/Burp-Suite-Extender-Montoya-Course\/tree\/main\">my Github repository<\/a>. To deploy it, a Java application server is necessary. I used <strong>Apache Tomcat<\/strong>, which is easy to configure. Specifically, I used Tomcat 9, running with OpenJDK 17 (if you use a too old version of Java, the provided application might not function correctly as it may be compiled with a more recent version of Java). Details on how to configure and run Tomcat are beyond the scope of this article.<\/p>\n<p>Let&#8217;s start from our test case. After the deployment of the test application, we can reach the homepage (in my deployment at http:\/\/localhost:8080\/sampleCommonsCollections3\/):<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3594 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-19-2.png\" alt=\"\" width=\"1322\" height=\"434\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-19-2.png 1322w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-19-2-300x98.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-19-2-1024x336.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-19-2-768x252.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-19-2-350x115.png 350w\" sizes=\"(max-width: 1322px) 100vw, 1322px\" \/><\/p>\n<p>The application is very simple. It offers some links that send a serialized Java object to the backend in different ways and with different encodings (and a backend that deserializes them). Let&#8217;s click on &#8220;Serialzied Java Object in parameter, encoded in Base64&#8221;.<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3595 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-22-2.png\" alt=\"\" width=\"1323\" height=\"382\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-22-2.png 1323w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-22-2-300x87.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-22-2-1024x296.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-22-2-768x222.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-22-2-350x101.png 350w\" sizes=\"(max-width: 1323px) 100vw, 1323px\" \/><\/p>\n<p>The sample application simply tells us to inspect the traffic from Burp, where we can see the request and response.<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3596 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-23-2.png\" alt=\"\" width=\"1246\" height=\"649\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-23-2.png 1246w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-23-2-300x156.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-23-2-1024x533.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-23-2-768x400.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-23-2-350x182.png 350w\" sizes=\"(max-width: 1246px) 100vw, 1246px\" \/><\/p>\n<p>But what will our extension do? Our extension will perform two tasks: it will add a <strong>passive check<\/strong> to the scanner to search for serialized objects in HTTP requests (useful for identifying potential vulnerable parameters), and it will add some <strong>active checks<\/strong> to the scanner to test if endpoints are actually exploitable, using specific attack vectors for Apache Commons Collections 3. Essentially, <strong>we will write a simplified version of the Java Deserialization Scanner using the Montoya API<\/strong>, which only executes payloads for a single vulnerable library (Commons Collection 3) and supports a single encoding (Base64), to keep the example simple.<\/p>\n<p>Before we begin, a few words about Burp Suite&#8217;s passive and active scanners. The purpose of the <strong>passive scanner<\/strong> is to identify issues simply by passively inspecting the traffic that passes through the tool, <strong>without making any request<\/strong>. In contrast, the <strong>active scanner<\/strong> tries to actively identify the presence of issues by sending specific attack vectors to the application and analyzing the responses. As we will see shortly, we can actually write Java code to extend both the passive and active scanners. Therefore, unless something has changed recently, <strong>there is nothing preventing us from adding code to the passive scanner that performs active checks<\/strong>. However, it is good practice to avoid this approach, as the user who will use the plugin will expect behavior consistent with the type of plugin they are using.<\/p>\n<p>As usual, we start from the Hello World plugin skeleton we wrote in <a href=\"https:\/\/hnsecurity.it\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-1\">part 1<\/a>\u00a0of the\u00a0<a href=\"https:\/\/hnsecurity.it\/tag\/extending-burp-suite\/\">series<\/a>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">package org.fd.montoyatutorial;\r\n\r\nimport burp.api.montoya.BurpExtension;\r\nimport burp.api.montoya.MontoyaApi;\r\nimport burp.api.montoya.logging.Logging;\r\n\r\npublic class ScanCheckExample implements BurpExtension {\r\n\r\n    MontoyaApi api;\r\n    Logging logging;\r\n\r\n    @Override\r\n    public void initialize(MontoyaApi api) {\r\n\r\n        \/\/ Save a reference to the MontoyaApi object\r\n        this.api = api;\r\n\r\n        \/\/ api.logging() returns an object that we can use to print messages to stdout and stderr\r\n        this.logging = api.logging();\r\n\r\n        \/\/ Set the name of the extension\r\n        api.extension().setName(\"Montoya API tutorial - Scan Check Example\");\r\n\r\n        \/\/ Print a message to the stdout\r\n        this.logging.logToOutput(\"*** Montoya API tutorial - Scan Check Example loaded ***\");\r\n\r\n        \/\/ Register our custom scan check\r\n        \/\/ TODO\r\n\r\n    }\r\n}\r\n<\/pre>\n<p>We will need to register our custom scan check after the creation of the classes that will handle it.<\/p>\n<p>The plugin we need is of type\u00a0<em><strong>ScanCheck <\/strong><\/em>and can be registered from the <em><a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/scanner\/Scanner.html\">Scanner<\/a><\/em>\u00a0object that we can get from the usual\u00a0<a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/MontoyaApi.html\"><em>MontoyaApi<\/em><\/a>\u00a0(the object supplied as argument to the\u00a0<em>initialize<\/em>\u00a0function of the plugin).<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3601 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-40-2.png\" alt=\"\" width=\"1708\" height=\"659\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-40-2.png 1708w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-40-2-300x116.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-40-2-1024x395.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-40-2-768x296.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-40-2-1536x593.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-40-2-350x135.png 350w\" sizes=\"(max-width: 1708px) 100vw, 1708px\" \/><\/p>\n<p>To register our plugin we need to code an object that implements the interface\u00a0<a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/scanner\/ScanCheck.html\"><em>ScanCheck<\/em><\/a> and that will contain active and passive scan logic. The interface <em>ScanCheck<\/em>\u00a0is documented as follows:<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3599 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-36-3.png\" alt=\"\" width=\"1691\" height=\"571\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-36-3.png 1691w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-36-3-300x101.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-36-3-1024x346.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-36-3-768x259.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-36-3-1536x519.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_10-36-3-350x118.png 350w\" sizes=\"(max-width: 1691px) 100vw, 1691px\" \/><\/p>\n<p>As we can see, the <em>ScanCheck<\/em> interface requires the implementation of the following three methods:<\/p>\n<ul>\n<li><em>AuditResult passiveAudit<wbr \/>(HttpRequestResponse baseRequestResponse):<\/em> this method will be called each time Burp Suite&#8217;s <strong>passive scanner<\/strong> runs. It will be provided with an object containing the request and the response on which the passive scanner was executed, allowing us to perform some checks on it to identify issues <strong>passively<\/strong> (i.e., simply by analyzing the request\/response <strong>without making further requests<\/strong>). The method should return an object that contains a list of identified issues, which will be integrated into Burp Suite&#8217;s scanner results.<\/li>\n<li><em>AuditResult activeAudit<wbr \/>(HttpRequestResponse baseRequestResponse, AuditInsertionPoint auditInsertionPoint):<\/em> this method will be called each time Burp Suite&#8217;s <strong>active scanner<\/strong> runs on a request, once for each insertion point selected by the scanner engine or manually by the user (via the &#8220;Scan defined insertion points&#8221; feature of the Intruder &#8211; more info at the end of the article). Here, we will have, in addition to the request and response on which the scanner was executed, an object containing information about the <strong>current insertion point<\/strong>, so that we can correctly position our attack vectors. As before, the method should return an object that contains a list of identified issues, which will be integrated into Burp Suite&#8217;s scanner results.<\/li>\n<li><em>ConsolidationAction consolidateIssues<wbr \/>(AuditIssue newIssue, AuditIssue existingIssue):<\/em> the method is called when our custom scan check has returned multiple issues for the same URL. In this scenario, each time a new issue is identified by our check, this method is called once for every other issue identified by our check on the same URL. Within this method, we need to define logic to <strong>determine whether the issue is a duplicate<\/strong> or should be reported.<\/li>\n<\/ul>\n<p>The skeleton of our new class that will contain the scan checks is the following:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">package org.fd.montoyatutorial;\r\n\r\nimport burp.api.montoya.MontoyaApi;\r\n\r\npublic class CustomScanCheck implements ScanCheck {\r\n\r\n    MontoyaApi api;\r\n    Utilities utilities;\r\n\r\n    public CustomScanCheck(MontoyaApi api) {\r\n\r\n        \/\/ Save references to usefull objects\r\n        this.api = api;\r\n        this.utilities = this.api.utilities();\r\n\r\n    }\r\n\r\n    @Override\r\n    public AuditResult activeAudit(HttpRequestResponse baseRequestResponse, AuditInsertionPoint auditInsertionPoint) {\r\n        return null;\r\n    }\r\n\r\n    @Override\r\n    public AuditResult passiveAudit(HttpRequestResponse baseRequestResponse) {\r\n        return null;\r\n    }\r\n\r\n    @Override\r\n    public ConsolidationAction consolidateIssues(AuditIssue newIssue, AuditIssue existingIssue) {\r\n        return null;\r\n    }\r\n\r\n}\r\n<\/pre>\n<p>Let&#8217;s start with the <strong><em>activeAudit<\/em> method<\/strong>. Our goal is to identify a serialization issue in the backend with an active probe (so, we can use our payloads to identify the issues). As said before, we will try to identify only serialization issues in the Apache Commons Collections 3 library, in order to simplify our demo plugin.<\/p>\n<p>To generate serialization payloads to exploit most Java vulnerable libraries we can use the <a href=\"https:\/\/github.com\/frohoff\/ysoserial\">ysoserial<\/a> tool. It&#8217;s the main tool for generating exploitation payloads for Java serialization vulnerabilities, created by Chris Frohoff (one of the researchers who discovered the issue). However, the tool is designed for exploitation and not for detection, and most of the payloads aim to execute commands on the operating system. To make detection more difficult, the exploitation is &#8220;blind,&#8221; meaning we cannot see the result of the command inserted into the payload. To address this problem, a few years ago when I wrote the Java Deserialization Scanner plugin I also made a <a href=\"https:\/\/github.com\/federicodotta\/ysoserial\">fork of ysoserial<\/a>, modifying the payloads to add some detection mechanisms. The fork adds some modules to the tool, including the ability to generate payloads that, instead of executing commands on the operating system, execute <strong>native Java synchronous sleeps<\/strong>. This provides a <strong>reliable detection mechanism based on the timing of the responses<\/strong>.<\/p>\n<p>So first, let&#8217;s generate every ysoserial payload for the Apache Commons Collections 3 that <strong>sleep for 10 seconds<\/strong> using my fork (there are 5 payloads that may work differently in different target environments; CommonsCollections2 and CommonsCollections4 are skipped because they are for Apache Commons Collections version 4):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">$ java -jar ysoserial-fd-0.0.6.jar CommonsCollections1 10000 sleep base64\r\nrO0ABXNyADJzdW4ucmVm[...]AAAAAAAAAAAAAB4cHEAfgA5\r\n\r\n$ java -jar ysoserial-fd-0.0.6.jar CommonsCollections3 10000 sleep base64\r\nrO0ABXNyADJzd[...]AAAAAeHBxAH4ALg==\r\n\r\n$ java -jar ysoserial-fd-0.0.6.jar CommonsCollections5 10000 sleep base64\r\nrO0ABXNyAC5qYXZheC5tYW5hZ[...]AB3CAAAABAAAAAAeHg=\r\n\r\n$ java -jar ysoserial-fd-0.0.6.jar CommonsCollections6 10000 sleep base64\r\nrO0ABXNyABFqYX[...]AQAAAAAHh4eA==\r\n\r\n$ java -jar ysoserial-fd-0.0.6.jar CommonsCollections7 10000 sleep base64\r\nrO0ABXNyABNqYX[...]4ALQAAAAJ4<\/pre>\n<p>Once generated, we put all these payloads in a dedicated class of our code, in order to keep the code with the logic clean:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">package org.fd.montoyatutorial;\r\n\r\npublic class StaticItems {\r\n\r\n    public static String[] apacheCommonsCollections3Payloads = new String[] {\r\n           \"rO0ABXNyADJzdW4ucmVmbGVjdC[...]AAAAAAAAAAAB4cHEAfgA5\",      \r\n           \"rO0ABXNyADJzdW4u[...]WRlAAAAAAAAAAAAAAB4cHEAfgAu\",\r\n           \"rO0ABXNyAC5[...]AAAAB3CAAAABAAAAAAeHg\",\r\n           \"rO0ABXN[...]AAHh4eA==\",\r\n           \"rO0ABXNyABNq[...]AH4ALQAAAAJ4\"\r\n    };\r\n\r\n}\r\n<\/pre>\n<p>Now let&#8217;s build the skeleton of our method for active scan:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Override\r\npublic AuditResult activeAudit(HttpRequestResponse baseRequestResponse, AuditInsertionPoint auditInsertionPoint) {\r\n\r\n    \/\/ Initialize an empty list of audit issues that we will eventually populate and return at the end of the function\r\n    List&lt;AuditIssue&gt; activeAuditIssues = new ArrayList&lt;AuditIssue&gt;();\r\n\r\n    \/\/ For each CommonsCollections 3 payload we defined, we try to exploit the issue\r\n    for(int i=0;i&lt;SerializationPayloads.apacheCommonsCollections3Payloads.length;i++) {\r\n\r\n        \/\/ We create an HTTP request containing our payload in the current insertion point\r\n\r\n        \/\/ We record the current time, execute the request and record the time again\r\n\r\n        \/\/ We calculate the interval between when we sent the request and when we received the response (converted in seconds)\r\n\r\n        \/\/ If the interval is greater than 9 seconds we may have a vulnerable endpoint (our payloads sleep for 10 seconds)\r\n        if (((int) duration) &gt;= 9) {\r\n\r\n            \/\/ In this case, we create an issue object and adds it to the list of issues to be returned\r\n\r\n        }\r\n\r\n    }\r\n\r\n    \/\/ Return the list of issues\r\n    return AuditResult.auditResult(activeAuditIssues);\r\n\r\n}<\/pre>\n<p>We will execute the following steps in order:<\/p>\n<ol>\n<li>We <strong>initialize<\/strong> an empty list of <em><a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/scanner\/audit\/issues\/AuditIssue.html\">AuditIssue<\/a><\/em>, that we will put in the object of type <em>AuditResult<\/em> that we have to return<\/li>\n<li>We <strong>loop<\/strong> through all our Commons Collections 3 payloads and:\n<ol>\n<li>For each payload we will create an HTTP request containing our payload in the current insertion point<\/li>\n<li>We send the HTTP request to the backend, taking record of the time passed till we receive the response<\/li>\n<li>If the time is greater than 9 seconds we create the issue and add it to the result list (we avoid using 10 in order to allow for a little margin due to calculations and conversions)<\/li>\n<\/ol>\n<\/li>\n<li>Finally we <strong>return<\/strong> the list of issues, using a static method of the <em><a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/scanner\/AuditResult.html\">AuditResult<\/a> <\/em>class that creates an object of this type for us, that contains our list<\/li>\n<\/ol>\n<p>Let&#8217;s take a closer look inside the for loop.<\/p>\n<p>First, we <strong>create an HTTP request<\/strong> containing our payload in the current insertion point. This step is quite simple, thanks to the <em><a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/scanner\/audit\/insertionpoint\/AuditInsertionPoint.html#buildHttpRequestWithPayload(burp.api.montoya.core.ByteArray)\">buildHttpRequestWithPayload<\/a> <\/em>method of the <em>AuditInsertionPoint<\/em> class, which takes as input our attack vector and creates the final <em>HttpRequest<\/em> on its own with the payload in the correct place:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">\/\/ We create an HTTP request containing our payload in the current insertion point\r\nHttpRequest commonsCollectionsCheckRequest = auditInsertionPoint.buildHttpRequestWithPayload(\r\n        ByteArray.byteArray(SerializationPayloads.apacheCommonsCollections3Payloads[i]))\r\n        .withService(baseRequestResponse.httpService());<\/pre>\n<p>You may have noticed the <em>withService<\/em> method called in the last line. This method of the <em><a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/http\/message\/requests\/HttpRequest.html\">HttpRequest<\/a><\/em> class adds the so-called &#8220;service&#8221; to the request, which includes the host, port, and protocol (to be more precise, generates a new <em>HttpRequest<\/em> that contains also the service supplied as argument). In order to be able to send an <em>HttpRequest<\/em> object in Burp, it must contain both the bytes of the request and the information on where to send it (host, port, and protocol). Some methods in Burp that create these types of objects also copy the &#8220;service&#8221;, while others do not. To be safe, it doesn&#8217;t hurt to manually include it, taking it from the original request sent to the scanner provided as a parameter.<\/p>\n<p>You may also have noticed that we sent the payloads encoded in Base64. What if the serialized object is sent in ASCII HEX or with a different encoding? According to the documentation, we should provide the attack vector in RAW format and the insertion point will handle the data encoding properly:<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3618 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-18-1.png\" alt=\"\" width=\"1225\" height=\"354\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-18-1.png 1225w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-18-1-300x87.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-18-1-1024x296.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-18-1-768x222.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-18-1-350x101.png 350w\" sizes=\"(max-width: 1225px) 100vw, 1225px\" \/><\/p>\n<p>So, why did we supply a Base64 encoded attack vector? Because based on the tests I&#8217;ve done the encoding is not always handled correctly. If I&#8217;m not mistaken, Burp Suite only manages the encoding given by the request content type and the position of the insertion point (URL encoding in forms, escape in JSON, etc.), but it does not (or maybe not always) identify additional encodings of the specific parameters (e.g., a parameter encoded in Base64, as in this case). In a real extension, all these cases need to be handled, either by extracting the value contained in the vulnerable parameter of the original request (which we have in the baseRequestResponse variable) and applying the same encoding, or by sending a request for each encoding\/compression mechanism\/etc. that we want to support. To keep the example simple, I will send only payloads encoded in Base64.<\/p>\n<p>Secondly, we <strong>send the <em>HttpRequest<\/em> to the application<\/strong>, recording the time just before and just after, in order to calculate the response time. To send the request we can use the <em>sendRequest\u00a0<\/em>function offered by the<em> <a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/http\/Http.html\">Http<\/a> <\/em>object that we can obtain directly from the <em>MontoyaApi<\/em> object (the object that we receive and save in the <em>initialize<\/em> method of every plugin and that we use for everything):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">\/\/ We record the current time, execute the request and record the time again\r\nlong startTime = System.nanoTime();\r\nHttpRequestResponse commonsCollectionsCheckRequestResponse = api.http().sendRequest(commonsCollectionsCheckRequest);\r\nlong endTime = System.nanoTime();\r\n\r\n\/\/ We calculate the internal between when we sent the request and when we received the response (converted in seconds)\r\nlong duration = TimeUnit.SECONDS.convert((endTime - startTime), TimeUnit.NANOSECONDS);<\/pre>\n<p>Finally, if the response time is greater than 9 we <strong>create an issue<\/strong> and add it to the result list. Luckily for us, the Montoya API of Burp Suite offers a convenient method for creating an issue from various pieces of information about it, such as title, description, severity, etc. (in the previous API, this convenient method was not available and you had to create a specific class). Here too, to keep the code clean, we can place these static strings in an external class, like <em>StaticItems<\/em> that we created to collect the serialization payloads.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">package org.fd.montoyatutorial;\r\n\r\nimport burp.api.montoya.scanner.audit.issues.AuditIssueSeverity;\r\nimport burp.api.montoya.scanner.audit.issues.AuditIssueConfidence;\r\n\r\npublic class StaticItems {\r\n\r\n    [...]\r\n\r\n    public static String apacheCommonsCollections3IssueName = \"Remote Code Execution through Java Unsafe Deserialization, vulnerable library: Apache Commons Collections 3\";\r\n    public static String apacheCommonsCollections3IssueDetail = \"The application deserializes untrusted serialized Java objects,\"+\r\n            \" without first checking the type of the received object and run on an unpatched Java environment. This issue can be\"+\r\n            \" exploited by sending malicious objects that, when deserialized,\"+\r\n            \" execute custom Java code. Several objects defined in popular libraries\"+\r\n            \" can be used for the exploitation.\";\r\n    public static AuditIssueSeverity apacheCommonsCollections3IssueSeverity = AuditIssueSeverity.HIGH;\r\n    public static AuditIssueConfidence apacheCommonsCollections3IssueConfidence = AuditIssueConfidence.FIRM;\r\n    public static AuditIssueSeverity apacheCommonsCollections3IssueTypicalSeverity = AuditIssueSeverity.HIGH;\r\n\r\n    public static String passiveSerializationIssueName = \"Serialized Java objects detected\";\r\n    public static String passiveSerializationIssueDetail = \"Serialized Java objects have been detected in the body\"+\r\n            \" or in the parameters of the request. If the server application does \"+\r\n            \" not check on the type of the received objects before\"+\r\n            \" the deserialization phase, it may be vulnerable to the Java Deserialization\"+\r\n            \" Vulnerability.\";\r\n    public static AuditIssueSeverity passiveSerializationIssueSeverity = AuditIssueSeverity.INFORMATION;\r\n    public static AuditIssueConfidence passiveSerializationIssueConfidence = AuditIssueConfidence.FIRM;\r\n    public static AuditIssueSeverity passiveSerializationIssueTypicalSeverity = AuditIssueSeverity.INFORMATION;\r\n\r\n}\r\n<\/pre>\n<p>The method we can use to create the issue is the static method <em>auditIssue<\/em> of the <em><a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/scanner\/audit\/issues\/AuditIssue.html\">AuditIssue<\/a><\/em> class:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-3611\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_17-43-1.png\" alt=\"\" width=\"816\" height=\"725\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_17-43-1.png 816w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_17-43-1-300x267.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_17-43-1-768x682.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-25_17-43-1-350x311.png 350w\" sizes=\"(max-width: 816px) 100vw, 816px\" \/><\/p>\n<p>We may add only the fields we want to insert, leaving others as <em>null <\/em>(it is not necessary to fill every field):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">\/\/ If the interval is greater than 9 seconds we may have a vulnerable endpoint (our payloads sleep for 10 seconds)\r\nif (((int) duration) &gt;= 9) {\r\n\r\n    \/\/ In this case, we create an issue object and adds it to the list of issues to be returned\r\n    AuditIssue auditIssue = AuditIssue.auditIssue(SerializationPayloads.apacheCommonsCollections3IssueName,\r\n            SerializationPayloads.apacheCommonsCollections3IssueDetail,\r\n            null, \/\/ remediation\r\n            baseRequestResponse.request().url(),\r\n            SerializationPayloads.apacheCommonsCollections3IssueSeverity,\r\n            SerializationPayloads.apacheCommonsCollections3IssueConfidence,\r\n            null, \/\/ background\r\n            null, \/\/ remediationBackground\r\n            SerializationPayloads.apacheCommonsCollections3IssueTypicalSeverity,\r\n            commonsCollectionsCheckRequestResponse); \/\/Request\/response can be highlighted\r\n\r\n    activeAuditIssues.add(auditIssue);\r\n\r\n}<\/pre>\n<p>The last parameter is the request that we used to detect the issue (or list of requests, because we can add to the issue as many request\/response objects as we need). We can also highlight a portion of the request or the response in order to clearly mark the evidence of the issue. In this case it is not so useful, because we detected the issue with side channel information (the response time), but we will use that feature in the method related to the passive scanner.<\/p>\n<p>The final code of the <em>activeAudit<\/em> function is the following:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Override\r\npublic AuditResult activeAudit(HttpRequestResponse baseRequestResponse, AuditInsertionPoint auditInsertionPoint) {\r\n\r\n    \/\/ Initialize an empty list of audit issues that we will eventually populate and return at the end of the function\r\n    List&lt;AuditIssue&gt; activeAuditIssues = new ArrayList&lt;AuditIssue&gt;();\r\n\r\n    \/\/ For each CommonsCollections 3 payload we defined, we try to exploit the issue\r\n    for(int i = 0; i&lt; StaticItems.apacheCommonsCollections3Payloads.length; i++) {\r\n\r\n        \/\/ We create an HTTP request containing our payload in the current insertion point\r\n        HttpRequest commonsCollectionsCheckRequest = auditInsertionPoint.buildHttpRequestWithPayload(\r\n                ByteArray.byteArray(StaticItems.apacheCommonsCollections3Payloads[i]))\r\n                .withService(baseRequestResponse.httpService());\r\n\r\n        \/\/ We record the current time, execute the request and record the time again\r\n        long startTime = System.nanoTime();\r\n        HttpRequestResponse commonsCollectionsCheckRequestResponse = api.http().sendRequest(commonsCollectionsCheckRequest);\r\n        long endTime = System.nanoTime();\r\n\r\n        \/\/ We calculate the interval between when we sent the request and when we received the response (converted in seconds)\r\n        long duration = TimeUnit.SECONDS.convert((endTime - startTime), TimeUnit.NANOSECONDS);\r\n\r\n        \/\/ If the interval is greater than 9 seconds we may have a vulnerable endpoint (our payloads sleep for 10 seconds)\r\n        if (((int) duration) &gt;= 9) {\r\n\r\n            \/\/ In this case, we create an issue object and adds it to the list of issues to be returned\r\n            AuditIssue auditIssue = AuditIssue.auditIssue(StaticItems.apacheCommonsCollections3IssueName,\r\n                    StaticItems.apacheCommonsCollections3IssueDetail,\r\n                    null, \/\/ remediation\r\n                    baseRequestResponse.request().url(),\r\n                    StaticItems.apacheCommonsCollections3IssueSeverity,\r\n                    StaticItems.apacheCommonsCollections3IssueConfidence,\r\n                    null, \/\/ background\r\n                    null, \/\/ remediationBackground\r\n                    StaticItems.apacheCommonsCollections3IssueTypicalSeverity,\r\n                    commonsCollectionsCheckRequestResponse); \/\/Request\/response can be highlighted\r\n\r\n            activeAuditIssues.add(auditIssue);\r\n\r\n        }\r\n\r\n    }\r\n\r\n    \/\/ Return the list of issues\r\n    return AuditResult.auditResult(activeAuditIssues);\r\n\r\n}<\/pre>\n<p>Moving on to the <strong><em>passiveAudit<\/em> method<\/strong> for adding checks to the passive scanner, our goal is simply to identify HTTP request parameters containing potential serialized Java objects. These objects always start with the same bytes (magic bytes) and can therefore be easily identified. For simplicity, we will limit our search to objects sent in ASCII HEX format and encoded in Base64. The goal is to find requests that send serialized objects to the backend, as they are potentially vulnerable to RCE.<\/p>\n<div class=\"group\/conversation-turn relative flex w-full min-w-0 flex-col agent-turn\">\n<div class=\"flex-col gap-1 md:gap-3\">\n<div class=\"flex flex-grow flex-col max-w-full\">\n<div class=\"min-h-[20px] text-message flex w-full flex-col items-end gap-2 whitespace-pre-wrap break-words [.text-message+&amp;]:mt-5 overflow-x-auto\" dir=\"auto\" data-message-author-role=\"assistant\" data-message-id=\"246ad955-c7f8-41d0-81ec-36e347315279\">\n<div class=\"flex w-full flex-col gap-1 empty:hidden first:pt-[3px]\">\n<div class=\"markdown prose w-full break-words dark:prose-invert light\">\n<p>The method is very similar to the previous one, but unlike its active counterpart, it does not make any requests. Let&#8217;s start by looking at the method and then explain its different parts:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">private byte[] serializationMagicBytes = {(byte)0xac, (byte)0xed, (byte)0x00, (byte)0x05};\r\nprivate byte[] base64MagicBytes = {(byte)0x72, (byte)0x4f, (byte)0x30, (byte)0x41};\r\n\r\n@Override\r\npublic AuditResult passiveAudit(HttpRequestResponse baseRequestResponse) {\r\n\r\n    \/\/ Initialize an empty list of audit issues that we will eventually populate and return at the end of the function\r\n    List&lt;AuditIssue&gt; passiveAuditIssues = new ArrayList&lt;AuditIssue&gt;();\r\n\r\n    \/\/Extract request bytes\r\n    ByteArray request = baseRequestResponse.request().toByteArray();\r\n\r\n    \/\/ Check for the magic bytes of Java serialized object (not encoded and Base64 encoded)\r\n    int indexOfSerializationMagicBytes = request.indexOf(ByteArray.byteArray(serializationMagicBytes));\r\n    int indexOfBase64MagicBytes = request.indexOf(ByteArray.byteArray(base64MagicBytes));\r\n\r\n    \/\/ Improvement -&gt; Search all matches with a while instead of an if\r\n\r\n    \/\/ If we found the magic bytes we report the passive issue\r\n    if(indexOfSerializationMagicBytes != -1 || indexOfBase64MagicBytes != -1) {\r\n\r\n        \/\/ Calculate the indexes to highlight the start of the serialized object in the request\r\n        int startIndex;\r\n        if(indexOfSerializationMagicBytes != -1)\r\n            startIndex = indexOfSerializationMagicBytes;\r\n        else\r\n            startIndex = indexOfBase64MagicBytes;\r\n        int endIndex = startIndex+4;\r\n\r\n        \/\/ Create the markers to highlight the request in the reported issue\r\n        List&lt;Marker&gt; highlights = new ArrayList&lt;Marker&gt;();\r\n        Marker marker = Marker.marker(startIndex, endIndex);\r\n        highlights.add(marker);\r\n\r\n        \/\/ Report the passive issue\r\n        AuditIssue auditIssue = AuditIssue.auditIssue(StaticItems.passiveSerializationIssueName,\r\n                StaticItems.passiveSerializationIssueDetail,\r\n                null, \/\/ remediation\r\n                baseRequestResponse.request().url(),\r\n                StaticItems.passiveSerializationIssueSeverity,\r\n                StaticItems.passiveSerializationIssueConfidence,\r\n                null, \/\/ background\r\n                null, \/\/ remediationBackground\r\n                StaticItems.passiveSerializationIssueTypicalSeverity,\r\n                baseRequestResponse.withRequestMarkers(highlights));\r\n\r\n        passiveAuditIssues.add(auditIssue);\r\n\r\n\r\n    }\r\n\r\n    \/\/ Return the list of issues\r\n    return AuditResult.auditResult(passiveAuditIssues);\r\n\r\n}<\/pre>\n<p>In this method we extract the body of the request, we convert it in <em><a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/core\/ByteArray.html\">ByteArray<\/a><\/em> format (an object offered by the Montoya API to handle byte arrays in a comfortable way) and we search for the magic bytes of serialized objects (ASCII HEX and Base64) using the <em>indexOf<\/em> method. If we find a serialized object, we create a passive issue. Just before creating the issue, we created a <em><a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/core\/Marker.html\">Marker<\/a><\/em> object that is a simple container for a couple if integers (start and end), that we will use to highlight the serialized object we found in the reported issue. As we can see in the last line of the <em>auditIssue\u00a0<\/em>function, instead of simply passing an <em>HttpRequestResponse<\/em> object to insert in the issue, we call the <em>withRequestMarkers<\/em> method of <em><a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/http\/message\/HttpRequestResponse.html\">HttpRequestResponse<\/a> <\/em>supplying the marker object, which returns a new <em>HttpRequestResponse <\/em>with markers that will highlight in the issue the portion of the request that contains the serialized object (to be more precise, the first 4 bytes of the serialized object).<\/p>\n<p>Finally, we have to code the <em>consolidateIssues <\/em>that will be called each time a new issue is identified by our check, once for every other issue identified by our check on the same URL, to <strong>avoid reporting duplicate issues<\/strong>. In order to keep the demo code simple, we keep only the existing issue if we have the same base URL and the same issue name, otherwise we keep both issues. The return value is of type <em><a href=\"https:\/\/portswigger.github.io\/burp-extensions-montoya-api\/javadoc\/burp\/api\/montoya\/scanner\/ConsolidationAction.html\">ConsolidationAction<\/a><\/em>, an enum with three values: KEEP_EXISTING, KEEP_NEW and KEEP_BOTH. If the issue is a duplicate, I use the KEEP_EXISTING (discard the new issue and keep the old one) because from my tests the KEEP_NEW status often does not cause the deletion of the old issue, causing duplicates. The function can be improved in many ways, for example by extracting the <em>HttpRequestResponse<\/em> object from the <em>AuditIssue<\/em> objects and discarding the new issue only if the attack vector has been inserted in the exactly same parameter (in order to report multiple issues if our scanner exploited the issue in different parameters of the same request), but it adds complexity (not useful for a demo application).<\/p>\n<p>The code of the function is the following:<\/p>\n<\/div>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Override\r\npublic ConsolidationAction consolidateIssues(AuditIssue newIssue, AuditIssue existingIssue) {\r\n\r\n    \/\/ Improvement: extract HttpRequestResponses and keep existing only if the\r\n    \/\/ attack vector has been inserted in the same parameter, but adds complexity\r\n\r\n    \/\/ If the new issue has the same name and base URL of the one of the older ones, keep only the new one\r\n    if(newIssue.name().equals(existingIssue.name()) &amp;&amp; newIssue.baseUrl().equals(existingIssue.baseUrl())) {\r\n        return ConsolidationAction.KEEP_EXISTING;\r\n    } else {\r\n        \/\/ Otherwise keep both the issues\r\n        return ConsolidationAction.KEEP_BOTH;\r\n    }\r\n\r\n}<\/pre>\n<p>As, always, now that we have our scan check class, we must register it in the <em>initialize<\/em> function of the main class of our extension:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@Override\r\npublic void initialize(MontoyaApi api) {\r\n\r\n    [...]\r\n\r\n    \/\/ Register our custom scan check\r\n    this.api.scanner().registerScanCheck(new CustomScanCheck(api));\r\n\r\n}<\/pre>\n<p>After compiling and packaging the extension and loading it in Burp Suite (see <a href=\"https:\/\/hnsecurity.it\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-1\/\">part 1<\/a> for details), we can try it out!<\/p>\n<p>First, <strong>let&#8217;s try the passive scanner<\/strong>. It should be enabled by default (and report issues while we navigate the target application), but we can also force its use as follows:<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3625 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-28-1.png\" alt=\"\" width=\"1283\" height=\"553\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-28-1.png 1283w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-28-1-300x129.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-28-1-1024x441.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-28-1-768x331.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-28-1-350x151.png 350w\" sizes=\"(max-width: 1283px) 100vw, 1283px\" \/><\/p>\n<p>And that&#8217;s the result:<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3626 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-30-1.png\" alt=\"\" width=\"1288\" height=\"709\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-30-1.png 1288w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-30-1-300x165.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-30-1-1024x564.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-30-1-768x423.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-30-1-350x193.png 350w\" sizes=\"(max-width: 1288px) 100vw, 1288px\" \/><\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Then we can <strong>run the active scan<\/strong>. A little trick: when you test a scanner plugin, in order to avoid wasting time, my advice is to configure a scan configuration that only executes extender checks, in order to check if the plugin works without having to wait for a full scan. To do so, first open the scan launcher:<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3628 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-31-1.png\" alt=\"\" width=\"1301\" height=\"556\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-31-1.png 1301w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-31-1-300x128.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-31-1-1024x438.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-31-1-768x328.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-31-1-350x150.png 350w\" sizes=\"(max-width: 1301px) 100vw, 1301px\" \/><\/p>\n<p>Then in &#8220;Scan configuration&#8221; create a new configuration and deselect all the individual issues in the &#8220;Issues Reported&#8221; section (CTRL-A to select all, right click and remove the flag on &#8220;Selected):<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3629 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-32-1.png\" alt=\"\" width=\"917\" height=\"770\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-32-1.png 917w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-32-1-300x252.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-32-1-768x645.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-32-1-350x294.png 350w\" sizes=\"(max-width: 917px) 100vw, 917px\" \/><\/p>\n<p>Finally flag only &#8220;Extension generated issue&#8221; (you have a search form at the top right)<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3630 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-32_1-1.png\" alt=\"\" width=\"885\" height=\"236\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-32_1-1.png 885w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-32_1-1-300x80.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-32_1-1-768x205.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-32_1-1-350x93.png 350w\" sizes=\"(max-width: 885px) 100vw, 885px\" \/><\/p>\n<p>Save, run and the result is the following:<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3631 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-34-1.png\" alt=\"\" width=\"1496\" height=\"853\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-34-1.png 1496w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-34-1-300x171.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-34-1-1024x584.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-34-1-768x438.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-34-1-350x200.png 350w\" sizes=\"(max-width: 1496px) 100vw, 1496px\" \/><\/p>\n<p>One last tip that you may not know: you don&#8217;t have to run a full scan on all insertion points of the request all the times you use Burp Suite&#8217;s active scanner. <strong>Burp allows to scan only specific insertion points<\/strong>. To do so, send the request to Burp Intruder, highlight the insertion point(s) you want to scan, right click and select &#8220;Scan defined insertion points&#8221; (very useful feature not only when you develop a plugin but also during everyday&#8217;s pentesting):<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3632 aligncenter\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-44-1.png\" alt=\"\" width=\"1073\" height=\"716\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-44-1.png 1073w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-44-1-300x200.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-44-1-1024x683.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-44-1-768x512.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2024\/07\/2024-07-26_09-44-1-350x234.png 350w\" sizes=\"(max-width: 1073px) 100vw, 1073px\" \/><\/p>\n<p>And that\u2019s all for today. In the next part, we will see <strong>how to use the Collaborator in our plugins<\/strong>.<\/p>\n<p>As always, the complete code of the backend and of the plugins can be downloaded from\u00a0<a href=\"https:\/\/github.com\/federicodotta\/Burp-Suite-Extender-Montoya-Course\">my GitHub repository.<\/a><\/p>\n<p>Cheers!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Setting up the environment + Hello World Inspecting and tampering HTTP requests and responses Inspecting and tampering WebSocket messages Creating [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":159897,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[88,91],"tags":[186,187,188,189,104,115,185],"class_list":["post-3507","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tools","category-articles","tag-extender-course","tag-extending-burp-suite","tag-montoya-api","tag-tutorial","tag-burp-suite","tag-web","tag-extender"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>HN Security Extending Burp Suite for fun and profit - The Montoya way - Part 6<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"HN Security Extending Burp Suite for fun and profit - The Montoya way - Part 6\" \/>\n<meta property=\"og:description\" content=\"Setting up the environment + Hello World Inspecting and tampering HTTP requests and responses Inspecting and tampering WebSocket messages Creating [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/\" \/>\n<meta property=\"og:site_name\" content=\"HN Security\" \/>\n<meta property=\"article:published_time\" content=\"2024-07-30T12:16:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-12-10T09:00:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t<meta property=\"og:image:height\" content=\"836\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Federico Dotta\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@hnsec\" \/>\n<meta name=\"twitter:site\" content=\"@hnsec\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Federico Dotta\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/\"},\"author\":{\"name\":\"Federico Dotta\",\"@id\":\"https:\/\/hnsecurity.it\/it\/#\/schema\/person\/e0e6046bd2bc829f7d945ad361bce702\"},\"headline\":\"Extending Burp Suite for fun and profit &#8211; The Montoya way &#8211; Part 6\",\"datePublished\":\"2024-07-30T12:16:18+00:00\",\"dateModified\":\"2025-12-10T09:00:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/\"},\"wordCount\":3234,\"publisher\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/#organization\"},\"image\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg\",\"keywords\":[\"Extender course\",\"Extending Burp Suite\",\"Montoya API\",\"Tutorial\",\"Burp Suite\",\"web\",\"Extender\"],\"articleSection\":[\"Tools\",\"Articles\"],\"inLanguage\":\"it-IT\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/\",\"url\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/\",\"name\":\"HN Security Extending Burp Suite for fun and profit - The Montoya way - Part 6\",\"isPartOf\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg\",\"datePublished\":\"2024-07-30T12:16:18+00:00\",\"dateModified\":\"2025-12-10T09:00:05+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#primaryimage\",\"url\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg\",\"contentUrl\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg\",\"width\":1600,\"height\":836},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/hnsecurity.it\/it\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Extending Burp Suite for fun and profit &#8211; The Montoya way &#8211; Part 6\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/hnsecurity.it\/it\/#website\",\"url\":\"https:\/\/hnsecurity.it\/it\/\",\"name\":\"HN Security\",\"description\":\"Offensive Security Specialists\",\"publisher\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/hnsecurity.it\/it\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/hnsecurity.it\/it\/#organization\",\"name\":\"HN Security\",\"url\":\"https:\/\/hnsecurity.it\/it\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/hnsecurity.it\/it\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2026\/01\/hn-libellula.jpg\",\"contentUrl\":\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2026\/01\/hn-libellula.jpg\",\"width\":696,\"height\":696,\"caption\":\"HN Security\"},\"image\":{\"@id\":\"https:\/\/hnsecurity.it\/it\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/hnsec\",\"https:\/\/www.linkedin.com\/company\/hnsecurity\/\",\"https:\/\/github.com\/hnsecurity\",\"https:\/\/infosec.exchange\/@hnsec\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/hnsecurity.it\/it\/#\/schema\/person\/e0e6046bd2bc829f7d945ad361bce702\",\"name\":\"Federico Dotta\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/02d5d800b81f2a125ac23ee31a108ee2404d123bd3b722f2e263f0130cc1df42?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/02d5d800b81f2a125ac23ee31a108ee2404d123bd3b722f2e263f0130cc1df42?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/02d5d800b81f2a125ac23ee31a108ee2404d123bd3b722f2e263f0130cc1df42?s=96&d=mm&r=g\",\"caption\":\"Federico Dotta\"},\"url\":\"https:\/\/hnsecurity.it\/it\/blog\/author\/federico-dotta\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"HN Security Extending Burp Suite for fun and profit - The Montoya way - Part 6","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/","og_locale":"it_IT","og_type":"article","og_title":"HN Security Extending Burp Suite for fun and profit - The Montoya way - Part 6","og_description":"Setting up the environment + Hello World Inspecting and tampering HTTP requests and responses Inspecting and tampering WebSocket messages Creating [&hellip;]","og_url":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/","og_site_name":"HN Security","article_published_time":"2024-07-30T12:16:18+00:00","article_modified_time":"2025-12-10T09:00:05+00:00","og_image":[{"width":1600,"height":836,"url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg","type":"image\/jpeg"}],"author":"Federico Dotta","twitter_card":"summary_large_image","twitter_creator":"@hnsec","twitter_site":"@hnsec","twitter_misc":{"Scritto da":"Federico Dotta","Tempo di lettura stimato":"17 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#article","isPartOf":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/"},"author":{"name":"Federico Dotta","@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/person\/e0e6046bd2bc829f7d945ad361bce702"},"headline":"Extending Burp Suite for fun and profit &#8211; The Montoya way &#8211; Part 6","datePublished":"2024-07-30T12:16:18+00:00","dateModified":"2025-12-10T09:00:05+00:00","mainEntityOfPage":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/"},"wordCount":3234,"publisher":{"@id":"https:\/\/hnsecurity.it\/it\/#organization"},"image":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#primaryimage"},"thumbnailUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg","keywords":["Extender course","Extending Burp Suite","Montoya API","Tutorial","Burp Suite","web","Extender"],"articleSection":["Tools","Articles"],"inLanguage":"it-IT"},{"@type":"WebPage","@id":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/","url":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/","name":"HN Security Extending Burp Suite for fun and profit - The Montoya way - Part 6","isPartOf":{"@id":"https:\/\/hnsecurity.it\/it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#primaryimage"},"image":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#primaryimage"},"thumbnailUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg","datePublished":"2024-07-30T12:16:18+00:00","dateModified":"2025-12-10T09:00:05+00:00","breadcrumb":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#primaryimage","url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg","contentUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg","width":1600,"height":836},{"@type":"BreadcrumbList","@id":"https:\/\/hnsecurity.it\/it\/blog\/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-6\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/hnsecurity.it\/it\/"},{"@type":"ListItem","position":2,"name":"Extending Burp Suite for fun and profit &#8211; The Montoya way &#8211; Part 6"}]},{"@type":"WebSite","@id":"https:\/\/hnsecurity.it\/it\/#website","url":"https:\/\/hnsecurity.it\/it\/","name":"HN Security","description":"Offensive Security Specialists","publisher":{"@id":"https:\/\/hnsecurity.it\/it\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/hnsecurity.it\/it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":"Organization","@id":"https:\/\/hnsecurity.it\/it\/#organization","name":"HN Security","url":"https:\/\/hnsecurity.it\/it\/","logo":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/logo\/image\/","url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2026\/01\/hn-libellula.jpg","contentUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2026\/01\/hn-libellula.jpg","width":696,"height":696,"caption":"HN Security"},"image":{"@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/hnsec","https:\/\/www.linkedin.com\/company\/hnsecurity\/","https:\/\/github.com\/hnsecurity","https:\/\/infosec.exchange\/@hnsec"]},{"@type":"Person","@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/person\/e0e6046bd2bc829f7d945ad361bce702","name":"Federico Dotta","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/secure.gravatar.com\/avatar\/02d5d800b81f2a125ac23ee31a108ee2404d123bd3b722f2e263f0130cc1df42?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/02d5d800b81f2a125ac23ee31a108ee2404d123bd3b722f2e263f0130cc1df42?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/02d5d800b81f2a125ac23ee31a108ee2404d123bd3b722f2e263f0130cc1df42?s=96&d=mm&r=g","caption":"Federico Dotta"},"url":"https:\/\/hnsecurity.it\/it\/blog\/author\/federico-dotta\/"}]}},"jetpack_featured_media_url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/BURP.jpg","_links":{"self":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts\/3507","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/comments?post=3507"}],"version-history":[{"count":2,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts\/3507\/revisions"}],"predecessor-version":[{"id":161263,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts\/3507\/revisions\/161263"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/media\/159897"}],"wp:attachment":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/media?parent=3507"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/categories?post=3507"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/tags?post=3507"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}