Saudi and Oman National Cyber Security CTF

Qualifying round for Oman National Cyber Security CTF and Saudi Arabia Cyber Security CTF.
February 7 - February 9 2019

Saudi and Oman National Cyber Security CTF 2019

This one was just for fun, as non-citizens of Oman and Saudi Arabia were not eligible to advance, but one of our club's members brought it up in a meeting and I had a day over the weekend to play with it. We had some good collaboration over Discord, and I'm certain we were close to a solution on the hard web hacking challenge (Maria).

Just Another Conference (General Information)

famous Cybersecurity conference runs by OWASP in different locations

A quick Google easily locates the roaming AppSec conference run by OWASP.


Back to Basics (Web)

not pretty much many options. No need to open a link from a browser, there is always a different way

There’s no entry in the Wayback Machine, and the provided link redirects you to Google when opened in a browser. I tried to interrupt the redirect with a Burp intercept, and I can see it’s running a script:

<script> document.location = ""; </script>

I started my alternatives to browsers with curl and got:

<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.10.3 (Ubuntu)</center>

sftp to the was unsuccessful (permission denied(public key))

wget returns the same 301 message and the redirect script. I’m sensing a theme…

Some research into the RFC for HTTP 1.1 Semantics (including the 301 response), shows that a redirect site can respond to GET as well as to POST. Our site is using GET in its request, and changing that to POST in Burp gets us a different response before the redirect:

<!-- var _0x7f88=["","join","reverse","split","log","ceab068d9522dc567177de8009f323b2"];function reverse(_0xa6e5x2){flag= _0xa6e5x2[_0x7f88[3]](_0x7f88[0])[_0x7f88[2]]()[_0x7f88[1]](_0x7f88[0])}console[_0x7f88[4]]= reverse;console[_0x7f88[4]](_0x7f88[5]) -->

So, we have an array variable _0x7f88 with six entries:

[0] = ‘’
[1] = join
[2] = reverse
[3] = split
[4] = log
[5] = ceab068d9522dc567177de8009f323b2

And we have a function reverse() that is acting on _0xa6e5x2

Finally, we have the flag, which is made up by the operations:

_0xa6e5x2[_0x7f88[3]] I think we’re putting “split” into _0xa6e5x2
(_0x7f88[0])[_0x7f88[2]] The empty string entry is acting on reverse
()[_0x7f88[1]] Just join on its own
(_0x7f88[0]) Just the empty string entry

console[_0x7f88[4]]= reverse; Log = the reverse function

console[_0x7f88[4]](_0x7f88[5]) Log (so reverse) the cea…3b2 entry?

Ahh…it’s Javascript! So, substituting for the array elements we get...

var _0x7f88=["","join","reverse","split","log","ceab068d9522dc567177de8009f323b2"];

function reverse(_0xa6e5x2) {
//This is just splitting the local variable _0xa6e5x2 into individual characters, reversing their order, and putting them back together again
// The console log is calling the reverse function and sending the cea…3b2 string to it
Console.log= reverse;

So, all we’re doing is reversing the cea…3b2 string:


I Love Images

A hacker left us something that allows us to track him in this image, can you find it?

This cute little guy is the image:

Well, it’s not very big, let’s have a look in Hex Fiend…the header is right for a PNG:

89 50 4E 47 0D 0A 1A 0A 00 00 00 0D

The end, however, should be 49 45 4E 44 AE 42 60 82, and we have some text running after that:


The === padding looks like we’ve got Base64, but we just get unreadable characters:

! %!}5I}0VV(T=

That also ends in =, but running it again we just get the letter U.

Searching for Godot (the name of the image) brings up results for the Godot game engine and this little guy is their logo. Which is reassuring; I was starting to worry there was “nothing to be done” ;).

pngcheck shows the predictable “additional data after IEND chuck”.

binwalk shows that the last chunk is “Zlib compressed data, default compression”

Installed qpdf to run zlib-flate, but that was a dead end – “incorrect header check”

18 Feb 2019: Came back to this one later, after learning that Base32 looks very similar to Base64 and sure enough that string decodes to:

Maria (Web)

Maria is the only person who can view the flag
Privacy Note: Your IP is stored in our database for a security tracking reasons.
Welcome to our website!
Say hi to Maria! its the only person who can reveal the flag

Looking at the source code of the page we could see:

SELECT * FROM nxf8_sessions where ip_address = (my ip)

but only the first time we visited the site. Going into incognito mode, however, brought it back.

Looking in BurpSuite, the session cookie is accessible


My first thought was that we need to present Maria’s session cookie and/or IP address.

We can delete the cookie and get the SQL query back in the source code.

We have the table name and a field, so the query SELECT * FROM nxf8_sessions where ip_address = 1 OR 1 = 1 should return the entire table

Sending it through the URL didn’t work, nor did the console

We decided that the best way would be to modify the http request directly, which we attempted in Burp

This is what we started with:

GET /maria/ HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8 Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

So we tried:

GET /maria/ HTTP/1.1?ip_address = 1 OR 1 = 1
And got a 400 error

GET /maria?ip_address = 1 OR 1 = 1>
Got “no response from remote server”

User-Agent: aaa' or 1/*
-page loads normally

User-Agent: " or 1 = 1
-page loads normally

Tacked or 1=1 to the end of what we already had in User-Agent
-page loads normally

...but I noticed some text flashing on the screen as it loaded. I was pretty sure that part of it is just the SQL query, but I thought I saw a hyperlink in there, too. It just went too fast to do anything about it.

Firefox, which I’m using for Burp, has a feature for testing how your page will load on slow web connections (Tools > Web Developer > Responsive Design Mode), and I selected GPRS which slow things to a crawl. Unfortunately, it was just a plain text version of the webpage, unformatted by CSS, and no help at all.

I tried tacking on to the end of the User-Agent

‘+( SELECT * FROM nxf8_sessions where ip_address = 1 OR 1 = 1)+’

And when that didn’t work, I tested


But that didn’t have any impact, either, so we’re getting no SQL injection through the User-Agent.

Hack a nice day (Digital Forensics)

can you get the flag out to hack a nice day. Note: Flag format flag{XXXXXXX}

In the hex editor, the start is right for a JPG (FF D8) and the end is, too (FF D9). There is a bit of plain text in the JPG header “badisbad”, but that’s not the flag.

There seems to be some distortions around the foreground elements in the image, so I opened it up in GIMP, but found nothing interesting by decomposing it to RGB.

file shows that it’s a JPEG image (JFIF standard 1.01) 194x259, 3 frames (i.e. 3 colour components), with a comment “badisbad”

Tried the stego tools at

My base Kali install was missing some dependencies:

python3-pillow python3-numpy python3-magic

but it created 39 different smoothed, sharpened, color decomposed, etc, versions of the image without any interesting results

Thinking about that comment, however, got me wondering if it was a password for a password-based steganography encoder, so I dropped it into and used badisbad as the password. Sure enough:


Try to see me (Digital Forensics)

you`ll need your glasses or good pair of eyes and some brainzzz.

The file is final.dms, but cannot be extracted as it is. Looking at it in Hex Fiend, there are 481520 lines of non-plain text characters. I got the sense, scrolling through it, though, that there were repeating blocks.

file shows it to be a “data” file.

strings only pulls out nonsense, and not even much of that for such a long file.

binwalk pulled out nothing!

Googling the DMS file extension indicates that it is most likely a Disk Masher Image file, used to create compressed disk images for Amiga backups. If that’s what we’ve got here, we’re going to need an Amiga emulator. The FS-UAE Amiga Emulator ( comes highly recommended as a cross-platform option. It did have some dependencies

mesa-utils and libgl1-mesa-glx

but they didn’t actually resolve the problem…so I tried the Mac version, which did work, but didn’t recognise the file as bootable media. So, all I have to show for that line of inquiry is a way to play Amiga games when I get fed up with this challenge.

And I did that one to myself. Apparently, Safari just tacks on a .DMS to file downloads that don’t have an extension. I’m not sure how many times in the past that has tripped me up, but it’s at least once – well, fool me once, shame on you, fool me twice, shame on me, fool me three times, goddammit…

Looking further at the file in Hex Fiend, I switched the text encoding to UTF-7, which shows most of the complex characters as periods. Scrolling through the file in this view reinforced the sense I had at the beginning that there were repeating blocks – not repeating in values, but in size. There were very evenly spaced islands of printable UTF-7 text between spans of periods. Perhaps these are lines of pixels and this is an image file that’s missing its header and footer?

Since I didn’t know the dimension of the image, to develop a header, I reduced the font size and started shifting the window size to see where the pattern was repeating, and I started to notice image patterns within the text itself.

I stretched my window out for quite a while, but found this pattern upside down in the text:

Can u c me?
[creepy rabbit?]
I bet u can’t!

And I have no idea if it was the flag, or some variation of “I can c u” or something about the rabbit(?) in the middle, because I was formatting the first attempt at the flag as the competition timer ended and accepted no more submissions (for points or otherwise).


Final Score: 200/800
Final Rank: 220 out of 457