当前位置: 首页 > news >正文

HFCTF-2021-Final-easyflask

考点:

环境变量信息泄露

pickle 反序列化RCE

Flask_seesion 伪造

__ruduce__魔术方法利用

思路:

反序列化肯定包含 创建新对象的操作,如果__reduce__里包含攻击代码就可以实现RCE,但是被反序列化的输出储存在session里,需要知道密钥进行伪造。

密钥获得途径:一般都可以在 代码里、配置文件里(app.config)、环境变量里(/proc/self/environ)获得。这题属于第三者。

 首先拿到secret_key=glzjin22948575858jfjfjufirijidjitg3uiiuuhOLDPWD

/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对应的值是字典,会读取  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  但是我在kali 用 flask-session-cookie-manager  加密后的session 没有 反弹shell 成功。 在 window 用的脚本 也没成功。

看到别的师傅用这个脚本,试一下:

""" 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 下使用

连上了之后就再也连不上了。 不搞了 这题真的浪费时间 

 

相关文章:

  • 神经网络系统技术是什么,神经网络系统技术应用
  • java+SpringBoot+HTML+Mysq基于微信小程序的大咖读书系统的设计与实现
  • 前端周刊第三十四期
  • Maven私服搭建与使用:nexus,repository,mirror,distributionManagement
  • ubuntu22.04安装Kubernetes1.25.0(k8s1.25.0)高可用集群
  • 高等教育学:技能的形成
  • 快来看,数据分析BI软件居然也能完成基金变迁大数据分析?
  • 16.线程通信1:生产者/消费者问题
  • SpringBoot校园二手书管理系统
  • 初识Nginx + Linux 中安装Nginx
  • 关于 SAP UI5 控件的 Densities 话题讨论
  • 禁忌搜索算法TS求解连续函数最值
  • 分布式精讲系列 实现分布式服务应该具备哪些核心技术组件?
  • 【博客479】prometheus-----时序数据模型及其存储机制
  • 利用cmake工具生成VisualStudio工程文件
  • [译]CSS 居中(Center)方法大合集
  • 【347天】每日项目总结系列085(2018.01.18)
  • eclipse的离线汉化
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • JavaScript DOM 10 - 滚动
  • Js基础知识(四) - js运行原理与机制
  • leetcode386. Lexicographical Numbers
  • LeetCode算法系列_0891_子序列宽度之和
  • SQL 难点解决:记录的引用
  • Web标准制定过程
  • 阿里研究院入选中国企业智库系统影响力榜
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 二维平面内的碰撞检测【一】
  • 给新手的新浪微博 SDK 集成教程【一】
  • 蓝海存储开关机注意事项总结
  • 两列自适应布局方案整理
  • 入手阿里云新服务器的部署NODE
  • 收藏好这篇,别再只说“数据劫持”了
  • 通信类
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 协程
  • 再次简单明了总结flex布局,一看就懂...
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • #define
  • #LLM入门|Prompt#3.3_存储_Memory
  • #pragma once
  • ${ }的特别功能
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (八)Spring源码解析:Spring MVC
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (待修改)PyG安装步骤
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (排序详解之 堆排序)
  • (三)elasticsearch 源码之启动流程分析
  • (一)WLAN定义和基本架构转
  • (转)一些感悟
  • .gitattributes 文件