Upload
grutz
View
2.589
Download
0
Embed Size (px)
DESCRIPTION
What's old is what's new - or never been really fixed yet. Web developers still don't get client-side security is no security at all. Presentation given at SyScan Hong Kong conference.
Citation preview
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Web Security Mistakes
Giving the Client Your Trust
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Agenda
• Who Am I?
• Three Examples of Awesome Badness
• Rich Internet Apps (RIA) are not immune
• Internal Apps need review, too
• Q&A
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Who Am I?• Professional Corporate Penetration Tester
(with a CISSP for business purposes) for nearly a decade
• Managed internal PT team for Federal Reserve Bank, now working at Pacific Gas & Electric
• Community contributor to Metasploit
• Developer of NTLM attack toolkit (coming soon)
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
What is Client-Side Security?
Using client-side technology such as JavaScript, Java, Flash, etc to validate data before it is transmitted to the server. Not a new threat but one I regularly see “forgotten” about when performing penetration tests.
“Hiding” data and performing functions within the client that should logically be performed on the server as well.
Not the W3 Client-Side Security document by Lincoln Stein (http://www.w3.org/Security/Faq/wwwsf2.html) Still a good history on what we used to fear before the days of XSS - ActiveX, Java, IE 4.01, etc.
Not talking about DOM security, same-origin policy, VM sandboxes, etc. Only concerned with values the end user can modify.
Specifically, what do I mean by it?
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
http://grutztopia.jingojango.net
How many of these sites used JavaScript to “protect” themselves from SQL Injection?
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
OWASP Top 10 (2007)1. Cross Site Scripting (XSS)2. Injection Flaws3. Insecure Remote File Include4. Insecure Direct Object Reference5. Cross Site Request Forgery (CSRF)6. Information Leakage and Improper Error Handling7. Broken Authentication and Session Management8. Insecure Cryptographic Storage9. Insecure Communications10.Failure to Restrict URL Access
http://www.owasp.org/index.php/Top_10
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
• Not really. Client-Side validation can enhance the user’s experience by not allowing good people to make data entry mistakes. For example:
• BUT…. Should not depend upon it for SECURITY?
• NO! Users can always submit requests from outside of the client, modify in-line, use a proxy, etc.
Is It All Bad?
function validateEmpty(fld) { var error = ""; if (fld.value.length == 0) { fld.style.background = 'Yellow'; error = "The required field has not been filled in.\n" } else { fld.style.background = 'White'; } return error; }
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Agenda
• Who Am I?
• Three Examples of Awesome Badness
• Rich Internet Apps (RIA) are not immune
• Internal Apps need review, too
• Q&A
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Three Examples of Bad
Example 1: Protecting a page location with JavaScript
Example 2: Protecting an application from Input Validation attacks (SQL, XSS, etc)
Example 3: Business Logic flaw
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Real Life Bad Example #1
Encrypted Password Script (from 2001 but still found in use) http://www.dynamicdrive.com/dynamicindex9/password.htm
“JavaScript password scripts have improved substantially over time, with the latest enhancement being an encrypted password, archived using "fuzzy" algorithms. The result are password scripts that won't crumble as soon as the user views the page's source. Use this script to password protect your webpage; based on a simple yet effective encryption method, it's one of the best of its kind.”
Thanks, Garrett Gee!
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
“best of its kind”function submitentry() {password = document.password1.password2.value.toLowerCase()username = document.password1.username2.value.toLowerCase()passcode = 1usercode = 1for(i = 0; i < password.length; i++) {passcode *= password.charCodeAt(i);}for(x = 0; x < username.length; x++) {usercode *= username.charCodeAt(x);}if(usercode==134603040&&passcode==126906300){window.location=password+".htm"} else {alert("password/username combination wrong")}}</script>
<form name="password1"><strong>Enter username: </strong><input type="text" name="username2" size="15"><br><strong>Enter password: </strong><input type="password" name="password2" size="15"><input type="button" value="Submit" onClick="submitentry()"></form>
function calculate(){
passworda = document.password1.user1.value.toLowerCase()passwordb = document.password1.pass1.value.toLowerCase()
var user = 1var pass = 1 for(d=0;d<passwordb.length;d++) {pass*= passwordb.charCodeAt(d);}for(e=0;e< passworda.length; e++) {user *= passworda.charCodeAt(e);}document.password1.outputuser1.value = user;document.password1.outputpass1.value = pass;}
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Breaking “the best”
sub factor { @F = (); $num = shift; foreach $i (97..122) { last if ($num == 1); if (!($num % $i)) { $num /= $i; push @F, chr($i); redo ; } }return @F;}
# thank you internet (and perl)sub perm{@_?map{my$e=$_[$_];map[$e,@{$_}],perm(@_[0..$_-1,$_+1..$#_])}0..$#_:[]}@SOL = factor($_);print "@$_\n" for perm @SOL;
Code by Seth Bromberger
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Lessons LearnedGiving the client everything thing they need to break your security is not any “kind” to be the best of.
Don’t build a castle and then forget to fill the moat with water!
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Real Life Bad Example #2
Me: “Hello, I was using your system and I appear to have discovered an SQL Injection flaw with your site. Here are the details . . .”
Them: Thank you for your assistance.
Answer? WE FIX IN JAVASCRIPT!
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
http://grutztopia.jingojango.net
We have a page with some input boxes...
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
http://grutztopia.jingojango.net
function ValidateDate(z) {
var x = new Boolean(true); if (z != "") { var DatePattern = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/; // MM/DD/YYYY // Date Pattern var TempString = z.match(DatePattern);
if (TempString == null) { x = false; } else { var dayLengths = [31,29,31,30,31,30,31,31,30,31,30,31]; var m = TempString[1], d = TempString[3], y = TempString[4];
if(!((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)) {
dayLengths [1] = 28; }
if (m <= 0 || m > 12 || d <= 0 || d > 31 || y <= 0 || dayLengths[m-1] < d) { x = false; } } } return x;}
function validate(theForm) {
if (!ValidateInt(theForm.NumberOfDays.value)) { alert("The number of days must be an integer value."); theForm.NumberOfDays.focus(); }
else if (!ValidateDate(theForm.StartDate.value)) { alert("The start date must be entered in MM/DD/YYYY format."); theForm.StartDate.focus(); }
else if (!ValidateDate(theForm.EndDate.value)) { alert("The end date must be entered in MM/DD/YYYY format."); theForm.EndDate.focus(); }
else { theForm.submit(); }
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
http://grutztopia.jingojango.net
Using a proxy (like WebScarab, TamperData, etc) the attacker can bypass any client-side validation steps:
Great Great Job!Job!
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Agenda
• Who Am I?
• Three Examples of Awesome Badness
• Rich Internet Apps (RIA) are not immune
• Internal Apps need review, too
• Q&A
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Adobe Flex/AIR
• HTTP requests made by the client to a server-side back end -- but with “Web 2.0”! (XML, SOAP, WSDL, JSON, CSV, etc.)
• Data entry can be “Validated” by the client using mx.validator library (length, SSN, zip, e-mail or regex) prior to sending to the server
• Validation can also be done inside ActionScript (Flex/AIR are simply Shockwave binaries that use the Flash engine)
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Adobe AIR/Flex
$user = urldecode($_REQUEST['username']);$pass = $user = urldecode($_REQUEST['username']);$pass = urldecode($_REQUEST['password']);urldecode($_REQUEST['password']);/* magic_quotes_runtime = on, gpc = off */$sql = "SELECT * FROM /* magic_quotes_runtime = on, gpc = off */$sql = "SELECT * FROM users WHERE username = ‘$user’";$result = @mysql_query($sql);if users WHERE username = ‘$user’";$result = @mysql_query($sql);if (mysql_num_rows($result) == 0) {echo $sql . "\n";echo (mysql_num_rows($result) == 0) {echo $sql . "\n";echo "unknown_user";"unknown_user";} else {$sql = "SELECT * FROM users WHERE username = ‘$user’ } else {$sql = "SELECT * FROM users WHERE username = ‘$user’ AND password = ‘$pass’ LIMIT 1";AND password = ‘$pass’ LIMIT 1";echo $sql . "\n";$result = @mysql_query($sql);if echo $sql . "\n";$result = @mysql_query($sql);if (mysql_num_rows($result) == 0) {echo "login_fail";} else {echo (mysql_num_rows($result) == 0) {echo "login_fail";} else {echo "login_pass";}"login_pass";}
<?xml version="1.0" encoding="utf-8"?> <mx:Application>
<mx:HTTPService id="userRequest" url="http://server/login.php" useProxy="false" method="GET"> <mx:request xmlns=""> <username>{username.text}</username><password>{password.text}</password> </mx:request></mx:HTTPService>
<mx:emailValidator id=”emV” source=”{username}” property=”text”/><mx:StringValidator source=”{password}” property=”text” minLength=”8” maxLength=”25”/>
</mx:Application>
private function validateData():void {var pattern:RegExp = new RegExp("['\"()]+");// Validate the e-mail addressvar result:Object = pattern.exec(username.text);if (result) {myAlert = Alert.show("Letters and numbers only!", "Bad Chars", Alert.OK); return; }// Validate the passwordresult = pattern.exec(password.text);if (result) {myAlert = Alert.show("Letters and numbers only!", "Bad Chars", Alert.OK);return;}// Everything is good, send!userRequest.send();}
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
No Checks? No Good!
$user = urldecode($_REQUEST['username']);$pass = $user = urldecode($_REQUEST['username']);$pass = urldecode($_REQUEST['password']);urldecode($_REQUEST['password']);/* magic_quotes_runtime = on, gpc = off */$sql = "SELECT * FROM /* magic_quotes_runtime = on, gpc = off */$sql = "SELECT * FROM users WHERE username = ‘users WHERE username = ‘$user$user’";$result = @mysql_query($sql);if ’";$result = @mysql_query($sql);if (mysql_num_rows($result) == 0) {echo $sql . "\n";echo (mysql_num_rows($result) == 0) {echo $sql . "\n";echo "unknown_user";"unknown_user";} else {$sql = "SELECT * FROM users WHERE username = ‘} else {$sql = "SELECT * FROM users WHERE username = ‘$user$user’ ’ AND password = ‘AND password = ‘$pass$pass’ LIMIT 1";’ LIMIT 1";echo $sql . "\n";$result = @mysql_query($sql);if echo $sql . "\n";$result = @mysql_query($sql);if (mysql_num_rows($result) == 0) {echo "login_fail";} else {echo (mysql_num_rows($result) == 0) {echo "login_fail";} else {echo "login_pass";}"login_pass";}
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
http://grutztopia.jingojango.net
QuickTime™ and aH.264 decompressor
are needed to see this picture.
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Example 2: Lessons Learned
Javascript, Java, Flash, etc are not good enough to stop Injection, XSS, or other attacks
Validate the data on the server-side!
When you have an SQL Injection and are told about it, fix it in the server code, don’t just mask it.
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Real Life Bad Example #3
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
I’ve got a blue ticket
The flaw: Storing critical data on the client side for validation purposes
The tools: Browser, text editor, password cracker, a little research, and time
The result: A free pass to MacWorld!
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Password Cracking 101
KeyspaceSet of all possible keys that can be used to initialize a crypto algorithm
Key length Size of a key used in a cryptographic algorithm
Brute force attack
Method of defeating a cryptographic scheme by trying a large number of possibilities. Sometimes known as “Incremental”
Dictionary Attack
Method of defeating a cryptographic scheme by using a list of words
Rainbow Tables
A pre-computed lookup table of a keyspace and key length offering a time-memory tradeoff for recovering plaintext
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Step 1 - Hashes!Obtain the MD5 hashes from the source code and format them for processing (John The Ripper and RainbowCrack both can use “userid:password” format):
553:77c34ddea4adf4aa79c69ab471539847554:2476fee59de2c14f3bcc305f84c32209555:1d2863778fb0fe89c9e4c2929e437c14556:90fd53a2967995804bfb3ab639c9f6d0557:d6fdf20e7995d08c2ce75fe2dd943af0558:c47cbb4b92b68d4b9fe85fc0ea4e0042559:d31830730fd84233bdd1bfe1969cb24e560:eac8780bdd7c8d39bda71bb854425b21561:ac910361ffec9261802b907788d446a4562:852c6738e01803f64ac785abe3ae6659563:6e5d4f697d7aa4901460cd0257484176564:fcc66c568b7fd1f7cdde953628238ee1565:cf0c737b854ce6e97654542f200e0f42566:df2fe494621ae661d93e52190086c794567:3c65bb39ee7b2e81
06e9cc375fac804a568:b61818555bc3740a368aa32b5c35a5e6
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Step 2a - Get Crackin’
Run John The Ripper. . .
Run RainbowCrack. . .
Search the hashes on Google. . .
Wait some amount time. . .
Nothing? Time to crack smarter.
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Maths BreakThe size of your keyspace (k) and the maximum word length (l) determine the total number of permutations that have to be encrypted to check every instance (P). P=k^l.
Take the benchmark cracks-per-second your machines do (Cs), run the math (P/Cs) and you have the number of seconds it takes to run an Incremental.
This is a total time required to exhaust the keyspace and length. Randomness and chaos play a big part to achieve a successful crack.
k = 69l = 8
Cs = 30M
698 / 30M
60
285,443.54 minutes
(3.68 months)
k = 69l = 7
Cs = 30M
697 / 30M
60
4,136.86 minutes
(69 hours)
k = 69l = 6Cs = 30M
696 / 30M
60
59.95 minutes
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Step 2b: Learnin’
Brute force password cracking is time consuming. We have no idea the size of the keyspace or the length we’re looking for. If only we could crack a billion MD5 hashes per second. . . .
We can crack smarter however. We know a general format of the codes because free Expo passes are given out by Vendors all the time. A quick Google search:
http://www.google.com/search?hl=en&q=macworld+priority+code+2008
...and then...
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
0 8 - E - V F 0 1
0 8 - G - P C 2 6 0
0 8 - G - P C 1 8 9
Pattern forming?YES!
0 8 - E - V F 0 1
0 8 - G - P C 2 6 0
0 8 - G - P C 1 8 9
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Step 2c: Filterin’
A word filter helps reduce the keyspace and length to a manageable size. Since we have a guess of the plaintext (08-x-y*(z)), restricting the incremental mode to that format will lessen the length and amount of time we’ll need to process.
[Incremental:MW]File = $JOHN/lanman.chrMinLen = 7MaxLen = 7CharCount = 69[List.External:MW]void filter(){ int i, c; i = 0; while (c = word[i]) { // If character is lower case, convert to upper if (c >= 'a' && c <= 'z') word[i] &= 0xDF; i++; } // We know the static filter 08-?-???? // Add or remove word[]s to fit the length word[10] = word[6]; word[9] = word[5]; word[8] = word[4]; word[7] = word[3]; word[6] = word[2]; word[5] = word[1]; word[4] = '-'; word[3] = word[0]; word[2] = '-'; word[1] = '8'; word[0] = '0';}
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Step 3: Smart Crackin’
QuickTime™ and aH.264 decompressor
are needed to see this picture.
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Step 4: Tryin’
QuickTime™ and aH.264 decompressor
are needed to see this picture.
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Example 3: Lessons Learned
This could have been mitigated better if the codes listed only provided Free Expo passes.
Just because you have a longer password doesn’t mean the hash can’t be broken (crack smarter!)
Business logic flaws can be discovered before implementation if you think about the process flow and ask, “Is this secure?”
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
.NET/C# ViewState• ViewState tracks and restores the state of control values that
may be lost because they’re not transferred with the POST form variables.
• Stored as a System.Web.UI.Triplet on the server
• Can be modified and accepted by the app if not MAC signed or encrypted.
• Add the following lines to your web.config or machine.config files:
<%@Page EnableViewStateMAC=true %> <machineKey validation="3DES" validationkey=”somekey” />
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Ruby On Rails 2.0
• The Rails CookieStore session object is used to store session variables in an encrypted browser cookie by default.
• Add these lines to your environment.rb script and use a super-secret secret:
config.action_controller.session = { :session_key => '_cookies2_session',
:secret => 'super-secret secret',
} http://www.rorsecurity.info/2007/11/20/rails-20-cookies/
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Solutions!• Do Not Trust The Client, ever.
• Use client-side validation to improve the customer experience.
• Verify all data on the server before processing.
• Beware of business logic flaws as they are not typically caught by scanning tools. Find them during development/design. Review your workflow and ask yourself “Are we doing this in a secure way? What are my risks?”
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Agenda
• Who Am I?
• Three Examples of Awesome Badness
• Rich Internet Apps (RIA) are not immune
• Internal Apps need review, too
• Q&A
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Web Single-SignOn
• An Enterprise needs Single Sign-On
• Microsoft’s SSO options: NTLM or Microsoft Kerberos
• But NTLM should be deprecated
• Any XSS attack can fully compromise your organization!
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Metasploit NTLM Updates• SMBRelay implemented as MSF exploit
module, only works if user is local administrator of PC and SMB ports are accessible
• NTLM Type Message support added end of ’07
• Attacks can now be performed against HTTP, IMAP, POP3, SMTP or any other service using NTLM authentication (not v2 yet….yet)
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Why not SMB?
• Some locations may deny SMB access except to specific systems (file servers, domain controllers)
• Usually HTTP is not blocked
• Tools freely exist today to take advantage of this!
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
Not entirely new...• LM/NTLM Attacks Through The Ages:
• SMBRelay and SMBRelay2 - SirDystic in 2001, re-implemented for Metasploit in 2007
• L0phtCrack - by L0pht, then @Stake in the 90s
• LM/NTLM downgrade - Cain & Abel, ettercap, etc.
• Jesse Burns (iSec) - HTTP to SMB (no code released) - 2004 @ SyScan
• Scurvy - 2008, HTTP to SMB python code by Eric Rachner
• Metasploit Integration - 2007, by yours truly
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
QuickTime™ and aH.264 decompressor
are needed to see this picture.
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
URLs
• http://grutz.jingojango.net/exploits/pokehashball.html
• http://www.metasploit.com/
• http://www.rachner.us/files/scurvy
• http://www.oxid.it/cain.html
• http://www.owasp.org/
http://grutztopia.jingojango.net
SyScan - May 29, 2008
Giving The Client Your Trust -- Don’t.
QUESTIONS?
THANK YOU!