{"id":17812,"date":"2020-02-25T07:21:07","date_gmt":"2020-02-25T15:21:07","guid":{"rendered":"https:\/\/www.palada.net\/index.php\/2020\/02\/25\/news-11545\/"},"modified":"2020-02-25T07:21:07","modified_gmt":"2020-02-25T15:21:07","slug":"news-11545","status":"publish","type":"post","link":"http:\/\/www.palada.net\/index.php\/2020\/02\/25\/news-11545\/","title":{"rendered":"\u2018Cloud Snooper\u2019 Attack Bypasses Firewall Security Measures"},"content":{"rendered":"<p><strong>Credit to Author: Sergei Shevchenko| Date: Tue, 25 Feb 2020 13:30:43 +0000<\/strong><\/p>\n<div class=\"entry-content\">\n<p>In the course of investigating a malware infection of cloud infrastructure servers hosted in the Amazon Web Services (AWS) cloud, SophosLabs discovered a sophisticated attack that employed a unique combination of techniques to evade detection and that permits the malware to communicate freely with its command and control (C2) servers through a firewall that should, under normal circumstances, prevent precisely that kind of communication from reaching the infected server.<\/p>\n<p>We have published <a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/CloudSnooper_report.pdf\" target=\"_blank\" rel=\"noopener noreferrer\">an in-depth report on the attack<\/a>, which we have named <strong>Cloud Snooper<\/strong>.<\/p>\n<p>Though we discovered the technique in use on AWS, the problem is not an AWS problem per se. It represents a method of piggybacking C2 traffic on a legitimate traffic, such as normal web traffic, in a way that can bypass many, if not most, firewalls.<\/p>\n<p>The complexity of the attack and the use of a bespoke APT (Advanced Persistent Threat) toolset gives us reason to believe that the malware and its operators were an advanced threat actor, possibly nation-state sponsored.<\/p>\n<p>The compromised systems were running both Linux and Windows EC2 instances.<\/p>\n<h2>Anomalous traffic raises alerts<\/h2>\n<p>As often happens with incidents like this, our investigation started when someone noticed an anomaly. While the AWS security groups (SGs) were properly tuned, set up only to allow inbound HTTP or HTTPS traffic, the compromised Linux system was still listening for inbound connections on ports 2080\/TCP and 2053\/TCP.<\/p>\n<p>An analysis of this system revealed the presence of a rootkit that granted the malware&#8217;s operators the ability to remotely control the server through the AWS SGs. But this rootkit&#8217;s capabilities are not limited to doing this in the Amazon cloud: It also could be used to communicate with, and remotely control, malware on any server behind any boundary firewall, even an on-premises server.<\/p>\n<p>By unwinding other elements of this attack, we further identified other Linux hosts, infected with the same or a similar rootkit.<\/p>\n<p>Finally, we identified a compromised Windows system with a backdoor that communicated with a similar C2 as other compromised Linux hosts, using a very similar configuration format. The backdoor is apparently based on source code of the infamous Gh0st RAT malware.<\/p>\n<p>At this point in the investigation, we still have some open questions. For example, it is still unclear how the attackers managed to compromise the client&#8217;s system in the first place. One of the working theories is that the attackers broke into a server through SSH, protected with password authentication.<\/p>\n<h2>High-level illustration<\/h2>\n<p>Before we start our technical description, let us provide a high-level view of the Cloud Snooper attack. Doing so might help the reader to get an overall idea of how its elements are related to each other.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/snoopy.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-64514 size-large\" style=\"border: 1px solid #777\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/snoopy_x4_labels-1.png?w=640\" alt=\"\" width=\"640\" height=\"432\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/snoopy_x4_labels-1.png 4096w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/snoopy_x4_labels-1.png?resize=300,202 300w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/snoopy_x4_labels-1.png?resize=768,518 768w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/snoopy_x4_labels-1.png?resize=1024,691 1024w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/snoopy_x4_labels-1.png?resize=1536,1037 1536w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/snoopy_x4_labels-1.png?resize=2048,1382 2048w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>In the illustration above, our castle represents the targeted server infrastructure; In the case of the incident we investigated, the server was hosted by Amazon Web Services (AWS). At its perimeter, the <em>AWS Security Groups<\/em> (SGs) &#8211; a set of firewall rules that provide security at the protocol and port access level \u2013 limit the inbound network traffic.<\/p>\n<p>For example, you might typically set up an AWS Security Group that only allows web traffic \u2013 that is, TCP packets that arrive at ports 80 or 443 \u2013 to reach your server. Network traffic with any other destination port never makes it past the SGs.<\/p>\n<p>The infection involves a rootkit that inspects network traffic, and a backdoor that the attackers leverage the rootkit to send commands to, and receive data from, the backdoor.<\/p>\n<p>In order to get around the firewall rules, depicted here as guards, the attackers communicate with the rootkit by sending innocent-looking requests (depicted in the illustration as a wolf in sheep&#8217;s clothing) to the web server on the normal web server ports. A listener that inspects inbound traffic before it reaches the web server intercepts the specially-crafted requests, and sends instructions to the malware based on characteristics of those requests.<\/p>\n<p>The listener sends a &#8220;reconstructed&#8221; C2 command to the backdoor Trojan installed by the rootkit. Depending on the commands included into C2 traffic, the attacker may use the backdoor to steal sensitive data from the target.<\/p>\n<p>The collected data is then delivered back with the C2 traffic. Only this time, the rootkit has to masquerade it again in order to bypass the guards: the wolf dresses itself in sheep&#8217;s clothing once again. Once outside, the C2 traffic delivers the collected data back to the attackers.<\/p>\n<p>During an entire operation, the normal web traffic, depicted as sheep, keeps flowing to and from the web server through the allowed gate. Visually, the C2 traffic stays largely indistinguishable from the legitimate web traffic.<\/p>\n<h2>Dismantling the Cloud Snooper tools<\/h2>\n<p>As you will see from the description below, some samples that we collected are directly related to each other, while others belong to a completely different malware family. Nevertheless, all these samples were collected from the same infrastructure, and thus, we consider them part of the same toolset.<\/p>\n<p>The description starts with the Linux malware, then progresses into its Windows counterpart that is apparently based on Gh0st RAT.<\/p>\n<p>Overall, we discovered and studied 10 samples in the course of the investigation, which can be broken down as:<\/p>\n<h2>The Cloud Snooper communications handler<\/h2>\n<p>The central piece of the attack is a file named <code>snd_floppy<\/code> \u2013 a kernel module that sets up a network packet filter, using a Netfilter hook (<code>NF_INET_LOCAL_IN<\/code> and <code>NF_INET_LOCAL_OUT<\/code>).<\/p>\n<p>This component was instrumental in giving the malware&#8217;s operators the ability to communicate with the malware, despite the firewall protecting the AWS EC2 servers.<\/p>\n<p>The <code>NF_INET_LOCAL_IN<\/code> is a type of hook that is triggered before the packet reaches the destination port.<\/p>\n<p>The installed hook handler inspects the socket buffer of every IPv4 packet, looking for a command concealed within a header \u2013 the command being the source port number of the packet originating from the attacker&#8217;s machine. These commands\/source ports can be one of the following port numbers: <code>1010<\/code>, <code>2020<\/code>, <code>6060<\/code>, <code>7070<\/code>, <code>8080<\/code>, <code>9999<\/code>.<\/p>\n<p>Firewalls typically prevent machines behind the firewall from receiving traffic sent to arbitrary <em>destination<\/em> ports, but they don&#8217;t pay attention to the <em>source<\/em> ports, because source ports are normally ephemeral, and not relevant to the server or the services it is hosting.<\/p>\n<p>In a typical cloud instance, the server may be set up to receive traffic from any IP address on port 80\/TCP (for HTTP) and on 443\/TCP (for HTTPS), so the firewall will let any traffic to those ports through to the server. So long as the traffic coming in to one of these standard ports fits the pattern the communications handler is looking for, it will execute one of its built-in instructions. Anything else will be ignored, and the server will serve web pages as normal to browsers.<\/p>\n<p>For example, if the communications handler receives a TCP SYN packet with an origin port of <code>6060<\/code>, the malware will decrypt an embedded file that has been encrypted with RC4 (the key is <em>&#8216;YaHo0@&#8217;<\/em>).<\/p>\n<p>It will then drop that decrypted file as <code>\/tmp\/snoopy<\/code>, wait for half a second, and then execute it as a usermode application with the <em>call_usermodehelper()<\/em> syscall. Immediately after that, it deletes the <code>\/tmp\/snoopy<\/code> file, so the snoopy application remains running in memory with no physical file present.<\/p>\n<p>If the command is <code>9999<\/code> as a TCP SYN packet, the <code>\/tmp\/snoopy<\/code> process self-terminates (in case <code>killall<\/code> is supported by OS), by passing the following commands to <em>call_usermodehelper()<\/em> syscall.<\/p>\n<pre style=\"background-color: #fff\">\/bin\/sh -c \/tmp\/snoopy  rm -rf \/tmp\/snoopy  killall \/tmp\/snoopy  <\/pre>\n<p>NOTE: executing <code>snoopy<\/code> again while it\u2019s already running has no effect; by using a file lock mechanism, <code>snoopy<\/code> makes sure only one instance is running. If that happens, it will output:<\/p>\n<pre style=\"background-color: #fff\">[ERROR] there is already a instance.  <\/pre>\n<p>Here is the logic of the <code>NF_INET_LOCAL_IN<\/code> hook handler, which listens for SYN packets sent to the server, using the various source ports:<\/p>\n<pre style=\"margin: 0;line-height: 125%;background-color: #fff\"><span style=\"color: #0000ff\">if<\/span> tcp:      <span style=\"color: #0000ff\">if<\/span> tcp.src_port == 6060:          <span style=\"color: #0000ff\">if<\/span> tcp.flags == SYN:              drop_payload()        <span style=\"color: #008000\"># drops\/runs snoopy<\/span>              <span style=\"color: #0000ff\">return<\/span> NF_STOP      <span style=\"color: #0000ff\">elif<\/span> tcp.src_port == 7070:          tcp.dst_port = 2080          adjust_tcp_checksum()          <span style=\"color: #0000ff\">return<\/span> NF_STOP      <span style=\"color: #0000ff\">elif<\/span> tcp.src_port == 9999:          <span style=\"color: #0000ff\">if<\/span> tcp.flags == SYN:              kill_payload()        <span style=\"color: #008000\"># kills snoopy process<\/span>              <span style=\"color: #0000ff\">return<\/span> NF_STOP      <span style=\"color: #0000ff\">elif<\/span> tcp.src_port == 2020:          <span style=\"color: #0000ff\">return<\/span> NF_STOP      <span style=\"color: #0000ff\">elif<\/span> tcp.src_port == 1010:          tcp.dst_port = 22          adjust_tcp_checksum()          <span style=\"color: #0000ff\">return<\/span> NF_STOP      <span style=\"color: #0000ff\">else<\/span>:          <span style=\"color: #0000ff\">return<\/span> NF_ACCEPT  <span style=\"color: #0000ff\">elif<\/span> udp:      <span style=\"color: #0000ff\">if<\/span> udp.src_port == 8080:          udp.dst_port = 2053          adjust_udp_checksum()          <span style=\"color: #0000ff\">return<\/span> NF_STOP  <span style=\"color: #0000ff\">else<\/span>:      <span style=\"color: #0000ff\">return<\/span> NF_ACCEPT  <\/pre>\n<p>And here is the logic of the <code>NF_INET_LOCAL_OUT<\/code> hook handler:<\/p>\n<pre style=\"margin: 0;line-height: 125%;background-color: #fff\"><span style=\"color: #0000ff\">if<\/span> tcp:      <span style=\"color: #0000ff\">if<\/span> tcp.dst_port == 7070:          tcp.src_port = 443        <span style=\"color: #008000\"># or, 80 in another variant<\/span>          adjust_udp_checksum()          <span style=\"color: #0000ff\">return<\/span> NF_STOP      <span style=\"color: #0000ff\">if<\/span> tcp.dst_port == 2020:          <span style=\"color: #0000ff\">return<\/span> NF_STOP      <span style=\"color: #0000ff\">if<\/span> tcp.dst_port == 1010:          tcp.src_port = 443        <span style=\"color: #008000\"># or, 80 in another variant<\/span>          adjust_udp_checksum()          <span style=\"color: #0000ff\">return<\/span> NF_STOP      <span style=\"color: #0000ff\">else<\/span>:          <span style=\"color: #0000ff\">return<\/span> NF_ACCEPT  <span style=\"color: #0000ff\">elif<\/span> upd:      <span style=\"color: #0000ff\">if<\/span> udp.dst_port == 8080:          udp.src_port = 53          <span style=\"color: #0000ff\">return<\/span> NF_STOP  <span style=\"color: #0000ff\">else<\/span>:      <span style=\"color: #0000ff\">return<\/span> NF_ACCEPT  <\/pre>\n<h2>Explanation<\/h2>\n<p>To trigger the payload (<code>snoopy<\/code>) activation, an attacker would send the following packet:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/01\/sophos-cloud-snooper-diagram1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-64509\" style=\"border: 1px solid #c9c9c9\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram1_new.png\" alt=\"\" width=\"640\" height=\"238\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram1_new.png 1301w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram1_new.png?resize=300,111 300w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram1_new.png?resize=768,285 768w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram1_new.png?resize=1024,380 1024w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>Next, the <code>snoopy<\/code> module would be accessed by the C2, using source port 7070 for TCP-based or 8080 for UDP-based control:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/01\/sophos-cloud-snooper-diagram2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-64511 size-large\" style=\"border: 1px solid #c9c9c9\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram2_new.png?w=640\" alt=\"\" width=\"640\" height=\"204\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram2_new.png 1950w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram2_new.png?resize=300,96 300w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram2_new.png?resize=768,245 768w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram2_new.png?resize=1024,327 1024w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram2_new.png?resize=1536,491 1536w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>On the way back, the <code>NF_INET_LOCAL_OUT<\/code> hook handler rebuilds the packet again, to make sure its source port is restored back to the original port where the incoming packet was destined for. This way, the C2 traffic transparently flows through the port(s) allowed by AWS SGs:<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/01\/sophos-cloud-snooper-diagram3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-64512 size-large\" style=\"border: 1px solid #c9c9c9\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram3_new.png?w=640\" alt=\"\" width=\"640\" height=\"212\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram3_new.png 1794w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram3_new.png?resize=300,99 300w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram3_new.png?resize=768,254 768w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram3_new.png?resize=1024,338 1024w, https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/diagram3_new.png?resize=1536,508 1536w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>No other Netfilter hooks within the chain, such as iptables INPUT\/OUTPUT rules, will process the packet if the hook returns <code>NF_STOP<\/code>. This appears to be the purpose of the TCP command 2020: to bypass other Netfilter hooks.<\/p>\n<p>In instances where the Netfilter receives inbound traffic with a source port of 1010\/TCP, it directs the contents to the Secure Shell (SSH) port, 22\/TCP. For outbound traffic we have seen two variants using either port 80 or port 443. This will allow for an SSH connection to step around an AWS SG with IP restrictions on traffic to port 22.<\/p>\n<p>Hence, the ultimate purpose of the <code>snd_floppy<\/code> rootkit is to provide a covert control channel for the <code>snoopy<\/code> usermode process, running on a compromised host.<\/p>\n<p>Such covert control channels can be established via any port allowed by AWS SGs, be it 80, 443, 22, or any other port.<\/p>\n<p>From the outside, the compromised system will show an unusually large volume of traffic that comes from the remote ports 6060, 7070, 8080, and 9999.<\/p>\n<p>But what is the <code>snoopy<\/code> module? What does it do?<\/p>\n<h2>The Snoopy Module<\/h2>\n<p><code>snoopy<\/code> is a backdoor trojan that can be executed both as a command line tool and as a daemon (though it needs to be launched with the <code>-d<\/code> flag for that). The backdoor&#8217;s internal version is 3.0.1-2.20170303.<\/p>\n<p>It opens HTTP and\/or DNS services on a compromised system, and allows tunneling of the traffic, operating both as a reverse SOCKS5 proxy server, and client.<\/p>\n<p>For example, the incoming control traffic can also be relayed to a different server.<\/p>\n<p>When run with <code>-h<\/code> option, the tool prints the following syntax:<\/p>\n<pre style=\"background-color: #fff\">Usage: rrtserver [OPTIONS]  OPTIONS:  \t-h  \t-d  \t-s IPv4[:PORT:{udp|tcp}:{dns|http|none}]  <\/pre>\n<p>Where:<\/p>\n<ul>\n<li><code>-h<\/code> option will print out the usage above<\/li>\n<li><code>-d<\/code> will run the tool as daemon<\/li>\n<li><code>-s<\/code> allows to specify a server address to bind the listening socket to, its port number, and what protocol is used for the traffic: either UDP-based DNS or TCP-based HTTP<\/li>\n<\/ul>\n<p>The binary requires root privilege; when run, it calls <code>geteuid()<\/code> to get the user ID. If it fails, it prints the line below and quits:<\/p>\n<pre style=\"background-color: #fff\"><em>\"Administrator privileges are required.\"<\/em>  <\/pre>\n<p>It sets the working directory to <code>\/tmp<\/code>, and obtains a lock for the file <code>\/tmp\/rrtserver-lock<\/code>. The lock file is used to make sure there is only one version of the tool running.<\/p>\n<p>The incoming HTTP traffic is accepted on port 2080, and DNS traffic on port 2053.<\/p>\n<p><strong>NOTE<\/strong>: the port numbers 2080 and 2053 are default ones; the tool can be executed with different port numbers specified as parameters.<\/p>\n<p>Snoopy parses the received DNS\/HTTP traffic to extract hidden commands within it &#8211; such commands are called <em>&#8220;rrootkit messages&#8221;<\/em> and are distinguished by the presence of a magic header or marker.<\/p>\n<p>For example, to find <em>&#8220;rrootkit messages&#8221;<\/em> in HTTP traffic, Snoopy parses the HTTP request to see if it starts with <code>\"GET \/* HTTP\/1.1rndata:\"<\/code> or <code>\"HTTP\/1.1 200 OKrndata:\"<\/code>.<\/p>\n<p>Next, the <em>&#8220;rrootkit messages&#8221;<\/em> would start from a magic header <code>0xE381B7F5<\/code>. If this header is found, such data is called <em>msg-data<\/em>.<\/p>\n<p>The received <em>msg-data<\/em> is then decrypted with RC4, using the quite specific key <em>&#8216;A YARN-based system for parallel processing of large data sets&#8217;<\/em>.<\/p>\n<p>The tool then initiates several additional components. These components will process the received <em>msg-data<\/em>.<\/p>\n<p>Depending on a separate magic header within each <em>msg-data<\/em>, the data will be processed by a different component.<\/p>\n<p>The initiated components are:<\/p>\n<ul>\n<li><strong>view-shell<\/strong> (magic header <code>0xFC72E392<\/code>): pty (pseudo terminal) that allows remote shell\n<ul>\n<li>the <code>HISTFILE<\/code> variable is cleared, to make sure <code>\/bin\/sh<\/code> execution leaves no history<\/li>\n<li>the received commands are then executed with <code>\/bin\/sh<\/code><\/li>\n<\/ul>\n<\/li>\n<li><strong>view-file<\/strong> (magic header <code>0xFC72E393<\/code>): file manager that accepts 3 commands:\n<ul>\n<li><em>&#8216;get&#8217;<\/em> &#8211; read files<\/li>\n<li><em>&#8216;put&#8217;<\/em> &#8211; save file<\/li>\n<li>any other command &#8211; execute file with <em>popen()<\/em> syscall<\/li>\n<\/ul>\n<\/li>\n<li><strong>view-proxy<\/strong> (magic header <code>0xFC72E394<\/code>): proxy server that accepts the following commands:\n<ul>\n<li><em>&#8216;exit&#8217;<\/em> or <em>&#8216;quit&#8217;<\/em> &#8211; quit proxy server<\/li>\n<li><em>&#8216;socks5&#8217;<\/em> &#8211; starts SOCKS5 proxy server, authentication is provided with user\/password passed with the <code>'-u'<\/code> and <code>'-p'<\/code> parameters<\/li>\n<li><em>&#8216;rcsocks-cmd: socks is closed.&#8217;<\/em> &#8211; closes SOCKS proxy<\/li>\n<\/ul>\n<p>The SOCKS5 server is based on <a href=\"https:\/\/github.com\/tostercx\/ssocks\">the open-source sSocks proxy<\/a> implementation.<\/li>\n<li><strong>view-pipe<\/strong> (magic header <code>0xFC72E398<\/code>): p2p communicator, that receives commands <em>&#8216;pwd&#8217;<\/em>, <em>&#8216;exit&#8217;<\/em>, <em>&#8216;quit&#8217;<\/em>, <em>&#8216;connect&#8217;<\/em><br \/> On receiving the <em>&#8216;connect&#8217;<\/em> command, it accepts the same parameters as the command-line tool (server IP, port, protocol) and starts tunneling commands to another peer.<br \/> The pipe appears to be used to establish connections to other peers.<br \/> The negotiation protocol to other peers includes a message <em>&#8216;rrootkit-negotiation: hello&#8217;<\/em>.<br \/> Once the connection is established, the logged message displays what peers have been connected, and that a new network node is now open:<\/p>\n<ul>\n<li><em>&#8220;view-pipe: left[address, port]-&gt;right[address, port].&#8221;<\/em><\/li>\n<li><em>&#8220;view-pipe: the network node is opened.&#8221; <\/em><\/li>\n<\/ul>\n<\/li>\n<li><strong>view-myproto<\/strong> (magic header <code>0xFC72E397<\/code>): a &#8216;ping&#8217;\/&#8217;pong&#8217;; depending on a flag it receives, it either:\n<ul>\n<li>receives a message <em>&#8220;rrootkit-negotiation: hello&#8221;<\/em>, then responds back <em>&#8220;rrootkit-negotiation: ok, go on&#8221;<\/em><\/li>\n<li>checks if the received message was <em>&#8220;rrootkit-negotiation: ok, go on&#8221;<\/em><\/li>\n<\/ul>\n<\/li>\n<li><strong>loop-notifier<\/strong> &#8211; creates a pipe, a data channel for inter-process communication (IPC).<br \/> The backdoor allows control via IPC pipe as a backup control channel.<\/li>\n<\/ul>\n<h2>Logging<\/h2>\n<p><code>snoopy<\/code> stores many debug messages in clear text.<\/p>\n<p>However, with the internal level of logging set to 0 (none), no debug messages are ever printed. Hence, these debug messages are only used in the testing phase of the malware.<\/p>\n<p>Some of the debug messages are in Chinese:<\/p>\n<ul>\n<li>\u8fdc\u7a0b\u8def\u5f84\u592a\u957f! &#8211; The remote path is too long!<\/li>\n<li>\u8fdc\u7a0b\u6587\u4ef6\u4e0d\u5b58\u5728! &#8211; The remote file does not exist!<\/li>\n<li>\u8fdc\u7a0b\u5185\u5b58\u7a7a\u95f4\u5206\u914d\u5931\u8d25! &#8211; Remote memory space allocation failed!<\/li>\n<li>\u8fdc\u7a0b\u8def\u5f84\u4e0d\u5b58\u5728! &#8211; The remote path does not exist!<\/li>\n<li>\u8fdc\u7a0b\u6587\u4ef6\u5df2\u5b58\u5728! &#8211; The remote file already exists!<\/li>\n<li>\u8fde\u63a5\u5931\u8d25! &#8211; Connection failed!<\/li>\n<li>\u8fde\u63a5\u6210\u529f! &#8211; Connection succeeded!<\/li>\n<li>\u53c2\u6570\u9519\u8bef! &#8211; Parameter error!<\/li>\n<\/ul>\n<p>Some messages reveal poor English grammar:<\/p>\n<ul>\n<li>view don&#8217;t found<\/li>\n<li>view-shell: data do not belong to SHELL<\/li>\n<\/ul>\n<h2>Building a Client<\/h2>\n<p>By knowing how the C2 protocol works, it is possible to build a client to talk to <code>snoopy<\/code> either directly, or via <code>snd_floppy<\/code> rootkit.<\/p>\n<p>What for?<\/p>\n<p>Firstly, the client can ping a host located in the same network to see if it&#8217;s infected or not.<\/p>\n<p>Secondly, if a host is infected, the client can disinfect it remotely by instructing <code>snoopy<\/code> to execute its disinfection routine (see the <code>rmmod<\/code> command below \u2013 after serving it, the rootkit stopped responding as it was unloaded).<\/p>\n<p>Last but not least, building such a client is cool.<\/p>\n<p>The following screenshot demonstrates the client in action. The <code>snd_floppy<\/code> rootkit intercepts traffic on port 22, even though it\u2019s destined to the SSH daemon (seen as <code>981\/sshd<\/code> in the snapshot below). Next, it re-routes such traffic internally to the <code>snoopy<\/code> module.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image7.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-62270\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image7.png\" alt=\"\" width=\"640\" height=\"434\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image7.png 1154w, https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image7.png?resize=300,203 300w, https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image7.png?resize=768,520 768w, https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image7.png?resize=1024,694 1024w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>As long as the rootkit is active, the attackers may attempt to smuggle the control traffic through any port allowed by the firewall (the screenshot demonstrates that using ports 21 and 24 makes no difference \u2013 these packets are still re-routed by the rootkit to the backdoor).<\/p>\n<h2>Gh0st RAT (the Linux version)<\/h2>\n<p>Apart from those samples, we have also recovered a different Linux backdoor, a backdoor that does not open any ports. Instead, it relies on a C2 polling mechanism.<\/p>\n<p>The analysis of this bot functionality reveals it belongs to <a href=\"https:\/\/en.wikipedia.org\/wiki\/Gh0st_RAT\">Gh0st RAT<\/a>, only it&#8217;s a version that has been written for Linux.<\/p>\n<p>It is hard to tell if Gh0st always existed as a multi-platform RAT, or whether the attackers developed a Linux-based Gh0st after <a href=\"https:\/\/github.com\/sincoder\/gh0st\">the source code of Gh0st for Windows was leaked online<\/a>.<\/p>\n<p>At the end of the day, it makes sense to have clients deployed across various platforms, using a unified configuration format and C2 protocol, while having a single server for all those clients.<\/p>\n<p>Still, we will leave the guesswork out of this description, rather focusing on what the recovered samples actually do.<\/p>\n<p><code>\/bin\/snort<\/code> is a backdoor that contacts a remote C2 to fetch and execute commands. Its internal config file is encrypted with RC4, using the password: <code>\"r0st@#$\"<\/code>:<\/p>\n<pre style=\"background-color: #fff\">185[.]86[.]151[.]67:443;|1;1;1;1;1;0;0;|10-20;|10  <\/pre>\n<p>the <code>'1;1;1;1;1;0;0;'<\/code> part of the config are the flags that stand for seven days of the week.<\/p>\n<p>the <code>'10-20;'<\/code> seem to indicate working hours (10am to 8pm), so current weekday and current hour should match what&#8217;s in config.<\/p>\n<p>If there is no match, the bot falls asleep for just over seven minutes (423.756 seconds), then checks the time again.<\/p>\n<p>In case of a match, it attempts to reach the C2; if it cannot, it retries again in one minute.<\/p>\n<p>Traffic to the C2 is encrypted with double RC4, where a key is randomly generated based on the current time.<\/p>\n<p>The backdoor has six commands:<\/p>\n<ul>\n<li>The bot clears environmental variable <code>HISTFILE<\/code>, to make sure no history is kept for <code>\/bin\/bash<\/code> execution; the C2 responds with a string, the bot sets the <code>TERM<\/code> variable to that string<br \/> Next, it receives a command and executes it with <code>\/bin\/bash<\/code>, with or without the <code>'-c'<\/code> switch (allows for executing commands as provided within the quotes)<br \/> The output from the executed command is sent back<\/li>\n<li>File manipulations:\n<ul style=\"list-style-type: circle\">\n<li>Locate and obtain timestamp for the specified file<\/li>\n<li>Rename specified file<\/li>\n<li>Recursively delete all files in the specified directory<\/li>\n<\/ul>\n<\/li>\n<li>More file manipulations:\n<ul style=\"list-style-type: circle\">\n<li>Read the contents of the specified file<\/li>\n<li>Recursive search for files<\/li>\n<li>Write data into a specified file<\/li>\n<li>Create specified directory<\/li>\n<\/ul>\n<\/li>\n<li>The next two commands manipulate file descriptors with <em>fcntl()<\/em> syscall, and fork child processes<\/li>\n<li>Receive data and save it into a local file <code>\/usr\/include\/sdfwex.h<\/code><\/li>\n<\/ul>\n<p>It appears that <code>\/usr\/include\/sdfwex.h<\/code> contains a timestamp (year, month, day, hour, minutes) for when the C2 connection should commence.<\/p>\n<p>If the bot cannot open this file, it tries to open <code>\/tmp\/.llock<\/code> &#8211; if that file also cannot be opened, the bot skips the timestamp check, and proceeds with trying to connect to the C2.<\/p>\n<p>Other variations of this sample use different configurations, such as:<\/p>\n<pre style=\"background-color: #fff\">cloud[.]newsofnp[.]com:443;|1;1;1;1;1;1;1;|00-24;|1  load[.]CollegeSmooch[.]com:82;|1;1;1;1;1;1;1;|00-24;|10  <\/pre>\n<p>For the beacon signal it sends to the C2, it collects basic system configuration into a fingerprint. This info consists of:<\/p>\n<ul>\n<li>Hostname and IP address<\/li>\n<li>Platform type, as read from <code>\/proc\/version<\/code>, such as <code>'x86_64'<\/code><\/li>\n<li>Full name of the Linux version, as read from <code>\/etc\/issue.net<\/code> and <code>\/etc\/issue<\/code>, such as:\n<ul style=\"list-style-type: circle\">\n<li><em>&#8216;Red Hat Enterprise Linux Server release 6.10 (Santiago)&#8217;<\/em><\/li>\n<li><em>&#8216;Ubuntu 16.04.5 LTS&#8217;<\/em><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>The communications with the C2 are always encrypted using a bespoke algorithm that relies on a time-based random RC4 key with extra encryption layers.<\/p>\n<h2>Windows Malware<\/h2>\n<p><code>NSIProvider.dll<\/code> is a malicious Windows service DLL, executed under <code>svchost.exe<\/code>.<\/p>\n<p>The service name is NSIProvider, registered with the description name <em>&#8220;Netword Store Interface Provider&#8221;<\/em>.<\/p>\n<p><strong>NOTE<\/strong>: &#8216;Netword&#8217; with &#8216;d&#8217;.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image8.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-62279\" style=\"border: 1px solid #bbb\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image8.png\" alt=\"\" width=\"512\" height=\"205\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image8.png 512w, https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image8.png?resize=300,120 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/a><\/p>\n<p>The DLL is heavily obfuscated.<\/p>\n<p>Once started as a service, it conveniently spits out debug messages documenting the operation.<\/p>\n<p>Sysinternal&#8217;s DebugView shows these messages:<\/p>\n<pre style=\"background-color: #fff\">00000000\t0.00000000\t[4052] DLL_PROCESS_ATTACH.\t  00000001\t0.00489140\t[4052] Rundll32Entry()\t  00000002\t0.01733349\t[4052] ServerLoadPayload()\t  00000003\t0.01749189\t[4052] Get Module File Name.\t  00000004\t0.01753826\t[4052] Get Payload File Name.\t  00000005\t0.01757095\t[4052] Switch to payload directory.\t  00000006\t0.01768074\t[4052] Read Payload File.\t  00000007\t0.01811264\t[4052] Decrypt Payload Data.\t  00000008\t0.06122175\t[4052] Verify Payload Data.\t  00000009\t0.06732560\t[4052] ServerExecutePayload()\t  00000010\t0.06740102\t[4052] Call Shellcode.\u202c\u202c\u202c  <\/pre>\n<p>Once loaded, the DLL locates the encrypted payload file and loads it into memory.<br \/> The steps are:<\/p>\n<ul>\n<li>Get current module filename with <em>GetModuleFileName()<\/em> API, i.e. <code>%PATH%NSIProvider.dll<\/code><\/li>\n<li>Concatenate current module filename with <code>\u2018.crt\u2019<\/code>, e.g. <code>%PATH%NSIProvider.dll.crt<\/code><\/li>\n<li>Allocate memory with <em>VirtualAlloc()<\/em> and read the entire payload file into memory<\/li>\n<li>Initialise a permutation table that consists of 256 DWORDs<br \/> Each value of the permutation table is calculated as:<\/p>\n<pre style=\"background-color: #fff\">*ptr= ((*ptr &gt;&gt; 1) &amp; 0x54384748 | ~(*ptr &gt;&gt; 1) &amp; 0xABC7B8B7) ^ 0x467F3B97;  ...  PERM_TABLE[*index] = *ptr;  <\/pre>\n<\/li>\n<li>Start decryption loop &#8211; in this loop, a key value is subtracted from each byte of the encrypted payload; the key value itself is calculated in each iteration based on the previous key value, current index of the decrypted byte, and the permutation table:\n<pre style=\"background-color: #fff\">ptr = __ptr_index++;  val = PERM_TABLE[((*ptr &amp; 0x67612505 | ~*ptr &amp; 0x989EDAFA) ^ (KEY &amp; 0x67612505 | ~KEY &amp; 0x989EDAFA)) &amp; ((*ptr &amp; 0x67612505 | ~*ptr &amp; 0x989EDAFA) ^ (KEY &amp; 0x67612505 | ~KEY &amp; 0x989EDAFA) ^ 0xFFFFFF00)];  KEY = (val &amp; 0x432AA81D | ~val &amp; 0xBCD557E2) ^ ((KEY &gt;&gt; 8) &amp; 0x432AA81D | ~(KEY &gt;&gt; 8) &amp; 0xBCD557E2);  <\/pre>\n<\/li>\n<li>The decrypted payload reveals a checksum, a number of zero bytes, followed with the initial shellcode itself:<br \/> <a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image9.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-62283\" style=\"border: 1px solid #c9c9c9\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image9.png\" alt=\"\" width=\"640\" height=\"208\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image9.png 746w, https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image9.png?resize=300,97 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/li>\n<\/ul>\n<p>The decrypted payload blob is copied into a newly allocated memory buffer and the initial shellcode (starts from bytes <code>EB 17 58<\/code> in the image above) is called.<\/p>\n<p>The initial shellcode will then decrypt the rest of the blob, using an XOR key that starts from <code>0x2B<\/code>, and then incremented by the index of the decrypted byte, i.e. the XOR key values are: <code>0x2B<\/code>, <code>0x2C<\/code>, <code>0x2E<\/code>, <code>0x31<\/code>, etc.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image10.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-62285\" style=\"border: 1px solid #c9c9c9\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image10.png\" alt=\"\" width=\"640\" height=\"446\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image10.png 750w, https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image10.png?resize=300,209 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>As the rest of the blob is decrypted, the configuration file is decrypted as well, followed by other parts.<\/p>\n<p>After the initial shellcode has finished the decryption, the fully decrypted blob will consist of:<\/p>\n<ul>\n<li>Initial shellcode<\/li>\n<li>Decrypted config:\n<pre style=\"background-color: #fff\">Microsoft.Windows.BNG|\u202assl[.]newsofnp[.]com:443\u202c;|1;1;1;1;1;1;1;|00-24;|1  <\/pre>\n<\/li>\n<li>Zlib-compressed LIBEAY32.dll (77,871 bytes, 167,936 bytes when decompressed)<\/li>\n<li>Zlib-compressed LIBEAY32.dll (386,876 bytes, 851,968 bytes when decompressed)<\/li>\n<li>Backdoor, implemented in the form of a second-stage shellcode<\/li>\n<\/ul>\n<p>Once it\u2019s decoded, the second-stage shellcode is called \u2013 this is the backdoor itself.<\/p>\n<p>When it gets control, it dynamically obtains all APIs it needs by using hard-coded API hashes. To find matching hashes from the API names, the shellcode relies on a a slight modification of the ROR-13 algorithm. The only difference is that it checks if the zero byte is at the end of the loop, thus has an additional ROR for the terminating zero byte.<\/p>\n<p><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image11.jpeg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-62287\" style=\"border: 1px solid #c9c9c9\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image11.jpeg\" alt=\"\" width=\"465\" height=\"498\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image11.jpeg 465w, https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image11.jpeg?resize=280,300 280w\" sizes=\"auto, (max-width: 465px) 100vw, 465px\" \/><\/a><\/p>\n<p>All the required DLLs are loaded dynamically.<\/p>\n<p>Next, it will decompress and load 2 stubs as DLLs. Both DLLs have the internal name LIBEAY32.dll.<\/p>\n<p>Both DLLs rely on an older (2004) build of the libeay32.dll \u2013 below are some strings found in the body of these DLLs:<\/p>\n<pre style=\"background-color: #fff\">MD2 part of OpenSSL 0.9.7d 17 Mar 2004  MD4 part of OpenSSL 0.9.7d 17 Mar 2004  MD5 part of OpenSSL 0.9.7d 17 Mar 2004  SHA part of OpenSSL 0.9.7d 17 Mar 2004  SHA1 part of OpenSSL 0.9.7d 17 Mar 2004  <\/pre>\n<p>The backdoor relies on these DLLs for crypto-functions required to communicate with the C2.<\/p>\n<p>The config format is consistent with the ELF binaries, i.e., the seven <code>'1;'<\/code> means the bot should be active seven days a week, all hours (00-24), the C2 communicates via HTTPS.<\/p>\n<p>The same config is <a href=\"https:\/\/www.nccgroup.trust\/uk\/about-us\/newsroom-and-events\/blogs\/2018\/april\/decoding-network-data-from-a-gh0st-rat-variant\/\">known to be used by Gh0st RAT<\/a>.<\/p>\n<p>Just like <code>\/bin\/snort<\/code> described above, the bot also checks if the current day and hour match what&#8217;s specified in the config.<\/p>\n<p>If there is no match, the bot also falls asleep for just over seven minutes (423.756 seconds), then checks the time again.<\/p>\n<p>The code snippets below demonstrate that the 423,756-millisecond delay specified within <code>\/bin\/snort<\/code> executable is identical to its Windows counter-part:<\/p>\n<table>\n<tbody>\n<tr>\n<th>ELF executable: \/bin\/snort<\/th>\n<th>Windows<br \/> shellcode:<\/th>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image12.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-62290\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image12.png\" alt=\"\" width=\"640\" height=\"245\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image12.png 642w, https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image12.png?resize=300,115 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/td>\n<td><a href=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image13.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-62291\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image13.png\" alt=\"\" width=\"640\" height=\"223\" srcset=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image13.png 705w, https:\/\/news.sophos.com\/wp-content\/uploads\/2019\/11\/image13.png?resize=300,105 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>On Linux, the number 423,756 is multiplied by 1,000, then passed to <em>usleep()<\/em> syscall that takes an argument in microseconds.<\/p>\n<p>On Windows, the same number is passed to Sleep() API, which takes the argument in milliseconds.<\/p>\n<p>In both cases, the achieved delay is identical: 7.062 seconds.<\/p>\n<h2>Conclusion<\/h2>\n<p>This case is extremely interesting as it demonstrates the true multi-platform nature of a modern attack.<\/p>\n<p>A well-financed, competent, determined attacker will unlikely ever to be restricted by the boundaries imposed by different platforms.<\/p>\n<p>Building a unified server infrastructure that serves various agents working on different platforms makes perfect sense for them.<\/p>\n<p>When it comes to prevention against this or similar attacks, AWS SGs provide a robust boundary firewall for EC2 instances. However, this firewall does not eliminate the need for network administrators to keep all external-facing services fully patched.<\/p>\n<p>The default installation for the SSH server also needs extra steps to harden it against attacks, turning it into a rock-solid communication daemon.<\/p>\n<h2>IOC<\/h2>\n<p><strong>Ports open on a local host<\/strong><\/p>\n<ul>\n<li>tcp 2080<\/li>\n<li>udp 2053<\/li>\n<li>tcp 10443<\/li>\n<\/ul>\n<p><strong>Example:<\/strong><\/p>\n<pre style=\"background-color: #fff\">user@host:~$ sudo netstat -peanut | grep \":2080 |:2053 \"  tcp  0  0 0.0.0.0:<mark>2080<\/mark>    0.0.0.0:*    LISTEN  0  34402  2226\/<mark>snoopy<\/mark>  udp  0  0 0.0.0.0:<mark>2053<\/mark>    0.0.0.0:*            0  34398  2224\/<mark>snoopy<\/mark><\/pre>\n<p><strong>To check if these ports are open on a remote compromised host with IP 192.168.5.150:<\/strong><\/p>\n<pre style=\"background-color: #fff\">user@host:~$ sudo nmap 192.168.5.150 -p 2080  ...  PORT     STATE    SERVICE  <mark>2080<\/mark>\/tcp filtered autodesk-nlm<\/pre>\n<pre style=\"background-color: #fff\">user@host:~$ sudo nmap 192.168.5.150 -p 2053 -sU  ...  PORT     STATE    SERVICE  <mark>2053<\/mark>\/udp filtered lot105-ds-upd<\/pre>\n<p><strong>Inbound connections from the remote ports:<\/strong><br \/> <code>1010<\/code>, <code>2020<\/code>, <code>6060<\/code>, <code>7070<\/code>, <code>8080<\/code>, <code>9999<\/code><\/p>\n<p><strong>Domains:<\/strong><\/p>\n<ul>\n<li>cloud[.]newsofnp[.]com<\/li>\n<li>ssl[.]newsofnp[.]com<\/li>\n<li>load[.]CollegeSmooch[.]com<\/li>\n<\/ul>\n<p><strong>IPs:<\/strong><\/p>\n<ul>\n<li>62[.]113[.]255[.]18<\/li>\n<li>89[.]33[.]246[.]111<\/li>\n<li>185[.]86[.]151[.]67<\/li>\n<\/ul>\n<p><strong>Filenames:<\/strong><\/p>\n<ul>\n<li>\/tmp\/rrtserver-lock<\/li>\n<li>\/proc\/sys\/rrootkit<\/li>\n<li>\/tmp\/rrtkernel.ko<\/li>\n<li>\/usr\/bin\/snd_floppy<\/li>\n<\/ul>\n<p><strong>Kernel module:<\/strong><\/p>\n<ul>\n<li>snd_floppy<br \/> <strong>Example:<\/strong><\/p>\n<pre style=\"background-color: #fff\">user@host:~$ sudo lsmod | grep \"snd_floppy\"  <mark>snd_floppy<\/mark> 316594 0  <\/pre>\n<\/li>\n<\/ul>\n<p><strong>Syslog messages:<\/strong><\/p>\n<ul>\n<li><em>&#8220;&#8230;insmod: ERROR: could not insert module \/usr\/bin\/snd_floppy: File exists&#8221;<\/em><\/li>\n<li><em>&#8220;&#8230;kernel: snd_floppy: loading out-of-tree module taints kernel.&#8221;<\/em><\/li>\n<li><em>&#8220;&#8230;kernel: snd_floppy: module verification failed: signature and\/or required key missing \u2013 tainting kernel&#8221;<\/em><\/li>\n<\/ul><\/div>\n<p><a href=\"http:\/\/feedproxy.google.com\/~r\/sophos\/dgdY\/~3\/IHnT34CbOqM\/\" target=\"bwo\" >http:\/\/feeds.feedburner.com\/sophos\/dgdY<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/news.sophos.com\/wp-content\/uploads\/2020\/02\/snoopy_x4_labels-1.png?w=640\"\/><\/p>\n<p><strong>Credit to Author: Sergei Shevchenko| Date: Tue, 25 Feb 2020 13:30:43 +0000<\/strong><\/p>\n<p>In the course of investigating a malware infection of cloud infrastructure servers hosted in the Amazon Web Services (AWS) cloud, SophosLabs discovered a sophisticated attack that employed a unique combination of techniques to evade detection and that permits the malware to communicate freely with its command and control (C2) servers through a firewall that should, [&amp;#8230;]&lt;img src=&#8221;http:\/\/feeds.feedburner.com\/~r\/sophos\/dgdY\/~4\/IHnT34CbOqM&#8221; height=&#8221;1&#8243; width=&#8221;1&#8243; alt=&#8221;&#8221;\/&gt;<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[10378,10377],"tags":[18513],"class_list":["post-17812","post","type-post","status-publish","format-standard","hentry","category-security","category-sophos","tag-sophoslabs-uncut"],"_links":{"self":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts\/17812","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/comments?post=17812"}],"version-history":[{"count":0,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts\/17812\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/media?parent=17812"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/categories?post=17812"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/tags?post=17812"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}