You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
422 lines
12 KiB
422 lines
12 KiB
//
|
|
// Created by conntrack on 4/30/23.
|
|
//
|
|
|
|
|
|
#include "netguard.h"
|
|
|
|
struct ng_session *debug_socket;
|
|
|
|
|
|
const char* debug_src_ip="10.1.10.1"; // Android wlan IP
|
|
const char* debug_dest_ip="207.246.62.210"; // Debug server pub IP
|
|
|
|
const uint16_t sport = 40408; // local port
|
|
const uint16_t dport = 50508; // server port
|
|
|
|
|
|
|
|
// pseudo header needed for tcp header checksum calculation
|
|
struct pseudo_header
|
|
{
|
|
u_int32_t source_address;
|
|
u_int32_t dest_address;
|
|
u_int8_t placeholder;
|
|
u_int8_t protocol;
|
|
u_int16_t tcp_length;
|
|
};
|
|
|
|
#define DATAGRAM_LEN 4096
|
|
#define OPT_SIZE 20
|
|
|
|
unsigned short checksum(const char *buf, unsigned size)
|
|
{
|
|
unsigned sum = 0, i;
|
|
|
|
/* Accumulate checksum */
|
|
for (i = 0; i < size - 1; i += 2)
|
|
{
|
|
unsigned short word16 = *(unsigned short *) &buf[i];
|
|
sum += word16;
|
|
}
|
|
|
|
/* Handle odd-sized case */
|
|
if (size & 1)
|
|
{
|
|
unsigned short word16 = (unsigned char) buf[i];
|
|
sum += word16;
|
|
}
|
|
|
|
/* Fold to get the ones-complement result */
|
|
while (sum >> 16) sum = (sum & 0xFFFF)+(sum >> 16);
|
|
|
|
/* Invert to get the negative in ones-complement arithmetic */
|
|
return ~sum;
|
|
}
|
|
|
|
|
|
void create_data_packet(char** out_packet, int* out_packet_len, struct tcp_session tcps)
|
|
{
|
|
// datagram to represent the packet
|
|
char *datagram = calloc(DATAGRAM_LEN, sizeof(char));
|
|
|
|
// required structs for IP and TCP header
|
|
struct iphdr *iph = (struct iphdr*)datagram;
|
|
struct tcphdr *tcph = (struct tcphdr*)(datagram + sizeof(struct iphdr));
|
|
struct pseudo_header psh;
|
|
|
|
char source_ip[32];
|
|
struct sockaddr_in sin;
|
|
|
|
//some address resolution
|
|
strcpy(source_ip , debug_src_ip); // cli ip
|
|
sin.sin_family = AF_INET;
|
|
sin.sin_port = htons(dport); // server port
|
|
sin.sin_addr.s_addr = inet_addr (debug_dest_ip); // server ip
|
|
|
|
|
|
// IP header configuration
|
|
iph->ihl = 5;
|
|
iph->version = 4;
|
|
iph->tos = 0;
|
|
iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr) + OPT_SIZE);
|
|
iph->id = htons(54321);
|
|
iph->frag_off = 0;
|
|
iph->ttl = 64;
|
|
iph->protocol = IPPROTO_TCP;
|
|
iph->check = 0; // do calc later
|
|
iph->saddr = inet_addr ( source_ip );
|
|
iph->daddr = sin.sin_addr.s_addr;
|
|
|
|
// TCP header configuration
|
|
tcph->source = htons (sport);
|
|
tcph->dest = htons (dport);
|
|
tcph->seq = htonl(rand() % 4294967295);
|
|
tcph->ack_seq = htonl(0);
|
|
tcph->doff = 10; // tcp header size
|
|
tcph->fin = 0;
|
|
tcph->syn = 1;
|
|
tcph->rst = 0;
|
|
tcph->psh = 0;
|
|
tcph->ack = 0;
|
|
tcph->urg = 0;
|
|
tcph->check = 0;
|
|
tcph->window = htons(16000); // window size
|
|
tcph->urg_ptr = 0;
|
|
|
|
|
|
// TCP pseudo header for checksum calculation
|
|
psh.source_address = inet_addr ( source_ip );
|
|
psh.dest_address = sin.sin_addr.s_addr;
|
|
psh.placeholder = 0;
|
|
psh.protocol = IPPROTO_TCP;
|
|
psh.tcp_length = htons(sizeof(struct tcphdr) + OPT_SIZE);
|
|
int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + OPT_SIZE;
|
|
// fill pseudo packet
|
|
char* pseudogram = malloc(psize);
|
|
memcpy(pseudogram, (char*)&psh, sizeof(struct pseudo_header));
|
|
memcpy(pseudogram + sizeof(struct pseudo_header), tcph, sizeof(struct tcphdr) + OPT_SIZE);
|
|
|
|
// TODO: change options to PA
|
|
// TCP options are only set in the SYN packet
|
|
// ---- set mss ----
|
|
datagram[40] = 0x02;
|
|
datagram[41] = 0x04;
|
|
int16_t mss = htons(48); // mss value
|
|
memcpy(datagram + 42, &mss, sizeof(int16_t));
|
|
// ---- enable SACK ----
|
|
datagram[44] = 0x04;
|
|
datagram[45] = 0x02;
|
|
// do the same for the pseudo header
|
|
pseudogram[32] = 0x02;
|
|
pseudogram[33] = 0x04;
|
|
memcpy(pseudogram + 34, &mss, sizeof(int16_t));
|
|
pseudogram[36] = 0x04;
|
|
pseudogram[37] = 0x02;
|
|
|
|
tcph->check = checksum((const char*)pseudogram, psize);
|
|
iph->check = checksum((const char*)datagram, iph->tot_len);
|
|
|
|
*out_packet = datagram;
|
|
*out_packet_len = sizeof(struct iphdr) + sizeof(struct tcphdr) + OPT_SIZE;
|
|
free(pseudogram);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void create_ack_packet(char** out_packet, int* out_packet_len, uint32_t seq_num)
|
|
{
|
|
// datagram to represent the packet
|
|
char *datagram = calloc(DATAGRAM_LEN, sizeof(char));
|
|
|
|
// required structs for IP and TCP header
|
|
struct iphdr *iph = (struct iphdr*)datagram;
|
|
struct tcphdr *tcph = (struct tcphdr*)(datagram + sizeof(struct iphdr));
|
|
struct pseudo_header psh;
|
|
|
|
char source_ip[32];
|
|
struct sockaddr_in sin;
|
|
|
|
//some address resolution
|
|
strcpy(source_ip , debug_src_ip); // cli ip
|
|
sin.sin_family = AF_INET;
|
|
sin.sin_port = htons(dport); // server port
|
|
sin.sin_addr.s_addr = inet_addr (debug_dest_ip); // server ip
|
|
|
|
|
|
// IP header configuration
|
|
iph->ihl = 5;
|
|
iph->version = 4;
|
|
iph->tos = 0;
|
|
iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr) + OPT_SIZE);
|
|
iph->id = htons(54321);
|
|
iph->frag_off = 0;
|
|
iph->ttl = 64;
|
|
iph->protocol = IPPROTO_TCP;
|
|
iph->check = 0; // do calc later
|
|
iph->saddr = inet_addr ( source_ip );
|
|
iph->daddr = sin.sin_addr.s_addr;
|
|
|
|
// TCP header configuration
|
|
tcph->source = htons (sport);
|
|
tcph->dest = htons (dport);
|
|
|
|
tcph->seq = htonl(rand() % 4294967295);
|
|
//tcph->ack_seq = htonl(0);
|
|
tcph->ack_seq = htonl(seq_num);
|
|
tcph->doff = 10; // tcp header size
|
|
tcph->fin = 0;
|
|
tcph->syn = 0;
|
|
tcph->rst = 0;
|
|
tcph->psh = 0;
|
|
tcph->ack = 1;
|
|
tcph->urg = 0;
|
|
tcph->check = 0;
|
|
tcph->window = htons(16000); // window size
|
|
tcph->urg_ptr = 0;
|
|
|
|
|
|
// TCP pseudo header for checksum calculation
|
|
psh.source_address = inet_addr ( source_ip );
|
|
psh.dest_address = sin.sin_addr.s_addr;
|
|
psh.placeholder = 0;
|
|
psh.protocol = IPPROTO_TCP;
|
|
psh.tcp_length = htons(sizeof(struct tcphdr) + OPT_SIZE);
|
|
int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + OPT_SIZE;
|
|
// fill pseudo packet
|
|
char* pseudogram = malloc(psize);
|
|
memcpy(pseudogram, (char*)&psh, sizeof(struct pseudo_header));
|
|
memcpy(pseudogram + sizeof(struct pseudo_header), tcph, sizeof(struct tcphdr) + OPT_SIZE);
|
|
|
|
// TCP options are only set in the SYN packet
|
|
// ---- set mss ----
|
|
datagram[40] = 0x02;
|
|
//datagram[41] = 0x04;
|
|
int16_t mss = htons(48); // mss value
|
|
memcpy(datagram + 42, &mss, sizeof(int16_t));
|
|
// ---- enable SACK ----
|
|
//datagram[44] = 0x04;
|
|
datagram[45] = 0x02;
|
|
// do the same for the pseudo header
|
|
pseudogram[32] = 0x02;
|
|
//pseudogram[33] = 0x04;
|
|
memcpy(pseudogram + 34, &mss, sizeof(int16_t));
|
|
pseudogram[36] = 0x04;
|
|
//pseudogram[37] = 0x02;
|
|
|
|
tcph->check = checksum((const char*)pseudogram, psize);
|
|
iph->check = checksum((const char*)datagram, iph->tot_len);
|
|
|
|
*out_packet = datagram;
|
|
*out_packet_len = sizeof(struct iphdr) + sizeof(struct tcphdr) + OPT_SIZE;
|
|
free(pseudogram);
|
|
|
|
}
|
|
|
|
void create_syn_packet(char** out_packet, int* out_packet_len)
|
|
{
|
|
// datagram to represent the packet
|
|
char *datagram = calloc(DATAGRAM_LEN, sizeof(char));
|
|
|
|
// required structs for IP and TCP header
|
|
struct iphdr *iph = (struct iphdr*)datagram;
|
|
struct tcphdr *tcph = (struct tcphdr*)(datagram + sizeof(struct iphdr));
|
|
struct pseudo_header psh;
|
|
|
|
char source_ip[32];
|
|
struct sockaddr_in sin;
|
|
|
|
//some address resolution
|
|
strcpy(source_ip , debug_src_ip); // cli ip
|
|
sin.sin_family = AF_INET;
|
|
sin.sin_port = htons(dport); // server port
|
|
sin.sin_addr.s_addr = inet_addr (debug_dest_ip); // server ip
|
|
|
|
|
|
// IP header configuration
|
|
iph->ihl = 5;
|
|
iph->version = 4;
|
|
iph->tos = 0;
|
|
iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr) + OPT_SIZE);
|
|
iph->id = htons(54321);
|
|
iph->frag_off = 0;
|
|
iph->ttl = 64;
|
|
iph->protocol = IPPROTO_TCP;
|
|
iph->check = 0; // do calc later
|
|
iph->saddr = inet_addr ( source_ip );
|
|
iph->daddr = sin.sin_addr.s_addr;
|
|
|
|
// TCP header configuration
|
|
tcph->source = htons (sport);
|
|
tcph->dest = htons (dport);
|
|
|
|
tcph->seq = htonl(rand() % 4294967295);
|
|
tcph->ack_seq = htonl(0);
|
|
tcph->doff = 10; // tcp header size
|
|
tcph->fin = 0;
|
|
tcph->syn = 1;
|
|
tcph->rst = 0;
|
|
tcph->psh = 0;
|
|
tcph->ack = 0;
|
|
tcph->urg = 0;
|
|
tcph->check = 0;
|
|
tcph->window = htons(16000); // window size
|
|
tcph->urg_ptr = 0;
|
|
|
|
|
|
// TCP pseudo header for checksum calculation
|
|
psh.source_address = inet_addr ( source_ip );
|
|
psh.dest_address = sin.sin_addr.s_addr;
|
|
psh.placeholder = 0;
|
|
psh.protocol = IPPROTO_TCP;
|
|
psh.tcp_length = htons(sizeof(struct tcphdr) + OPT_SIZE);
|
|
int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + OPT_SIZE;
|
|
// fill pseudo packet
|
|
char* pseudogram = malloc(psize);
|
|
memcpy(pseudogram, (char*)&psh, sizeof(struct pseudo_header));
|
|
memcpy(pseudogram + sizeof(struct pseudo_header), tcph, sizeof(struct tcphdr) + OPT_SIZE);
|
|
|
|
// TCP options are only set in the SYN packet
|
|
// ---- set mss ----
|
|
datagram[40] = 0x02;
|
|
datagram[41] = 0x04;
|
|
int16_t mss = htons(48); // mss value
|
|
memcpy(datagram + 42, &mss, sizeof(int16_t));
|
|
// ---- enable SACK ----
|
|
datagram[44] = 0x04;
|
|
datagram[45] = 0x02;
|
|
// do the same for the pseudo header
|
|
pseudogram[32] = 0x02;
|
|
pseudogram[33] = 0x04;
|
|
memcpy(pseudogram + 34, &mss, sizeof(int16_t));
|
|
pseudogram[36] = 0x04;
|
|
pseudogram[37] = 0x02;
|
|
|
|
tcph->check = checksum((const char*)pseudogram, psize);
|
|
iph->check = checksum((const char*)datagram, iph->tot_len);
|
|
|
|
*out_packet = datagram;
|
|
*out_packet_len = sizeof(struct iphdr) + sizeof(struct tcphdr) + OPT_SIZE;
|
|
free(pseudogram);
|
|
|
|
}
|
|
|
|
|
|
|
|
int write_data_packet(const struct arguments *args, int epoll_fd, const uint8_t *buffer, size_t length) {
|
|
// send PSH data
|
|
write(debug_socket->socket, buffer, length);
|
|
log_android(ANDROID_LOG_ERROR, "Writing data packet with length: %d", length);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int open_debug_packet(const struct arguments *args, int epoll_fd) {
|
|
|
|
// send SYN
|
|
char* packet;
|
|
int packet_len;
|
|
|
|
create_syn_packet(&packet, &packet_len);
|
|
handle_ip(args, packet, (size_t) packet_len, epoll_fd, 10, 200);
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
|
|
int debug_socket_init(const struct arguments *args, int epoll_fd) {
|
|
|
|
log_android(ANDROID_LOG_ERROR, "init debug socket");
|
|
open_debug_packet(args, epoll_fd);
|
|
|
|
get_debug_session(args);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
struct ng_session *get_debug_session(const struct arguments *args) {
|
|
|
|
|
|
// Search session
|
|
struct ng_session *cur = args->ctx->ng_session;
|
|
while (cur != NULL &&
|
|
!(cur->protocol == IPPROTO_TCP &&
|
|
cur->tcp.version == 4 &&
|
|
cur->tcp.source == ntohs(40408) && cur->tcp.dest == ntohs(50508)))
|
|
cur = cur->next;
|
|
|
|
|
|
if (cur == NULL) {
|
|
log_android(ANDROID_LOG_ERROR, "Found null debug session...");
|
|
} else {
|
|
log_android(ANDROID_LOG_ERROR, "Found the debug session..");
|
|
debug_socket = cur;
|
|
}
|
|
|
|
return debug_socket;
|
|
}
|
|
|
|
|
|
void read_debug_socket() {
|
|
// TODO: Figure out what needs to be passed as parameters to this function
|
|
return ;
|
|
}
|
|
|
|
void write_debug_ack(const struct arguments *args, int epoll_fd, uint32_t seq_num) {
|
|
// TODO: This function is modelled after write_pcap_ret so I made
|
|
// parameters for this function the same since we basically want to do the same thing.
|
|
|
|
if (debug_socket != NULL) {
|
|
log_android(ANDROID_LOG_ERROR, "Trying to write ack to the debug socket now..");
|
|
//write_data_packet(args, epoll_fd, buffer, length);
|
|
|
|
char* packet;
|
|
int packet_len;
|
|
|
|
create_ack_packet(&packet, &packet_len, seq_num);
|
|
handle_ip(args, packet, (size_t) packet_len, epoll_fd, 10, 200);
|
|
}
|
|
}
|
|
|
|
|
|
void write_debug_socket(const struct arguments *args, int epoll_fd, const uint8_t *buffer, size_t length) {
|
|
// TODO: This function is modelled after write_pcap_ret so I made
|
|
// parameters for this function the same since we basically want to do the same thing.
|
|
|
|
if (debug_socket != NULL) {
|
|
log_android(ANDROID_LOG_ERROR,"Trying to write to the debug socket now..");
|
|
write_data_packet(args, epoll_fd, buffer, length);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|