Update faking strategies

Use random ip4 id for frags, use sequential ip4 id for fakes
This commit is contained in:
Vadim Vetrov
2024-10-12 12:19:33 +03:00
parent 30bc3a8d3f
commit e9b033ccca
14 changed files with 397 additions and 270 deletions

103
utils.c
View File

@@ -418,7 +418,6 @@ int tcp_frag(const uint8_t *pkt, uint32_t buflen, uint32_t payload_offset,
uint8_t *seg1, uint32_t *s1len,
uint8_t *seg2, uint32_t *s2len) {
// struct ip6_hdr *hdr6;
void *hdr;
uint32_t hdr_len;
struct tcphdr *tcph;
@@ -485,6 +484,11 @@ int tcp_frag(const uint8_t *pkt, uint32_t buflen, uint32_t payload_offset,
struct iphdr *s2_hdr = (void *)seg2;
s1_hdr->tot_len = htons(s1_dlen);
s2_hdr->tot_len = htons(s2_dlen);
s1_hdr->id = randint();
s2_hdr->id = randint();
set_ip_checksum(s1_hdr, sizeof(struct iphdr));
set_ip_checksum(s2_hdr, sizeof(struct iphdr));
} else {
struct ip6_hdr *s1_hdr = (void *)seg1;
struct ip6_hdr *s2_hdr = (void *)seg2;
@@ -523,6 +527,19 @@ void z_function(const char *str, int *zbuf, size_t len) {
}
}
void shift_data(uint8_t *data, uint32_t dlen, uint32_t delta) {
uint8_t *ndptr = data + delta + dlen;
uint8_t *dptr = data + dlen;
uint8_t *ndlptr = data;
for (size_t i = dlen + 1; i > 0; i--) {
*ndptr = *dptr;
--ndptr, --dptr;
}
for (size_t i = 0; i < delta; i++) {
*ndlptr++ = 0;
}
}
#define TCP_MD5SIG_LEN 16
#define TCP_MD5SIG_KIND 19
struct tcp_md5sig_opt {
@@ -534,7 +551,7 @@ struct tcp_md5sig_opt {
// Real length of the option, with NOOP fillers
#define TCP_MD5SIG_OPT_RLEN 20
int fail_packet(unsigned int strategy, uint8_t *payload, uint32_t *plen, uint32_t avail_buflen) {
int fail_packet(struct failing_strategy strategy, uint8_t *payload, uint32_t *plen, uint32_t avail_buflen) {
void *iph;
uint32_t iph_len;
struct tcphdr *tcph;
@@ -554,38 +571,29 @@ int fail_packet(unsigned int strategy, uint8_t *payload, uint32_t *plen, uint32_
}
if (strategy == FAKE_STRAT_RAND_SEQ) {
if (strategy.strategy == FAKE_STRAT_RAND_SEQ) {
lgtrace("fake seq: %u -> ", ntohl(tcph->seq));
if (config.fakeseq_offset) {
tcph->seq = htonl(ntohl(tcph->seq) - config.fakeseq_offset);
} else {
#ifdef KERNEL_SPACE
tcph->seq = 124;
#else
tcph->seq = random();
#endif
}
tcph->seq = htonl(ntohl(tcph->seq) - (strategy.randseq_offset + dlen));
lgtrace_addp("%u", ntohl(tcph->seq));
} else if (strategy == FAKE_STRAT_PAST_SEQ) {
} else if (strategy.strategy == FAKE_STRAT_PAST_SEQ) {
lgtrace("fake seq: %u -> ", ntohl(tcph->seq));
tcph->seq = htonl(ntohl(tcph->seq) - dlen);
lgtrace_addp("%u", ntohl(tcph->seq));
} else if (strategy == FAKE_STRAT_TTL) {
lgtrace_addp("set fake ttl to %d", config.faking_ttl);
} else if (strategy.strategy == FAKE_STRAT_TTL) {
lgtrace_addp("set fake ttl to %d", strategy.faking_ttl);
if (ipxv == IP4VERSION) {
((struct iphdr *)iph)->ttl = config.faking_ttl;
((struct iphdr *)iph)->ttl = strategy.faking_ttl;
} else if (ipxv == IP6VERSION) {
((struct ip6_hdr *)iph)->ip6_hops = config.faking_ttl;
((struct ip6_hdr *)iph)->ip6_hops = strategy.faking_ttl;
} else {
lgerror("fail_packet: IP version is unsupported", -EINVAL);
return -EINVAL;
}
} else if (strategy == FAKE_STRAT_TCP_MD5SUM) {
} else if (strategy.strategy == FAKE_STRAT_TCP_MD5SUM) {
int optp_len = tcph_len - sizeof(struct tcphdr);
int delta = TCP_MD5SIG_OPT_RLEN - optp_len;
lgtrace_addp("Incr delta %d: %d -> %d", delta, optp_len, optp_len + delta);
@@ -594,14 +602,9 @@ int fail_packet(unsigned int strategy, uint8_t *payload, uint32_t *plen, uint32_
if (avail_buflen - *plen < delta) {
return -1;
}
uint8_t *ndata = data + delta;
uint8_t *ndptr = ndata + dlen;
uint8_t *dptr = data + dlen;
for (size_t i = dlen + 1; i > 0; i--) {
*ndptr = *dptr;
--ndptr, --dptr;
}
data = ndata;
shift_data(data, dlen, delta);
data += delta;
tcph_len = tcph_len + delta;
tcph->doff = tcph_len >> 2;
if (ipxv == IP4VERSION) {
@@ -629,13 +632,57 @@ int fail_packet(unsigned int strategy, uint8_t *payload, uint32_t *plen, uint32_
}
}
if (ipxv == IP4VERSION) {
((struct iphdr *)iph)->frag_off = 0;
}
set_ip_checksum(iph, iph_len);
set_tcp_checksum(tcph, iph, iph_len);
if (strategy == FAKE_STRAT_TCP_CHECK) {
if (strategy.strategy == FAKE_STRAT_TCP_CHECK) {
lgtrace_addp("break fake tcp checksum");
tcph->check += 1;
}
return 0;
}
int seqovl_packet(uint8_t *payload, uint32_t *plen, uint32_t seq_delta) {
int ipxv = netproto_version(payload, *plen);
void *iph;
uint32_t iph_len;
struct tcphdr *tcph;
uint32_t tcph_len;
uint8_t *data;
uint32_t dlen;
int ret = tcp_payload_split(payload, *plen,
&iph, &iph_len, &tcph, &tcph_len,
&data, &dlen);
if (ret < 0) {
return -1;
}
if (ipxv == IP4VERSION) {
struct iphdr *ip4h = iph;
ip4h->tot_len = htons(ntohs(ip4h->tot_len) + seq_delta);
} else if (ipxv == IP6VERSION) {
struct ip6_hdr *ip6h = iph;
ip6h->ip6_plen = htons(ntohs(ip6h->ip6_plen) + seq_delta);
} else {
return -1;
}
tcph->seq = htons(ntohs(tcph->seq) - seq_delta);
shift_data(data, dlen, seq_delta);
*plen += seq_delta;
set_ip_checksum(iph, iph_len);
set_tcp_checksum(tcph, iph, iph_len);
return 0;
}