netspi / awssigner Goto Github PK
View Code? Open in Web Editor NEWBurp Extension for AWS Signing
License: MIT License
Burp Extension for AWS Signing
License: MIT License
There is an issue that results in incorrect signatures that appears to be the result of GET parameter names and ordering. By reordering the parameters its possible to have a resulting correct signature. Changing the parameter value from a string to a integer, or vice versa did not show any change in behavior. Attempts at encoding did not help. Examples of parameter strings that resulted in correct and incorrect signatures are below.
Incorrect sig: GET /?pnum=1111111111&userFirstname=Bob×tamp=1642407088910
Incorrect sig: GET /?userFirstname=Bob&pnum=1111111111×tamp=1642407088910
Correct sig: GET /?pnum=1111111111×tamp=1642407088910&userFirstname=Bob
// --------------------
Incorrect sig: GET /?userFirstname=Bob&userLastname=SmithuserEmail=Bob.Smith%40example.com×tamp=1564258409354
Incorrect sig: GET /?userFirstname=Bob&userLastname=Smith×tamp=1564258409354&userEmail=Bob.Smith%40example.com
Incorrect sig: GET /?timestamp=1564258409354&userFirstname=Bob&userLastname=Smith&userEmail=Bob.Smith%40example.com
Incorrect sig: GET /?timestamp=1564258409354&userFirstname=1111111111&userLastname=1111111111&userEmail=1111111111
Incorrect sig: GET /?timestamp=1564258409354&e=Bob.Smith%40example.com&f=Bob&l=Smith
Incorrect sig: GET /?%74%69%6d%65%73%74%61%6d%70%3d%31%35%36%34%32%35%38%34%30%39%33%35%34%26%75%73%65%72%45%6d%61%69%6c%3d%42%6f%62%2e%53%6d%69%74%68%25%34%30%65%78%61%6d%70%6c%65%2e%63%6f%6d%26%75%73%65%72%46%69%72%73%74%6e%61%6d%65%3d%42%6f%62%26%75%73%65%72%4c%61%73%74%6e%61%6d%65%3d%53%6d%69%74%68
Correct sig: GET /?timestamp=1564258409354&userEmail=Bob.Smith%40example.com&userFirstname=Bob&userLastname=Smith
Correct sig: GET /?timestamp=1564258409354&userEmail=11111111111&userFirstname=1111111111&userLastname=1111111111
// --------------------
Incorrect sig: GET /?username=Example.com_123456×tamp=1564290688176
Correct sig: GET /?timestamp=1564290688176&username=Example.com_123456
Some application request that some custom headers needs to be signed.
is it possible to add extra configuration parameter, so i can specify what additional HTTP headers needs to be signed?
I am using the extension latest version from the release (loaded latest jar file), and i get the "java.lang.NullPointerException" showing in the Error tab. the Output tab shows Signing with profile 1 with key: iuhqwieuhfqilwuehf123423jiuh
burp 2.0.18beta
java comes with burp.
Issue: A malformed request that sends POST data using the GET method is not properly signed. The result is a request that truncates that POST body and signs the GET request.
Proposed Solution: Ensure that requests are not truncated and that, regardless of the HTTP method used, the entire request is signed.
Base Request:
GET /[REDACTED]/capability HTTP/1.1
Host: [REDACTED]
Accept-Encoding: gzip, deflate
Content-Length: 61
User-Agent: aws-cli/1.16.278 Python/3.7.4 Windows/10 botocore/1.13.14
X-Amz-Date: 20200324T182027Z
Authorization: [REDACTED]
Connection: close
{
[REDACTED]
}
AWS Signer Modified Request:
GET /[REDACTED]/capability HTTP/1.1
Host: [REDACTED]
Accept-Encoding: gzip, deflate
Content-Length: 61
User-Agent: aws-cli/1.16.278 Python/3.7.4 Windows/10 botocore/1.13.14
X-Amz-Date: 20200324T182027Z
Authorization: [REDACTED]
Connection: close
Some services require this header to be updated as part of the new signature.
X-Amz-Content-Sha256
Hey folks,
I'm seeing some examples in an API where, when HTTP/2 requests are enabled (and AWS Signer is signing the request), the request is malformed and rejected by the API server.
Some things I've noted:
AWS Signer and Logger++ seem to be mis-interacting as well, as I'm unable to view the response data for HTTP/2 requests in Logger++ after AWS Signer signs the request.
Any ideas?
Currently, the signed headers list added to the Authorization
header is not sorted after adding x-amz-security-token
in case a session token is used in the signer. This results in a signature error.
Hello,
thanks for providing this addon.
gradle can build it successfully, but importing the .jar file fails in burp.
java.lang.NullPointerException
at burp.BurpExtender.createNewProfile(BurpExtender.java:60)
at burp.BurpExtender.setupTab(BurpExtender.java:96)
at burp.BurpExtender.registerExtenderCallbacks(BurpExtender.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at burp.is.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
The reason is that the UI-Components like the following in BurpExtender.java
private JPanel panel;
private JTextField accessKey;
private JTextField secretKey;
private JTextField region;
private JTextField service;
private JComboBox profileComboBox;
are not generated by the gradle building process correctly.
My guess is because you used the IntelliJ UI Designer.
According to this https://stackoverflow.com/a/38423072/2835625 answer this problem can be resolved very easily.
Is there any way to highlight to identify AWS Signer is active or use the edited column within the proxy tab? Initially I didn't realize AWS Signer was active and changing the authorization header in my proxy when I had activated it within the Repeater tab.
Currently, strings like  are not handled properly in the signer and cause signing errors when encountered. These characters should be encoded before being used in the signer. A user is able to do that encoding manually, but it would be helpful to do the encoding automatically as well.
The above line is used during the import process for profile files (either exported by AWS Signer, or from the ~/.aws/config
file locally). The former supports profile names with spaces in them. However, importing these files breaks, with AWS Signer detecting no profiles in the file:
[DEBUG] Import Profile Button Clicked.
[DEBUG] Selected path from file dialog: /fake_path/aws_signer.ini
[INFO] Imported 0 profile(s) from file: /fake_path/aws_signer.ini
Here's an example export file from AWS Signer that causes this:
[profile Foo: Bar]
signer_enabled=true
signer_in_scope_only=true
credential_process=/fake_path/bin/gimme --account foo --role bar
duration_seconds=60
[profile Foo external]
signer_enabled=true
signer_in_scope_only=true
role_arn=arn:aws:iam::123456789012:role/external
source_profile=Foo: Bar
role_session_name=aph3rson_external
[profile Foo: Baz]
signer_enabled=true
signer_in_scope_only=true
credential_process=/fake_path/bin/gimme --account foo --role baz
duration_seconds=60
[profile Creds: OhYes]
signer_enabled=true
signer_in_scope_only=true
credential_process=/fake_path/bin/gimme --account creds --role ohyes
duration_seconds=60
It may be more appropriate to use an INI library for this - the ~/.aws/config
file is INI-formatted, as mentioned here if that's what AWS Signer is shooting for.
Hey!
I tried using this extension. However, I get the error {"message":"'Host' must be a 'SignedHeader' in the AWS Authorization."}
and the request is indeed lacking SignedHeaders information:
Authorization: AWS4-HMAC-SHA256 Credential=[...]eu-west-1[...], SignedHeaders=, Signature=
Also AWS Signer throws the following exception for each request:
java.lang.UnsupportedOperationException: Request has already been issued
at burp.e3f.setRequest(Unknown Source)
at burp.gqz.setRequest(Unknown Source)
at burp.BurpExtender.processHttpMessage(BurpExtender.java:275)
at burp.dyn.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Can't figure it out though why the header is missing.
The notUnicode
regex fails to match some characters (I've only so far noticed [
and ]
) which then cause an exception when attempting to parse into a URI object:
https://github.com/NetSPI/AWSSigner/blob/master/src/main/java/burp/Utility.java#L130-L144
Example stack trace below:
java.net.URISyntaxException: Illegal character in path at index 11: /test(hello]
at java.base/java.net.URI$Parser.fail(URI.java:2915)
at java.base/java.net.URI$Parser.checkChars(URI.java:3086)
at java.base/java.net.URI$Parser.parseHierarchical(URI.java:3168)
at java.base/java.net.URI$Parser.parse(URI.java:3127)
at java.base/java.net.URI.<init>(URI.java:600)
at burp.Utility.signRequest(Utility.java:144)
at burp.BurpExtender.processHttpMessage(BurpExtender.java:500)
at burp.e0t.run(Unknown Source)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Stacktrace is
java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at burp.Utility.signRequest(Utility.java:104)
at burp.BurpExtender.processHttpMessage(BurpExtender.java:268)
at burp.dh0.run(Unknown Source)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter
at burp.Utility.signRequest(Utility.java:104)
at burp.BurpExtender.processHttpMessage(BurpExtender.java:268)
at burp.dh0.run(Unknown Source)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Looks like it doesn't work properly with java version more than 8 as said at
stackoverflow
P.S. I don't know java well
The signer has changed header handling behavior that is negatively impacting some of my testing. Specifically, when I make a request in Repeater that has a Host header that is different than the Target set, the signer rewrites the Host header to be equivalent to the Repeater Target. With my proxy setup, this is a breaking change and I had to grab an old version of the signer in order to continue my work. Please consider adding a setting to modify this behavior or turn it off.
Ex.
Initial request in repeater:
Target: localhost:12345
Host: vpce-blahblah.com
Result, as seen in Flow (logging extension):
Target: localhost:12345
Host: localhost:12345
Also, I’m unclear if it uses the Host or the Target to sign, but I would want the Host to be the signed header.
Just something to consider: instead of having a checkbox to use default creds, why not populate all the profiles from the creds file right when the extension loads? Then users can just select whatever profile they want from their creds file, or add a new one like normal.
I have installed BURP and the AWS signer addon.
I can enter access key, secret, service, and region.
But I don't know how to invoke the AWS signing from BURP.
Tried to open repeater when I can craft a GET request, inserting x-amz-date, but the request is sent as is, without AWS signer inserting the authorization header.
Where in BURP do I send GET request with the AWS signer created headers?
Thanks.
[DEBUG] Handling incoming HTTP message.
[DEBUG] Message is not a SigV4 request.
[DEBUG] Handling incoming HTTP message.
[DEBUG] Ignoring response.
The headers do not contain the keys and are instead submitted in the form-data boundaries.
The keys I'm looking to update are x-amz-security-token, policy, and x-amz-signature. Am I doing it right or should I be looking elsewhere?
Previously, Burp did not allow for easy state tracking for extensions across restarts of Burp/reloads of the extension/reloads of the project. This meant that extensions had to either be reconfigured across every reload, or do hacky things to track extension state as a bogus request in the sitemap.
However, Burp now supports the saveExtensionSetting
and loadExtensionSetting
API methods, which allows saving simple key/value pairs associated with the extension. These settings are durable across extension reloads, project reloads, and Burp restarts.
It'd be great if AWSSigner supported these methods, and saved extension state into the project file itself.
On certain APIs, it appears the body isn't used for signing in the canonical request (e.g. when the body is part of a multipart upload, this API is one example where this happens)
In the example above, there is an X-Amz-Content-Sha256 header that provides the value UNSIGNED-PAYLOAD that's used in place of the actual body SHA256 in the canonical request when calculating the signature.
Is it possible to add an option to use the value of the X-Amz-Content-Sha256 header instead of the calculated payload SHA256 when signing?
Current idea is to add just one input field for a role ARN to assume, and a refresh button to manually refresh when the creds expire. Could add some kind of polling but that would be trickier.
This way, just add the ARN you want to assume, and use the creds in the normal input fields to assume that role.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.