r/PiratedGames drama. Is it malware? Yes. Is it cool malware? No
Yesterday, or today, I don't remember, I had like, two people ask me about stuff happening on Reddit and asking if something was malware. I briefly skimmed the Reddit page, saw nerds bickering about stuff, and shrugged. Then, later in the day, I had more stinky nerds ask me about the exact same Reddit page.
Okay, I guess I'll poke it with a stick.
Reddit link: https://www.reddit.com/r/PiratedGames/comments/1qb4kai/who_do_you_think_it_is/
Page asking for help: https://fitgirl-repacks.site/malware-analysis-help-needed/
The shared file from fitgirl-repacks is a .zip file named "Possible_Malware_Dataset.zip". As a person who has collected over 40,000,000 malwares, I had hoped it would be much more interesting that what was inside of it.
Fitgirl (no idea what to call them, I'll just say "Fitgirl"), saved me some time by sharing their extraction script they wrote which they labeled "0.py". 0.py also comes with a .bat script which automatically executes the .py to autoextract any potential malware payloads from a file named "Data.bin"
Her code:
#!/usr/bin/env python3
import struct
import os
import sys
MZ_SIGNATURE = b"MZ"
PE_SIGNATURE = b"PE\x00\x00"
def read_u16(data, offset):
return struct.unpack_from("<H", data, offset)[0]
def read_u32(data, offset):
return struct.unpack_from("<I", data, offset)[0]
def is_valid_pe(data, base):
try:
if data[base:base+2] != MZ_SIGNATURE:
return False
e_lfanew = read_u32(data, base + 0x3C)
pe_offset = base + e_lfanew
if pe_offset + 4 > len(data):
return False
if data[pe_offset:pe_offset+4] != PE_SIGNATURE:
return False
machine = read_u16(data, pe_offset + 4)
number_of_sections = read_u16(data, pe_offset + 6)
size_of_optional_header = read_u16(data, pe_offset + 20)
optional_header_offset = pe_offset + 24
section_table_offset = optional_header_offset + size_of_optional_header
if number_of_sections == 0 or number_of_sections > 96:
return False
max_end = 0
for i in range(number_of_sections):
sec_offset = section_table_offset + i * 40
if sec_offset + 40 > len(data):
return False
raw_ptr = read_u32(data, sec_offset + 20)
raw_size = read_u32(data, sec_offset + 16)
end = raw_ptr + raw_size
if end > max_end:
max_end = end
if max_end == 0:
return False
return max_end
except Exception:
return False
def extract_pes(input_file, output_dir):
with open(input_file, "rb") as f:
data = f.read()
os.makedirs(output_dir, exist_ok=True)
found = 0
offset = 0
data_len = len(data)
while offset < data_len - 2:
if data[offset:offset+2] == MZ_SIGNATURE:
pe_size = is_valid_pe(data, offset)
if pe_size:
pe_data = data[offset:offset+pe_size]
name = f"pe_{found:04d}.exe_do_not_run"
out_path = os.path.join(output_dir, name)
with open(out_path, "wb") as out:
out.write(pe_data)
print(f"[+] Extracted PE at offset 0x{offset:X} -> {name}")
found += 1
offset += pe_size
continue
offset += 1
print(f"\nDone. Extracted {found} PE files.")
if __name__ == "__main__":
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <input_file> <output_dir>")
sys.exit(1)
extract_pes(sys.argv[1], sys.argv[2])
Her batch file:
python.exe 0.py Data.bin DataRunning her script dumps 40 binaries. Each file is indeed a Windows binary, it has the traditional MZ header. Very cool. They're all legit binaries (from high-level overview). Interestingly, each file is also roughly the same size.
7760384 pe_0000.exe_do_not_run
7762432 pe_0001.exe_do_not_run
7770112 pe_0002.exe_do_not_run
7751168 pe_0003.exe_do_not_run
7777792 pe_0004.exe_do_not_run
7772160 pe_0005.exe_do_not_run
7788032 pe_0006.exe_do_not_run
7766528 pe_0007.exe_do_not_run
7764992 pe_0008.exe_do_not_run
7751168 pe_0009.exe_do_not_run
7760896 pe_0010.exe_do_not_run
7778816 pe_0011.exe_do_not_run
7766016 pe_0012.exe_do_not_run
7756800 pe_0013.exe_do_not_run
7761408 pe_0014.exe_do_not_run
7753216 pe_0015.exe_do_not_run
7789568 pe_0016.exe_do_not_run
7748608 pe_0017.exe_do_not_run
7776256 pe_0018.exe_do_not_run
7768576 pe_0019.exe_do_not_run
7773184 pe_0020.exe_do_not_run
7769088 pe_0021.exe_do_not_run
7765504 pe_0022.exe_do_not_run
7762432 pe_0023.exe_do_not_run
7784960 pe_0024.exe_do_not_run
7773696 pe_0025.exe_do_not_run
7769088 pe_0026.exe_do_not_run
7780352 pe_0027.exe_do_not_run
7762432 pe_0028.exe_do_not_run
7765504 pe_0029.exe_do_not_run
7752704 pe_0030.exe_do_not_run
7778816 pe_0031.exe_do_not_run
7766016 pe_0032.exe_do_not_run
7755264 pe_0033.exe_do_not_run
7778304 pe_0034.exe_do_not_run
7776768 pe_0035.exe_do_not_run
7753728 pe_0036.exe_do_not_run
7763456 pe_0037.exe_do_not_run
7777280 pe_0038.exe_do_not_run
7757824 pe_0039.exe_do_not_runI'll save you the trouble. I'll get to the point now.
This is cryptomining malware. When the binary is detonated (you run it) it uses your machines resources (GPU, CPU, hamster on a wheel) to mine cryptocurrency for someone else.
Each binary is Themida packed, this is extremely common in malware campaigns. Each binary is XMRig, a cryptocurrency mining software. When the binary is executed it "unpacks" to a 21.2MB binary file. Each binary comes with a JSON file inside of the cryptocurrency miner.
{
"api": {
"id": null,
"worker-id": null
},
"http": {
"enabled": false,
"host": "127.0.0.1",
"port": 0,
"access-token": null,
"restricted": true
},
"autosave": false,
"version": 1,
"background": true,
"colors": true,
"title": true,
"randomx": {
"init": -1,
"init-avx2": -1,
"mode": "auto",
"1gb-pages": false,
"rdmsr": false,
"wrmsr": false,
"cache_qos": false,
"numa": true,
"scratchpad_prefetch_mode": 1
},
"cpu": {
"max-threads-hint": 50,
"enabled": true,
"huge-pages": true,
"huge-pages-jit": false,
"hw-aes": null,
"priority": 0,
"memory-pool": true,
"yield": true,
"asm": true,
"argon2-impl": null,
"cn/0": false,
"cn-lite/0": false
},
"opencl": {
"enabled": false,
"cache": true,
"loader": null,
"platform": "AMD",
"adl": true,
"cn/0": false,
"cn-lite/0": false
},
"cuda": {
"enabled": false,
"loader": null,
"nvml": true,
"cn/0": false,
"cn-lite/0": false
},
"donate-level": 0,
"donate-over-proxy": 0,
"log-file": null,
"pools": [
{
"algo": null,
"coin": null,
"url": "proxy00003.com:443",
"user": "x",
"pass": "x",
"rig-id": null,
"nicehash": true,
"keepalive": true,
"enabled": true,
"tls": true,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
},
{
"algo": null,
"coin": null,
"url": "proxy00004.com:443",
"user": "x",
"pass": "x",
"rig-id": null,
"nicehash": true,
"keepalive": true,
"enabled": true,
"tls": true,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
},
{
"algo": null,
"coin": null,
"url": "proxy00005.com:443",
"user": "x",
"pass": "x",
"rig-id": null,
"nicehash": true,
"keepalive": true,
"enabled": true,
"tls": true,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
},
{
"algo": null,
"coin": null,
"url": "vpnetworkc.com:443",
"user": "x",
"pass": "x",
"rig-id": null,
"nicehash": true,
"keepalive": true,
"enabled": true,
"tls": true,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
},
{
"algo": null,
"coin": null,
"url": "proxifyme49.com:443",
"user": "x",
"pass": "x",
"rig-id": null,
"nicehash": true,
"keepalive": true,
"enabled": true,
"tls": true,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null,
"submit-to-origin": false
}
],
"print-time": 60,
"health-print-time": 60,
"dmi": true,
"retries": 5,
"retry-pause": 5,
"syslog": false,
"tls": {
"enabled": false,
"protocols": null,
"cert": null,
"cert_key": null,
"ciphers": null,
"ciphersuites": null,
"dhparam": null
},
"user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0",
"verbose": 0,
"watch": true,
"pause-on-battery": false,
"pause-on-active": false
}To figure out more about the crypto wallets and stuff I'd have to do a bunch of work and I don't feel like it. This is a pretty insignificant malware campaign in regards to sophistication and novelty. XMRig malware campaigns are extremely common.
Yes, it is malware. Is it cool malware? No.
Last updated