Monkey Ransomware — Some AI-written Ransomware

A new ransomware family surfaced recently (credit: Gameel Ali). He didn’t plan a deep dive, so we decided to take one. The result is… odd. Dissection was easy; the design is incoherent. Our working theory is that this is largely AI-generated malware.

People often ask: “Why analyze ransomware? It’s destructive; by the time analysis happens, it’s too late”. That’s only half true. Analysis matters because sometimes samples exploit bugs to spread or escalate (think WannaCry/EternalBlue), they often ship persistence or exfiltration tricks that translate into detection rules, custom crypto occasionally ships with fixable flaws allowing recovering from ransomware, infrastructure and dev breadcrumbs surface through pathnames and URLs, and, being honest, it’s fun.

TL;DR

x64 ELF, written in Go, not stripped. Go’s main is recognizable, and function names already reveal most of the story. The specimen — let’s call it Monkey Ransomware — is trivial to pick apart and weirdly stitched together.

Technical Overview

Function names alone give away intent (Figure 1). The binary relies heavily on the Go standard library, so call patterns like os_exec_Command + os_exec__ptr_Cmd_Run repeat throughout.

High-level function map from the Go main package; names already reveal intent
High-level function map from the Go main package; names already reveal intent

Elevate Privileges

First, the ransomware checks whether it’s running elevated and then re-execs itself with sudo. After launching the elevated instance, it exits.

Elevation helper: re-exec via sudo, mirror stdout/stderr, then exit
Elevation helper: re-exec via sudo, mirror stdout/stderr, then exit

Readable Go equivalent:

(1) cmd := exec.Command("sudo", os.Args…) 
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr 
(2) _ = cmd.Run() 
os.Exit(0)

main then calls two routines: disableSecurity and setupPersistence, described in the following sections.

Disabling local protections

The code attempts a quick clean-up of common controls: pkill -9 selinux, pkill -9 apparmor, then systemctl firewalld stop and systemctl ufw stop. The pkill here is a classic sledgehammer: signal -9 (SIGKILL) for immediate termination, while the systemctl lines aim for a quieter network edge.

Under the hood, the sample repeatedly carves strings out of a single big blob inside the default section .rodata, addressing by offset and length; pkill is literally sliced out this way.

String slice trick: constants are embedded in a long blob and referenced by offset/length (e.g., carving pkill from a larger string)
String slice trick: constants are embedded in a long blob and referenced by offset/length (e.g., carving pkill from a larger string)

At this point, you can cruise through the binary on autopilot: nothing clever, just orchestration.

Persistence (three paths)

Instead of one reliable path, there are three, redundant and arguably noisy. First, a user crontab entry at @reboot, assembled by concatenating the discovered path to the executable: crontab -l | { cat; echo "@reboot "; } | crontab -.

Crontab @reboot line built by string concatenation using the executable path
Crontab @reboot line built by string concatenation using the executable path

Second, the dinosaur that is /etc/rc.local, still honored on some systems, gets an invocation appended to it. It’s a belt-and-suspenders move. Third, the modern route: a systemd unit. The malware writes /etc/systemd/system/monkey.service with mode 0644 and enables the service.

On Kali in our lab, that unit resolved to:

[Unit]
Description=Monkey Service
After=network.target

[Service]
ExecStart=/home/kali/Desktop/257de0e2744c99a12cbc1c1b37c76e0e8a010dde3125ec09468a16e4f8e0f121.infected
Restart=always

[Install]
WantedBy=multi-user.target
systemd persistence: monkey.service dropped to /etc/systemd/system/ and enabled
systemd persistence: monkey.service dropped to /etc/systemd/system/ and enabled

System information gathering

With the foothold secured, main turns to identification and telemetry. The flow is simple enough that you can follow it statically; if you prefer dynamic confirmation, it also debugs cleanly with a couple of breakpoints.

As a victim identifier, the sample uses a unique machine ID calculated by SHA-256(hostname || MAC), formatted as hex. The code calls os_hostname() and main_getMacAddress(), concatenates the results, converts the concatenation to a byte slice, hashes it, and formats the result.

System information gathering orchestration
System information gathering orchestration

Dynamically, you can verify main_getMacAddress() by breaking right after the call (e.g., 0x006752bf) and reading the Go string return in (RAX=ptr, RBX=len).

Live debug tip: after main_getMacAddress() returns, grab (RAX, RBX) to print the Go string
Live debug tip: after main_getMacAddress() returns, grab (RAX, RBX) to print the Go string

main_getSystemInfo() fetches the public IP via https://api.ipify.org, then the country name via https://ipapi.co/%s/country_name/ with %s replaced by that IP. The routine updates two globals: publicIp and country.

Public IP lookup: GET to api.ipify.org with body used as the IP string
Public IP lookup: GET to api.ipify.org with body used as the IP string

main_sendSystemInfo posts a JSON blob to: https://179[.]43[.]139[.]126:5000/api/report/ to register the victim machine.

Example we captured:

{"country": "Unknown", "key": "WLUbqhaVveCx2k1ibA5JL6gWpvDt7mBLEWkxHGXRgR8=", "machineId": "8cdf017926c90740", "publicIp": "Unknown"}
System info upload: country, public IP, hashed machine ID, and a base64 key in JSON
System info upload: country, public IP, hashed machine ID, and a base64 key in JSON

Vssadmin and shadow copies (…on Linux?)

Then the narrative swerves. A function named Main_encryptShadowCopies issues Windows-only vssadmin commands:

vssadmin list shadows 
vssadmin delete /all /quiet

This doesn’t belong in a Linux ELF. It reads like a cargo-culted Windows playbook, lines pasted into the wrong project. It also aligns with the runtime behavior we observed: hangs, non-functional encryption, and sections we had to patch out just to keep execution going. Despite the technical muddle, the cosmetic layer is present.

A README lands on the desktop—in our case /root/Desktop/README.txt—with a generic note and an onionmail address:

ATTENTION!

Your network has been encrypted!

To recover your data, you have 24 hours to contact us via email and pay a ransom

To reach us, add our email: monkeyransomware@onionmail.org

Important:
- After 24 hours, the ransom will double.
- If no payment is received, we will report this to the authorities and leak ALL your data, including documents and databases.
- Consider what's more valuable to you. 
Ransom note (README.txt) placed on the desktop
Ransom note (README.txt) placed on the desktop

Separately, the sample fetches a wallpaper from http://179[.]43[.]139[.]126/stol.png and sets it as the wallpaper.

Ransom wallpaper fetched from the C2 host
Ransom wallpaper fetched from the C2 host

The note doesn’t match established group styles; the tone and structure feel templated. The mismatch between platform cues elsewhere and the cosmetic bits here reinforces that “assembled from parts” smell.

Wrapping up

Viewed piece by piece, Monkey Ransomware is straightforward. Viewed as a whole, it’s incoherent. The binary mixes Windows-specific tactics into a Linux executable, duplicates persistence, sprinkles in novice network enumeration, and relies on external commands for almost everything. That’s consistent with an unfinished project, a learning exercise, or most plausibly AI-authored slop glued together without a human’s sense of fit and finish .

Even so, the analysis is valuable. We walked away with practical detection points (pkill/systemctl abuse, crontab/rc.local/systemd artifacts), concrete IOCs (service name, file paths, URLs, JSON schema), and a clearer idea of the operator’s competency. When the “ransomware” doesn’t ransom, the surrounding tradecraft still teaches, and that’s reason enough to keep looking under the hood.

Indicators

dgm0td.exe, SHA256: 257de0e2744c99a12cbc1c1b37c76e0e8a010dde3125ec09468a16e4f8e0f121

179[.]43[.]139[.]126

Table of Contents

Our primary goal is to deliver reliable and secure IT solutions to our clients and contribute resources to creating a more secure world. Copyright © 2021 – 2025 Hexastrike Cybersecurity UG (haftungsbeschraenkt)