《渗透模块Socket Nmap Scapy》

Socket模块:

socket是一个类,三个参数: 第一个地址族(ip),第二个是流(tcp/udp),第三个参数为使用的协议

参数1 family:
    常用的协议有 AF_INET,AF_INET6,AF_LOCAL(OR AF_UNIX,UNIX域Socket),AF_ROUTE等
    默认为AF_INET
参数2 type:
    SOCK_STREAM: TCP类型,默认值
    SOCKDGRAM: UDP类型
    SOCK_RAW:原始类型,允许底层协议如IP或ICMP来进行直接访问
参数3 使用的协议:
    通常赋值0 由系统自己选择

初始化一个TCP类型的Socket: s = socket.socket() >>> s = socket.socket(AF_INET,SOCK_STREAM)

服务端常用函数:
    bind():由服务端调用,在创建socket之前与指定的ip地址,端口进行绑定,如果已经初始化,则使用元组(host,port)的形式来表示地址 >>> s.bind(('127.0.0.1',2345))
    
    listen():开启监听模式,可以使用一个参数来指定最大连接数 最小为1 一般设置为5 >>> s.listen(5)

    accept(): 服务端接受连接,一般为阻塞态等待态,接受tcp连接并返回(conn,address)
    conn为新的套接字对象,可以用来接受和发送数据,address为客户端地址

客户端常用函数:
    connect(): 连接服务端,使用方法  s.connect(("127.0.0.1",2345))

服务器和客户端都可以使用的函数:
    send(): 用于使用TCP时发送数据 使用方法: send(string[,flag])

    sendall(): 与send()类似,也是用于在使用tcp时发送数据,使用方法:sendall(string,[,flag])
    与send()类似,区别是完整发送tcp数据。将string中的数据发送到连接的套字,但返回之前会尝试发送所有的数据,成功返回None,失败则抛出异常   >>> sendall("hello word")

    recv(): 用于使用tcp接受数据,使用:recv(bufsize[,flag]) 例如通过函数接受长度为1024的字符
        obj.recv(1024)

    sendto(): 用于UDP发送数据,使用: sendto(string[,flag],address)  >>> address --> (ipaddr,port)

    recvfrom():用于UDP接收数据,返回值为(data,address)

    close()关闭 socket

Nmap模块:

概念:nmap可以实现1、主机发现功能,2、端口扫描,3、服务及版本检测,4、操作系统检测
安装:apt-get install nmap    pip install python-nmap
介绍:nmap核心模块为:PortScanner,PortScannerAsync,PortScannerError、PortScannerHostDict、PortScannerYield等,其中最重要的就是 PortScanner
使用:
    实例化 nmap.PortScanner() >>> nm = nmap.PortScanner()
           namp.PortScannerAsync() >>> nm = nmap.PortScannerAsync() //可以实现异步扫描
    PortScanner函数:
        scan():
            对指定目标进行扫描,参数有 hosts、ports和arguments
            scan(self,hosts='127.0.0.1',ports = None,arguments='-sV',sudo=False)
            hosts:顾名思义就是主机ip或者域名
            ports:就是端口 可以个单个也可以多个 多个用逗号来进行分割
            arguments:就是类型,参数。
                -sP:表示对目标进行Ping主机在线扫描,
                -PR:表示对目标进行一个ARP的主机在线扫描,
                -sS:表示对目标进行一个TCP半开(SYN)类型的端口扫描,
                -sT:表示对目标进行一个TCP全开类型的端口扫描,
                -O:表示扫描目标的操作系统类型,
                -sV:表示扫描目标上所安装网络服务软件的版本。

        练习:对192.168.1.101的1~500端口进行一次TCP半开扫描
            import nmap
            nm = nmap.PortScanner()
            nm.scan("192.168.1.101","1-500","-sS")

        all_hosts():返回一个被扫描的所有主机列表  nm.all_hosts()
        
        command_line():返回在当前扫描中使用的命令 nm.command_line()
        
        csv():返回一个比较工整的扫描结果 nm.csv()
        
        has_host(self,host):检查是否有host结果,有为T 无为F,>>> nm.has_hosts("192.168.1.100")

        scaninfo():列出扫描信息结构 nm.scaninfo()


    PortScannerAsync函数:
        scan():
            同PortScanner中的一样,只不过多了一个回调函数
            scan(self, hosts='127.0.0.1',ports=None, arguments='-sV', callback=None, sudo=False)
            callback是以(host,scann_data)为参数的函数
        
        still_scanning():如果扫描正在进行,则返回True,否则返回False
            st = nm.still_scanning()
        
        wait(self, timeout=None):函数表示等待时间
            nm.wait(2)

        stop(): 停止扫描



    Scapy:
        概念:在Scapy中每一个协议就是一个类
        ip:
            ip = IP(src="ip_address",dst="ip_address",ttl=32)  范围:target = 192.168.1.0/24 ip = IP(dest = target)
            查看每一个数据包: [p fpr p in ip]
        Ether:
            由于scapy采用分层的形式来构造数据包,ip无法构造arp的请求和应答报文,所以要使用Ether来进行构造
            构造广播包 >>> Ether(dst="ff:ff:ff:ff:ff:ff")
        TCP:
            可以使用 Ether()/IP()/TCP() 来构造一个完整的tcp数据包
        HTTP:
            IP()/TCP()/"GET / HTTP/1.0\r\n\r\n "
        ls函数:
            ls函数可以查看一个类所拥有的属性,ls(IP())
        send和sendp模块:
            send模块工作在第三层,sendp模块工作在第二层
            send模块发送IP数据,sendp模块发送Ether数据包
            send(IP(dst="192.168.1.1")/ICMP())  >>> successful > Sent 1 packets
            sendp(Ether(dst="ff:ff:ff:ff:ff:ff")) >>> successful > Sent 1 Packets
            这两个函数的特点在于 只发不收
        fuzz函数:
            负责内容随机填充
            IP(dst = "192.168.1.1")/fuzz(TCP())
        sr()、sr1()、srp():
            sr和sr1主要用于第三层,srp则用于第二层
            sr当数据发送出去,同时scapy会监听返回的数据, received表示收到的数据包个数、answer表示对应的应答数据包
            sr()函数为scapy的核心,它的返回值是两个列表,第一个列表是收到了应答的包和对应的应答,第二个列表是未收到应答的包。所以可以使用两个列表来保存 sr() 的返回值
            ans,unans = sr(IP(dst = "192.168.1.1")/ICMP()) >>> 使用ans,unans来保存   ans.summary() >>> 来查看列表内容

            sr1与sr函数大同小异,但是只返回一个应答包,可以使用sr1函数来测试目标的某个端口是否开放采用半开SYN扫描法
            >>> sr1(IP(dst="192.168.26.101")/TCP(dport=80,flags="S"))
        sniff()
            在终端开启sniff,scapy就属于捕获网卡数据的状态,如有流量经过网卡,ctrl+c就可以获取sniff的数据
            sniff 可以使用 filter参数进行过滤
            例如,指定只捕获与192.168.1.102有关的数据包,可以使用“host 192.168.1.102”:     >>>sniff(filter=" host 192.168.1.102")
                    如果要同时满足多个条件可以使用“and”“or”等关系运算符来表达:     >>>sniff(filter=" host 192.168.1.102 and icmp")

            iface:可以指定网卡  >>> sniff(iface = "eth1")

            count: 指定最大监听数量  >>> sniff(count = 3)

            练习:设计一个综合性的监听器,它会在网卡eth0上监听源地址或者目的地址为192.168.1.102的icmp数据包,当收到了三个这样的数据包之后,就会停止监听。
            
            首先在Scapy中创建如下监听器:
                >>> sniff(filter="icmp and host 192.168.16.128“,count=3,iface="eth0")
                Ctrl C 停止结束捕获 即可查看结果

            如果需要查看 捕获到的三个数据包具体的内容,可以使用_来进行查看,在scapy中_代表上一条语句的结果
                a=_   a.nsummary()

            刚刚使用过的函数pkt.summary()用来以摘要的形式显示pkt的内容,这个摘要的长度为一行   pkt packet
            p = IP(dst="www.baidu.com")     
            p.summary()     
            "192.168.169.130>Net('www.baidu.com') hopopt"

        综合案例:
            使用Scapy进行ACK端口扫描
                ACK扫描:扫描主机向目标主机发送ACK数据包。根据返回的RST数据包有两种方法可以得到端口的信息。
                        若返回的RST数据包的TTL值小于或等于64,则端口 开放,反之端口 关闭

                对192.168.1.102 的 21、23、135、443、445 这5个端口是否被屏蔽进行扫描,注意是屏蔽不是关闭,采用ACK扫描模式,

                ans,unans = sr(IP(dst="192.168.1.102")/TCP(dport=[21,23,135,443,445],flags="A"))

                按照TCP三次握手的规则,如果目标端口没有被过滤,发出的数据包就会得到回应,否则没有回应。
                for s,r in ans:
                ... if s[TCP].dport == r[TCP].sport:  
                    ... print str(s[TCP].dport) + " is unfiltered"

            使用Scapy来设计一个端口是否开放的扫描器。
            tips:
                如果一个端口处于屏蔽状态,那么它将不会产生任何响应报文。
                如果一个端口处于开放状态,那么它在收到syn数据包之后,就会回应一个ack数据包。
                反之,如果一个端口处于关闭状态,那么它在收到syn数据包之后,就会回应一个rst数据包。
            步骤:
                1、导入模块
                    from scapy.all import fuzz,TCP,IP,sr

                2、生成syn数据包
                    ans,unans = sr(IP(dst="192.168.26.100")/fuzz(TCP(dport=80,flags="S")))
                3、循环遍历结果
                    如果r[TCP].flags==18,则表示返回数据包flags的值为0x012 (SYN,ACK)目标端口为开放状态。
                    如果r[TCP].flags==20,则表示返回数据包flags的值为0x014 (RST,ACK)目标端口为关闭状态。
                    for s,r in ans:
                        ...if r[TCP].flags==18:
                                print "This port is Open"
                        ...if r[TCP].flags == 20:
                                print "This port is Closed"

 

posted @ 2021-04-07 17:18  我的莴苣不给你吃  阅读(385)  评论(0)    收藏  举报