В этой небольшой статье рассказывается, как с помощью пары компьютеров, нескольких забавных инструментов и операционной системы получить беспроводной доступ в Интернет везде, где это возможно. Техническую сторону я описал вполне понятно и оснастил комментариями.
1. Введение.
У меня только появился мой первый ноутбук, и я хотел попробовать и сделать что-нибудь непотребное с его помощью (даже пробовал сделать какую-то работу, но это было слишком утомительно
:)). Wardriving по началу был довольно увлекательным занятием, но мне стало скучновато когда я понял, что сети, защищенные
WEP`ом, мне не по зубам (так как внутрисетевого трафика не было – сети можно было считать умершими), а незащищенные сетки вообще не представляют никакого интереса. К счастью, беспроводная сетка в моем студенческом городке оказалась немного более интересной.
Сеть предоставляет бесплатный беспроводной Интернет, но требует регистрации твоего MAC адреса на свое имя перед разрешением доступа – незарегистрированные пользователи переадресовываются на страницу провайдера (на страницу регистрации). Регистрация повлекла бы двухминутное общение с администратором, но я подумал: «Может есть
способ получить доступ избежав подобного общения?» Разумеется, он был.
2.Первый способ проникновения – МАС spoofing.
Поскольку все крутилось вокруг МАС адреса, первое, что пришло на ум,
было узнать уже зарегистрированный МАС адрес и заняться его
спуфингом. Разумеется, говорить легко, но это не требовало почти никаких усилий даже учитывая то, что раньше я этим никогда не занимался.
Первое что я сделал, это запустил kismet ('kismet -c orinoco,eth1,wifi') и поснифал сетку. Kismet сохраняет все поснифанную
информацию в файл ('/var/log/kismet/*.dump' в моем случае), результаты снифинга можно смотреть по мере их
поступления. В результате я смог просмотреть всю информацию и
записать подходящий МАС адрес.
Команды, используемые для смены МАС адреса сетевой карты:
ifconfig eth1 down
killall dhclient
ifconfig hw ether 00:11:22:33:44:55
ifconfig eth1 up
dhclient eth1
Не все команды необходимы, но они бывают очень полезны, когда пытаешься поменять несколько МАС адресов один за другим, что
мне как раз и пригодилось, т.к. МАС адрес, который я пытался сменить, не сработал сразу. Меня забанили, сеть отрубилась и не включалась снова, из-за чего мне пришлось повозиться с немного раздражающими неполадками
в своей системе. Возможно эти неполадки
проявились из-за бажной прошивки, а возможно потому, что в сети уже была сетевая карта с таким МАС-адресом.
Не все рабочие станции были активны, и использование kismet с просмотром результатов по мере поступления было неэффективно, так что я попробовал другой метод.
В сети фильтрация по MAC-адресу была выполнена на довольно высоком уровне. В любой момент я мог получить доступ к сети, т.к. при попытке присоединения я попадал на страницу с предложением зарегистрироваться.
Естественно, по ходу размышлений об активных хостах мне на ум пришел nmap. Так что я запустил проверку IP диапазона на предмет активных станций.
marktwain:~# nmap -sP 10.0.0.1/22
Starting nmap 3.81 ( http://www.insecure.org/nmap/ ) at 2005-05-23 12:54 EEST
Host 10.1.0.14 appears to be up.
MAC Address: 00:0E:35:97:8C:A7 (Intel)
Host 10.1.0.95 appears to be up.
MAC Address: 00:02:2D:4D:1C:43 (Agere Systems)
Host 10.1.0.109 appears to be up.
MAC Address: 00:0D:54:A0:81:39 (3Com Europe)
... snip ...
Host 10.1.2.92 appears to be up.
MAC Address: 00:02:2D:4D:1C:CE (Agere Systems)
Host 10.1.2.187 appears to be up.
MAC Address: 00:02:2D:4D:1C:43 (Agere Systems)
Nmap finished: 1024 IP addresses (20 hosts up) scanned in 53.980 seconds
Куча МАС адресов. Большая часть
получившейся таблицы адресов (как я предполагаю) – МАС-адреса машин, посетивших сеть за последние несколько дней. В таблице было 245 различных МАС
адреса. Я не знаю , нормальное ли это поведение для
точки доступа, но думаю ребятам стоит что-либо
изменить в раздаче Интернета. Как бы там ни было, сейчас у меня есть достаточно МАС-адресов машин, которые посетили сетку, но, вероятнее всего, давно ушли. Пара попыток спуфинга, и я уже плыл к neworder.box.sk...
3. Попытка номер 2 - ICMP-туннелинг.
Я выполнил все, что хотел, но в этой сети еще было где покопаться. Но что
я мог бы сделать, если бы в этой сети не было
бы ни одной машины, принадлежащей мне? Если
бы nmap не открыл и не показал все эти МАС адреса? Так что как бы то ни было, я решил попробовать другой путь получения доступа.
Это не упоминалось ранее, но в обход системы
раздачи Интернета, дающей разрешение, и DHCP, сетка разрешала ICMP сообщениям проходить свободно. Проверка активности любого Интернет сайта работала отлично (действительно не могу понять, почему они ее не заблокировали – разве что забыли), ping
обнаруживался даже на сниффере, который работал на моем сервере.
Мой план был попытаться создать туннель между моим ноутбуком в университете и сервером дома. И пропустить все соединения через него.
Я поискал приложения ICMP туннелинга в Интернете, но ни одно не работало так, как мне бы хотелось (а именно, мне хотелось, чтобы оно было простым – таким, что если я запущу мой любимый браузер или любую другую программу, она будет просто работать с туннелем) или хотя бы
выглядело удобоваримым.
4. Немного кодинга.
Сначала я не планировал что-либо кодить. Просто пробовал некоторые приложения ICMP туннелей
с packetstorm, но тут неожиданно обнаружил, что читаю исходник одного из них, и осознаю, насколько это изумительно просто, и насколько легко будет сделать что-то наподобие. Название программы – itunnel -
обычная утилита для ICMP- туннелинга. Itunnel потрясающий. Но это всего лишь туннель. Вы запускаете ее на одной машине, и в итоге это выглядит так, как будто вы соединили две
сетевых карты вместе. Этого было недостаточно для того, что я хотел сделать.
Я уже слышал о модуле kernel module TUN/TAP, который позволяет процессам пользователя получать и отправлять пакеты информации прямо в/из ядра.
Программа создает виртуальный сетевой интерфейс.
Она создает сетевой интерфейс, который
работает совершенно аналогично
стандартному. Самое интересное то, что
пользовательские программы должны
работать как физический уровень для интерфейса
туннеля. Они должна читать пакеты информации из
файла устройства (например, '/dev/net/tun0') и пересылать их любыми средствами и писать ответные пакеты
обратно в файл.
Я не смог найти ни одного хорошего ресурса
по TUN/TAP, но существует программа – vtun – которая использовала TUN/TAP для своих туннелей, так что я
поюзал исходники vtun. После небольшого исследования выяснилось, что там была крошечная библиотека функций, используемых, чтобы создавать, читать из и писать в tun*
устройства. Зачем мне писать программу самому, если ее можно сделать, исправив пару бит?
Код, который я фактически написал:
#include "driver.h" /*декларируем библиотеку vtun */
#include<string.h>
#include<stdio.h>
/* немного модифицированный main() из itunnel
*/
int run_icmp_tunnel (int id, int packetsize, char *desthost, int tun_fd);
/* максимальный unit – максимальный
размер капсулированного пакета
*/
const int mtu = 1400;
int main(int argc, char **argv) {
char *dev;
int tun_fd = 0;
/* создание tunnel-устройства */
dev = (char *) malloc(16);
if (dev == NULL) {
printf( "если у вас никогда не было проблем с
выделением 16 bytes\"
"памяти – это ваш первый раз. Fatal.n");
return 1;
}
dev[0] = 0;
/* неплохая библиотечная функция
из vtun принимает пустую строку как*
* аргумент, создает tunX девайс и
передает его *dev */
tun_fd = tun_open(dev);
if (tun_fd < 1) {
printf("Не удается создать устройство. Fatal.n");
return 1;
}
else {
printf("Создано тунелинг устройство: %sn", dev);
}
/* 7530 - это ICMP id поле,
используемое для пакетов в туннеле
*/
run_icmp_tunnel(7530, mtu, argv[1], tun_fd);
tun_close(tun_fd, dev);
}
Вот он. И большая его часть – комментарии и проверка ошибок
Как я уже упоминал, itunnel идеальна для строительства туннеля. У нее есть главная функция, которая
открывала файлы для ввода, вывода и socket; так же
получала какие-то параметры для командной строки (что могло пригодиться для моих целей). Далее она вызывала немного абстрактную функцию, которая по существу просто транспортировала пакеты информации. ICMP заголовок свободно
описан в коде и может быть легко изменен на любой другой заголовок,
ввод/вывод/socket может быть настроен по какой-то другой логической схемой – функция будет работать с минимальными корректировками.
Самая большое изменение, которое я сделал – удаление всех манипуляций с командной строкой – по существу удаление нескольких блоков кода. Что наиболее важно для логической схемы туннеля, я удалил различие между вводом и выводом, так как они оба
висят на одном и том же дескрипторе (tunX девайс) –
это дало мне то, что вместо того, чтобы вести себя как
netcat и форвардить stdin в ICMP сокет и ICMP сокет в stdout,
он посылает исходящий сигнал в tunX девайс (как http запросы с браузера) к ICMP
сокет и ICMP сокет вывод (как если бы HTTP
запросы от сервера посылались обратно
через туннель) в tunX девайс (чтобы
возвратится обратно к браузеру). Так как последнее предложение очень длинное и витиеватое, я предоставляю небольшую схему, чтобы показать наглядно:
Ответные пакеты информации идут по той же дорожке, но
обратным путем.
В одном месте я уже достаточно свихнулся и фактически написал новую строку кода. Она выглядит так:
memcpy(&(target->sin_addr.s_addr), &(from.sin_addr.s_addr), 4);
Ее функция – начать отсылать все пакеты информации туда, откуда прибыл последний пакет. Я могу
запустить ее на моем сервере и соединившись
из любого места отослать пакет через туннель
и она мгновенно изменяет IP получателя на IP
моего ноутбука.
То, что получилось в результате, вы можете взять отсюда:
http://p6drad-teel.net/~windo/release/icmp_tunnel.tar.gz
5. Установка туннелей.
Я испытал туннель дома и он работал отлично, но дома не было firewall`a. На следующий день в университете я был готов проверить его в реальной жизни. Случайно, сидя за столиком в кафе, я с помощью спуфинга нашел МАС адрес и установил туннель.
Сложно запомнить все глупые способы, которые я пробовал, и небольшие эксперименты, которые я провел, так что я постарался сделать эту часть как можно более систематизированной. На самом деле я не делал все так четко.
На то, что бы заставить все работать у меня
ушло 3 часа, и я попробовал все, что можно пока занимался сниффингом везде, где только можно, и модифицировал код так, чтобы он скандировал "Pаcket!", когда получает пакет информации, и что-нибудь раздражающее, когда отправляет свой пакет. И так далее.
Я запустил эти команды на сервере:
tsee-diees:~# ./create_tun wifi.ttu.ee
Created tunnel device: tun0
[1]+ Stopped ./create_tun wifi.ttu.ee
tsee-diees:~# ifconfig tun0 mtu 1400 192.168.3.1 up
tsee-diees:~# route add 192.168.3.2 tun0
tsee-diees:~# tethereal -i eth0 -f 'icmp'
Я подумал, что это будет работать немедленно, и просто запустил это на своем ноутбуке:
marktwain:~# ./create_tun 194.204.48.52
Created tunnel device: tun0
[1]+ Stopped ./create_tun 194.204.48.52
marktwain:~# ifconfig tun0 mtu 1400 192.168.3.2 up
marktwain:~# route add 192.168.3.1 tun0
marktwain:~# tethereal -i eth0 -f 'icmp'
То, что мне нужно было сделать – это создать
сеть с двумя хостами на нем – сервер как 192.168.3.1 и ноутбук как 192.168.3.2. Простой нормальный LAN, только его физический слой будет ICMP туннелем. Как вы наверное
поняли из оставшегося текста в статье
способ не особо сработал. Я запустил пинг ('ping 192.168.3.1'), но пакеты все равно не проходили.
К счастью сниффер на ноутбуке дал мне небольшой ключ – пакеты ICMP были обратными ответами. Разумеется, они не
отправлялись. Так что убиваем туннель, включаем itunnel на ноуте и используем обратные ответы icmp (меняем 'icmp->type = 0;' на 'icmp->type = 8;'), возвращаем туннель.
Система все еще не заработала, но на этот раз пакеты
появились на сниффере на сервере.
Что может быть не так? Я попробовал одну модификацию, которая должна была кричать "Pаcket!", когда очередной пакет приходил, но восклицания не
возникало. «А почему, собственно, должно – удивился я, - если firewall установлен блокировать все ICMP пакеты из Интернета?» Через некоторое время я понял, что так и есть на самом деле (все ICMP пакеты из Интернета блокировались).
Уже лучше. Туннель восклицает "Pаcket!" , и ответы можно увидеть на сниффере на сервере. На самом деле, там два ответа на каждый запрос, только один из которых можно увидеть на сниффере на ноутбуке. А пинг до сих пор не работает.
Так как один из двух пакетов избыточный, я указал ядру (kernel) не отвечать на обратные запросы icmp:
tsee-diees:~# echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
И пинги начали проходить! В этот момент я все еще полагался на полученный в ходе спуфинга МАС-адрес, чтобы получить доступ на сервер. Так как идея была получить перемещающиеся в обоих направлениях пакеты со стороны незарегистрированного пользователя, я прекратил спуфить МАС-адреса. При этом туннель продолжил работать, что было довольно приятным сюрпризом.
Поток пакетов удалось наладить, и наступило время заставить «интернет» работать.
Нужно было внести некоторые изменения в IP
роутинг на ноутбуке. Путь через
университетский маршрутизатор беспроводной сети должен был быть заменен туннельным адресом сервера (192.168.3.1 в данном случае). Здесь все еще должен быть путь к серверу, такой, чтобы туннель сам по себе мог работать (туннельным ICMP пакетам тоже нужен путь, чтобы по нему следовать).
Я получил неплохие результаты:
marktwain:~# route add 194.204.48.52 gw 10.0.0.111 # through the wireless router
marktwain:~# route del default
marktwain:~# route add default gw 192.168.3.1 # everything else through the tunnel.
И так как я вроде умный, я подумал, что может быть несовпадение между
числом пакетов, посылаемых на и с сервера. Я запустил пинг
в бекграунде, чтобы отследить ситуацию:.
marktwain:~# ping 194.204.48.52 -i 0.2
PING 194.204.48.52 (194.204.48.52) 56(84) bytes of data.
Разумеется, никаких ответов не было, потому что это не были «туннельные пинги», а ответы с ядра были
выключены.
Так как мой сервер уже был научен
разделять Интернет соединение между несколькими компьютерами, все, что мне надо было сделать на сервере – это добавить два правила для
FORWARD chain в iptables чтобы принимать пакеты из и к tun0. Когда я в плановом порядке проверял текущие правила ('iptables -vL FORWARD'), соединение внезапно умерло. Я повторно соединился и исследовал этот вопрос,
но вскоре соединение снова умерло. Я был действительно удивлен – почему соединение такое неустойчивое?
Подумав я понял, что каждый раз, когда сервер посылал большой ICMP ответ
(ведь только заголовок пинга составлял 1400+), его отбрасывало
само оборудование. Так как туннель был физическим
уровнем IP, TCP естественно пыталось послать пакеты снова, но размер был все тот же, и их все так же отбрасывало. Так что я поменял MTU для туннеля на 300 (в
общем говоря случайно)
marktwain:~# ifconfig tun0 mtu 300
tsee-diees:~# ifconfig tun0 mtu 300
И вся система заработала.
6. Заключение.
А теперь сделай это сам.