监控模式/数据包注入不起作用

问题描述 投票:0回答:1

我正在尝试使用 scapy 在监控模式下将数据包注入到 wifi 网络中。这是我的代码

from scapy.all import *
 
class Dot11EltRates(Packet):
    """ Our own definition for the supported rates field """
    name = "802.11 Rates Information Element"
    # Our Test STA supports the rates 6, 9, 12, 18, 24, 36, 48 and 54 Mbps
    supported_rates = [0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c]
    fields_desc = [ByteField("ID", 1), ByteField("len", len(supported_rates))]
    for index, rate in enumerate(supported_rates):
        fields_desc.append(ByteField("supported_rate{0}".format(index + 1),
                                     rate))
src = "4c:5e:0c:11:01:95"
dst = "d0:39:57:b8:a8:bf"
packet = Dot11(
    addr1=src,
    addr2=dst,
    addr3=src) / Dot11AssoReq(
            cap=0x1100, listen_interval=0x00a) / Dot11Elt(
                ID=0, info="MY_BSSID")
    packet /= Dot11EltRates()
    sendp(packet, iface="wlan0mon")
    packet.show()

我使用

iw list

检查了两张 wifi 卡的费率

此外,两张卡都支持监控模式和数据包注入:使用aircrack-ng套件检查

sudo aireplay-ng <interface> --test
- 都显示

注射起作用了!

然而,当我用一张卡注入一个数据包时,它只在那台计算机上可见,另一张卡看不到它(我为此使用wireshark),我已将两个wifi卡设置为相同的通道和波特率。

我错过了什么?

network-programming scapy packet packet-injection
1个回答
0
投票

好的,我很高兴分享我想出的解决方案。它是用 C 语言编写的,我使用原始套接字和 radiotap 标头来制作合法的数据包。我最初使用的网卡并不完全支持数据包注入。所以,现在我使用 Atheros AR9271 注入数据包,使用 Realtek RTL8812BU 进行嗅探。无论如何,这是注入代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <net/if.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <sys/ioctl.h>
#include <openssl/rand.h>

struct radiotap_header
{
    unsigned char it_version;
    unsigned char it_pad;
    unsigned short it_len;
    unsigned int it_present;
};

struct ieee80211_header
{
    unsigned short frame_control;
    unsigned short duration_id;
    unsigned char addr1[ETHER_ADDR_LEN];
    unsigned char addr2[ETHER_ADDR_LEN];
    unsigned char addr3[ETHER_ADDR_LEN];
    unsigned short seq_ctrl;
};

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s <interface>\n", argv[0]);
        return 1;
    }

    int sockfd;
    struct sockaddr_ll sll;
    char *interface = argv[1];

    sockfd = socket(AF_PACKET, SOCK_RAW, 0); 
    if (sockfd < 0)
    {
        perror("socket");
        return 1;
    }

    struct ifreq if_idx;
    memset(&if_idx, 0, sizeof(struct ifreq));
    strncpy(if_idx.ifr_name, interface, IFNAMSIZ - 1);
    if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
    {
        perror("ioctl");
        return 1;
    }

    memset(&sll, 0, sizeof(sll));
    sll.sll_family = AF_PACKET;
    sll.sll_ifindex = if_idx.ifr_ifindex;
    sll.sll_protocol = htons(ETH_P_ALL);
    if (bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0)
    {
        perror("bind");
        return 1;
    }

    struct radiotap_header radiotap_hdr;
    radiotap_hdr.it_version = 0;
    radiotap_hdr.it_pad = 0;
    radiotap_hdr.it_len = 0x08;
    radiotap_hdr.it_present = 0;

    struct ieee80211_header wifi_hdr;
    wifi_hdr.frame_control = htons(0x0800);
    wifi_hdr.duration_id = htons(0x0000);
    memset(wifi_hdr.addr1, 0xff, 6); 
    memset(wifi_hdr.addr2, 0x11, 6);
    memset(wifi_hdr.addr3, 0x11, 6);
    wifi_hdr.seq_ctrl = htons(0x0000);

    int buffer_size = 1450;
    char *bufferToSend = malloc(buffer_size);
    char *str_to_append = "TestingTestingTesting";
    int str_to_append_len = strlen(str_to_append);
    int packet_size = sizeof(struct radiotap_header) + sizeof(struct ieee80211_header) + buffer_size;
    unsigned char *complete_packet = (unsigned char *)malloc(packet_size);

    if (RAND_poll() != 1)
    {
        printf("RAND_poll");
        return 1;
    }
    if (RAND_bytes(bufferToSend, buffer_size) != 1)
    {
        printf("RAND_bytes");
        return 1;
    }
    strncpy(bufferToSend + (buffer_size - str_to_append_len), str_to_append, str_to_append_len);
    strncpy(bufferToSend, str_to_append, str_to_append_len);

    memcpy(complete_packet, &radiotap_hdr, sizeof(struct radiotap_header));
    memcpy(complete_packet + sizeof(struct radiotap_header), &wifi_hdr, sizeof(struct ieee80211_header));
    memcpy(complete_packet + sizeof(struct radiotap_header) + sizeof(struct ieee80211_header), bufferToSend, buffer_size);

    int ret = write(sockfd, complete_packet, packet_size);
    if (ret < 0)
    {
        perror("write");
        return 1;
    }
    
    printf("Packet sent successfully\n");

    free(complete_packet);
    free(bufferToSend);
    close(sockfd);

    return 0;
}

这是嗅探器:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <linux/if_packet.h>
#include <net/if.h>
#include <signal.h>

static volatile int keep_running = 1;

void int_handler(int dummy) {
    keep_running = 0;
}


struct radiotap_header
{
    unsigned char it_version;
    unsigned char it_pad;
    unsigned short it_len;
    unsigned int it_present;
};

struct ieee80211_header
{
    unsigned short frame_control;
    unsigned short duration_id;
    unsigned char addr1[6];
    unsigned char addr2[6];
    unsigned char addr3[6];
    unsigned short seq_ctrl;
};

size_t bytes_received = 0;

void packet_handler(const unsigned char *packet, int packet_len)
{
    bytes_received += packet_len;
    struct radiotap_header *radiotap_hdr = (struct radiotap_header *)packet;
    struct ieee80211_header *wifi_hdr = (struct ieee80211_header *)(packet + radiotap_hdr->it_len);
    if (packet_len == 1516){
    printf("Packet size: %d\n", packet_len);

    printf("==============================================\n");
    printf("Received packet:\n");
    printf("Frame Control: 0x%04x\n", ntohs(wifi_hdr->frame_control));
    printf("Duration ID: %d\n", ntohs(wifi_hdr->duration_id));
    printf("Address 1: %02x:%02x:%02x:%02x:%02x:%02x\n", wifi_hdr->addr1[0], wifi_hdr->addr1[1], wifi_hdr->addr1[2], wifi_hdr->addr1[3], wifi_hdr->addr1[4], wifi_hdr->addr1[5]);
    printf("Address 2: %02x:%02x:%02x:%02x:%02x:%02x\n", wifi_hdr->addr2[0], wifi_hdr->addr2[1], wifi_hdr->addr2[2], wifi_hdr->addr2[3], wifi_hdr->addr2[4], wifi_hdr->addr2[5]);
    printf("Address 3: %02x:%02x:%02x:%02x:%02x:%02x\n", wifi_hdr->addr3[0], wifi_hdr->addr3[1], wifi_hdr->addr3[2], wifi_hdr->addr3[3], wifi_hdr->addr3[4], wifi_hdr->addr3[5]);
    printf("Sequence Control: 0x%04x\n", ntohs(wifi_hdr->seq_ctrl));
    printf("radiotap_hdr->it_len: %d\n", radiotap_hdr->it_len);
    printf("sizeof(struct ieee80211_header): %d\n", sizeof(struct ieee80211_header));
    int payload_start = radiotap_hdr->it_len + sizeof(struct ieee80211_header);
    int payload_size = packet_len - payload_start;
    
    printf("Payload start: %d\n", payload_start);
    printf("Payload size: %d\n", payload_size);
    
    printf("\n\n");
    printf("Payload at start: \n");
    for (int i = payload_start; i < payload_start + 20; i++){
        printf("%c", packet[i]);
    }

    printf("\n");
    printf("Payload at end: \n");
    for (int i = payload_size - 20; i < packet_len; i++){
        printf("%c", packet[i]);
    }

    printf("\n");
    printf("==============================================\n");
    }
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s <interface>\n", argv[0]);
        return 1;
    }
    signal(SIGINT, int_handler);

    int sockfd;
    struct sockaddr_ll sll;
    char buffer[BUFSIZ];

    sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (sockfd < 0)
    {
        perror("socket");
        return 1;
    }

    memset(&sll, 0, sizeof(sll));
    sll.sll_family = AF_PACKET;
    sll.sll_ifindex = if_nametoindex(argv[1]);

    if (sll.sll_ifindex == 0)
    {
        perror("if_nametoindex");
        return 1;
    }

    if (bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0)
    {
        perror("bind");
        return 1;
    }

    printf("Listening on %s...\n", argv[1]);

    while (keep_running)
    {
        int recv_len = recv(sockfd, buffer, BUFSIZ, 0);
        if (recv_len < 0)
        {
            perror("recv");
            return 1;
        }

        packet_handler((unsigned char *)buffer, recv_len);
    }

    close(sockfd);

    printf("Total bytes received: %zu\n", bytes_received);

    return 0;
}

我使用 openssl 随机标头为有效负载生成随机字节。对于嗅探器来说,packet_handler 中有一个 if ,它是仅针对长度为 1516 的数据包的过滤器(仅过滤我注入的数据包)。

© www.soinside.com 2019 - 2024. All rights reserved.