用户
搜索
  • TA的每日心情
    开心
    2018-9-11 11:32
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]经常看看I

    i春秋-核心白帽

    Rank: 4

    113

    主题

    142

    帖子

    1577

    魔法币
    收听
    0
    粉丝
    31
    注册时间
    2016-6-6
    发表于 2019-8-19 16:16:24 1975
    本篇文章主要以一个ctf选手的视角来讲一下flask session所可能存在的问题,既然提到了session,那么首先普及一下session这个知识点,简单来说session是浏览器与服务器交互的会话,这个session可以来验证访问者的身份,大多数的session都是保存在服务器的,但是也有少部分是客户端session,就比如我们今天所要将的flask框架。


    传统PHP中session都是被放在服务器中的,用户只是看到一串随机字符串,真正的session内容在服务器中,flask是一个python轻量级web框架,他的session存储在客户端的cookie字段中,为了防止session篡改,flask进行了如下的处理,代码存放在flask模块中sessions.py文件中。

    class SecureCookieSessionInterface(SessionInterface):
    """The default session interface that stores sessions in signed cookies
    through the :mod:`itsdangerous` module.
    """

    #: the salt that should be applied on top of the secret key for the
    #: signing of cookie based sessions.
    salt = "cookie-session"
    #: the hash function to use for the signature. The default is sha1
    digest_method = staticmethod(hashlib.sha1)
    #: the name of the itsdangerous supported key derivation. The default
    #: is hmac.
    key_derivation = "hmac"
    #: A python serializer for the payload. The default is a compact
    #: JSON derived serializer with support for some extra Python types
    #: such as datetime objects or tuples.
    serializer = session_json_serializer
    session_class = SecureCookieSession

    def get_signing_serializer(self, app):
    if not app.secret_key:
    return None
    signer_kwargs = dict(
    key_derivation=self.key_derivation, digest_method=self.digest_method
    )
    return URLSafeTimedSerializer(
    app.secret_key,
    salt=self.salt,
    serializer=self.serializer,
    signer_kwargs=signer_kwargs,
    )
    ……
    ……

    seesion通过序列化对键以及键值进行进行序列化,通过hmacsha1进行签名,最终生成一串如下字符
    .eJyrViotTi2Kz0xRsqpWUkhSslLyDbS1VarVgYjnJeamwmUiw4NKEsNNgLK1AN_uEPo.XVOD9w.oMvtM-ubK-dy8p40rr4uuCncdFk
    流程为:json->zlib->base64后的源字符串 . 时间戳 . hmac签名信息
    这是由{'user_id':'1','user_name':'admin'}所生成的session。
    flask session 加解密工具:https://github.com/noraj/flask-session-cookie-manager
    SECRET_KEY 爆破工具:https://github.com/Paradoxis/Flask-Unsign
    这串session我是用KEY为admin生成出来的session,虽然你可以通过session的解密工具解出对应的{'user_id':'1','user_name':'admin'},但是无法篡改这中间的数据,篡改会导致签名校验失败导致验证失败。

    在CTF中获取flask的KEY从而进行伪造用户登录是一个种常见的题型,可以通过很多方法来获取KEY。

    下面以一道CTF题目来作为案例,本题目为DVP周年活动的题目。

    题目界面:

    界面.webp.jpg


    正常操作,一般都是admin/admin尝试一下, 提示发现密码错误,于是就尝试了一下帐号方法,结果发现显示的是权限不足。

    权限.webp.jpg

    明白了这是一个登录即注册的功能,admin之所以登录不了,是因为之前就已经被题目创建者所登录,本题的意图大概也就是伪造身份登录了。
    关注一下cookie,发现有2个字段,一个是session一个是remember_tocken。

    ken.webp.jpg


    flask的session信息是存到客户端的cookie里的,不是存在服务端的,所以将这个session使用flask-unsign模块解一下试试。

    试试.webp.jpg


    发现其中有一个user_id,前面提示“权限不足”应该就是要我们使用有权限的账号登陆,所以接下来需要做的是伪造session。
    flask中默认SECRET_KEY使用的都是同一个,了解了一下remember_tocken,这是一个记住登录的功能,采用的是hmacsha512来进行加密的,有了加密前后对照,那就直接写一个脚本来爆破。

    或者也可以用上面的SECRET_KEY 爆破工具直接爆破session,根据提示成功爆破出KEY,爆破出KEY后就可以进行身份伪造。

    伪造.webp.jpg

    将session放回浏览器中,即可伪造id为1的账户登录,登录后还有第二个点。

    第二个.webp.jpg


    这里需要8位激活码,这在解题过程中是没有出现的,通过暴力破解8位明显是不合实际的,获取这个数值其实并不难,前面说过flask的session是存储在客户端中的,那么我们可以看看返回包中的set-cookie字段中有哪些信息。

    信息.webp.jpg

    不难发现邀请码隐藏在session中,其实这是一些开发者会出现的问题,将一些敏感信息存放在session中,最后一步是一个区块链特有的“假充值”漏洞,就不在这描述了。


    总结:

    1、弱SECRET_KEY
    2、seesion中可能存在敏感信息,如验证码,邀请码等
    3、不同token使用相同的SECRET_KEY
    类似的session的题目有很多,例如hctf中的admin和hide and seek,大家如果感兴趣可以自行收集一波这类型的题目来进一步了解。

    qrcode_for_gh_223e082fe8a7_430.jpg

    顶顶顶顶顶顶
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册