Skip to content

Commit d30953b

Browse files
authored
Adding a script to encrypt requests using RSA (#437)
* Created RsaEncryptPayloadForZap.py Signed-off-by: Michał Walkowski <[email protected]>
1 parent a33e339 commit d30953b

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
88
- extender/arpSyndicateSubdomainDiscovery.js - uses the API of [ARPSyndicate's Subdomain Center](https://www.subdomain.center/)
99
to find and add subdomains to the Sites Tree.
1010
- passive/JavaDisclosure.js - Passive scan for Java error messages leaks
11+
- httpsender/RsaEncryptPayloadForZap.py - A script that encrypts requests using RSA
1112

1213
## [18] - 2024-01-29
1314
### Added
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# RSA Encrypt Payload Script for Zed Attack Proxy - ZAP
2+
# HelpAddOn Script - HTTPSender
3+
# Michal Walkowski - https://mwalkowski.github.io/
4+
#
5+
# Tested with Jython 14 beta and ZAP 2.14.0
6+
# Based On: https://mwalkowski.github.io/post/using-burp-python-scripts-to-encrypt-requests-with-rsa-keys/
7+
# You can test the script's functionality using https://github.com/mwalkowski/api-request-security-poc
8+
9+
10+
11+
import json
12+
import base64
13+
import subprocess
14+
15+
# path to public.pem
16+
PUBLIC_KEY = "public.pem"
17+
18+
PAYLOAD_PLACEHOLDER = "PAYLOAD"
19+
PAYLOAD = '{\"keyId\": \"init\", \"encryptedPayload\": \"' + PAYLOAD_PLACEHOLDER + '\"}'
20+
21+
22+
def encrypt_body(body):
23+
body_b64 = base64.standard_b64encode(json.dumps(body, ensure_ascii=False).encode()).decode()
24+
25+
cmd = 'printf %s "{}" | openssl pkeyutl -encrypt -pubin -inkey {} | openssl base64'.format(body_b64, PUBLIC_KEY)
26+
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
27+
output, err = process.communicate()
28+
if err.decode() != "":
29+
raise Exception(err)
30+
31+
return output.decode().replace("\n", "")
32+
33+
34+
def sendingRequest(msg, initiator, helper):
35+
body = msg.getRequestBody().toString()
36+
msg.setNote(body)
37+
body = json.loads(body)
38+
encrypted_body = encrypt_body(body)
39+
new_payload = PAYLOAD.replace(PAYLOAD_PLACEHOLDER, encrypted_body)
40+
msg.setRequestBody(new_payload)
41+
msg.getRequestHeader().setContentLength(msg.getRequestBody().length())
42+
43+
44+
def responseReceived(msg, initiator, helper):
45+
# Restoring the original value of the sent request from before encryption to facilitate work in the Requester module.
46+
# Without this change, ZAP would automatically replace the value with an encrypted one. Additionally, to more easily
47+
# identify the requests sent to the server in the history, we store the plain text in notes.
48+
body = msg.getNote()
49+
msg.setRequestBody(body)

0 commit comments

Comments
 (0)