Skip to content

The modified TCP packet was successfully sent, but the message before the modification was still retransmitted #100

Open
@BinaryRyan

Description

@BinaryRyan

What I did?

I tried to add a small piece of my own data to the PSH tcp payload, and it can be seen that the transmission was successful and the server was able to respond to the ACK message. However, the Linux kernel seems to have dropped this reply ACK message and continued to send the message I modified before.

send successfully

send successfully

retransmitted

send successfully

Soure Code

int packet_callback(struct nfq_q_handle* qh, struct nfgenmsg* nfmsg,
                    struct nfq_data* nfa, void* data)
{
    struct nfqnl_msg_packet_hdr* ph;
    unsigned char* raw;
    int nfp_len, status;
    struct pkt_buff* pktbuf;
    struct iphdr* iph;
    struct tcphdr* tcph;
    uint16_t seq;
    unsigned char* payload;
    int plen;
    uint32_t verdict = NF_ACCEPT;
    uint8_t local_out = 0;

    ph = nfq_get_msg_packet_hdr(nfa);
    if (!ph)
    {
        printf("error: cannot get nf message packet hdr\n");
        return NF_ACCEPT;
    }

    nfp_len = nfq_get_payload(nfa, &raw);
    if (nfp_len < 0)
    {
        printf("error: invalid payload length %d\n", nfp_len);
        return NF_ACCEPT;
    }

    pktbuf = pktb_alloc(AF_INET, raw, nfp_len, 0x1000);
    if (!pktbuf)
    {
        printf("error: cannot allocate pkt buff\n");
        return NF_ACCEPT;
    }

    iph = nfq_ip_get_hdr(pktbuf);
    if (iph->protocol != IPPROTO_TCP)
    {
        pktb_free(pktbuf);
        return NF_ACCEPT;
    }

    status = nfq_ip_set_transport_header(pktbuf, iph);
    if (status < 0)
    {
        printf("error: cannot set transport header to pkt buff\n");
        pktb_free(pktbuf);
        return NF_ACCEPT;
    }

    tcph = nfq_tcp_get_hdr(pktbuf);
    if (!tcph)
    {
        printf("error: cannot get tcp hdr\n");
        pktb_free(pktbuf);
        return NF_ACCEPT;
    }

    payload = nfq_tcp_get_payload(tcph, pktbuf);
    plen = nfq_get_payload(nfa, &payload);

    const char* rep = "hello server\n";
    if ((local_out = nfq_get_outdev(nfa)))
    {
        uint32_t tcp_plen = get_tcp_payload_len(iph, tcph);
        if (tcph->ack && tcph->psh && !tcph->fin && !tcph->rst&&!injected)
        {
            printf("injected\n");
            nfq_tcp_mangle_ipv4(pktbuf, 0, 0, rep, strlen(rep));
            injected = true;
        }
    }

    _print_conn_info(iph, tcph);
    nfq_ip_set_checksum(iph);
    return nfq_set_verdict(qh, ntohl(ph->packet_id), verdict, pktb_len(pktbuf),
                           pktb_data(pktbuf));
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions