Tuesday, March 9, 2010

Reflection over "How to implement effective security" of Dr.Cole

Dr.Cole's presentation is great. His approaches sound reasonable and practical. Here is his ways to implement effective security:
1) Fully understand your assets. As a security professionals, we should know what we are protecting. Although this seems to be an obvious question, it is a very difficult. Ask yourself this question "what's most important data within my organization? What are five most important business processes dealing with the data?"

2) Reduce the number of vulnerabilities of the systems. The threats are mutating every minute, it is so difficult to catch with bad guys. It is more worthwhile to spend time and efforts reducing attack surface. His idea of "airline security models" is great. It is almost impossible to protect thousands of different machines within one organization. However, the task is easier if the number of different machines is reduced to less than ten. Coupled with strict change management process, we can make the task really manageable.

3)Pay more attention to insider attack. The statistics show that the number of insider attacks almost equal the number of outside attacks. However, only 20% of money and efforts are spent on defense against insider attacks. There are general two types of insider attackers: malicious insiders and unintentional attackers. Malicious insiders intend to harm your organization driven by different factors such as money, revenge, etc. Unintentional attackers are victims who helped bad guys without even knowing what's going on. It might be an employee who clicked a malicious link of within a spear phishing email. Or it might be a help desk technician who happily assist a "so-called" manager on vacation to reset his/her password so that he/she can get some urgent tasks finished. Or, it might be just a customer service representative who is helping his customer using an vulnerable Intranet application which read malicious payload dropped by bad guys. The list goes on and on. The castle can be easily broken down from inside. However, people seem to be reluctant to trust insiders more since we are working for the same company. This is fine. In fact, most organization encourage employee socialization to boost productivity. However, we should also educate the employees about the insider risks and deploy defenses.

4) Correlation, correlation and correlation. The attacks are become more sophisticated as the systems are evolving too. How to detect multiple stage attack? How to detect encrypted payload? The solution is "correlation". Individual events might not be so interesting. But they might suggest something really bad is happening if correlated together. Here is Dr. Cole's example:
  • download some content from a unsafe website
  • Untrusted programs runs
  • Something is changing registry and system files
  • the machine talks to strange outside servers
  • huge amount of data is transferred outside
Putting everything together, it is a classic example of phishing attack with malware targeting to steal data.

5) Pay more attention to outbound traffic. The goal of the attacker is "making money". They want your sensitive data or finding other ways to make money for themselves. Stealing your data is one of most common ways to get them rich. The impact is more serious than denial of service attacks. The data needs to be transferred out of your organization. Pay attention to those outbound connections:
  • Connection using IP address or dynamic DNS
  • Long live connection
  • connection with large amount of traffic
6) Detection is key.

7) Automation is must.


Tuesday, February 23, 2010

AppSec Challenge 9's solution

Ok, the first one is easy and pwd1=OWASP. Next, it is turn to brute force md2, md4 and md5. Unfortunately, C# does not support md2 and md4 due to its security issue. However, a quick Google search find bouncycastle,
http://www.bouncycastle.org/csharp/.

After downloding their library, now it is time to brute force all the hashes one by one.

1) md2, this one is fast:
16189F5462BF906E9D88CF6F152DE86F
Found a Match
password is:GnuOWASP
hash is: 16189F5462BF906E9D88CF6F152DE86F

so, pwd2=Gnu

2) md4, this one is fast too:
FA8F46A6D347087D6980C3FA77DD4DE9
Found a Match
password is:lOOpGnu
hash is: FA8F46A6D347087D6980C3FA77DD4DE9

so, pwd3 = lOOp

3) md5, this one is fast too:
Found a Match
password is:SthlmlOOp
hash is: 425B33D6F60394C897B8413B5C185845

so, pwd4 = Sthlm

4) RIPEMD160, I use System.Security.Cryptography.RIPEMD160. It is fast
35F34671D30472D403937820DCABC1C78C837071
Found a Match
password is:klueSthlm
hash is: 35F34671D30472D403937820DCABC1C78C837071
so pwd5 =klue

5)SHA1, I use System.Security.Cryptography.SHA1 and it is fast:
AE81A30510B2931921934218636B26A803330EB1
Found a Match
password is:ZaQxklue
hash is: AE81A30510B2931921934218636B26A803330EB1

so pwd6 = ZaQx

6) sha256, SHA256 within System.Security.Cryptography is ready to use. This one does take some more than 10 minutes.
B2FF0269E927C6559804A37590A0688C45DF143F85CEE0E3F239F846B65C9644
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
Found a Match
password is:pryLZaQx
hash is: B2FF0269E927C6559804A37590A0688C45DF143F85CEE0E3F239F846B65C9644

pwd7 = pryL
7) GOST3411, bouncycastle already implemented it. And it only took about 10 minutes.
0 0 1 2 3 4 5 6 7 8 9 10 11 12 13
Found a Match
password is:winnapryL
hash is: 16CC9F1FF65688E040F5ADA82A41A258FF948769CDA4C4A17D85228A6F358971

pwd8 = winna


In summary, it is pretty easy to brute force these hashes due to limit length (maximum lenght is five) and not so large character set (52 alpha characters). That's another reason why we should enforce password complexity rules.

The following is the code used to crack these hashes. They are not neat.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Digests;

namespace hashCrack
{
class Program
{
static String md2Hash(String clearText)
{
MD2Digest md2 = new MD2Digest();
byte[] strBytes = Encoding.Default.GetBytes(clearText);
md2.BlockUpdate(strBytes, 0, strBytes.Length);
byte[] hash = new byte[16];
md2.DoFinal(hash, 0);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sBuilder.Append(hash[i].ToString("x2"));
}
return sBuilder.ToString().ToUpper();
}

static String md4Hash(String clearText)
{
MD4Digest md4 = new MD4Digest();
byte[] strBytes = Encoding.Default.GetBytes(clearText);
md4.BlockUpdate(strBytes, 0, strBytes.Length);
byte[] hash = new byte[16];
md4.DoFinal(hash, 0);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sBuilder.Append(hash[i].ToString("x2"));
}
return sBuilder.ToString().ToUpper();
}

static String md5Hash(String clearText)
{
MD5Digest md5 = new MD5Digest();
byte[] strBytes = Encoding.Default.GetBytes(clearText);
md5.BlockUpdate(strBytes, 0, strBytes.Length);
byte[] hash = new byte[16];
md5.DoFinal(hash, 0);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sBuilder.Append(hash[i].ToString("x2"));
}
return sBuilder.ToString().ToUpper();
}
static String gost3411Hash(String clearText)
{
Gost3411Digest gost = new Gost3411Digest();
byte[] strBytes = Encoding.Default.GetBytes(clearText);
gost.BlockUpdate(strBytes, 0, strBytes.Length);
byte[] hash = new byte[32];
gost.DoFinal(hash, 0);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sBuilder.Append(hash[i].ToString("x2"));
}
return sBuilder.ToString().ToUpper();
}


static String ripemd160Hash(String clearText)
{
RIPEMD160 myRIPE = RIPEMD160Managed.Create();
byte[] strBytes = Encoding.Default.GetBytes(clearText);

byte[] hash = myRIPE.ComputeHash(strBytes);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sBuilder.Append(hash[i].ToString("x2"));
}
return sBuilder.ToString().ToUpper();
}


static String sha1Hash(String clearText)
{
byte[] strBytes = Encoding.Default.GetBytes(clearText);
SHA1 sha = new SHA1CryptoServiceProvider();
byte[] hash = sha.ComputeHash(strBytes);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sBuilder.Append(hash[i].ToString("x2"));
}
return sBuilder.ToString().ToUpper();


}

static String sha256Hash(String clearText)
{
byte[] strBytes = Encoding.Default.GetBytes(clearText);
SHA256 shaM = new SHA256Managed();

byte[] hash = shaM.ComputeHash(strBytes);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sBuilder.Append(hash[i].ToString("x2"));
}
return sBuilder.ToString().ToUpper();


}


static void crackRipe()
{
String pwd4 = "Sthlm";
String targetHash = "35F34671D30472D403937820DCABC1C78C837071";

Console.WriteLine(targetHash);
String elements = "abcdefghijklmnopqrstuvwxyz";
elements = elements + elements.ToUpper();

//for (int n = 0; n < elements.Length; n++)
//{
//Console.WriteLine(" " + n);

for (int m = 0; m < elements.Length; m++)
{


for (int k = 0; k < elements.Length; k++)
{

for (int j = 0; j < elements.Length; j++)
{

for (int i = 0; i < elements.Length; i++)
{
// String strTest = elements.Substring(i, 1) + elements.Substring(j, 1) + elements.Substring(k, 1) + elements.Substring(m, 1) + elements.Substring(n, 1) + pwd4;
String strTest = elements.Substring(i, 1) + elements.Substring(j, 1) + elements.Substring(k, 1) + elements.Substring(m, 1) + pwd4;

String hash = ripemd160Hash(strTest);

//Console.WriteLine(" " + strTest);
//Console.WriteLine(" " + hash);

if (hash.Equals(targetHash))
{
Console.WriteLine("Found a Match");
Console.WriteLine("password is:" + strTest);
Console.WriteLine("hash is: " + hash);
}


}
}
}
}
//}




//pwd5 = "klue";
//AE81A30510B2931921934218636B26A803330EB1



}

static void crackSha1()
{
String pwd5 = "klue";
String targetHash = "AE81A30510B2931921934218636B26A803330EB1";

Console.WriteLine(targetHash);
String elements = "abcdefghijklmnopqrstuvwxyz";
elements = elements + elements.ToUpper();

//for (int n = 0; n < elements.Length; n++)
//{
//Console.WriteLine(" " + n);

for (int m = 0; m < elements.Length; m++)
{


for (int k = 0; k < elements.Length; k++)
{

for (int j = 0; j < elements.Length; j++)
{

for (int i = 0; i < elements.Length; i++)
{
// String strTest = elements.Substring(i, 1) + elements.Substring(j, 1) + elements.Substring(k, 1) + elements.Substring(m, 1) + elements.Substring(n, 1) + pwd4;
String strTest = elements.Substring(i, 1) + elements.Substring(j, 1) + elements.Substring(k, 1) + elements.Substring(m, 1) + pwd5;

String hash = sha1Hash(strTest);

//Console.WriteLine(" " + strTest);
//Console.WriteLine(" " + hash);

if (hash.Equals(targetHash))
{
Console.WriteLine("Found a Match");
Console.WriteLine("password is:" + strTest);
Console.WriteLine("hash is: " + hash);
}


}
}
}
}
//}




//pwd5 = "klue";
//



}

static void crackSha256()
{
String pwd6 = "ZaQx";
String targetHash = "B2FF0269E927C6559804A37590A0688C45DF143F85CEE0E3F239F846B65C9644";

Console.WriteLine(targetHash);
String elements = "abcdefghijklmnopqrstuvwxyz";
elements = elements + elements.ToUpper();

//for (int n = 0; n < elements.Length; n++)
//{
//Console.WriteLine(" " + n);

for (int m = 0; m < elements.Length; m++)
{
Console.WriteLine(" " + m);

for (int k = 0; k < elements.Length; k++)
{

for (int j = 0; j < elements.Length; j++)
{

for (int i = 0; i < elements.Length; i++)
{
// String strTest = elements.Substring(i, 1) + elements.Substring(j, 1) + elements.Substring(k, 1) + elements.Substring(m, 1) + elements.Substring(n, 1) + pwd4;
String strTest = elements.Substring(i, 1) + elements.Substring(j, 1) + elements.Substring(k, 1) + elements.Substring(m, 1) + pwd6;

String hash = sha256Hash(strTest);

//Console.WriteLine(" " + strTest);
//Console.WriteLine(" " + hash);

if (hash.Equals(targetHash))
{
Console.WriteLine("Found a Match");
Console.WriteLine("password is:" + strTest);
Console.WriteLine("hash is: " + hash);
}


}
}
}
}
//}








}



static void crackGOST3411()
{
String pwd7 = "pryL";
String targetHash = "16CC9F1FF65688E040F5ADA82A41A258FF948769CDA4C4A17D85228A6F358971";

Console.WriteLine(targetHash);
String elements = "abcdefghijklmnopqrstuvwxyz";
elements = elements + elements.ToUpper();

for (int n = 0; n < elements.Length; n++)
{
Console.WriteLine(" " + n);

for (int m = 0; m < elements.Length; m++)
{
Console.Write(" " + m);

for (int k = 0; k < elements.Length; k++)
{

for (int j = 0; j < elements.Length; j++)
{

for (int i = 0; i < elements.Length; i++)
{
String strTest = elements.Substring(i, 1) + elements.Substring(j, 1) + elements.Substring(k, 1) + elements.Substring(m, 1) + elements.Substring(n, 1) + pwd7;
//String strTest = elements.Substring(i, 1) + elements.Substring(j, 1) + elements.Substring(k, 1) + elements.Substring(m, 1) + pwd7;

String hash = gost3411Hash(strTest);

//Console.WriteLine(" " + strTest);
//Console.WriteLine(" " + hash);

if (hash.Equals(targetHash))
{
Console.WriteLine("Found a Match");
Console.WriteLine("password is:" + strTest);
Console.WriteLine("hash is: " + hash);
}


}
}
}
}
}








}


//

static void Main(string[] args)
{
//String pwd1 = "OWASP";
//String pwd2 = "Gnu";
String pwd3 = "lOOp";
//String targetHash = "FA8F46A6D347087D6980C3FA77DD4DE9";
//crackRipe();
//crackSha1();
//crackSha256();
crackGOST3411();

}


}
}

Some interview techniques

show details 12:06 PM (19 hours ago)

Monday, February 22, 2010

AppSec Research Challenge 9: Crack 'Em Hashes

OWASP just posted its challenge 9:


They gave a list of Hash values:
  • LM(pwd1) 0C04DACA901299DBAAD3B435B51404EE
  • MD2(pwd2 + pwd1) 16189F5462BF906E9D88CF6F152DE86F
  • MD4(pwd3 + pwd2) FA8F46A6D347087D6980C3FA77DD4DE9
  • MD5(pwd4 + pwd3) 425B33D6F60394C897B8413B5C185845
  • RIPEMD160(pwd5 + pwd4) 35F34671D30472D403937820DCABC1C78C837071
  • SHA1(pwd6 + pwd5) AE81A30510B2931921934218636B26A803330EB1
  • SHA256(pwd7 + pwd6) B2FF0269E927C6559804A37590A0688C45DF143F85CEE0E3F239F846B65C9644
  • GOST3411(pwd8 + pwd7) 16CC9F1FF65688E040F5ADA82A41A258FF948769CDA4C4A17D85228A6F358971

Step 1, use Cain to crack LM(pwd1),
pwd1 = OWASP
and that's 1 point

Step 2,

Wednesday, February 10, 2010

How to test Flash Application

If you were interested into testing Flash Application. Here is good article, "A lazy Pen Tester's guide to Testing Flash Application"

How to use urlEncode to encode Request.Url?

Microsoft UrlEncode is designed to encode untrusted data within URL context. It is not meant to encode whole URL. However, sometimes, we do need to encode whole URL. Here is some codes that can do it:

String pagingUrl = string.Empty;
//get the url part without query string
pagingUrl = Request.Url.GetLeftPart(UriPartial.Path) + "?";
NameValueCollection coll = Request.QueryString;

// encode the name and values for all query strings
foreach (String key in coll.Keys)
{
pagingUrl += AntiXss.UrlEncode(key) + "=" + AntiXss.UrlEncode(coll[key]) + "&" ;
}