Stuck on the CTP registration challenge? Here’s how I did it!

So, one of the things on my list of stuff to do this year was the OSCP, after completing my CompTIA Security+, EC-Council Certified Ethical Hacker, CompTIA Cyber Security Analyst, ISO 27001 Foundation and just recently my CISSP qualification, I thought it would be good to round my portfolio off with a more ‘hands-on’ certification, whilst browsing around the Offensive Security website, I stumbled across the OSCE CTP registration challenge.

Basically, the challenge is to assess whether you are ready for the CTP exam or not, if you can crack it, you are ready, if not, better get back to studying. But, you know, some times I think its good just to see how something is done, follow along with someone else doing it, so you can see how someone elses mindset works or just be aware of the sorts of things you should be looking out for, so I set out to complete the challenge one evening when I got home from work.

Now, the reason I decided to write this article was because when I got a little bit stuck along the way and reached out to my good friend Google, he wasn’t much help, so I soldiered on, on my own, and eventually came across the solution, yay me!…. but, I wanted to write this up, not as a way for people to cheat, but as a teaching tool, so those who aspire to get into the Cyber Security community can just walk it through, give it a go, who knows, maybe one day this might spark somebody’s interest and give someone the leg up I struggled to find!

So, first things first! What does the challenge look like? head over to the fc4.me to start the challenge and see for your self!

Screenshot of the fc4.me homepage

You will need to provide a genuine email address if you are planning on actually registering for the exam! Lets fill in the form with a genuine email address and try and find our security string!

Clue #1

“Use of automated scanners will result in a 3 minute block from the website. No exploitation or vulnerability scanning is required to bypass the form. Use the source Luke!”

Who missed that? you? I hope you didn’t!

Let’s check the source code…

First things I noticed where the 2 JavaScript files int he header of the page, let’s open them up for later.

Second thing I noticed was on the form:

<input onClick="var srvstr='Sunday 3rd of March 2019';fc4me(srvstr);document.pleazfc4me.securitystring.value='';return false;" name="submit" type="image" src="images/button-submit.png" />

Notice the variable being declared and then being set to today’s date? interesting….

OK, let’s take a look into fc4.js:

function fc4me(srvstr) {
  
   if(!document.pleazfc4me.email.value || !document.pleazfc4me.securitystring.value) {
      alert("Please fill in all the required fields!");
      return false;
   }
   if(document.pleazfc4me.securitystring.value != hexMD5("\x74\x72\x79\x68\x61\x72\x64\x65\x72"+srvstr)) {
      alert("Registration Authorization String not accepted! Try Harder! ");
      return false;
    } else {
      document.pleazfc4me.submit();
    }
   
}

The second statement is what we are interested in, as it basically says if the security.string value is not equal to an MD5 hash of the shell code “\x74\x72\x79\x68\x61\x72\x64\x65\x72” followed by the value in the srvstr variable, then return false, however, to return true all we need to do is input an MD5 hash value of that shell code and the date as formatted in the form field from earlier.. so we need to create an MD5 hash of “\x74\x72\x79\x68\x61\x72\x64\x65\x72Sunday 3rd of March 2019”

How do we create an MD5 hash of this value? Well, I run Linux, so for me its as easy as running this from a terminal window:

echo -ne "\x74\x72\x79\x68\x61\x72\x64\x65\x72Sunday 3rd of March 2019" | md5sum

Great, so now just submit this hash along with your email on the original form, my hash was: 899585af6972dacf9a4465cfd09e9053.

Clue #2

Screenshot showing the second clue int he CTP challenge.

Great job so far! so now we are through the first half of the challenge, if you thought that was the hard part, it wasn’t…

So, what on earth is that lot! it’s obviously some kind of obfuscated text or code. How can we see if we can work out what it is so that we can decipher it? the first thing I tried was Base 64, you can attempt to decode it at https://www.base64decode.org/ here are my results:

Email: REDACTED , Registration Code: 53236 | Now decode your CTP Secret Key and you are done! : \x31\xC0\x50\x68\x76\x24\x27\x78\x68\x73\x22\x78\x24\x68\x77\x71\x78\x78\x68\x23\x71\x23\x75\x68\x72\x73\x77\x23\x68\x23\x24\x71\x79\x68\x23\x71\x27\x22\x68\x71\x77\x70\x20\x68\x20\x23\x70\x22\x68\x22\x78\x27\x24\x68\x25\x79\x73\x78\x68\x74\x20\x25\x25\x68\x20\x70\x74\x71\x68\x76\x74\x73\x72\x68\x72\x79\x79\x27\x68\x76\x20\x24\x25\x68\x79\x25\x71\x71\x68\x71\x22\x75\x79\x68\x73\x76\x74\x75\x68\x20\x27\x22\x77\x68\x77\x22\x71\x75\x68\x70\x27\x25\x22\x68\x24\x79\x22\x77\x68\x27\x24\x71\x22\x68\x77\x22\x22\x24\x68\x71\x70\x70\x79\x68\x73\x76\x25\x23\x68\x24\x22\x71\x23\x68\x22\x23\x79\x23\x68\x79\x79\x20\x24\x68\x23\x77\x24\x75\x68\x25\x24\x22\x75\x54\x5E\x8B\xFE\x8B\xD7\xFC\xB9\x80\x00\x00\x00\xBB\x41\x00\x00\x00\x31\xC0\x50\xAC\x33\xC3\xAA\xE2\xFA\x54\x5E\xCC

W00p! awesome! but, wait… there’s more by the looks of it!

**Massive Sigh**, OK, focus, it’s shell code right? Any one who has played around with payloads in Kali Linux will recognise this as shell code.

Urgh, what can we do to see what it is doing, or saying? well, first of all, having Linux as an Operating system does make this a little easier..

Let’s try and decode the shell code and see what it is doing first of all.

perl -e 'print "\x31\xC0\x50\x68\x76\x24\x27\x78\x68\x73\x22\x78\x24\x68\x77\x71\x78\x78\x68\x23\x71\x23\x75\x68\x72\x73\x77\x23\x68\x23\x24\x71\x79\x68\x23\x71\x27\x22\x68\x71\x77\x70\x20\x68\x20\x23\x70\x22\x68\x22\x78\x27\x24\x68\x25\x79\x73\x78\x68\x74\x20\x25\x25\x68\x20\x70\x74\x71\x68\x76\x74\x73\x72\x68\x72\x79\x79\x27\x68\x76\x20\x24\x25\x68\x79\x25\x71\x71\x68\x71\x22\x75\x79\x68\x73\x76\x74\x75\x68\x20\x27\x22\x77\x68\x77\x22\x71\x75\x68\x70\x27\x25\x22\x68\x24\x79\x22\x77\x68\x27\x24\x71\x22\x68\x77\x22\x22\x24\x68\x71\x70\x70\x79\x68\x73\x76\x25\x23\x68\x24\x22\x71\x23\x68\x22\x23\x79\x23\x68\x79\x79\x20\x24\x68\x23\x77\x24\x75\x68\x25\x24\x22\x75\x54\x5E\x8B\xFE\x8B\xD7\xFC\xB9\x80\x00\x00\x00\xBB\x41\x00\x00\x00\x31\xC0\x50\xAC\x33\xC3\xAA\xE2\xFA\x54\x5E\xCC"' > shellcodefromctp

Then lets convert the shell code:

ndisasm -b 32 shellcodefromctp
00000000  31C0              xor eax,eax
00000002  50                push eax
00000003  6876242778        push dword 0x78272476
00000008  6873227824        push dword 0x24782273
0000000D  6877717878        push dword 0x78787177
00000012  6823712375        push dword 0x75237123
00000017  6872737723        push dword 0x23777372
0000001C  6823247179        push dword 0x79712423
00000021  6823712722        push dword 0x22277123
00000026  6871777020        push dword 0x20707771
0000002B  6820237022        push dword 0x22702320
00000030  6822782724        push dword 0x24277822
00000035  6825797378        push dword 0x78737925
0000003A  6874202525        push dword 0x25252074
0000003F  6820707471        push dword 0x71747020
00000044  6876747372        push dword 0x72737476
00000049  6872797927        push dword 0x27797972
0000004E  6876202425        push dword 0x25242076
00000053  6879257171        push dword 0x71712579
00000058  6871227579        push dword 0x79752271
0000005D  6873767475        push dword 0x75747673
00000062  6820272277        push dword 0x77222720
00000067  6877227175        push dword 0x75712277
0000006C  6870272522        push dword 0x22252770
00000071  6824792277        push dword 0x77227924
00000076  6827247122        push dword 0x22712427
0000007B  6877222224        push dword 0x24222277
00000080  6871707079        push dword 0x79707071
00000085  6873762523        push dword 0x23257673
0000008A  6824227123        push dword 0x23712224
0000008F  6822237923        push dword 0x23792322
00000094  6879792024        push dword 0x24207979
00000099  6823772475        push dword 0x75247723
0000009E  6825242275        push dword 0x75222425
000000A3  54                push esp
000000A4  5E                pop esi
000000A5  8BFE              mov edi,esi
000000A7  8BD7              mov edx,edi
000000A9  FC                cld
000000AA  B980000000        mov ecx,0x80
000000AF  BB41000000        mov ebx,0x41
000000B4  31C0              xor eax,eax
000000B6  50                push eax
000000B7  AC                lodsb
000000B8  33C3              xor eax,ebx
000000BA  AA                stosb
000000BB  E2FA              loop 0xb7
000000BD  54                push esp
000000BE  5E                pop esi
000000BF  CC                int3

Interesting… so what you can see here is that the code is pushing a bunch of DWORD values into the ESI register, the ESI register is a non-volatile general purpose register that stores data that is used throughout the entire function . Maybe that is where our registration code will be! let’s see if we can find it!

Now, I came across several problems using debuggers at this stage, my system just would not let me run a debugger and access the ESI register, so to make things easier, we will switch across to a Windows 10 system and use a debugger called WinRepl you can find it over on GitHub https://github.com/zerosum0x0/WinREPL.

Specifically, you will want the x86 version https://github.com/zerosum0x0/WinREPL/releases/

Once you have downloaded it, open Powershell from the same location and flick back to your Linux machine, so that we can clean up the shell code before we try to debug it. Start by creating a new file:

vim shellcodetoclean

Paste your shell code into the file, so now you have something like this:

Output of VIM before cleaning up the shell code.

Now we need to clean it up, type a colon ‘:’ in order to start typing a command, then type: %s/\\//g then press enter then type another colon and %s/x//g, you will get an output similar to this:

Output of the VIM program after cleaning up the shell code.

You will need to “:wq” this vim window, then cat out the file in order to copy the text:

Output of the cat shellcodetoclean command.

Then switch back to your Windows 10 system and type the following into your Powershell window to run the debugger:

winrepl_x86.exe
Output of running WinREPL

Now type .shell code and then paste your shell code into the line before pressing enter:

Output of the WinREPL program and the .shellcode command.

You will notice the ESI register has changed values from the first screenshot. We need to read the contents of the ESI register, you will need to use the ‘.read’ command as well as the value that is in your ESI register, it will be different from mine, you will also need to specify a size value to read, I chose 200, if this didn’t work we could play around with it later.

output of WinREPL and the .read command

You see that value in the right hand column, starting dec4b6e… that is your registration code! Copy the block into notepad and clean it up, and you get “dec4b6e488aecb8bec0b27db01186ccefe0ce8c61fdc6c04afc627540c488d007aed388f7523a1505addd829c9feab1c061ab0fcbe08326bb0b460992c9e7ef9”

It is important to note, you only want the continuous string of characters from the output, as soon as you see a full stop, that’s the end of your registration code!

Meme showing a woman chewing her computer.

I’m exhausted just writing this! I hope you stuck with it, are able to understand it and have learned as much as I did whilst I was doing it!

On to the next one!