#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#ifdef __LITTLE_ENDIAN

#define IPQUAD(addr) /

((unsigned char *)&addr)[0], /

((unsigned char *)&addr)[1], /

((unsigned char *)&addr)[2], /

((unsigned char *)&addr)[3]

#else

#define IPQUAD(addr) /

((unsigned char *)&addr)[3], /

((unsigned char *)&addr)[2], /

((unsigned char *)&addr)[1], /

((unsigned char *)&addr)[0]

#endif

static u_int16_t checksum(u_int32_t init, u_int8_t *addr, size_t count){

/*Compute Internet Checksum for "count" bytes

* beginning at location "addr".*/

u_int32_t sum = init;

while( count > 1 ) {

/*This is the inner loop*/

sum += ntohs(* (u_int16_t*) addr);

addr += 2;

count -= 2;

}

/*Add left-over byte, if any*/

if( count > 0 )

sum += * (u_int8_t *) addr;

/*Fold 32-bit sum to 16 bits*/

while (sum>>16)

sum = (sum & 0xffff) + (sum >> 16);

return (u_int16_t)~sum;

}

static u_int16_t ip_checksum(struct iphdr* iphdrp){

return checksum(0, (u_int8_t*)iphdrp, iphdrp->ihl<<2);

}

static void set_ip_checksum(struct iphdr* iphdrp){

iphdrp->check = 0;

iphdrp->check = htons(checksum(0, (u_int8_t*)iphdrp, iphdrp->ihl<<2));

}

static u_int16_t tcp_checksum2(struct iphdr* iphdrp, struct tcphdr* tcphdrp){

size_t tcplen = ntohs(iphdrp->tot_len) - (iphdrp->ihl<<2);

u_int32_t cksum = 0;

cksum += ntohs((iphdrp->saddr >> 16) & 0x0000ffff);

cksum += ntohs(iphdrp->saddr & 0x0000ffff);

cksum += ntohs((iphdrp->daddr >> 16) & 0x0000ffff);

cksum += ntohs(iphdrp->daddr & 0x0000ffff);

cksum += iphdrp->protocol & 0x00ff;

cksum += tcplen;

return checksum(cksum, (u_int8_t*)tcphdrp, tcplen);

}

static u_int16_t tcp_checksum1(struct iphdr* iphdrp){

struct tcphdr *tcphdrp =

(struct tcphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<2));

return tcp_checksum2(iphdrp, tcphdrp);

}

static void set_tcp_checksum2(struct iphdr* iphdrp, struct tcphdr* tcphdrp){

tcphdrp->check = 0;

tcphdrp->check = htons(tcp_checksum2(iphdrp, tcphdrp));

}

static void set_tcp_checksum1(struct iphdr* iphdrp){

struct tcphdr *tcphdrp =

(struct tcphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<2));

set_tcp_checksum2(iphdrp, tcphdrp);

}

static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,

struct nfq_data *nfa, void *data){

(void)nfmsg;

(void)data;

u_int32_t id = 0;

struct nfqnl_msg_packet_hdr *ph;

unsigned char *pdata = NULL;

int pdata_len;

ph = nfq_get_msg_packet_hdr(nfa);

if (ph){

id = ntohl(ph->packet_id);

}

pdata_len = nfq_get_payload(nfa, (char**)&pdata);

if(pdata_len == -1){

pdata_len = 0;

}

struct iphdr *iphdrp = (struct iphdr *)pdata;

printf("len %d iphdr %d %u.%u.%u.%u ->",

pdata_len,

iphdrp->ihl<<2,

IPQUAD(iphdrp->saddr));

printf(" %u.%u.%u.%u %s",

IPQUAD(iphdrp->daddr),

getprotobynumber(iphdrp->protocol)->p_name);

printf(" ipsum %hu", ip_checksum(iphdrp));

if(iphdrp->protocol == IPPROTO_TCP){

printf(" tcpsum %hu", tcp_checksum1(iphdrp));

}

#define TO "220.181.37.55"

#define DNAT_TO "64.233.189.104"

if(iphdrp->daddr == inet_addr(TO)){

printf(" !hacked!");

iphdrp->daddr = inet_addr(DNAT_TO);

set_ip_checksum(iphdrp);

if(iphdrp->protocol == IPPROTO_TCP){

set_tcp_checksum1(iphdrp);

printf(" ipsum+ %hu tcpsum+ %hu",

ip_checksum(iphdrp), tcp_checksum1(iphdrp));

}

}

if(iphdrp->saddr == inet_addr(DNAT_TO)){

iphdrp->saddr = inet_addr(TO);

printf(" !hacked!");

set_ip_checksum(iphdrp);

if(iphdrp->protocol == IPPROTO_TCP){

set_tcp_checksum1(iphdrp);

printf(" ipsum+ %hu tcpsum+ %hu",

ip_checksum(iphdrp), tcp_checksum1(iphdrp));

}

}

printf("/n");

return nfq_set_verdict_mark(qh, id, NF_REPEAT, 1,

(u_int32_t)pdata_len, pdata);

}

int main(int argc, char **argv){

struct nfq_handle *h;

struct nfq_q_handle *qh;

struct nfnl_handle *nh;

int fd;

int rv;

char buf[4096];

h = nfq_open();

if (!h) {

exit(1);

}

if (nfq_unbind_pf(h, AF_INET) < 0){

exit(1);

}

if (nfq_bind_pf(h, AF_INET) < 0) {

exit(1);

}

int qid = 0;

if(argc == 2){

qid = atoi(argv[1]);

}

printf("binding this socket to queue %d/n", qid);

qh = nfq_create_queue(h, qid, &cb, NULL);

if (!qh) {

exit(1);

}

if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {

exit(1);

}

nh = nfq_nfnlh(h);

fd = nfnl_fd(nh);

while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {

nfq_handle_packet(h, buf, rv);

}

/*never reached*/

nfq_destroy_queue(qh);

nfq_close(h);

exit(0);

}

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐