欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

浅谈Flask cookie与密钥的安全性

来源:本站整理 作者:佚名 时间:2019-02-01 TAG: 我要投稿

一、前言
几星期之前,我和我的一个小伙伴正在讨论web框架,小伙伴声称他构造了一个“绝对无法绕过的”登录表单。征得小伙伴同意后,他把相关代码发给我审阅。
正如我所料,他说的有一定道理,代码看上去的确非常安全,不存在SQL注入XSS漏洞,他甚至限制了访问速率并会审计日志。看来如果不知道密码,我们似乎无法绕过登录表单。
这种实现非常完美,直到我注意到他使用的密钥(secret key)为“CHANGEME”。
 
二、利用人为错误
我的小伙伴没有意识到一点:使用脆弱的密钥会比在客户端存储当前用户的状态其实更加危险。考虑如下一个示例程序(该程序完全摘抄自小伙伴提供的代码):
# Requirements: Flask
from flask import Flask, session
app = Flask(__name__)
app.config['SECRET_KEY'] = 'CHANGEME'
@app.route('/')
def index():
    if 'logged_in' not in session:
        session['logged_in'] = False
    if session['logged_in']:
        return 'You are logged in!'
    else:
        return 'Access Denied', 403
if __name__ == '__main__':
    app.run()
乍看之下,代码似乎有点难以理解,我甚至都想直接删除登录表单(因为我们永远无法猜到正确的密码)。那么我们如何才能看到“You are logged in!”消息呢?
 
三、Flask的会话管理
默认情况下,Flask会使用名为“signed cookies”的一种机制,这是在客户端(而非服务端)存储当前会话(session)数据的一种简单方式,使其(从理论上)无法被篡改。
然而这种方法存在一些缺点,比如cookie值并非经过加密处理,而是经过签名处理。这意味着我们不需要密钥也能读取会话内容。
此外,我还与许多Python开发人员交流过,大部分人都认为客户端无法读取会话数据,因为用来签名cookie的代码为SecureCookieSessionInterface,这个函数名也给他们带来不可靠的安全感。我们来考虑如下会话:

图1. 一个“安全的”cookie可以切分成若干部分
会话数据
会话数据实际上就是会话的内容,虽然第一眼看上去这种数据很难理解,但其实这只是经过Base64编码的一个字符串。如果我们使用itsdangerous的base64解码器对其进行解码,可以得到如下输出:

图2. 服务端设置的会话数据
时间戳
时间戳可以告诉服务端数据最后一次更新的时间。根据我们所使用的itsdangerous的具体版本,该时间戳可能对应当前的Unix时间戳、或者当前当前Unix时间戳减去epoch时间(即1970-01-01 00:00:00 UTC)所对应的值(由于之前存在一个bug,我们无法设置早于2011年的时间,因此存在两种不同的时间戳版本,参考此处资料)。
如果时间戳已超过31天,那么会话就会被打上过期标记,变成无效会话。
加密哈希
这就是让cookie变得“安全”的字段。服务器向我们发送最新的会话数据之前,会结合我们的会话数据、当前时间戳以及服务器的私钥来计算sha1哈希。
每当服务器再次看到该会话,就会解析这几部分字段,然后使用同样的方法验证这些数据。如果哈希与给定的数据不匹配,那么表明数据已被篡改,因此服务端会将该会话当成无效会话。
这意味着如果我们的私钥非常容易猜测,或者已对外公开,那么攻击者可以不费吹灰之力修改会话的内容。我们可以来看一下网上已公开的私钥情况,在GitHUb上搜索secret_key,可以看到如下结果:

图3. 在GitHub上搜索secret_key可以返回将近240万条记录
 
四、绕过认证
那么我们怎么才能绕过认证呢?我们来看如下示例(请复制前文代码,以便按步骤执行):
前提条件
安装Python解释器(我使用的是Python 3.6版)
使用pip install flask安装Flask(可以在虚拟环境中安装)
在进一步操作前,我们需要启动Flask,命令如下:
$ python server.py
获取会话cookie
为了获取会话cookie,我们需要先从服务器探测出可能使用的cookie格式。这里我使用curl发起请求,并带上-v选项以获得verbose输出信息(可以打印出请求头部),大家也可以直接访问服务器web页面,再配合浏览器插件(如EditThisCookie)来获取cookie的内容:

图4. 服务端返回会话cookie
需要注意的是,并非所有服务器都会立刻返回一个会话,有些服务器只会在出现错误时返回会话,而其他服务器只会在用户登录后返回会话。我们需要根据具体情况具体分析。为了演示方便,这里我们的示例程序无论何时都会设置会话信息。
创建字典
虽然我们可以组合各种可能的字母、数字以及符号来暴力破解,但更好的办法是创建一个字典集(wordlist),其中包含开发者已经公开过的秘钥。
为建立字典,我首先想到的是两个来源:GitHub(如前文所示)以及StackOverflow(我们可以通过archive.org来下载该网站上曾经发表过的每条评论、文章等数据)。

[1] [2] [3]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载