Saturday, June 30, 2012

Multifarious Security June 2012


In this blog post I am going to talk on various interesting items on security. I am going to try to do this at least once a month on various tidbits that I hope everyone finds interesting.

  1. Learn about web tracking and Panopticlick. https://panopticlick.eff.org/
  2. Security disclosers are still an issue. We need a Federal mandate to make companies tell employees, customers and investors if PI data has been breached. I wrote about legislation in a past blog post that congress is trying to get passed into a law. It doesn’t look like congress can do it. http://www.huffingtonpost.com/2012/06/29/cybercrime-disclosures-ra_0_n_1637008.html?utm_hp_ref=tw
  3. Check out http://www.openwall.com/ they have the John the Ripper project plus other projects. John the Ripper was just upgraded to use GPU support integrated.
  4. I have blogged about Microsoft’s Azure Cloud on security. Microsoft has a series of videos on Azure security. Everyone should view this series first before diving into the Azure How-to tutorials. http://blogs.technet.com/b/trustworthycomputing/archive/2012/05/22/cloud-fundamentals-video-series-data-center-security.aspx
  5. PGP Creator Phil Zimmermann has a new company. What he did for text and emails he is trying to do for IPhone and IPad users. https://silentcircle.com/
  6. Sad, funny, or both? You decide. http://instagram.com/p/MG2hHRMkSO/
  7. An interesting paper on selling 0-day vulnerabilities. http://securityevaluators.com/files/papers/0daymarket.pdf  
    And https://www.owasp.org/images/b/b7/OWASP_BeNeLux_Day_2011_-_T._Zoller_-_Rise_of_the_Vulnerability_Market.pdf

A few posts back I talked about how much information a system is willing to give up. One of the items was the chip set. Knowing the chip set gives you two distinct advantages. It allows you to date the system. This may help you to decide which vulnerabilities that can be tried first. Second it may help you determine what OS is running on the chip. Well now you have another vulnerability that you can use knowing the chip set. This vulnerability will give you escalated privileges. http://www.kb.cert.org/vuls/id/649219

Saturday, June 23, 2012

.Net Agile Cryptographic Function

A lot has recently been written about the recent LinkedIn hack. I am not going to delve into the details of the hack but I do want to show how you can have an agile cryptographic function for creating hash values. By agile I mean that the code we can use to create our hash value is not hard coded within the program. 
 MD5 is the weakest hashing algorithm we have in the .Net framework. MD5 might be strong enough when our first application was written but now we want to implement a stronger hashing function. We can re-code our application to use windows default hashing function. SHA-1 is the current default hashing algorithm but SHA-1 still doesn’t provide us with the strongest algorithm we can use. So now our boss has told us about the Linkedin hack and has asked us to use SHA512. Using an agile approach we can say “Ok, I can have that done in about 1 hour” without deploying any code. All we have to do is change our app or machine confg file. 

 We can accomplish this by using the following lines of code.


App Code File:



   <add key="HashMethod" value="SHA512"/>

C# Code:

1: preferredHash = HashAlgorithm.Create((string)ConfigurationManager.AppSettings["HashMethod"]);

   2:   
   3:  hash = computeHash(preferredHash, testString);
   4:   
   5:  private string computeHash(HashAlgorithm myHash, string input) {
   6:       byte[] data;
   7:       data = myHash.ComputeHash(Encoding.UTF8.GetBytes(input));
   8:       sb = new StringBuilder();
   9:       for (int i = 0; i < data.Length; i++) {
  10:           sb.Append(data[i].ToString("x2"));
  11:       }
  12:      return sb.ToString();
  13:  }



Line 1 let's us get our hashing algorithm we are going to use from the config file. If we use the machine config file our implementation would be server wide instead of application specific. 

The drawback to this method is key size. I would suggest of giving yourself twice the size of the largest key of hashing algorithm  you could possible use to store hash values. This means we need a varchar of 1024 if we are going to store our hash value in the database.

I will leave it up to the reader to take the hash values through Rainbow tables to see how quickly Raindow tables can return the value of the hash. 

Demo Code:

using System;
using System.Text;
using System.Security.Cryptography;
using System.Configuration;
using System.Collections;

namespace HashDemo {
    class HashTest {

        private MD5 md5Hash;
        private HashAlgorithm cryptoDefaultHash;
        private HashAlgorithm preferredHash;
        private Random random;
        private string testString = string.Empty;
        private string hash;
        private StringBuilder sb;
        private int minSaltSize = 8;
        private int maxSaltSize = 24;
        private int saltSize;

        public HashTest() {
            testString = "MySup3r#Secur3&Pa()sw0rd*";  // My Super Secure Password

            md5Hash = MD5.Create();  // Application hard codes Hash Algorithm. Not good must change code to use a newer Crypto Algorithm.

            cryptoDefaultHash = HashAlgorithm.Create(); // A little better, but uses windows default SHA-1 Crypto Algorithm, but SHA-1 is weak
            ///
            preferredHash = HashAlgorithm.Create((string)ConfigurationManager.AppSettings["HashMethod"]); // Best way is to use app or machine config file to set preferred Crypto Algorithm.
            ///
            Console.WriteLine("The crypto function is: " + md5Hash.GetType() + ".");
            Console.WriteLine("The crypto function is: " + cryptoDefaultHash.GetType() + ".");
            Console.WriteLine("The crypto function is: " + preferredHash.GetType() + ".");
            random = new Random();
            saltSize = random.Next(minSaltSize, maxSaltSize);
        }

        public void test() {
            hash = computeMd5Hash(testString);
            Console.WriteLine("MD5 - The hash is: " + hash + ".");
            hash = computeMd5HashWithSalt(testString);
            Console.WriteLine("MD5 with Salt - The hash is: " + hash + ".");

            hash = computeDefaultHash(cryptoDefaultHash, testString);
            Console.WriteLine("Default hash is: " + hash + ".");
            hash = computeDefaultHashWithSalt(cryptoDefaultHash, testString);
            Console.WriteLine("Default hash with Salt is: " + hash + ".");

            hash = computeHash(preferredHash, testString);
            Console.WriteLine("Preferred hash with Salt is: " + hash + ".");
            hash = computeHashWithSalt(preferredHash, testString);
            Console.WriteLine("Preferred hash with Salt is: " + hash + ".");
        }

        private string computeMd5Hash(string input) {
            byte[] data;
            data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
            sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++) {
                sb.Append(data[i].ToString("x2"));
            }
            return sb.ToString();
        }
        private string computeMd5HashWithSalt(string input) {
            byte[] data;
            data = md5Hash.ComputeHash(GetSalt(input));
            sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++) {
                sb.Append(data[i].ToString("x2"));
            }
            return sb.ToString();
        }
        private string computeDefaultHash(HashAlgorithm myHash, string input) {
            byte[] data;
            data = myHash.ComputeHash(Encoding.UTF8.GetBytes(input));
            sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++) {
                sb.Append(data[i].ToString("x2"));
            }
            return sb.ToString();
        }
        private string computeDefaultHashWithSalt(HashAlgorithm myHash, string input) {
            byte[] data;
            data = myHash.ComputeHash(GetSalt(input));
            sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++) {
                sb.Append(data[i].ToString("x2"));
            }
            return sb.ToString();
        }
        private string computeHash(HashAlgorithm myHash, string input) {
            byte[] data;
            data = myHash.ComputeHash(Encoding.UTF8.GetBytes(input));
            sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++) {
                sb.Append(data[i].ToString("x2"));
            }
            return sb.ToString();
        }
        private string computeHashWithSalt(HashAlgorithm myHash, string input) {
            byte[] data;
            data = myHash.ComputeHash(GetSalt(input));
            sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++) {
                sb.Append(data[i].ToString("x2"));
            }
            return sb.ToString();
        }

        private byte[] GetSalt(string input) {
            byte[] data;
            byte[] saltBytes;
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            saltBytes = new byte[saltSize];
            rng.GetNonZeroBytes(saltBytes);
            data = Encoding.UTF8.GetBytes(input);
            byte[] dataWithSaltBytes =
                new byte[data.Length + saltBytes.Length];
            for (int i = 0; i < data.Length; i++)
                dataWithSaltBytes[i] = data[i];
            for (int i = 0; i < saltBytes.Length; i++)
                dataWithSaltBytes[data.Length + i] = saltBytes[i];
            return dataWithSaltBytes;
        }

        ~HashTest() { // dtor
            preferredHash.Clear();
            cryptoDefaultHash.Clear();
            md5Hash.Clear();
        }
    } // end of class
} // end of namespace

Program Output:

The crypto function is: System.Security.Cryptography.MD5CryptoServiceProvider.
The crypto function is: System.Security.Cryptography.SHA1CryptoServiceProvider.
The crypto function is: System.Security.Cryptography.SHA512Managed.

MD5 - The hash is: 6c27f9f54f905b815e01298ccef39420.
MD5 with Salt - The hash is: 60148ef74c3dbce6ab11c5897f110167.

Default hash is: 636f54fe86c4518308f2599e5f5d8adc72cdc79c.
Default hash with Salt is: 2b223ced9cb488dfe842f3acc32c192c14f0606b.

Preferred hash with Salt is: 48ccbc77e2f280e277ebd871af9871b624c915559f677ba5c16
2d9156e70c46aa5fcc539dec4cc51155101c4e638d226746cc4a7b821bbc5501e104fbeee5eb3.
Preferred hash with Salt is: 6cd578abf2d9b65d621d42fb23e57aede34b401507a4d57d3a7
00d2dbd4f2376b4632a3add3e44c71249e1ed5a4ee293ddfe45efd9e2d0102909d10b74b64483.

Sunday, June 3, 2012

Obtaining Windows security/audit information


We have good reasons to obtain information from our servers for security and audit information. Cyber criminals also have good reasons in needing the same information. Security professionals and code developers also need to understand what information is easily available for the asking. Remember we can’t protect our systems unless we know what to protect. We have to protect our servers, data and applications from unauthorized access. We also have to protect our assets from users trying to escalate their access beyond what has been granted to them. 

The following information can be accessed with a simple program. What information would help a user gain further unauthorized access?

System Environment Information:

   COMPUTERNAME - WIN-39OLKRF40NJ
   VisualStudioDir - \\vmware-host\Shared Folders\Documents\Visual Studio 2008
   HOMEPATH - \Users\User_Name
   LOCALAPPDATA - C:\Users\User_Name\AppData\Local
   PSModulePath - C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
   PROCESSOR_ARCHITECTURE - AMD64
   CommonProgramW6432 - C:\Program Files\Common Files
   CommonProgramFiles(x86) - C:\Program Files (x86)\Common Files
   ProgramFiles(x86) - C:\Program Files (x86)
   PROCESSOR_LEVEL - 6
   LOGONSERVER - \\WIN-39OLKRF40NJ
   USERNAME - User_Name
   HOMEDRIVE - C:
   USERPROFILE - C:\Users\User_Name
   SystemRoot - C:\Windows
   TEMP - C:\Users\USERN~1\AppData\Local\Temp
   PUBLIC - C:\Users\Public
   ALLUSERSPROFILE - C:\ProgramData
   FP_NO_HOST_CHECK - NO
   APPDATA - C:\Users\User_Name\AppData\Roaming
   ProgramData - C:\ProgramData
   PATHEXT - .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
   OS - Windows_NT
   CommonProgramFiles - C:\Program Files\Common Files
   PROCESSOR_IDENTIFIER - Intel64 Family 6 Model 23 Stepping 10, GenuineIntel
   ComSpec - C:\Windows\system32\cmd.exe
   SESSIONNAME - Console
   SystemDrive - C:
   PROCESSOR_REVISION - 170a
   ProgramFiles - C:\Program Files
   NUMBER_OF_PROCESSORS - 1
   VS90COMNTOOLS - C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\
   WecVersionForRosebud.268 - 2
   TMP - C:\Users\USERN~1\AppData\Local\Temp
   ProgramW6432 - C:\Program Files
   USERDOMAIN - WIN-39OLKRF40NJ
   windir - C:\WindowsEnvironment.SpecialFolder: C:\Windows\system32
   LogicalDrives: A:\, C:\, D:\, Z:\

   System Path:

   C:\Windows\system32
   C:\Windows
   C:\Windows\System32\Wbem
   C:\Windows\System32\WindowsPowerShell\v1.0\
   c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\
   c:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\

   Chipset information in Win Registry GenuineIntel running at 2522 MHz.
  
   Oem Id: 9
   Page Size: 4096
   Minimum Application Address: 65536
   Maximum Application Address: 0
   ProcessorMask: 4294901759
   Number Of Processors: 2047
   Processor Type: 1
   Allocation Granularity: 0
   Processor Level:  1
  
   Current Windows user log in:  WIN-39OLKRF40NJ\User_Name
   -----------------------------------Win32_UserAccount instance
   Caption: WIN-39OLKRF40NJ\Administrator
   Description: Built-in account for administering the computer/domain
   Domain: WIN-39OLKRF40NJ
   FullName:
   LocalAccount: True
   Lockout: False
   Name: Administrator
   PasswordChangeable: True
   PasswordExpires: False
   PasswordRequired: True
  
   Caption: WIN-39OLKRF40NJ\Guest
   Description: Built-in account for guest access to the computer/domain
   Domain: WIN-39OLKRF40NJ
   FullName:
   LocalAccount: True
   Lockout: False
   Name: Guest
   PasswordChangeable: False
   PasswordExpires: False
   PasswordRequired: False
  
   Caption: WIN-39OLKRF40NJ\User_Name
   Description:
   Domain: WIN-39OLKRF40NJ
   FullName:
   LocalAccount: True
   Lockout: False
   Name: User_Name
   PasswordChangeable: True
   PasswordExpires: True
   PasswordRequired: True
  
   -----------------------------------ACL Registry Info - Current access rules:
   User: CREATOR OWNER
   Type: Allow
   Rights: 268435456
   Inheritance: ContainerInherit
   Propagation: InheritOnly
   Inherited? False
  
   User: NT AUTHORITY\SYSTEM
   Type: Allow
   Rights: 268435456
   Inheritance: ContainerInherit
   Propagation: InheritOnly
   Inherited? False
  
   User: NT AUTHORITY\SYSTEM
   Type: Allow
   Rights: FullControl
   Inheritance: None
   Propagation: None
   Inherited? False
  
   User: BUILTIN\Administrators
   Type: Allow
   Rights: 268435456
   Inheritance: ContainerInherit
   Propagation: InheritOnly
   Inherited? False
  
   User: BUILTIN\Administrators
   Type: Allow
   Rights: FullControl
   Inheritance: None
   Propagation: None
   Inherited? False
  
   User: BUILTIN\Users
   Type: Allow
   Rights: -2147483648
   Inheritance: ContainerInherit
   Propagation: InheritOnly
   Inherited? False
  
   User: BUILTIN\Users
   Type: Allow
   Rights: ReadKey
   Inheritance: None
   Propagation: None
   Inherited? False






using System;
using System.Collections;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Security.Principal;
using System.Management;
using System.Security.AccessControl;

namespace env
{
    public class SystemEnvironement : System.Windows.Forms.Form {
        private System.Windows.Forms.TextBox textBox1;
        WindowsPrincipal wp;
        String DomainName;

        [StructLayout(LayoutKind.Sequential)]
        public struct SYSTEM_INFO {
            public uint dwOemId;
            public uint dwPageSize;
            public uint lpMinimumApplicationAddress;
            public uint lpMaximumApplicationAddress;
            public uint dwActiveProcessorMask;
            public uint dwNumberOfProcessors;
            public uint dwProcessorType;
            public uint dwAllocationGranularity;
            public uint dwProcessorLevel;
            public uint dwProcessorRevision;
        }

        [DllImport("kernel32")]
        static extern void GetSystemInfo(ref SYSTEM_INFO pSI);

        public SystemEnvironement() {
            this.SuspendLayout();
            InitForm();
            SystemInformation();
        }

        private void InitForm() {
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.textBox1.Location = new System.Drawing.Point(12, 12);
            this.textBox1.Multiline = true;
            this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.textBox1.Size = new System.Drawing.Size(560, 740);
            this.textBox1.TabIndex = 1;
            this.ClientSize = new System.Drawing.Size(584, 757);
            this.Controls.Add(this.textBox1);
        }

        private void SystemInformation() {
            string[] pathparts;
            textBox1.Text += "System Environment Information: \r\n";
            IDictionary environmentVariables = Environment.GetEnvironmentVariables();
            foreach (DictionaryEntry de in environmentVariables) {
                if (!de.Key.Equals("Path")) {
                    textBox1.Text += "\r\n   " + de.Key + " - " + de.Value;
                }
                if (de.Key.Equals("USERDOMAIN")) {
                     DomainName = de.Value.ToString();
                }

            }
            textBox1.Text += "Environment.SpecialFolder: " + Environment.GetFolderPath(Environment.SpecialFolder.System);
   
            String[] drives = Environment.GetLogicalDrives();

            textBox1.Text += "\r\n   LogicalDrives: " + String.Join(", ", drives);
            textBox1.Text += "\r\n\r\n   System Path: \r\n";
            pathparts = Environment.GetEnvironmentVariable("PATH").Split(new[] { System.IO.Path.PathSeparator   });
            int max = pathparts.Length - 1;
            for (int i = 0; i < max; i++) {
                 textBox1.Text += "\r\n   " + pathparts[i];
            }

            RegistryKey RegKey = Registry.LocalMachine;
            RegKey = RegKey.OpenSubKey("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
            Object cpuSpeed = RegKey.GetValue("~MHz");
            Object cpuType  = RegKey.GetValue("VendorIdentifier");
            textBox1.Text += "\r\n\r\n   Chipset information in Win Registry " + cpuType + " running at " + cpuSpeed  + " MHz.";
            textBox1.Text += "\r\n   ";

            try {
                SYSTEM_INFO sysInfo = new SYSTEM_INFO();
                GetSystemInfo(ref sysInfo);
                textBox1.Text += "\r\n   " + "Oem Id: " + sysInfo.dwOemId;
                textBox1.Text += "\r\n   " + "Page Size: " + sysInfo.dwPageSize;
                textBox1.Text += "\r\n   " + "Minimum Application Address: " + sysInfo.lpMinimumApplicationAddress;
                textBox1.Text += "\r\n   " + "Maximum Application Address: " + sysInfo.lpMaximumApplicationAddress;
                textBox1.Text += "\r\n   " + "ProcessorMask: " + sysInfo.dwActiveProcessorMask;
                textBox1.Text += "\r\n   " + "Number Of Processors: " + sysInfo.dwNumberOfProcessors;
                textBox1.Text += "\r\n   " + "Processor Type: " + sysInfo.dwProcessorType;
                textBox1.Text += "\r\n   " + "Allocation Granularity: " + sysInfo.dwAllocationGranularity;
                textBox1.Text += "\r\n   " + "Processor Level:  " + sysInfo.dwProcessorLevel;
                
            }
            catch (Exception e) {
                Console.WriteLine(e.ToString());
            }
            textBox1.Text += "\r\n   ";
            textBox1.ReadOnly = true;
            wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
            textBox1.Text += "\r\n   " + "Current Windows user log in:  " + wp.Identity.Name;

            textBox1.Text += "\r\n   ";
            ManagementObjectSearcher mSearcher = new ManagementObjectSearcher("root\\CIMV2","SELECT * FROM Win32_UserAccount");
            try {
              textBox1.Text += "-----------------------------------";
              textBox1.Text += "Win32_UserAccount instance";
              foreach (ManagementObject queryObj in mSearcher.Get()) {
                  textBox1.Text += "\r\n   " + "Caption: " + queryObj["Caption"].ToString();
                  textBox1.Text += "\r\n   " + "Description: " + queryObj["Description"].ToString();
                  textBox1.Text += "\r\n   " + "Domain: " + queryObj["Domain"].ToString();
                  textBox1.Text += "\r\n   " + "FullName: " + queryObj["FullName"].ToString();
                  textBox1.Text += "\r\n   " + "LocalAccount: " + queryObj["LocalAccount"].ToString();
                  textBox1.Text += "\r\n   " + "Lockout: " + queryObj["Lockout"].ToString();
                  textBox1.Text += "\r\n   " + "Name: " + queryObj["Name"].ToString();
                  textBox1.Text += "\r\n   " + "PasswordChangeable: " + queryObj["PasswordChangeable"].ToString();
                  textBox1.Text += "\r\n   " + "PasswordExpires: " + queryObj["PasswordExpires"].ToString();
                  textBox1.Text += "\r\n   " + "PasswordRequired: " + queryObj["PasswordRequired"].ToString();
                  textBox1.Text += "\r\n   ";
                }
              textBox1.Text += "\r\n   ";
            }
            catch (Exception ex) {
                Console.WriteLine(ex.ToString());
            }
            textBox1.Text += "-----------------------------------";
            textBox1.Text += "ACL Registry Info - Current access rules:";
            RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\");
            RegistrySecurity rSec = rk.GetAccessControl();
            foreach (RegistryAccessRule ar in rSec.GetAccessRules(true, true, typeof(NTAccount))) {
                textBox1.Text += "\r\n   " + "User: " + ar.IdentityReference;
                textBox1.Text += "\r\n   " + "Type: " + ar.AccessControlType;
                textBox1.Text += "\r\n   " + "Rights: " + ar.RegistryRights;
                textBox1.Text += "\r\n   " + "Inheritance: " + ar.InheritanceFlags;
                textBox1.Text += "\r\n   " + "Propagation: " + ar.PropagationFlags;
                textBox1.Text += "\r\n   " + "Inherited? " + ar.IsInherited;
                textBox1.Text += "\r\n   ";
            }

        }
 
        static void Main(string[] args)
        {
            Application.Run(new SystemEnvironement());

        } // end of main    
    } // end of class
} // end of namespace