Skip to content

Commit 0e8d3cf

Browse files
committed
first commit
0 parents  commit 0e8d3cf

10 files changed

+1607
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.iml
2+
.idea/
3+
out/
4+
target/

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 NCC Group Plc
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# `HTTPSignatures` Burp Suite Extension
2+
3+
`HTTPSignatures` is a Burp Suite extension that implements the Signing HTTP Messages [`draft-ietf-httpbis-message-signatures-01`](https://tools.ietf.org/html/draft-ietf-httpbis-message-signatures-01) specification draft document.
4+
This allows Burp Suite users to seamlessly test applications that require HTTP Signatures.
5+
6+
7+
## Features
8+
9+
- Automatically creates a new signature and digest in Burp Repeater, Intruder, and Scanner when the extension detects an existing HTTP Signature header.
10+
- Supports the `rsa-sha256` algorithm for signing messages (`RSASSA-PKCS1-v1_5` [[RFC8017](https://tools.ietf.org/html/rfc8017)] using SHA-256 [[RFC6234](https://tools.ietf.org/html/rfc6234)]) and SHA-256 for the digest header.
11+
- The extension works in Burp Suite Professional and in the free Burp Suite Community Edition.
12+
13+
## Usage
14+
15+
### Installation
16+
17+
Download the [latest JAR release](https://github.com/nccgroup/HTTPSignatures/releases/latest) file and add it in Burp Suite through Extender Tab / Extensions / Add.
18+
19+
### Configuration
20+
21+
1. After loading the extension a new *HTTP Signatures* menu item will be added to Burp.
22+
2. Open the configuration tab (click the *HTTP Signatures* menu item).
23+
3. The minimum configuration requires the `Header Name`, the ``keyId``, and the `Private key file name and path` to be configured. See below for the detailed description.
24+
4. You can now use Burp Proxy, Repeater, Intruder, and Scanner.
25+
The extension will create a new Signature for each request that contains the configured `Header Name`.
26+
27+
### Use
28+
29+
After `HTTPSignatures` has been correctly configured, the Burp Suite extension will replace the HTTP header value configured in the `Header Name` setting (e.g. `Signature`) with a new signature for every HTTP request sent through Burp Proxy, Repeater, Intruder, and Scanner.
30+
31+
![`HTTPSignatures` Configuration](screenshots/config.png)
32+
33+
## Documentation
34+
35+
The Burp Suite extension must be configured before it can be used.
36+
The `HTTPSignatures` configuration can be found in the Burp menu after it has been loaded (usually on the right of the Help menu).
37+
The `Header Name`, the `keyId`, and the `Private key file name and path` have to be correctly configured for the extension to work.
38+
The remaining settings can optionally be adjusted.
39+
40+
- **Header Name**: (sample values: `Authorization`, `Signature`): The name of the HTTP request header that includes the signature.
41+
The IETF draft is using the `Signature` header name. Oracle Cloud (OCI) is using the `Authorization` header name.
42+
43+
- **keyId**: The `keyId` parameter is a US-ASCII string used by a verifier to identify and/or obtain the signature's verification key.
44+
Sample values can look like `https://mastodon.example.com/users/myUser` (for ActivityPub) or `ocid1.tenancy.oc1.../ocid1.user.oc1.../{fingerprint}` for OCI.
45+
46+
- **Private key file name and path**: The full path and file name containing the private key (e.g. `/home/${USER}/private_key.pem`).
47+
- **Digest Header Name**: The name of the header containing the digest. This should be either `x-content-sha256` (for OCI) or `digest` for most other implementations.
48+
- **Header Names to Sign: GET**: The header names to include for GET requests (e.g. `date (request-target) host`).
49+
The `(request-target)` value is a special identifier consisting of the request method and the path and query of the request URI (e.g. `get /foo?param=value`).
50+
- **Header Names to Sign: HEAD**: The header names to include in HEAD requests (e.g. `date (request-target) host`).
51+
- **Header Names to Sign: DELETE**: The header names to include in DELETE requests (e.g. `date (request-target) host`).
52+
- **Header Names to Sign: PUT**: The header names to include in PUT requests (e.g. `date (request-target) host content-length content-type digest`).
53+
- **Header Names to Sign: POST**: The header names to inlcude in POST requets (e.g. `date (request-target) host content-length content-type digest`).
54+
- **Include query parameters in Signature**: This boolean value specifies if query parameters (e.g. `?param=value`) should be included in the signature.
55+
While the draft standard specifies that query parameters are part of the `(request-target)` identifier, not all implementations include query parameters.
56+
The default value is `true`.
57+
- **Include the port in Signature**: Some implementations do not include the port in the host header (e.g. `localhost:8080`).
58+
This setting allows to remove the port from the host header value if set to `false`.
59+
The default value is `true`.
60+
61+
### Profiles
62+
63+
The `HTTPSignatures` configuration allows to configure multiple profiles in tabs.
64+
Create a new tab by clicking on the `...` tab.
65+
You can name tabs by double clicking on a tab.
66+
To save a tab click the "Save" button.
67+
To mark a tab as the active profile, click the "Use this profile" button.
68+
The **active tab** (profile) is marked with red font and border.
69+
70+
### Global Configuration Settings
71+
72+
The global configuration section contains settings that apply to all profiles.
73+
74+
- **Enable the extension for the following Burp Suite tools**: The extension can be enabled or disabled for the following Burp Suite tools:
75+
- Proxy (default: disabled)
76+
- Scanner (default: enabled)
77+
- Intruder (default: enabled)
78+
- Repeater (default: enabled)
79+
80+
The proxy is disabled be default. The oder tools are enabled by default. The proxy tool should usually only be enabled when using the intercept feature. The extension will not update the signature when it is disabled.
81+
82+
- **Enable Debug Logs**: Enabling this checkbox will print debug logs to the standard output.
83+
The output can be configured in Burp Suite under Extender -> Extensions, then select the *Signing HTTP Messages* extension.
84+
In the *Output* tab you can select where the standard output will be shown.
85+
The default is *Shown in UI* where the output will be displayed within Burp Suite.
86+
87+
## Example Configurations
88+
89+
### ActivityPub
90+
91+
[ActivityPub](https://www.w3.org/TR/activitypub/) uses HTTP Signatures for [server to server authentication and authorization](https://www.w3.org/wiki/SocialCG/ActivityPub/Authentication_Authorization).
92+
93+
- Header Name: `Signature`
94+
- keyId: The keyId should link to the actor so that the publicKey field can be retrieved: `https://mastodon.online/users/viktor`.
95+
You can use `curl` to retrieve the key: `curl https://mastodon.online/users/viktor -H 'Accept: application/activity+json'|jq`
96+
- Private key file name and path: `/home/user/private_key.pem`
97+
- Digest Header Name: `digest`
98+
- Header Names to Sign: GET: `date (request-target) host`
99+
- Header Names to Sign: HEAD: `date (request-target) host`
100+
- Header Names to Sign: DELETE: `date (request-target) host`
101+
- Header Names to Sign: PUT: `date (request-target) host content-length content-type digest`
102+
- Header Names to Sign: POST: `date (request-target) host content-length content-type digest`
103+
- Include query parameters in Signature: `true`
104+
- Include the port in Signature: `true`
105+
106+
### Oracle Cloud Infrastructure (OCI)
107+
108+
All Oracle Cloud Infrastructure (OCI) API requests [require HTTP Signatures](https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/signingrequests.htm).
109+
The implementation is based on the draft specification with some modifications.
110+
111+
- Header Name: `Authorization`
112+
- keyId: `<TENANCY OCID>/<USER OCID>/<KEY FINGERPRINT>`, e.g. `ocid1.tenancy.oc1..<unique_ID>/ocid1.user.oc1..<unique_ID>/<key_fingerprint>`
113+
- Private key file name and path: `/home/user/private_key.pem`
114+
- Digest Header Name: `x-content-sha256`
115+
- Header Names to Sign: GET: `date (request-target) host`
116+
- Header Names to Sign: HEAD: `date (request-target) host`
117+
- eader Names to Sign: DELETE: `date (request-target) host`
118+
- Header Names to Sign: PUT: `date (request-target) host content-length content-type x-content-sha256`
119+
- Header Names to Sign: POST: `date (request-target) host content-length content-type x-content-sha256`
120+
- Include query parameters in Signature: `true`
121+
- Include the port in Signature: `true`
122+
123+
124+
## Building with IntelliJ IDEA
125+
126+
1. Clone this repository and *Open or Import* the `HTTPSignatures` folder in IntelliJ IDEA.
127+
2. Compile the project (Build -> Build Project)
128+
3. Create a JAR file to import in Burp Suite: Go to File -> Project Structure, select Project Settings -> Artifacts.
129+
4. Click the plus sign to create a new JAR file "From modules with dependencies" and click OK.
130+
5. Select the "Include in project build" checkbox to automatically create a JAR file when building the project and click OK.
131+
6. Build the project again (Ctrl+F9 or ⌘+F9).
132+
7. The JAR file is created in the project folder at `out/artifacts/HTTPSignatures_jar/HTTPSignatures.jar`.
133+
8. Load the JAR file in Burp through the Extender Tab -> Extensions -> Add.
134+
135+
## Building on the Command Line using Maven
136+
137+
1. Clone this repository.
138+
2. Compile the project and create a JAR file with the command `mvn package assembly:single`.
139+
3. The JAR file is created in the project folder at `target/HTTPSignatures-1.0-SNAPSHOT-jar-with-dependencies.jar`.
140+
4. Load the JAR file in Burp through the Extender Tab -> Extensions -> Add.
141+
142+
### Dependencies
143+
144+
Three dependencies are required to build the Java project:
145+
- Apache HttpClient (https://hc.apache.org/httpcomponents-client-ga/)
146+
- Tomitribe's HTTP Signatures Java Client (https://github.com/tomitribe/http-signatures-java)
147+
- Burp Extender API (https://github.com/PortSwigger/burp-extender-api)
148+
149+

pom.xml

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<groupId>com.nccgroup.HTTPSignatures</groupId>
7+
<artifactId>HTTPSignatures</artifactId>
8+
<version>1.0-SNAPSHOT</version>
9+
<name>HTTPSignatures</name>
10+
<build>
11+
<plugins>
12+
<plugin>
13+
<groupId>org.apache.maven.plugins</groupId>
14+
<artifactId>maven-compiler-plugin</artifactId>
15+
<version>3.8.1</version>
16+
<configuration>
17+
<source>11</source>
18+
<target>11</target>
19+
</configuration>
20+
</plugin>
21+
<plugin>
22+
<artifactId>maven-assembly-plugin</artifactId>
23+
<version>3.3.0</version>
24+
<configuration>
25+
<descriptorRefs>
26+
<descriptorRef>jar-with-dependencies</descriptorRef>
27+
</descriptorRefs>
28+
</configuration>
29+
</plugin>
30+
</plugins>
31+
</build>
32+
<dependencies>
33+
<dependency>
34+
<groupId>org.apache.httpcomponents</groupId>
35+
<artifactId>httpclient</artifactId>
36+
<version>4.5.12</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>org.tomitribe</groupId>
40+
<artifactId>tomitribe-http-signatures</artifactId>
41+
<version>1.3</version>
42+
</dependency>
43+
<!-- https://mvnrepository.com/artifact/net.portswigger.burp.extender/burp-extender-api -->
44+
<dependency>
45+
<groupId>net.portswigger.burp.extender</groupId>
46+
<artifactId>burp-extender-api</artifactId>
47+
<version>2.1</version>
48+
</dependency>
49+
</dependencies>
50+
</project>

screenshots/config.png

101 KB
Loading

src/main/java/burp/BurpExtender.java

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package burp;
2+
3+
import javax.swing.*;
4+
5+
public class BurpExtender implements IBurpExtender, IHttpListener {
6+
private IExtensionHelpers helpers;
7+
8+
public void registerExtenderCallbacks (IBurpExtenderCallbacks callbacks) {
9+
new Signing(callbacks);
10+
callbacks.setExtensionName("Signing HTTP Messages");
11+
this.helpers = callbacks.getHelpers();
12+
SwingUtilities.invokeLater(new ConfigMenu());
13+
14+
// register ourselves as an HTTP listener (any burp tool)
15+
callbacks.registerHttpListener(BurpExtender.this);
16+
17+
// Set the debug flag from the settings
18+
if ( Signing.callbacks.loadExtensionSetting("debug") != null &&
19+
Signing.callbacks.loadExtensionSetting("debug").equals("true") ) {
20+
Signing.DEBUG = true;
21+
}
22+
}
23+
24+
/**
25+
* This method is invoked when an HTTP request is about to be issued, and
26+
* when an HTTP response has been received.
27+
*
28+
* @param toolFlag A flag indicating the Burp tool that issued the request.
29+
* Burp tool flags are defined in the
30+
* <code>IBurpExtenderCallbacks</code> interface.
31+
* @param messageIsRequest Flags whether the method is being invoked for a
32+
* request or response.
33+
* @param messageInfo Details of the request / response to be processed.
34+
* Extensions can call the setter methods on this object to update the
35+
* current message and so modify Burp's behavior.
36+
*/
37+
@Override
38+
public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {
39+
40+
// Process only requests (and not responses)
41+
if (!messageIsRequest) {
42+
return;
43+
}
44+
45+
// Check if this extension is enabled for the current Burp tool request
46+
if (Signing.enabledForTool(toolFlag)) {
47+
48+
// if there is no active key, do not sign this request
49+
if (Signing.callbacks.loadExtensionSetting("ActiveKey") == null) {
50+
return;
51+
}
52+
53+
IRequestInfo request = helpers.analyzeRequest(messageInfo.getRequest());
54+
java.util.List<String> headers = request.getHeaders();
55+
String profileValues = Signing.callbacks.loadExtensionSetting("ActiveKey");
56+
// get the header value (first element) from profileValues
57+
String[] valuesParts = profileValues.split(";");
58+
String header = valuesParts[0].toLowerCase();
59+
60+
// Process only requests containing an HTTP header starting with the configured header name (e.g. Authorization, Signature)
61+
if (headers.stream().anyMatch((str -> str.trim().toLowerCase().contains(header)))) {
62+
messageInfo.setRequest(Signing.signRequest(messageInfo));
63+
}
64+
}
65+
}
66+
}

src/main/java/burp/ConfigMenu.java

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package burp;
2+
3+
import javax.swing.*;
4+
import javax.swing.event.MenuEvent;
5+
import javax.swing.event.MenuListener;
6+
import java.awt.event.MouseAdapter;
7+
import java.awt.event.MouseEvent;
8+
9+
class ConfigMenu implements Runnable, MenuListener, IExtensionStateListener {
10+
private JMenu menuButton;
11+
12+
ConfigMenu() {
13+
Signing.callbacks.registerExtensionStateListener(this);
14+
}
15+
16+
public void run() {
17+
menuButton = new JMenu("HTTP Signatures");
18+
menuButton.addMouseListener(new MouseAdapter() {
19+
@Override
20+
public void mouseClicked(MouseEvent e) {
21+
SwingUtilities.invokeLater(new Runnable() {
22+
public void run() {
23+
Signing.globalSettings.showSettings();
24+
}
25+
});
26+
}
27+
});
28+
JMenuBar burpMenuBar = ConfigSettings.getBurpFrame().getJMenuBar();
29+
if (burpMenuBar == null) {
30+
Signing.callbacks.printError("Unable to add HTTP Signatures menu button.");
31+
} else {
32+
burpMenuBar.add(menuButton);
33+
}
34+
}
35+
36+
public void menuSelected(MenuEvent e) {
37+
SwingUtilities.invokeLater(new Runnable() {
38+
public void run() {
39+
Signing.globalSettings.showSettings();
40+
}
41+
});
42+
}
43+
44+
public void menuDeselected(MenuEvent e) {
45+
}
46+
47+
public void menuCanceled(MenuEvent e) {
48+
}
49+
50+
public void extensionUnloaded() {
51+
ConfigSettings.getBurpFrame().getJMenuBar().remove(menuButton);
52+
}
53+
}

0 commit comments

Comments
 (0)