FluBot Malware Persists: Most Prevalent In Germany and Spain

count_ip vs country

Bitsight has been collecting FluBot infection telemetry data since March 2021. In total, we have identified 1.3 million IPs used by infected Android devices. Last month, it was mostly spread in Germany and Spain. Additionally, we are tracking an increase in IPs over time, which likely indicates an increase in infected devices.

First seen in early 2020, FluBot is a banking trojan used to steal banking, contact, SMS and other types of private data. Its operators have discovered creative means of distributing the malware, evolving their social engineering tactics and delivery methods to fuel the continued growth and expansion of FluBot.

FluBot gives threat actors full remote control of an infected device, including the ability to send, intercept, and hide SMS messages and notifications; exfiltrate user sensitive data, such as contacts, keystrokes, one-time passcodes, and personal information; and carry out overlay attacks.

The malware is commonly spread via SMS messages to the contacts on an infected device as well as contacts downloaded from FluBot’s C2 server. FluBot typically appears as a message for package delivery. Below are some examples:

Malicious SMS Messages

Malicious Text Example Brasil
(source: incibe.es)
Malicious Voicemail Text
(source: switch.ch)
malicious DHL message
(source: incibe.es)
Malicious voicemail message 1
(source: switch.ch)


Bitsight’s Observations

Bitsight currently observes FluBot is mostly spread in Europe, specifically in Germany, Spain and Italy (74%), but also in Australia (7%). This appears to track with recent reports that suggest Flubot operators specifically target different regions or countries. However, it may also be a function of how FluBot spreads. It stands to reason that the majority of a victim’s contacts are people in the same region or country. So, regional infection may not be intentional per se, but rather a consequence of the malware’s design.

Below is a chart showing daily FluBot infections by country that Bitsight has detected since March 2021, highlighting the consistent impact to German and Spanish users.

FluBot infections by country

Since Bitsight began tracking FluBot, we have also seen an increase of impacted IPs. The number of IPs does not directly correspond to the number of infected devices, because a mobile device can share the same IPv4 address as other devices due to network address translation (NAT) and IPv4 exhaustion. However, a rise in IPs may be an indicator of rising device infections.

The following diagrams show our visibility into the geographical distribution of all FluBot versions in January 2022.

count_ip vs country

In January, approximately 170,000 IPs (used by infected devices) contacted our sinkhole infrastructure. The majority of those are infected with FluBot versions 4.8 and earlier. These versions communicate with its C2 server via HTTPS. Since version 4.9, FluBot has communicated with its C2 server via DNS-Tunneling-over-HTTPS (DoH). Of the 170,000 IPs observed in January, approximately 30,000 were infected with FluBot 4.9 through 5.2 (the current version at the time of this writing).

FluBot uses a domain generation algorithm (DGA) to be able to communicate with its C2 server. On version 5.1, there was an update on the DGA (python version on the IOCs section). Changes include a new additional seed that is downloaded from the C2 server to generate more domains.

Using these newer versions, an attacker sets a nameserver that will act as a C2 server, receiving and sending data through the DNS protocol; FluBot uses DoH providers such as Google and Cloudflare to infiltrate and exfiltrate the data to the C2 server, allowing the infected device to communicate with its C2 server without knowing its IP address.

The DNS provider routes the DNS request to the C2 server (nameserver), which returns a TXT DNS response as requested by the bot. The request contains a symmetric key generated by the bot that is RSA encrypted, and the private key is on the C2 server side.

FluBot infections_ 1_3M IPs

Note: The drop reflected in August is due to temporary collection issues.

Mitigating FluBot

While FluBot operators do not appear to be specifically targeting organizations as opposed to individuals, it is still critical for security professionals to take appropriate steps to mitigate risk.

Since FluBot is spread using social engineering, employee education is essential. Share examples of FluBot SMS messages and malicious lure pages so employees know what to look for. Effective employee training can avert FluBot infection entirely.

Anti-malware software should be considered essential to prevent, detect, and remove FluBot infections. FluBot can be removed manually, however, manual removal may be time-consuming—especially if the infection is widespread. Mobile device management (MDM) solutions that can restrict the ability to install apps may be appropriate for some organizations, as well.

Bitsight has identified a number of indicators of compromise (IOC), which are detailed below:

FluBot samples (APKs)











FluBot DGA v3 implemented in Python


import argparse
from datetime import datetime
# https://github.com/MostAwesomeDude/java-random/blob/master/javarandom.py
from javarandom import Random
def get_seed(init, year, month):
   month = month - 1
   j = ((year ^ month) ^ 0)
   j2 = j * 2
   j3 = j2 * (year ^ j2)
   j4 = j3 * (month ^ j3)
   j5 = (j4 * j4) % 2 ** 64
   seed = j5 + init
   return seed
if __name__ == '__main__':
   parser = argparse.ArgumentParser(description='FluBot DGA v3')
       '-s', '--seed', choices=[1949, 1945, 1813, 1136, 2931, 1642, 1905], type=int, required=True)
       '-y', '--year', help='default current year (YYYY)', type=int, required=False)
       '-m', '--month', help='default current month (MM)', type=int, required=False)
   # parse arguments
   args = parser.parse_args()
   seedinit = args.seed
   now = datetime.utcnow()
   if args.year:
       year = args.year
       year = now.year
   if args.month:
       month = args.month
       month = now.month
   r = Random(seed=get_seed(seedinit, year, month))
   tlds = ['ru', 'cn', 'com', 'org',
           'pw', 'net', 'bar', 'host',
           'online', 'space', 'site',
           'xyz', 'website', 'shop',
           'kz', 'md', 'tj', 'pw', 'gdn',
           'am', 'com.ua', 'news', 'email',
           'icu', 'biz', 'kim', 'work',
           'top', 'info', 'br']
   for i in range(2500):
       domain = ''
       for _ in range(15):
           domain += chr(r.nextInt(25) + 97)
       domain = f'{domain}.{tlds[i % len(tlds)]}'


Attack Surface Analytics Report

Request your free custom report and see how you can start reducing your cyber risk exposure across your digital ecosystem: cloud assets across all geos & subsidiaries; discover shadow IT; security risk findings; and more!