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 tuplesac
andbc
from their permutaions - pass them to
ord
(labelr
) so we will get an ASCII value for a char - do an
xor
on them - convert back to char with
chr
(labelN
)
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 withcar
And lastly G(data)
:
- generate key with the function
p
with params 666 and length ofdata
- do the
xor
on key and data passed indata
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 modes 0x00400d7a
- move to the interesting partwx 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}