TASK 5
Task Description:
Based on the recovered hardware the device seems to to have an LTE modem and SIM card implying it connects to a GSM telecommunications network. It probably exfiltrates data using this network. Now that you can analyze the entire firmware image, determine where the device is sending data.
Analyze the firmware files and determine the IP address of the system where the device is sending data.
No files given, so only previous information is needed to solve this
Ooh! New files
Decrypting the volume from the last task gives a couple of interesting files:
total 19944
drwxr-xr-x 3 root 0 4096 May 15 2022 .
drwxr-xr-x 21 root 0 4096 Jan 1 02:11 ..
-rwxr-xr-x 1 root 0 891224 May 15 2022 agent
-rw-r--r-- 1 root 0 0 May 15 2022 agent_restart
-rw-r----- 1 root 0 567 May 15 2022 config
-rwx--x--x 1 root 0 7975035 May 15 2022 diagclient
-rwxr-xr-x 1 root 0 11483488 May 15 2022 dropper
drwx------ 2 root 0 16384 May 15 2022 lost+found
-rwxrwx--- 1 root 0 396 May 15 2022 start
To start, I looked at the file labled as such
Start:
#!/bin/sh
DIR=/agent
PROC=agent
RESTART_FILE=agent_restart
# start the navigation service
/bin/nav
mkdir -p /tmp/upload
dmesg > /tmp/upload/boot_log_`date -Iseconds`
# start agent and restart if it exists
while [ 1 ]; do
if [ ! -e $DIR/$RESTART_FILE ]; then
break
fi
if [ -z "`ps -o comm | egrep ^${PROC}$`" ]; then
$DIR/$PROC $DIR/config
fi
sleep 10
done
Breaking this down, it does a couple things:
- It starts by setting a couple variabled for where programs are
- The navigation service is started # TODO: find out more about this
- A new directory called “/tmp/upload” is created if it doesn’t exist, and a log file is put in
- A continuous while loop is started
[ ! -e $DIR/$RESTART_FILE ]
checks if the “agent_restart” file is in the above directory. If it isn’t it breaks[ -z "`ps -o comm | egrep ^${PROC}$`" ]
does a lot, so these are each part-z
returns true if the folling string is empty``
runs the script inside and will put the result in the stringps -o comm
outputs each of the commands being run for the current session|
takes the output of the previous command and sends it to the next commandegrep ^${PROC}$
takes the list of commands and filters them with regex to check if a line only contains “agent”- Putting it together says that the next line will be run if there isn’t a proccess that was just started with the command “agent”
- If the above is true, the agent program is run using the config file, and it gets re-run every 10 seconds if it has stopped
Onto the config file, it defines a couple useful parameters for the program:
Config:
logfile = "/tmp/log.txt"
# levels 0 (trace) - 5 (fatal)
loglevel = 1
daemonize = true
id_file = "/private/id.txt"
ssh_priv_key = "/private/id_ed25519"
priv_key = "/private/ecc_p256_private.bin"
cmd_host = "0.0.0.0"
cmd_port = 9000
collectors_usb = [ "/dev/ttyUSB0", "/dev/ttyUSB1" ]
collectors_ipc = [ "/tmp/c1.unix", "/tmp/c2.unix" ]
collect_enabled = true
dropper_exe = "/agent/dropper"
dropper_config = "/tmp/dropper.yaml"
dropper_dir = "/tmp/upload"
navigate_ipc = "/tmp/nav_service.unix"
key_file = "/agent/hmac_key"
restart_flag = "/agent/agent_restart"
At this point, I was a little stuck, so I ran strings on the binaries to see if any of them had IPs hard coded. All of the IPs I found were worthless like 0.0.0.0 (gateway), 127.0.0.1 (localhost), or 169.254.169.254 (cloud metadata endpoint). After that, I looked more into the file names and found out that dropper is a common name in malware for a program that puts malicious code on the target system. Because we want to find the IP, I decided that the dropper program would be the best way to go.
Dynamic Analysis
Looking into how to get data from the dropper program, I figured that it might be useful to let it run and look at netstat
to find the IP it was reaching out to. This became a problem when running it because it needed a configuration file that agent didn’t exist on the file system and wasn’t created by agent. To see what would happen, I ran it and passed in a random file, but that led to an error about the file formatting. To get arround this, I just tried a non-existant file, and it happened to spit out the answer on the command line?
1970/01/01 02:48:26 Connecting to server...
1970/01/01 02:48:26 ...Connected!
1970/01/01 02:48:26 Loading/tmp/upload
1970/01/01 02:50:26 Processing/tmp/upload/boot_log_1970-01-01T00:11:53+00:00boot_log_1970-01-01T00:11:53+00:00
1970/01/01 02:50:56 Failed to insert into MongoDB:server selection error: server selection timeout, current topology: { Type: Unknown, Servers: [{ Addr: 100.105.36.5:27017, Type: Unknown, Last error: dial tcp 100.105.36.5:27017: connect: network is unreachable }, ] }
(While this is technically the answer, it is not enough information to move on)
Static Analysis
After realizing that the configuration came from the file itself, I looked into how I could extract the data from the program. I realized that there was a program I have heard of, but hadn’t tried yet: binwalk
. binwalk
is a program that is specifically made to extract different types of files inside of the main file. To do this, run binwalk -Me /agent/dropper
. This extracts the zipped configuration file and unzips it to reveal:
database:
collection: files
database: snapshot-44180ec0a37b
url: mongodb://maintenance:36599080632635@100.105.36.5:27017/?authSource=snapshot-44180ec0a37b
server:
directory: /tmp/upload
This includes the information needed for task 6 to connect to the database