Brute Ratel v1.0 codename Sicilian Defense is now available for download. This release brings several new feature additions and improvements to the Badger and Commander. The release is focused towards the Egress comms of the badger. There will be a follow up blog, post the release which will showcase the external C2 capabilities. A quick summary of the changes can be found in the release notes.
The main highlight of this release is DNS Over Https. DNS has always been an integral part of Command & Control for red teams. But since the past few years, there is heavy focus on detecting DNS payloads. The primary source of detection for DNS beacons such as Cobaltstrike were DNS logs. When you use a cobaltstrike DNS beacon, it tends to send a lot of DNS queries such as request for A records, TXT records or AAAA records to an external DNS server. These queries contain base64 encoded subdomains which when stacked against an SIEM or Elasticsearch, will provide you a list of all queries which look suspicious from the word go. I remember doing a Red Team in Mandiant a few years back, when we were up against Crowdstrike and Defender ATP and it was almost impossible to use the DNS beacon. This was one of reason why I never bothered adding the DNS feature to the badger, since one can always use fronted domains and redirectors over HTTPS.
However things changed in 2020 when Google and Mozilla decided to support HTTPS DNS Resolvers. In order to support user privacy, these organizations decided to support resolving DNS requests over HTTPS. This means, the actual request to resolve DNS queries will be sent in a POST or a GET request over HTTPS to the resolvers of Google, Cloudfront, Mozilla, OpenDNS or similar other providers. DNS over HTTPS is very common for Google Chrome and Mozilla Firefox. This helps add privacy, which at the same time mean that we can hide our DNS queries inside POST and GET requests which would be sent to one of these DNS Service Providers. Badger provides a highly malleable listener for DOH. Below is the core architecture behind using a DOH badger.
To explain the architecture in short, The badger will always request A records to the DOH Resolver. Let’s take an example of our malicious domain being evasionlabs.com, and our DNS resolver being dns.google. When you execute a DOH badger, it will send a HTTPS request to dns.google and request for a subdomain such as payload.dns1.evasionlabs.com. Since the DOH resolver itself doesn’t have information about these A records, it will try to resolve the request by forwarding it in a chain to evasionlabs.com. On evasionlabs.com, we will create multiple subdomains, namely dns1.evasionlabs.com and dns2.evasionlabs.com. When evasionlabs.com receive the A record request, it will forward the request to it’s local listener on port 53 which is waiting to resolve requests for dns1 and dns2 subdomains. Once the request is received by the listener, it will extract the core subdomain requested i.e. ‘payload’ from payload.dns1.evasionlabs.com, and respond back with another A record. This ‘payload’ is our actual encrypted data from our badger.
Since our listener is highly malleable, we will configure it in such a manner that if there are no commands in queue, it will respond with an IP address called checkin-A, else with an IP called Idle-A. Both these IP addresses (A records) are configurable on the listener profile. Since we have received an A-record request, we cannot send TXT responses yet which will contain our actual encrypted commands. We will simply send checkin-A if we have any commands available, and the next time the badger checks in, it will send a request to fetch TXT records for the subdomain. When our listener receives the request for TXT records, it will then send the actual encrypted commands. Make note that a maximum of 64 bytes per subdomain can be sent per request as that is the RFC limitation and the DOH badgers will be slower as compared to the HTTPS badger. It also means the number of requests to the DOH resolvers will be comparatively high when compared with the HTTP badgers. I’ve used this alongside Slack External C2 during one of my Red Teams in February, and I was able to stage several dotnet executions over it, although the speed was considerably low. A single seatbelt request took around 8-10 minutes to respond back, but hey… who cares right? It just works flawlessly as compared to the painful redirectors and most defenders are not usually suspicious of requests to Google, Mozilla or Cloudfront domains.
To create a DNS Over HTTPS listener, select C4 Profiler->Add DOH Listener
The listener name is autogenerated unless an operator adds it explicitly. The information passed on to create the listener is used to both start a listener and create payloads out of them. The listener bind host takes an IP address which it will bind itself to, on the host. The rotational hosts are servers where the payload checks in. Any number of rotational hosts can be added here. These hosts get embedded in the badger, when you generate them, and is used to randomly switch domains when they check in. This rotational hosts need to be valid HTTP DNS Resolvers such as dns.google, OpenDns, cloudfront and so on. The DOH listener starts on port 53 by default, and the requests by the badgers are sent to port 443 of the DNS resolver in a POST request in HTTPS. The badger configuration can be changed from the Payload Profiler if you want it to send a request elsewhere.
The DNS Hosts takes in the DNS subdomains/hosts which need to be queried. From the above example, this would be dns1 or dns2.evasionlabs.com. Multiple DNS hosts can be added here which need to be resolved. Similarly the rotational hosts also take in multiple dns resolvers like dns.google, OpenDns, cloudfront, mozilla etc. Make sure your resolvers support DOH, else they wont responds to HTTP requests. The URI also has to be specific to the DNS resolvers. Most of the time this will be a static URI i.e. dns-query for all the domains mentioned above. The malleable DOH listener of badger also provide an option to return legitimate TXT record if there is a normal DNS request by blue team.
There is also an optional proxy input. This proxy field is used by the HTTP and DOH badgers for egress connections. The format is basically https://ip:port or http://ip:port. The remaining fields of the DOH Listener are similar to that of the HTTP listener.
Below is a quick example to validate whether your DOH listener is working properly. After starting your DOH listener, send in a DNS request for A and TXT records to validate it is responding as per the configured Idle-A, Checkin-A and Spoofed TXT records. If you get the exact response as configured in the DOH listener, it means they are working properly.
dig @126.96.36.199 dns1.evasionlabs.com # to query A record dig @188.8.131.52 dns2.evasionlabs.com -t TXT # to query TXT record
When working around DOH listeners, its a good idea to temporarily enable debug logs for the DOH server. You can enable/disable debug logs by selecting Server->Enable/Disable DOH Debug Logs in Commander.
The below video provides a demonstration of using DNS Over Https Badgers:
This release comes pre-built with an external Slack C2 which can be used with Brute Ratel. The whole source code repository for Slack C2 is packaged in the new release under the folder name adaptiveC2. As there are more releases in the future, this package will be updated with new external C2s. I will be writing a separate blog on the usage of this alongside the External C2 Specification of Brute Ratel. The below video provides a quick demonstration of the Slack C2.
The Slack C2 package provided in the release package comes with a detailed README file which explains the architecture of the External C2.
In the release v0.7, BRc4 introduced Encrypting of the RX region and sleeping with the use of ROP gadgets and APCs which used the method found by Austin Hudson. However, upon further research, multiple other techniques were found which utilize Windows Event Creation, Wait Objects and Timers. Badger now comes with multiple anti-detection sleeping techniques, such as not using the usual Sleep API, encrypting the RX region with and without using ROP gadgets, and various different types of Wait Object Events and Timers to hide the badger during sleep. Each of these sleeping techniques are a part of all the badgers and the techniques are randomly switched everytime they go to sleep to avoid detection.
The new wmiexec command uses COM to execute a process on the localhost or a target host. Usually, WMI is executed via powershell or wmic.exe, but Microsoft provides COM DLLs which can be used to interact with COM objects. Badger provides set_wmiconfig, get_wmiconfig and reset_wmiconfig to configure the wmi namespace, domain, username and password to interact with remote system. The below figure shows an example of local process creation for the process notepad.exe.
The above figure shows that the parent process is different after creating the process, even though we did not do PPID Spoofing. The reason behind this is COM. When you use COM objects to interact with the WinAPI calls, most of the tasks are performed with WmiPrvSE.exe instead of your own process. A quick look at Sysmon Logs show that notepad.exe was indeed created by WmiPrvSE.exe.
And further going down the rabbit hole shows that WmiPrvSE.exe was launched by DCOM and there is no parent process for it as it was launched by the COM Server.
The WMIExec command can also be used for remote process creation and lateral movement. Below is an example of lateral movement over SMB without creating a new service on the target host. The below figure can be explained as follows:
Note that processes on remote hosts are also created by the COM Server, so your badger would never be a parent process in this case (OPSEC much?).
Badger comes prebuilt with a miniature debugger written in Assembly since v0.9 release which is responsible for Dynamic Obfuscated Syscalls. The detect command, released today uses this feature to hunt down all hooks in a given DLL, similar to what it does when it tries to find the hooked Syscalls. This feature is not limited to just finding the hooks on an API call. It will enumerate the whole memory region recursively, follow any short or long jumps (Qword Ptrs) and any address stored in the registers or data segments [ds:] to hunt jump(short or long), call, pop and ret instructions. It will do this till it eventually finds the final region and entrypoint of the hooked instruction in the target DLL. Below is a quick example of Crowdstrike’s userland DLL ‘umppc14406.dll’ which hooks several Syscalls and NTAPI calls in ntdll.dll.
Kerberoast command now comes built-in, which performs an ASREQ to fetch a kerberos ticket for a valid SPN and return the KRB5 encoded ticket. You can specify any number of SPNs to this command and it will fetch the tickets recursively for all of them. The SPN name has to be in the format of name/host.
This ticket can be decoded and converted to the hashcat format using krb5decoder which is a part of the BRc4 package now.
A graphical File Explorer is introduced in this release which can interact with local and remote file systems. When you select File Explorer from the badger’s context menu, it opens the C: drive by default. You can double click each folder and view the content inside them. The right hand side shows the file names in the selected directory, date modified and the file size. If for some reason, the directory is not accessible, the error would show up in the badger’s console. You can also access network paths by entering them in the location input box in the File Explorer.
The icmp_ping command was something added out of necessity during my last red team engagement. It sends an ICMP request to a target machine to check if its alive or not. If it receives a valid acknowledgement, it returns that the host is alive. Make a note that if firewall is enabled on the host and ICMP is disabled, it will return the host is unreachable.
The Graphical process explorer is now heavily updated and comes with an option to search process directly in the Commander.
Alongside the graphical process manager, the ps and psgrep commands where also updated to show process architecture
The previous version of crisis_monitor only showed User Logon events, but did not show who actually logged in or disconnected. Normally, you would have to use the local_sessions command to view who actually logged in. During my previous Red Team, I faced a situation where my badger went down and I got a notification that some logged in, just before I lost the connection, but could not verify who actually logged in. In order to confirm the event, I decided to merge the local_sessions command with Crisis Monitor. Now if you enable Crisis Monitor, everytime a user logs in, you will get a notification as to which user logged and from where.
The preview command now uses syscall to avoid detections on opening of file handle. This can now be used to circumvent some DLP and Host based IDS where some sensitive files are locked.
This release got a bit delayed due to revamping of the website and the entire documentation which is much more detailed than before. Theres another upcoming release in the next few weeks which will focus on lateral movement and anti-debugging techniques which have never been seen before.