ECMS 2016 CTF

There's a little CTF developed by CERT and p4 CTF team that I was cracking my brain at few days ago. I found it quite enjoyable so I've put a written solution for it.

The whole CTF is in Polish but the solution here will be provided in English.

Let's begin.

Reconnaissance

We start at https://ecsm2016.cert.pl where we are informed that we should that we should investigate a malicious file that was found on one of the employees computer. We were given this file and SHA1.

suspicious (4.3 KB, SHA1: 81e553e35dcccaaef8d9f534dd03bd9ba6ed33e2)

After downloading we check that the file is correct

sha1sum suspicious

which gives us correct SHA1 sum

and running

file suspicious

gives

Extraction

Ok, so the file is a compiled python. With the help of uncompyle I extract the source.

quite an interesting file name. After replacing exec with print I can run this and extract another script

We've got a bit more here to analyze. It starts with importing a random package and substituting few functions with one-letter names - probably to make it harder to understand.

Next there's a definition of function X(a,b) that takes 2 params and returns string that is generated according to this:

  • join a and b with zip into tuples ac and bc from their permutaions
  • pass them to ord(label r) so we will get an ASCII value for a char
  • do an xor on them
  • convert back to char with chr (label N)

Now definition of p(seed, n)

  • set the seed of rand to seed
  • for each char in key generate a char with random.randint and convert to char with car

And lastly G(data):

  • generate key with the function p with params 666 and length of data
  • do the xor on key and data passed in data

The main method of this script is this

if we translate it to some meaningful names we get this

again with exec changed to print we can run it and obtain source code to the next level.

same steps applied here and we get a bit more verbose script

Reducing the names and applying more meaning and we get

with already changed exec to print so we run it and we land at this script

now we're getting somewhere.

It looks like it's some kind of C&C script. We can see and URL address https://secretpanel.ecsm2016.cert.pl and commands list

  • sleep
  • get_emails
  • get_passwords
  • start_vnc
  • eval_code

A bit interesting is a fact that start_vnc is duplicated. We can't of course run this code as there is no package trojan as the comment might suggest.

Admin panel

Ok, so we can't run the script then so let's check what is under the URL.

So it's an log panel but unfortunately the standard admin/admin doesn't work :( After few tries we can see that the page is leaking some information to us. In case of username/password entered as admin/admin we get Password is invalid whereas when we type a/admin we get Username is invalid.

We can see also that under the URL https://secretpanel.ecsm2016.cert.pl/get_command we get the response in the form of { "command": "sleep", "sleep_seconds": "60" }

By entering an invalid characters in the password field we can produce an SQL injection

ok, let's log in.

If we enter ' or 1=1-- as a password we get in.

We can see there few messages between our hacker and an admin of this panel. They are in Polish but the most important one is that the last bits of the communication is encrypted and in one of the last unencrypted we are given a tool to encrypt our communication. But we have only the encryper. We need to find out our way to decrypt those messages.

Also in the same message we are informed that the password to encrypt/decrypt those messages is the same as to the admin panel. Ok, so we will need to extract the password but for now, let's focus on the tool.

Encryptor analysis

We get a binary file that we load into the radare2

This is in fact only a stub - the real main is in sym.real_main The important thing is that in edx we pass sym.encrypt.

The important part is that edx is at 0x00400ba1 put into local [rbp - local_48h] and later at 0x00400c83 put to rax and executed with call rax. So we should expect som code at sym.encrypt. We navigate to it with s sym.encrypt and display it visually with VV.

By presence of methods like rc4keysched I assume that the crypto used is RC4. But what about decrypt method?

Lets move to rc4keysched and display it

we can clearly see that it's being references from sym.encrypt and sym.decrypt so our binary contains both. Awesome!

So let's change the method being passed at the very beginning of the program from sym.encrypt to sym.decrypt. In order to do that:

  • oo+ - reopen in writing mode
  • s 0x00400d7a - move to the interesting part
  • wx 3c0a - change the symbol used.

Quick check if everything is ok with pdf and we're ready to go.

Time to extract the password.

Password extraction

We managed to log in to the panel but we still do not know the password. It would not matter but it is used to encrypt the messages in the admin panel so we need to extract it. Since there's a SQL injection vulnerability we can do it with a simple script.

What we do here? Well - first we try to extract user password length by running few queries to the DB and comparing the length of the password with a number. If we guess it correctly - them we log in and that's why we know it's the correct one. The script could be simplified or better written but it does the job :)

After that we extract the password char by char with the same technique of comparing each char with every printable char. If we get a match we log in. If we run this script we get the passwords:

username: hacker
password: MakeCyberGreatAgain

Trump fans?

username: admin
password: VZnG9VX48M

Ok, having updated the tool and knowing the password we can decode the messages. Originally they are in Polish but I'm providing the translation after each one

Ok, teraz chyba jesteś›my bezpieczni? W takim razie możesz w końcu przekazać mi wykradzioną flagę.

(translation)

Ok, so now we're safe? In that case you can pass the stolen flag.

and

No nie wiem, w sumie ostatnio ciągle mam wrażenie że ktoś› próbuje nas śledzić‡.

Te wiadomości są niezbyt pewne, nawet po zaszyfrowaniu. Wyślę™ flagę™ przez stronę secretmessage.ecsm2016.cert.pl.

(translation)

I'm not sure. Recently I have the feeling we're being followed.

Those messages aren't safe even after being ciphered. I'll send the flag via page secretmessage.ecsm2016.cert.pl

and the last one

Ok, niech będzie.

W takim razie dołącz do rozmowy tutaj: https://secretmessage.ecsm2016.cert.pl/cd16c496f53e43e7a72db2255a0939fb/

(translation)

Ok, so be it. Join the conversation here: https://secretmessage.ecsm2016.cert.pl/cd16c496f53e43e7a72db2255a0939fb/

Secret message page

After visiting the page we can see the communication between the admin and the hacker.

again - it's in Polish but it does not matter. It's not that important. Important is the fact that we can see that the flag was being pasted few messages above and that it is hidden from us. We assume that the person who pasted the flag see it.

Very quickly we can see that the page is vulnerable to XSS. We prepare the JS script that when visited will send us the flag.

Again the script here could be simplified. What it does is that it gets the page with the conversation, extracts the link to the message with the flag, gets the page and extracts the flag and sets it go url.php script on the dedicated server. The only thing the script needs to to is to dump what is being send to it.

We post the script and wait a while. After few minutes we check the dump of the requests and we obtain the flag.

The flag is ours: ecsm{this.is.the.flag}