• We are trusted partners of:

CTF Write-Up: Web Challenges - INNOBYTE - Serious Web Development

Posted by | January 08, 2014 | Development, Fun, Offline, Team | No Comments

After a somewhat short holiday we finally found the time to properly discuss the solutions to our first CTF.

In the following days I will try to shed some light on the solutions to Innobyte’s first endeavor in organizing a CTF competition, to talk about how my team and I solved (some of) the challenges and the ups and downs of participating to our first CTF. We were the “Fermecătorii Haladiți” (which I am ashamed to translate to you, as it is a mockery of a name chosen at random). We are Catalin, Sorin and Alin.

Unfortunately my colleagues already had a busy weekend planned, so they were online just on Friday evening. But I was there, from start to finish. Literally. I didn’t leave the office until Monday evening. On Monday morning, at 9 AM, when my co-workers were coming for the morning coffee, I was right there, in the break-room, solving one final challenge, as the competition was coming to an end and I had to also go to work (in the next room).

But back to the scope of this post.

The first day was a busy one at work, but one that built up excitement until 6 PM, when it all started. My teammates and I started looking at the challenges and, after a quick peek at most of the challenges, I decided to start with the ones under the web category.

Naturally, I started with Web100. In front of me there was a blank page, taunting me. I quickly opened Developer Tools to get more information and there it was. The server was setting a cookie with the value looser. I quickly downloaded a Chrome extension to edit cookies, changed the cookie to winner and that was it!

Also, I don’t know if any of you guys noticed (I didn’t), but if you were watching the HTML source closely (or using nc/PuTTY, FTW!), you would have noticed that after the second refresh the page displayed like 1000 blank lines and an HTML comment: <!– you are labeled as a loser –>. Just a tiny easter-egg from Cristi!


Excited about solving web100, I quickly jumped to web200, where everything was looking a whole lot weirder than web100. The javascript seemed to do weird things. I started trying a few passwords that none of them worked. Although, nothing worked, I saw that the script was redirecting me to something encoded from javascript. I also noticed the message for the JavaScript prompt: “Enter this encoded password the-password-decoded”. So, without any hope of it working, I tried the URL in the browser: “http://ctf.innobyte.ro/challs/web/200/the-password-decoded”. I couldn’t believe that it worked! The JavaScript looked so menacing. It couldn’t have been That easy!

Apparently, it was supposed to be that easy. Just a tiny bit tougher. It seems that quite a few teams solved this one “the easy way”, but not the right way. On this one, we should have noticed that the code we entered was XORed with the real “code” and appended to location. So, naturally, we could enter the output of that XOR, and obtain the code (and also a redirect to the flag).


It was about 7 PM when I started web300 and I said “This is going to be tough…”. I was looking at a pretty nifty form of obfuscation. What could I do next ? I tried to make something of the mess before my eyes. Some jsbeautifier magic and I went from this


To this


I now had a slightly nicer version of a JavaScript mess. While looking at it I could see that on line 22 it was saving something and on line 23 it was obviously trying to call $.$ (from line 22) as a function. So, naturally, I replaced line 22 with something like

$.$ = function (a) { console.log(a); }

Now, after doing this, it all revealed itself: it was something like return”some javascript”, which was being eval()-ed.


The JavaScript was clearly doing a redirect in the end. I followed it and there was the flag!

// As a note, this was not really the easiest way to do this. The easiest was to remove the opening and closing parentheses at the end, so, without that call, it would return the JavaScript as a string (to be passed to eval).

Two hours in, we were in the lead with 600 points (of course, that was because none of the “big” contenders were there yet).

Stay tuned for the next part of our series, where I’ll write about web400 !

«Go back

Leave a Reply

Your email address will not be published.