从两道HCTF题分析flask客户端session安全问题

​ 客户端session,顾名思义就是存在客户端的session(即放在cookie里)。对于很多我们熟悉的web开发环境都是使用服务器session,就是把session存放在服务器中,而在cookie中设置一个sessionid字段,从而每次带cookie的访问,服务器都可以检索sessionid找到session值。

flsak 客户端session安全问题

​ 然而flask作为一个非常轻量级的web框架,并不支持将session保存到服务器,而是选择将session保存到cookie中返回给用户。当然虽然我们可以查看到session内容,因为给session加了签名,所以理论上如果我们不知道secret_key的话我们是无法伪造session的。但是如果我们能借助其他漏洞比如任意文件读取获得了secret_key值的话,我们就可以伪造session了。更多关于客户端session的安全问题详解可以看P牛的这篇文章

​ 接下来,我们来看两道2018年hctf的web题,都运用了伪造flask客户端session的方法。这两道题在github都有docker镜像可以下载,有兴趣的同学可以尝试本地搭建。

2018HCTF admin

​ 伪造session其实是这道题的一个非预期解,但既然可以用,那么我也来分析一下。

​ 进入网页后注册一个账号,登录,在修改密码功能的HTML源码中看到了整个项目源码的github地址

​ 拿到源码,是flask项目,发现了下面两个文件的关键信息


既然我们已经可以拿到了secret_key,而且,只要能伪装成admin用户访问index.html我们就可以拿到flag。

​ 怎么伪造session呢? 前面我们已经说了,客户端session意味着session是暴露给用户的,只是加了签名,我们就无法伪造了。既然这样我们先看看session内容是什么。

​ 纳尼,并不知道这一坨东西是什么鬼呀,其实p牛在它的文章中说了,session内容是经过base64编码和zlib压缩过的,https://github.com/noraj/flask-session-cookie-manager。  这个工具可以解码session,而且待会伪造session也要用到它。

​ 好,看到了session的内容,我们将其中的name字段和user_id字段伪造一下。

​ 拿这个session去访问主页就可以拿到flag了。

2018HCTF hideandseek

​ 这题打开有个登录界面,任意账号密码可以登录除了admin用户。进去后只能上传zip文件,而且上传后会把zip包解压缩并且返回压缩包中最后一个文件的内容。这样我们就可以压缩一个软链文件,指向我们希望读取的文件。

​ 下面这个脚本很简单,先接受用户输入一个文件名(比如/etc/passwd)并借此创建一个软链压缩成zip上传到题目服务器中查看返回信息。

读取/etc/passwd成功

​ 现在我们需要的是读取一些文件看看有啥有用的信息可以获取。我们从客户端session大概率能猜出来可能用的就是flask。既然可以读取文件我们就可以读取/proc/pid/environ(pid换成进程号),从进程环境变量中看看正在跑的是什么程序,以及一些敏感信息。

​ 扫了一遍,发现了nginx的环境变量,并且看到了uwsgi配置文件的位置/app/it_is_hard_t0_guess_the_path_but_y0u_find_it_5f9s5b5s9.ini读取这个文件,发现(flask)项目main函数真正位置。

​ 读取/app/hard_t0_guess_n9f5a95b5ku9fg/hard_t0_guess_also_df45v48ytj9_main.py看到flask源码。

​ 可以看到secret_key是通过random函数生成的,而random的种子是uuid.getnode(),即是mac地址。而我们是可以通过读取文件/sys/class/net/eth0/address来获取到mac地址的。这样的话我们就可以获得伪随机种子,那么就可以的到伪随机数,即secret_key就可以算出来了。

​ 并且在此时,我们读取templates/index.html可以看到几行关键性代码。

​ 此时,我们只要通过伪造session伪装成admin用户登录就可以了。

我拿到secret_key值为42.42408197657815,运用上面的那个工具,计算出伪造的session。

拿这个session登录,拿到flag。

发表评论

电子邮件地址不会被公开。 必填项已用*标注