Безопасный сниффинг Wi-Fi трафика при помощи Sniffglue

Безопасный сниффинг Wi-Fi трафика при помощи Sniffglue

Сниффинг сетевых пакетов – один из способов сбора информации о целевой системе без лишних телодвижений.

Сниффинг сетевых пакетов – один из способов сбора информации о целевой системе без лишних телодвижений. Однако этот метод несет в себе риски, если прослушивание происходит в неизвестной сети, поскольку полезная нагрузка внутри перехватываемых пакетов может выполниться в вашей системе. Песочницы, используемые утилитой Sniffglue, как раз позволяют обеспечить дополнительный уровень безопасности.

Пассивное прослушивание является скрытным, эффективным и, как правило, используется на начальной стадии хакерами и пентестерами, собирающими информацию о целевой сети. Однако если вы когда-либо запускали Wireshark от имени суперпользователя, то вероятно сталкивались с предупреждением, поскольку в этом случае ваша система подвергается риску. Запуск программы от имени суперпользователя и последующее компрометирование при помощи уязвимости нулевого дня – реальная угроза, которая существует во время перехвата случайного трафика. Цитата из документации на Wireshark:

«Очень небезопасно запускать Wireshark подобным образом, поскольку все возможные эксплоиты, заточенные под Wireshark, также будут запускаться от имени администратора, и ваша система может оказаться полностью скомпрометированной».

Соответственно, если какой-либо эксплоит под Wireshark уже разработан и известен узкому кругу лиц, то может быть запущен на вашем компьютере от имени суперпользователя в случае, если для Wireshark доступны эти привилегии. Поскольку мы часто сталкиваемся с неопределенностью, при получении разнообразной информации, важно предпринять шаги для минимизации ущерба и возможных неблагоприятных последствий.

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

Для всех, кто занимается снифффингом пакетов, будет интересно узнать, что в Sniffglue эти функции безопасности используются по умолчанию. Эта утилита является средством пассивной разведки, позволяющая прослушивать трафик в сети без риска оказаться обнаруженным. В отличие от ARP-scan и других утилит, использующих активное сканирование, Sniffglue пассивно слушает без каких-либо действий по генерации трафика, позволяющих раскрыть ваше присутствие.

Один из ключевых методов для реализации безопасного сканирования – песочница, которая встроена внутрь Sniffglue. Само по себе приложение не делает ничего лишнего и, соответственно, оберегает себя от эксплоитов. Sniffglue написан на языке Rust, оптимизирован для использования всех доступных ресурсов процессора во время обработки пакетов, наделен дополнительными мерами безопасности и вполне заслуживает внимания.

Что понадобится

Для работы с Sniffglue нужно установить Rust, поскольку программа написана на этом языке программирования. Рекомендую использовать Kali, Ubuntu или другую систему на базе Debian или Arch Linux. Я попробовал запускать Sniffglue в macOS, но столкнулся с трудностями. Вполне вероятно, что Rust у вас уже установлен, поскольку этот язык программирования предустановлен во многих системах.

Например, в системе со свежим дистрибутивом Kali Linux.

Кроме того, нужно установить библиотеки libseccomp-dev и libpcap-dev, предназначенные для модуля безопасных вычислений и парсинга pcap соответственно.

~$ sudo apt-get install libseccomp-dev libpcap-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  libseccomp2
The following packages will be upgraded:
  libseccomp-dev libseccomp2
2 upgraded, 0 newly installed, 0 to remove and 1760 not upgraded.
Need to get 0 B/116 kB of archives.
After this operation, 68.6 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Reading changelogs... Done
(Reading database ... 411760 files and directories currently installed.)
Preparing to unpack .../libseccomp-dev_2.4.2-2_amd64.deb ...
Unpacking libseccomp-dev:amd64 (2.4.2-2) over (2.4.1-2) ...
Preparing to unpack .../libseccomp2_2.4.2-2_amd64.deb ...
Unpacking libseccomp2:amd64 (2.4.2-2) over (2.4.1-2) ...
Setting up libseccomp2:amd64 (2.4.2-2) ...
Setting up libseccomp-dev:amd64 (2.4.2-2) ...
Processing triggers for man-db (2.8.5-2) ...
Processing triggers for libc-bin (2.28-8) ...

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be upgraded:
  libpcap-dev
1 upgraded, 0 newly installed, 0 to remove and 1759 not upgraded.
Need to get 0 B/29.0 kB of archives.
After this operation, 2,048 B of additional disk space will be used.
Reading changelogs... Done
(Reading database ... 411761 files and directories currently installed.)
Preparing to unpack .../libpcap-dev_1.9.1-2_amd64.deb ...
Unpacking libpcap-dev:amd64 (1.9.1-2) over (1.9.0-2) ...
Setting up libpcap-dev:amd64 (1.9.1-2) ...

Шаг 1. Загрузка и установка Sniffglue

Загрузка и запуск Sniffglue осуществляется при помощи менеджера пакетов Cargo (схожим образом Pip предназначен для Python), который появляется по умолчанию после установки Rust. После обновления системы проверьте, установлен ли Cargo, выполнив команду apt install cargo. Должны скомпилироваться множество других пакетов. Затем выполните команду cargo install sniffglue для установки Sniffglue при помощи этого менеджера пакетов или проверьте, установлен Snifglue, что должно произойти после установки Cargo.

~$ apt update

Hit:1 http://archive.linux.duke.edu/kalilinux/kali kali-rolling InRelease
Reading package lists... Done
Building dependency tree
Reading state information... Done
1759 packages can be upgraded. Run 'apt list --upgradable' to see them.

~$ apt install cargo

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following package was automatically installed and is no longer required:
  libgit2-27
Use 'apt autoremove' to remove it.
The following additional packages will be installed:
  libc-bin libc-dev-bin libc-l10n libc6 libc6-dbg libc6-dev libc6-i386
  libgit2-28 locales locales-all
Suggested packages:
  cargo-doc glibc-doc
...
Setting up cargo (0.37.0-3+b1) ...
Setting up libc6-i386 (2.29-3) ...
Setting up libc-dev-bin (2.29-3) ...
Setting up libc6-dev:amd64 (2.29-3) ...
Processing triggers for man-db (2.8.5-2) ...
Processing triggers for libc-bin (2.29-3) ...

~$ cargo install sniffglue

    Updating crates.io index
error: binary `sniffglue` already exists in destination as part of `sniffglue v0.9.0`
Add --force to overwrite

Шаг 2. Запуск Cargo

Теперь мы можем либо добавить Sniffglue в список путей или просто зайти в директорию, куда было установлено это приложение, и запустить напрямую. После запуска мы должны получить перечень команд с описанием, что свидетельствует об присутствии и готовности к запуску Sniffglue

~$ cd ~/.cargo/bin
~/.cargo/bin$ sudo ./sniffglue -h

sniffglue 0.9.0
kpcyrd 
Secure multithreaded packet sniffer

USAGE:
    sniffglue [FLAGS] [OPTIONS] [device]

FLAGS:
    -d, --detailed    Detailed output
    -h, --help        Prints help information
    -j, --json        Json output (unstable)
    -p, --promisc     Set device to promisc
    -r, --read        Open device as pcap file
    -V, --version     Prints version information
    -v, --verbose     Show more packets (maximum: 4)

OPTIONS:
    -n, --cpus     Number of cores

ARGS:
    

Шаг 3. Сниффинг сетевого интерфейса

Приступаем к прослушиванию сетевого интерфейса. Вначале находим имена сетевых карт:

~/.cargo/bin$ ip a | grep MULTICAST

2: enp2s0:  mtu 1500 qdisc fq_codel state UP group default qlen 1000
3: wlp1s0:  mtu 1500 qdisc noqueue state UP group default qlen 1000

Затем запускаем Sniffglue для сниффинга пакетов на нужном интерфейсе:

~/.cargo/bin$ sudo ./sniffglue enp2s0

Listening on device: "enp2s0"

50:7b:9d:7a:c8:8a -> 40:70:09:85:d1:a7, udp 192.168.0.37:57251 -> 209.18.47.62:53 dns req, (A, "null-byte.wonderhowto.com")

50:7b:9d:7a:c8:8a -> 40:70:09:85:d1:a7, udp 192.168.0.37:50381 -> 209.18.47.62:53 dns req, (AAAA, "null-byte.wonderhowto.com")

40:70:09:85:d1:a7 -> 50:7b:9d:7a:c8:8a, udp 209.18.47.62:53 -> 192.168.0.37:57251 dns resp, ("null-byte.wonderhowto.com", A(104.193.19.59))

40:70:09:85:d1:a7 -> 50:7b:9d:7a:c8:8a, udp 209.18.47.62:53 -> 192.168.0.37:50381 dns resp,

В результате прослушивания Ethernet-карты (enp2s0) видные DNS-запросы к сайту Null Byte. Если бы мы подключились к LAN tap или Hak5 Packet Squirrel, то легко могли бы считать любой незашифрованный трафик, проходящий через кабель, к которому у нас есть доступ.

Шаг 4. Сниффинг Wi-Fi в «неразборчивом» режиме

Далее переключаем внимание на беспроводную карту. Вначале, как и в предыдущем шаге, узнаем имя карты:

~/.cargo/bin$ ip a | grep MULTICAST

2: enp2s0:  mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
3: wlp1s0:  mtu 1500 qdisc noqueue state UP group default qlen 1000

Затем в нашей системе запускаем Sniffglue с аргументом –d для более детального просмотра каждого запроса и аргументом –p для перевода карты в «неразборчивый» режим (promiscuous mode). В примере ниже я зашел на сайт «badsite.com» после начала сниффинга беспроводного трафика на карте wlp1s0.

~/.cargo/bin$ sudo ./sniffglue wlp1s0 -d -p

Listening on device: "wlp1s0"
eth: EthernetFrame { source_mac: MacAddress([48, 82, 203, 107, 118, 95]), dest_mac: MacAddress([64, 112, 9, 133, 209, 167]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 73, id: 44379, flags: 2, fragment_offset: 0, ttl: 64, protocol: UDP, chksum: 52279, source_addr: 192.168.0.24, dest_addr: 209.18.47.62 }
        udp: UdpHeader { source_port: 43195, dest_port: 53, length: 53, checksum: 13395 }
            dns: Request(Request { questions: [(A, "googleads.g.doubleclick.net")] })
eth: EthernetFrame { source_mac: MacAddress([64, 112, 9, 133, 209, 167]), dest_mac: MacAddress([48, 82, 203, 107, 118, 95]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 114, id: 51085, flags: 2, fragment_offset: 0, ttl: 57, protocol: UDP, chksum: 47324, source_addr: 209.18.47.62, dest_addr: 192.168.0.24 }
        udp: UdpHeader { source_port: 53, dest_port: 43195, length: 94, checksum: 33904 }
            dns: Response(Response { answers: [("googleads.g.doubleclick.net", CNAME("pagead46.l.doubleclick.net")), ("pagead46.l.doubleclick.net", A(172.217.14.66))] })
eth: EthernetFrame { source_mac: MacAddress([48, 82, 203, 107, 118, 95]), dest_mac: MacAddress([64, 112, 9, 133, 209, 167]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 60, id: 45283, flags: 2, fragment_offset: 0, ttl: 64, protocol: UDP, chksum: 51388, source_addr: 192.168.0.24, dest_addr: 209.18.47.62 }
        udp: UdpHeader { source_port: 33734, dest_port: 53, length: 40, checksum: 35194 }
            dns: Request(Request { questions: [(AAAA, "www.google.com")] })
eth: EthernetFrame { source_mac: MacAddress([64, 112, 9, 133, 209, 167]), dest_mac: MacAddress([48, 82, 203, 107, 118, 95]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 88, id: 41776, flags: 2, fragment_offset: 0, ttl: 57, protocol: UDP, chksum: 56659, source_addr: 209.18.47.62, dest_addr: 192.168.0.24 }
        udp: UdpHeader { source_port: 53, dest_port: 33734, length: 68, checksum: 49539 }
            dns: Response(Response { answers: [("www.google.com", AAAA(2607:f8b0:4007:80c::2004))] })
eth: EthernetFrame { source_mac: MacAddress([48, 82, 203, 107, 118, 95]), dest_mac: MacAddress([64, 112, 9, 133, 209, 167]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 569, id: 20264, flags: 2, fragment_offset: 0, ttl: 64, protocol: TCP, chksum: 30553, source_addr: 192.168.0.24, dest_addr: 172.217.4.164 }
        tcp: TcpHeader { source_port: 46596, dest_port: 443, sequence_no: 766031290, ack_no: 3289351807, data_offset: 8, reserved: 0, flag_urg: false, flag_ack: true, flag_psh: true, flag_rst: false, flag_syn: false, flag_fin: false, window: 229, checksum: 42372, urgent_pointer: 0, options: None }
            tls: ClientHello { hostname: Some("www.google.com") }
eth: EthernetFrame { source_mac: MacAddress([48, 82, 203, 107, 118, 95]), dest_mac: MacAddress([64, 112, 9, 133, 209, 167]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 57, id: 45378, flags: 2, fragment_offset: 0, ttl: 64, protocol: UDP, chksum: 51296, source_addr: 192.168.0.24, dest_addr: 209.18.47.62 }
        udp: UdpHeader { source_port: 48260, dest_port: 53, length: 37, checksum: 40572 }
            dns: Request(Request { questions: [(A, "badsite.com")] })
eth: EthernetFrame { source_mac: MacAddress([64, 112, 9, 133, 209, 167]), dest_mac: MacAddress([48, 82, 203, 107, 118, 95]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 89, id: 8256, flags: 2, fragment_offset: 0, ttl: 57, protocol: UDP, chksum: 24643, source_addr: 209.18.47.62, dest_addr: 192.168.0.24 }
        udp: UdpHeader { source_port: 53, dest_port: 48260, length: 69, checksum: 26142 }
            dns: Response(Response { answers: [("badsite.com", A(104.200.23.95)), ("badsite.com", A(104.200.22.130))] })
eth: EthernetFrame { source_mac: MacAddress([48, 82, 203, 107, 118, 95]), dest_mac: MacAddress([64, 112, 9, 133, 209, 167]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 57, id: 45384, flags: 2, fragment_offset: 0, ttl: 64, protocol: UDP, chksum: 51290, source_addr: 192.168.0.24, dest_addr: 209.18.47.62 }
        udp: UdpHeader { source_port: 57772, dest_port: 53, length: 37, checksum: 61497 }
            dns: Request(Request { questions: [(AAAA, "badsite.com")] })
eth: EthernetFrame { source_mac: MacAddress([64, 112, 9, 133, 209, 167]), dest_mac: MacAddress([48, 82, 203, 107, 118, 95]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 125, id: 46568, flags: 2, fragment_offset: 0, ttl: 57, protocol: UDP, chksum: 51830, source_addr: 209.18.47.62, dest_addr: 192.168.0.24 }
        udp: UdpHeader { source_port: 53, dest_port: 57772, length: 105, checksum: 44123 }
            dns: Response(Response { answers: [] })
eth: EthernetFrame { source_mac: MacAddress([48, 82, 203, 107, 118, 95]), dest_mac: MacAddress([64, 112, 9, 133, 209, 167]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 371, id: 25136, flags: 2, fragment_offset: 0, ttl: 64, protocol: TCP, chksum: 38509, source_addr: 192.168.0.24, dest_addr: 104.200.23.95 }
        tcp: TcpHeader { source_port: 43706, dest_port: 80, sequence_no: 3479674440, ack_no: 2159468974, data_offset: 8, reserved: 0, flag_urg: false, flag_ack: true, flag_psh: true, flag_rst: false, flag_syn: false, flag_fin: false, window: 229, checksum: 33053, urgent_pointer: 0, options: None }
            http: "GET http://badsite.com/ HTTP/1.1" Request { method: "GET", uri: "/", version: "1.1", host: Some("badsite.com"), agent: Some("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"), referer: None, auth: None, cookies: None }
eth: EthernetFrame { source_mac: MacAddress([64, 112, 9, 133, 209, 167]), dest_mac: MacAddress([48, 82, 203, 107, 118, 95]), ethertype: IPv4 }
    ipv4: IPv4Header { version: 4, ihl: 20, tos: 0, length: 1040, id: 62478, flags: 2, fragment_offset: 0, ttl: 53, protocol: TCP, chksum: 3314, source_addr: 104.200.23.95, dest_addr: 192.168.0.24 }
        tcp: TcpHeader { source_port: 80, dest_port: 43706, sequence_no: 2159468974, ack_no: 3479674759, data_offset: 8, reserved: 0, flag_urg: false, flag_ack: true, flag_psh: false, flag_rst: false, flag_syn: false, flag_fin: true, window: 235, checksum: 55524, urgent_pointer: 0, options: None }
            remaining: "HTTP/1.1 302 Found\r\nServer: openresty/1.13.6.1\r\nDate: Mon, 24 Jun 2019 11:52:24 GMT\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 0\r\nConnection: close\r\nLocation: http://www6.badsite.com/?s_token=1561377144.1272041333&kw=Best+Personal+Credit+Cards&term=Best%20Personal%20Credit%20Cards&term=Fast%20Online%20College%20Degrees&term=Job%20Posting%20Boards&term=Movie%20Media%20Server&backfill=0&tdfs=1\r\nX-Mtm-Path: 0\r\nVary: Accept-Language\r\nContent-Language: en\r\nSet-Cookie: mtm_delivered=WyJiYWRzaXRlLmNvbSIsImh0dHA6Ly93d3c2LmJhZHNpdGUuY29tLz9zX3Rva2VuPTE1NjEzNzcxNDQuMTI3MjA0MTMzMyZrdz1CZXN0K1BlcnNvbmFsK0NyZWRpdCtDYXJkcyZ0ZXJtPUJlc3QgUGVyc29uYWwgQ3JlZGl0IENhcmRzJnRlcm09RmFzdCBPbmxpbmUgQ29sbGVnZSBEZWdyZWVzJnRlcm09Sm9iIFBvc3RpbmcgQm9hcmRzJnRlcm09TW92aWUgTWVkaWEgU2VydmVyJmJhY2tmaWxsPTAmdGRmcz0xIiwxLCIyMDE5LTA2LTI0IDExOjUyOjI0IiwiMTU2MTM3NzE0NC4xMjcyMDQxMzMzIiw3NCxudWxsLG51bGxd:1hfNWK:v7-Oji2CCHg8ECfi3-6CthImT5w; expires=Mon, 24-Jun-2019 12:52:24 GMT; Max-Age=3600; Path=/\r\n\r\n"

Всего за несколько секунд прослушивания трафика я узнал об операционной системе, отправляющей запрос, запрашиваемый сайт и даже ответ от сайта, закодированный в HTML. Я даже могу видеть поисковую систему, используемую по умолчанию, для выполнения этого запроса.

Заключение

Благодаря песочнице, используемой в Sniffglue, вы можете изучать сетевую активность и не беспокоиться о потенциальных эксплоитах запущенных от имени суперпользователя, которые могут скомпрометировать вашу систему. Эта утилита очень подходит для пассивной разведки через SSH с выделением только полезной информации. Поскольку Sniffglue, в отличие от многих активных сканеров, не оставляет следов внутри сети, вы можете работать с этой утилитой где угодно без боязни оказаться обнаруженным.
Надеюсь, это руководство, посвященное безопасному сниффингу пакетов, вам понравилось.

Устали от того, что Интернет знает о вас все?

Присоединяйтесь к нам и станьте невидимыми!