Today we’ll look at one of the external penetration tests that I carried out earlier this year. Due to the confidentiality agreement, we will use the usual domain of REDACTED.COM
So, to provide a bit of context to the test, it is completely black box with zero information being provided from the customer. The only thing we know is that we are allowed to test redacted.com and the subdomain my.redacted.com
I’ll skip through the whole passive information gathering process and will get straight to the point.
I start actively scanning and navigating through the website to discover potential entry points. There are no ports open other than 80 & 443.
So, I start directory bruteforcing with gobuster and straightaway, I see an admin panel that returns a 403 — Forbidden response.
gobuster
Seeing this, we navigate to the website to verify that it is indeed a 403 and to capture the request with Burp Suite for potential bypasses.
admin panel — 403
In my mind, I am thinking that it will be impossible to bypass this, because there is an ACL for internal IP addresses. Nevertheless, I tried the following to bypass the 403:
HTTP Methods fuzzing (GET, POST, TRACE, HEAD etc.)
Path fuzzing/force browsing (https://redacted.com/admin/index.html, https://redacted.com/admin/./index.html and more)
Protocol version changing (From HTTP 1.2, downgrade to HTTP 1.1 etc.)
String terminators (%00, 0x00, //, ;, %, !, ?, [] etc.) — adding those to the end of the path and inside the path
Long story short, none of those methods worked. So, I remember that sometimes the security controls are built around the literal spelling and case of components within a request. Therefore, I tried the ‘Case Switching’ technique — probably sounds dumb, but it actually worked!
To sum it up:
https://redacted.com/admin -> 403 Forbidden
https://redacted.com/Admin -> 200 OK
https://redacted.com/aDmin -> 200 OK
Swiching any of the letters to a capital one, will bypass the restriction.
Voila! We get a login page to the admin panel.
admin panel — bypassed 403
We get lucky with this one, nevertheless, we are now able to try different attacks (password spraying, brute forcing etc.). The company that we are testing isn’t small and we had collected quite a large number of employee credentials from leaked databases (leak check, leak peek and others). However, this is the admin panel and therefore we go with the usual tests:
See if there is username enumeration
See if there are any login restrictions
Check for possible WAF that will block us due to number of requests
To keep it short, there is neither. We are unable to enumerate usernames, however there is no rate limiting of any sort.
Considering the above, we load rockyou.txt and start brute forcing the password of the ‘admin’ account. After a few thousand attempts, we see the below:
admin panel brute forcing w/ Burp Suite
We found valid credentials for the admin account. Navigate to the website’s admin panel, authenticate and we are in!
Admin panel — successful authentication
Now that we are in, there isn’t much more that we need to do or can do (without the consent of the customer). The admin panel with administrative privileges allows you to change the whole configuration — control the users & their attributes, control the website’s pages, control everything really. So, I decided to write a Python script that scrapes the whole database of users (around 39,300 — thirty nine thousand and three hundred) that contains their names, emails, phones & addresses. The idea to collect all those details is to then present them to the client (victim) — to show the seriousness of the exploited vulnerabilities. Also, due to the severity of those security weaknesses, we wrote a report the same day for those specific issues, which were fixed within 24 hours.
Ultimately, there wasn’t anything too difficult in the whole exploitation process, however the unusual 403 bypass is really something that I see for the first time and I thought that some of you might weaponize this or add it to your future 403 bypass checklists.
Windows ZIP extraction bug (CVE-2022-41049) lets attackers craft ZIP files, which evade warnings on attempts to execute packaged files, even if ZIP file was downloaded from the Internet.
In October 2022, I’ve come across a tweet from 5th July, from @wdormann, who reported a discovery of a new method for bypassing MOTW, using a flaw in how Windows handles file extraction from ZIP files.
Will Dormann @wdormann The ISO in question here takes advantage of several default behaviors: 1) MotW doesn’t get applied to ISO contents 2) Hidden files aren’t displayed 3) .LNK file extensions are always hidden, regardless of the Explorer preference to hide known file extensions.
So if it were a ZIP instead of ISO, would MotW be fine? Not really. Even though Windows tries to apply MotW to extracted ZIP contents, it’s really quite bad at it. Without trying too hard, here I’ve got a ZIP file where the contents retain NO protection from Mark of the Web.
This sounded to me like a nice challenge to freshen up my rusty RE skills. The bug was also a 0-day, at the time. It has already been reported to Microsoft, without a fix deployed for more than 90 days.
What I always find the most interesting about vulnerability research write-ups is the process on how one found the bug, what tools were used and what approach was taken. I wanted this post to be like this.
Now that the vulnerability has been fixed, I can freely publish the details.
Background
What I found out, based on public information about the bug and demo videos, was that Windows, somehow, does not append MOTW to files extracted from ZIP files.
Mark-of-the-web is really another file attached as an Alternate Data Stream (ADS), named
Zone.Identifier
, and it is only available on NTFS filesystems. The ADS file always contains the same content:
[ZoneTransfer]
ZoneId=3
For example, when you download a ZIP file
file.zip
, from the Internet, the browser will automatically add
file.zip:Zone.Identifier
ADS to it, with the above contents, to indicate that the file has been downloaded from the Internet and that Windows needs to warn the user of any risks involving this file’s execution.
This is what happens when you try to execute an executable like a JScript file, through double-clicking, stored in a ZIP file, with MOTW attached.
Clearly the user would think twice before opening it when such popup shows up. This is not the case, though, for specially crafted ZIP files bypassing that feature.
Let’s find the cause of the bug.
Identifying the culprit
What I knew already from my observation is that the bug was triggered when
explorer.exe
process handles the extraction of ZIP files. I figured the process must be using some internal Windows library for handling ZIP files unpacking and I was not mistaken.
ProcessHacker revealed
zipfldr.dll
module loaded within Explorer process and it looked like a good starting point. I booted up IDA with conveniently provided symbols from Microsoft, to look around.
ExtractFromZipToFile
function immediately caught my attention. I created a sample ZIP file with a packaged JScript file, for testing, which had a single instruction:
WScript.Echo("YOU GOT HACKED!!1");
I then added a MOTW ADS file with Notepad and filled it with MOTW contents, mentioned above:
notepad file.zip:Zone.Identifier
I loaded up
x64dbg
debugger, attached it to
explorer.exe
and set up a breakpoint on
ExtractFromZipToFile
. When I double-clicked the JS file, the breakpoint triggered and I could confirm I’m on the right path.
CheckUnZippedFile
One of the function calls I noticed nearby, revealed an interesting pattern in IDA. Right after the file is extracted and specific conditions are meet,
CheckUnZippedFile
function is called, followed by a call to
_OpenExplorerTempFile
, which opens the extracted file.
Having a hunch that
CheckUnZippedFile
is the function responsible for adding MOTW to extracted file, I nopped its call and found that I stopped getting the MOTW warning popup, when I tried executing a JScript file from within the ZIP.
It was clear to me that if I managed to manipulate the execution flow in such a way that the branch, executing this function is skipped, I will be able to achieve the desired effect of bypassing the creation of MOTW on extracted files. I looked into the function to investigate further.
I noticed that
CheckUnZippedFile
tries to combine the TEMP folder path with the zipped file filename, extracted from the ZIP file, and when this function fails, the function quits, skipping the creation of MOTW file.
Considering that I controlled the filename of the extracted ZIP file, I could possibly manipulate its content to trigger
PathCombineW
to fail and as a result achieve my goal.
PathCombineW
turned out to be a wrapper around
PathCchCombineExW
function with output buffer size limit set to fixed value of
260
bytes. I thought that if I managed to create a really long filename or use some special characters, which would be ignored by the function handling the file extraction, but would trigger the length check in
CheckUnZippedFile
to fail, it could work.
I opened 010 Editor, which I highly recommend for any kind of hex editing work, and opened my sample ZIP file with a built-in ZIP template.
I spent few hours testing with different filename lengths, with different special characters, just to see if the extraction function would behave in erratic way. Unfortunately I found out that there was another path length check, called prior to the one I’ve been investigating. It triggered much earlier and prevented me from exploiting this one specific check. I had to start over and consider this path a dead end.
I looked if there are any controllable branching conditions, that would result in not triggering the call to
CheckUnZippedFile
at all, but none of them seemed to be dependent on any of the internal ZIP file parameters. I considered looking deeper into
CheckUnZippedFile
function and found out that when
PathCombineW
call succeeds, it creates a
CAttachmentServices
COM objects, which has its three methods called:
CAttachmentServices::SetReferrer(unsigned short const * __ptr64)
CAttachmentServices::SetSource(unsigned short const * __ptr64)
CAttachmentServices::SaveWithUI(struct HWND__ * __ptr64)
realized I am about to go deep down a rabbit hole and I may spend there much longer than a hobby project like that should require. I had to get a public exploit sample to speed things up.
I managed to copy over all relevant ZIP file parameters from the obtained exploit sample into my test sample and I confirmed that MOTW was gone, when I extracted the sample JScript file.
I decided to dig deeper into
SaveWithUI
COM method to find the exact place where creation of
error, when using the exploit sample and succeeded when using the original, untampered test sample.
It looked like the majority of parameters were constant, as you can see on the screenshot above. The only place where I’d expect anything dynamic was in the structure of
ObjectAttributes
parameter. After closer inspection and half an hour of closely comparing the contents of the parameter structures from two calls, I concluded that both failing and succeeding calls use exactly the same parameters.
This led me to realize that something had to be happening prior to the creation of the ADS file, which I did not account for. There was no better way to figure that out than to use Process Monitor, which honestly I should’ve used long before I even opened IDA 😛.
Backtracking
I set up my filters to only list file operations related to files extracted to TEMP directory, starting with
Temp
prefix.
The test sample clearly succeeded in creating the
Zone.Identifier
ADS file:
While the exploit sample failed:
Through comparison of these two listings, I could not clearly see any drastic differences. I exported the results as text files and compared them in a text editor. That’s when I could finally spot it.
Prior to creating
Zone.Identifier
ADS file, the call to
SetBasicInformationFile
was made with
FileAttributes
set to
RN
.
I looked up what was that
R
attribute, which apparently is not set for the file when extracting from the original test sample and then…
Facepalm
The
R
file attribute stands for
read-only
. The file stored in a ZIP file has the read-only attribute set, which is set also on the file extracted from the ZIP. Obviously when Windows tries to attach the
Zone.Identifier
ADS, to it, it fails, because the file has a read-only attribute and any write operation on it will fail with
ACCESS_DENIED
error.
It doesn’t even seem to be a bug, since everything is working as expected 😛. The file attributes in a ZIP file are set in
ExternalAttributes
parameter of the
ZIPDIRENTRY
structure and its value corresponds to the ones, which carried over from MS-DOS times, as stated in ZIP file format documentation I found online.
4.4.15 external file attributes: (4 bytes)
The mapping of the external attributes is
host-system dependent (see 'version made by'). For
MS-DOS, the low order byte is the MS-DOS directory
attribute byte. If input came from standard input, this
field is set to zero.
4.4.2 version made by (2 bytes)
4.4.2.1 The upper byte indicates the compatibility of the file
attribute information. If the external file attributes
are compatible with MS-DOS and can be read by PKZIP for
DOS version 2.04g then this value will be zero. If these
attributes are not compatible, then this value will
identify the host system on which the attributes are
compatible. Software can use this information to determine
the line record format for text files etc.
4.4.2.2 The current mappings are:
0 - MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)
1 - Amiga 2 - OpenVMS
3 - UNIX 4 - VM/CMS
5 - Atari ST 6 - OS/2 H.P.F.S.
7 - Macintosh 8 - Z-System
9 - CP/M 10 - Windows NTFS
11 - MVS (OS/390 - Z/OS) 12 - VSE
13 - Acorn Risc 14 - VFAT
15 - alternate MVS 16 - BeOS
17 - Tandem 18 - OS/400
19 - OS X (Darwin) 20 thru 255 - unused
4.4.2.3 The lower byte indicates the ZIP specification version
(the version of this document) supported by the software
used to encode the file. The value/10 indicates the major
version number, and the value mod 10 is the minor version
number.
Changing the value of external attributes to anything with the lowest bit set e.g.
0x21
or
0x01
, would effectively make the file read-only with Windows being unable to create MOTW for it, after extraction.
Conclusion
I honestly expected the bug to be much more complicated and I definitely shot myself in the foot, getting too excited to start up IDA, instead of running Process Monitor first. I started with IDA first as I didn’t have an exploit sample in the beginning and I was hoping to find the bug, through code analysis. Bottom line, I managed to learn something new about Windows internals and how extraction of ZIP files is handled.
As a bonus, Mitja Kolsek from 0patch asked me to confirm if their patch worked and I was happy to confirm that it did!
The patch was clean and reliable as seen in the screenshot from a debugger:
I’ve been also able to have a nice chat with Will Dormann, who initially discovered this bug, and his story on how he found it is hilarious:
I merely wanted to demonstrate how an exploit in a ZIP was safer (by way of prompting the user) than that *same* exploit in an ISO. So how did I make the ZIP? I:
1) Dragged the files out of the mounted ISO
2) Zipped them. That's it. The ZIP contents behaved the same as the ISO.
Every mounted ISO image is listing all files in read-only mode. Drag & dropping files from read-only partition, to a different one, preserves the read-only attribute set for created files. This is how Will managed to unknowingly trigger the bug.
Will also made me realize that 7zip extractor, even though having announced they began to add MOTW to every file extracted from MOTW marked archive, does not add MOTW by default and this feature has to be enabled manually.
I mentioned it as it may explain why MOTW is not always considered a valid security boundary. Vulnerabilities related to it may be given low priority and be even ignored by Microsoft for 90 days.
I haven’t yet analyzed how the patch made by Microsoft works, but do let me know if you did and I will gladly update this post with additional information.
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.
Disclaimer
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 —
00:00:0c:07:ac:xx
/ HSRPv2 —
00:00:0C:9F:FX:XX
) (XX is HSRP group number)
MCAST IP addresses. (HSRPv1 —
224.0.0.2
/ HSRPv2 —
224.0.0.102
)
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
224.0.0.18
Its identifier is
112
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 (
00:00:5E:01:XX
). 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.
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
172.16.60.100
Dustup — Windows 10 machine with IP address
172.16.40.1
Attacker (Mercy) — attacker system with Kali Linux at IP address
10.10.10.3
Boundless — Linux Mint client machine with IP address
10.10.10.5
The left side of the Distribution level switches are Cisco vIOS switches: Dist-SW1 and Dist-SW2 at
10.10.10.100
and
10.10.10.101
, 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
<strong>0</strong>
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 10.10.10.100 and 10.10.10.101
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
10.10.10.100
, its priority is
150
STANDBY device is a switch at
10.10.10.101
, its priority is
90
Cryptographic authentication (MD5) is used
Virtual IP address
10.10.10.254
Virtual MAC:
00:00:0c:07:ac:01
(ACTIVE)
HSRP group number
1
Since the ACTIVE switch has a priority of
150
out of
255
— 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
.pcap
format, then use
hsrp2john.py
(in my case the script is called
hsrpexfiltrate.py)
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
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
DAI
may well be surprised that with respect to
10.10.10.254
now has a different MAC-address.
Next, switch our network interface to promiscious mode and allow traffic routing.
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
255
, 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
10.10.10.254,
since we became the new ACTIVE router, we own this virtual address
(10.10.10.254)
, 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
10.10.10.254
, again, after the attack we are the owner of this address.
(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
10.10.10.101
with the special metric, i.e. here with the second route we already realize the floating static routing.
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 —
prayer:sleeper
!!! 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
10.10.10.100
, its priority is
150
Noauthentication
Virtual IP-address
10.10.10.254
Virtual MAC:
00:00:5e:00:01:01
VRRP group number
1
11.2 Stage 2: Injection
Change the MAC-address to the one belonging to MASTER, promisc mode and allow routing:
userIntercepted NetNTLMv2-SSP hash of user distanceWhy 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
224.0.0.2
or
224.0.0.102
,
UDP/1985
VRRP: ACL against
224.0.0.18
GLBP: ACL against
224.0.0.102
,
UDP/3222
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.
Write a class directly to call the decrypt function
cryptTag is
<strong>EnDecryptUtil.getCryptTag()</strong>
obtained by
Parse the persistence-configurations.xml file to get the CryptTag attribute and view the file content
Attempt to
<strong>MLITE_ENCRYPT_DECRYPT</strong>
decrypt unsuccessfully, and then found that an external entity was introduced at the top of the xml file
Finally
<strong>conf\customer-config.xml</strong>
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
<strong>-</strong>
, 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.
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.
The
conf\OpManager\do\RestApi.xml
key APIs that define the workflow are
<strong><em>EXPOSED_API=TRUE</em></strong>
the internal APIs.
At this point, the rce is broken. I traced back the
isInternalAPI()
function and found that all the APIs are in the database
, 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.
Replenish
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
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.
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:
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.
• “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