zoukankan      html  css  js  c++  java
  • flask中session伪造

    flask中session伪造

    前言

    • 环境:[HCTF 2018]admin1
    • 知识点:session伪造
    • 参考:wp1wp2

    做题

    题目页面,注册,登录两个窗口,先注册进去,进去之后有index,post,change password,logout四个功能窗口,在change password页面查看源码时发现了提示源码网站.

    思路一

    对于flask框架,其session是以cookie的形式存储在客户端的,所以造成了session可读,我们只要用网上的session解密脚本就可实现读取,解密读取之后我们知道了它的格式

    比如:

    {'_fresh': True, '_id': b'95d3b3cd79b0faa83832344b7912541e88d445d7b5d9420b09e1db77c768cc53467588bee26e8aa59a56b7894ebff266fd9d73ac10e87b3fc934ad815b1aec3f', 'csrf_token': b'01653cb0c99bd2c59551ea514544d421501448ca', 'image': b'nvO9', 'name': '123', 'user_id': '10'}

    但我们此时要伪造admin用户,我们就可以将name改成123然后再加密进行session伪造,但是怎样加密呢,这里需要知道secret_key 才能进行加密伪造

    session解密脚本

    #!/usr/bin/env python3
    import sys
    import zlib
    from base64 import b64decode
    from flask.sessions import session_json_serializer
    from itsdangerous import base64_decode
    
    def decryption(payload):
        payload, sig = payload.rsplit(b'.', 1)
        payload, timestamp = payload.rsplit(b'.', 1)
    
        decompress = False
        if payload.startswith(b'.'):
            payload = payload[1:]
            decompress = True
    
        try:
            payload = base64_decode(payload)
        except Exception as e:
            raise Exception('Could not base64 decode the payload because of '
                             'an exception')
    
        if decompress:
            try:
                payload = zlib.decompress(payload)
            except Exception as e:
                raise Exception('Could not zlib decompress the payload before '
                                 'decoding the payload')
    
        return session_json_serializer.loads(payload)
    
    if __name__ == '__main__':
        print(decryption(sys.argv[1].encode()))
    


    我们在题目的config.py里看到它的密钥是'ckj123'

    import os
    
    class Config(object):
        SECRET_KEY = os.environ.get('SECRET_KEY') or 'ckj123'
        SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:adsl1234@db:3306/test'
        SQLALCHEMY_TRACK_MODIFICATIONS = True
    

    然后利用flask_session加密脚本

    payload伪造的session

    {'_fresh': True, '_id': b'2ff34a5077d2f711c7aa5fb35b61ebe2d8cf4081a56609f46c43d95e51de0efa5713b6d78b48664e4d4bbf4aabb1fd6b6484b97d2b48997ce7a83878b78781d1', 'csrf_token': b'44463a5670f0c0ad61ab0d2dc0ae725a14808b81', 'image': b'MAuE', 'name': 'admin', 'user_id': '10'}

    session加密


    得到admin的session,然后替换session即可得到flag.

    思路二

    在python中自带lower 函数将大写字母转换为小写,我们注意到代码中出现了个strtolower ,我们仔细审计下这个函数

    def strlower(username):
        username = nodeprep.prepare(username)
        return username
    

    这里用的nodeprep.prepare函数,而nodeprep是从Twisted模块导入的,在requirements.txt文件中发现Twisted==10.2.0,而官网最新已经到了19.7.0(2019/9),版本差距很大,应该会存在漏洞

    使用nodeprep.prepare函数转换时过程如下:

    ᴬ=>A=>a

    啊这这里是python的flask框架,不熟悉,代码审计很迷,但是还是可以勉强审计出,注册,登录,改密码的时候都会调用strtolower 函数,也就是我们注册是用ᴬdmin ,那么存储到数据库就是Admin ,不对,不是这样,裂开,不会,以后来填这个坑。

  • 相关阅读:
    SQL怎么随机提取出一条信息 mysql 获取随机记录
    css3 渐变 各浏览器兼容
    php的curl和socket的区别 转
    php获取本机真实IP地址
    SSH超时断开 ssh 老掉线
    php 获取远程服务器信息 get_headers 的使用
    如何删除右键菜单中的Catalyst(TM) Control Center选项
    多线程概念、案例!
    网络编程
    我的博客开通啦
  • 原文地址:https://www.cnblogs.com/NineOne/p/14033379.html
Copyright © 2011-2022 走看看