zoukankan      html  css  js  c++  java
  • HCTF2018-admin

    注册账号登录,打开f12我们能够看到github的提示,我们把源码下载下来进行分析。

    查看初始化模块
    from flask import Flask
    from config import Config
    from flask_sqlalchemy import SQLAlchemy
    from flask_migrate import Migrate
    from flask_login import LoginManager
    
    app = Flask(__name__)
    app.config.from_object(Config)
    db = SQLAlchemy(app)
    migrate = Migrate(app, db)
    login = LoginManager(app)
    
    from app import routes, models  
    

    查看routes文件

    修改password模块
    @app.route('/change', methods = ['GET', 'POST'])
    def change():
        if not current_user.is_authenticated:
            return redirect(url_for('login'))
        form = NewpasswordForm()
        if request.method == 'POST':
            name = strlower(session['name'])
            user = User.query.filter_by(username=name).first()
            user.set_password(form.newpassword.data)
            db.session.commit()
            flash('change successful')
            return redirect(url_for('index'))
        return render_template('change.html', title = 'change', form = form)
    
    register登记注册模块
    @app.route('/register', methods = ['GET', 'POST'])
    def register():
    
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    
    form = RegisterForm()
    if request.method == 'POST':
        name = strlower(form.username.data)
        if session.get('image').lower() != form.verify_code.data.lower():
            flash('Wrong verify code.')
            return render_template('register.html', title = 'register', form=form)
        if User.query.filter_by(username = name).first():
            flash('The username has been registered')
            return redirect(url_for('register'))
        user = User(username=name)
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('register successful')
        return redirect(url_for('login'))
    return render_template('register.html', title = 'register', form = form)
    
    查看渲染的index页面
    {% 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 %}
    <!-- you are not admin -->
    <h1 class="nav">Welcome to hctf</h1>
    
    {% include('footer.html') %}  
    

    发现判断逻辑: {% if current_user.is_authenticated and session['name'] == 'admin' %} 证明要使用admin账号才能登陆。

    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  
    

    flask的session是存储在客户端cookie中的,而且flask仅仅对数据进行了签名。众所周知的是,签名的作用是防篡改,而无法防止被读取。而flask并没有提供加密操作,所以其session的全部内容都是可以在客户端读取的,这就可能造成一些安全问题。
    利用脚本我们将session解密,之后修改用户名为admin,然后再加密,burp截包替换session即可。

    {'_fresh': True, '_id': b'121de14bca66edf6cc98e254ab460d68f9122c75e64747a997410a84049d9295b53192aebf5c2b93641e5c58cc1596ed3850da7a17a5f3f6415ac0743afe3dc4', 'csrf_token': b'd2495789467d55d9e38c2ffd63e9c578ee1b267a', 'image': b'BUXE', 'name': 'admin', 'user_id': '10'}
    
    unicode欺骗

    无论是在register,changepassword模块他们都加了strlower()进行小写转换,右键转到函数的实现。

    def strlower(username):
        username = nodeprep.prepare(username)
        return username
    

    使用到nodeprep.prepare函数,该函数专函大小写字符如下:
    ᴬᴰᴹᴵᴺ -> ADMIN -> admin
    我们注册ᴬDMIN用户,在registr中这个函数没被使用不被转义,在login进行第一次的编码转换,在changepassword又进行第二次,此时我们用户名就由ᴬDMIN变为了admin,修改了admin的password。
    转换形式如下:
    ᴬᴰᴹᴵᴺ -> ADMIN -> admin

    条件竞争

    这个在刚入学时候极客大挑战已经碰见过了,我们利用burpsuit的intruder模块就能利用,要设置两个线程同时进行,一个是不行的。

  • 相关阅读:
    python之shutil模块
    python的os模块
    python的map函数
    Web基础知识
    Web基础知识 --- html中的meta元素有什么用?
    使用技巧 --- 与 FireFox 相关
    基础知识之WIN32 API
    资料索引
    基础知识之C++篇
    使用技巧 --- 与 Visual Studio 有关
  • 原文地址:https://www.cnblogs.com/ophxc/p/12887959.html
Copyright © 2011-2022 走看看