Sysrv Back

Now with updated obfuscation

The other day I stumbled across a nice summarised article by @herrcore regarding a new variant of Sysrv which caught my attention (especially given my previous post). Now, the article by @herrcore focussed on the Windows variant of the loader which deploys an interesting technique for retrieving the payload in order to try and avoid network detection. It also referenced what I believe to be the first blog post on new variants by the team over at Imperva1, though their post covers more on the Linux side of the house.

This post is an exercise in re-analyzing the new loaders and payload(s) of Sysrv already referenced in other blogs, confirming the reported behavior, and adding any additional insights worthy of mention.

What Are We Working With

So as to strike while the iron is hot (and before any infrastructure is taken down) I’ve captured the following binaries/files for analysis (hash values at bottom of the post):

File Description
cron Linux (ELF) binary/loader
d Retrieved page: hxxps://[.]com/view/osk05/osk/d Updated dropper script
w Retrieved page: hxxps://
wr.exe Windows (PE) binary/loader

Technical Analysis

With this analysis I’ll be touching on some key points from each of the dropper/loader files with some external references to the aforementioned articles.

Dropper Script (

As has been pointed out in my previous post, and the other articles referenced there, the dropper scripts do not change too much between iterations. Performing a diff between the last one I analysed and one from this current variant shows very little difference yet again.

The primary differences besides changing of the host for downloading the loader are:

  • Removed ufw and ip tables commands
  • Minor changes to some loops such as enabling the one shown below
    • Kills kthreaddk instead of continuing (looks instead for finfghsdhsda)
  • Minor command tweaks
  • Two new functions called if running as ‘root’
    • yy: configure hugepages in attempt to improve performance of memory intensive workloads
    • tt: configure MSR register values based on CPU architecture to optimize performance

As before, some noteworthy items:

  • Payload IP is hardcoded
  • Generate a unique ID (used later to name the binary download)
  • Defence evasion
  • Search for other miner like cron jobs, mounts and processes to be killed
  • Local enumeration and attempt at self propagation via SSH

The full dropper script can be found on on my GitHub repo here

Windows Loader (wr.exe)

The Windows sample is a UPX packed, 64-bit Golang binary that has been stripped and can be found on VirusTotal:



Interestingly, once unpacked, this version has not been obfuscated (see the cron section as to why). Thanks to this, recovery of many function names and packages etc. is clearly visible when decompiling in Ghidra.


A few interesting observations:

  • XMRIG name is hardcoded
    • avgrec.exe
  • Potential to run as a service using:
    • Config suggests name is VBoxServerManages
    • Display Name: VirtualBox Guest Additions Services
  • Payload URL is hardcoded
    • hxxps://

From main.main, flow ends up at main.outgowinexe which is where @herrcore referenced on his article an interesting compiled regex.


The regex picks up on some base64 encoded data, with the first few characters of the string looking mighty suspicious to those in the know!

data-code="<p style='display:none;'>win9990TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAA

Once successfully downloaded and processed, the loader continues execution by launching the payload.

I haven’t checked any more into this one as it has been covered pretty well already, but I wanted to see what differences, if any, Ghidra provided. Plus, I found it quite interesting to establish that the Windows variant is not obfuscated, which makes me wonder if the Linux variants use the same packages and could be recovered in some manner?

Anyway, IoCs for the Windows binaries can be at the end of the post.

Linux Loader (cron)

The Linux sample is a UPX packed, 64-bit Golang, statically linked binary and can be found on VirusTotal:


The unpacked version is still a 64-bit Golang, statically linked binary but it has been stripped and obfuscated. The sample can be found on VirusTotal:


The added obfuscation is quite the enhancement in terms of preventing static reverse engineering, making use it seems of a Go obfuscation tool called garble. Having done a little research into this tools usage recently, it has made recovering much useful data such as functions, packages, position info; ineffective, even with the newer Go recovery option in Ghidra or tools such as GoReSym. One of the reasons garble seems so effective is because when it is used to compile without a seed, a random one is utilised making it difficult to try and reverse (and each compiled binary will have different strings for the same packages etc.!). I do however, have a Yara Rule to detect Go binaries obfuscated with garble which is provided at the end of this post.

I have a theory to look into later about doing some sort of statistical analysis based on what I noted from the Windows binary, in an effort to recover names but that would likely require a lot of effort.

Dynamic Analysis

With static analysis proving more tricky, I took to running the cron sample to validate some of the findings pointed out by the Imperva team given that I was using a different sample.

The first item of note was that the binary has to be renamed to something other than cron as this conflicts with the system cron process and errors out. So I renamed the file malware and ran it. My general observations match up to those in the Imperva blog:

  • Spawns a listener
  • Drops binaries in multiple directories*

*I noted during analysis that the dropped binaries are all UPX packed but with different hashes. However, when run, the files do appear to be the same loader binary as cron in terms of behaviour. There is always one called SSHD2 and the others tend to meet naming condition [a-z0-9]{12,13}.


It also adds a cron entry like so:

*/1 * * * * /home/remnux/9zi4pso42di00

As well as a .bashrc and .profile entries like so:

.bashrc echo My>/dev/null 2>&1 &/home/remnux/o8srcdzloe1le >/dev/null 2>&1 &

Another observation was the creation of certificate/key files which I’ve uploaded here.

I performed a few detonations with snapshots to validate the behaviour and noted callouts to different IP’s each time on port 443. They are all Google addresses but I’ve not validated why these are seen when the malware is run:

  • 216[.]58[.]201[.]115
  • 142[.]250[.]178[.]19
  • 172[.]217[.]169[.]83
  • 142[.]250[.]180[.]19

With my setup, I was only able to ascertain via Wireshark and DNS requests that the loader was calling out to hxxps://, which I know the Windows version of this sample reached out to. Using the Imperva blog for inspiration, I added a path of d and, hey presto! I obtained a working payload to be retrieved, despite the actors efforts to make it appear like a Google 404 error has occurred.


As with the Windows payload, there is a base64 encoded payload for XMRig binary to be carved out of the HTML. This time, the regex can be presumed to be looking for UPXD(.*)UPXD based on source code review of the HTML.

Execution continues by running the XMRig miner, with details added at the end of this post.


It can be determined that the actors here are continually looking for new ways to evade detection. While the dropper scripts may not change much, the evidence of adding binary obfuscation to hinder reverse engineering highlights this fact. The Imperva post highlights that legitimate domains have been utilised as part of the current campaign which is something worth keeping an eye on. The Sysrv actors are known to target low hanging fruit such as unpatched servers and services to gain a foothold on a system.


Loader/Payload URLs:
hxxp:// hxxps:// hxxps://

Dropper script (SHA256): f0a299b93f1a2748edd69299f694d3a12edbe46485d29c1300172d4ac4fd09d4

Payload IPs:

cron (SHA256):
4ea3a10c32dc41f02faecced6522057b13ca3b13308d66d9e213f24fea7af108 packed 77e87669130e6aa98663ed3ee96cbc1747045e9e1cef54b678af41120746b2b9 unpacked

wr.exe (SHA256): a742c71ce1ae3316e82d2b8c788b9c6ffd723d8d6da4f94ba5639b84070bb639 packed 7edfffdf85bf1166137ab698b410f4309e5baa992ea8b3030e5f7e887e7e6226 unpacked

XMRig config as provided by @herrcore:

Pool URLs and Wallet (seen in both referenced articles):

gulf.moneroocean[.]stream:10128 483F2xjkCUegxPM7wAexam1Be67EqDRZpS7azk8hcGETSustmuxd1Agffa3XSHFyzeFprLyHKm37bTPShFUTKgctMSBVuuK

Pool URLs and Wallet (hxxps://

xmrig.moneroocean[.]stream:10001 89TxfrUmqJJcb1V124WsUzA78Xa3UYHt7Bg8RGMhXVeZYPN8cE5CZEk58Y1m23ZMLHN7wYeJ9da5n5MXharEjrm41hSnWHL


As outlined in the post, UPX was used on both the Linux and Windows binaries. It seems more common to find UPX Yara Rules that purely target PE files (at least doing a quick Google search). Therefore I’ve thrown together a rule to match basic UPX packed binaries regardless if its PE or ELF that can be found here.

Additionally, I’ve recently been doing some research into Go binary analysis and detection opportunities for those that have been obfuscated by a crafty tool called garble (as touched upon earlier in the post). You can find my Yara Rule to detect “garbled” Go binaries here.


Share: X Facebook LinkedIn