hctf2018-admin

1、问题分析

熟悉一下网站,有这些功能:注册、登录、上传文章、修改密码、登出

对源码进行观察,发现

源码中存在
<!-- you are not admin -->

可能我们要以管理员身份登录吧。

继续找线索,最后发现在修改密码的源码中有:
在这里插入图片描述https://github.com/woadsl1234/hctf_flask/
这个是网站用的flask源码,然后clone下来就可以进行代码审计了。

routes.py里面有页面所有功能的代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from flask import Flask, render_template, url_for, flash, request, redirect, session, make_response
from flask_login import logout_user, LoginManager, current_user, login_user
from app import app, db
from config import Config
from app.models import User
from forms import RegisterForm, LoginForm, NewpasswordForm
from twisted.words.protocols.jabber.xmpp_stringprep import nodeprep
from io import BytesIO
from code import get_verify_code

@app.route('/code')
def get_code():
    image, code = get_verify_code()
    # 图片以二进制形式写入
    buf = BytesIO()
    image.save(buf, 'jpeg')
    buf_str = buf.getvalue()
    # 把buf_str作为response返回前端,并设置首部字段
    response = make_response(buf_str)
    response.headers['Content-Type'] = 'image/gif'
    # 将验证码字符串储存在session中
    session['image'] = code
    return response

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html', title = 'hctf')

@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)

@app.route('/login', methods = ['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('index'))

    form = LoginForm()
    if request.method == 'POST':
        name = strlower(form.username.data)
        session['name'] = name
        user = User.query.filter_by(username=name).first()
        if user is None or not user.check_password(form.password.data):
            flash('Invalid username or password')
            return redirect(url_for('login'))
        login_user(user, remember=form.remember_me.data)
        return redirect(url_for('index'))
    return render_template('login.html', title = 'login', form = form)

@app.route('/logout')
def logout():
    logout_user()
    return redirect('/index')

@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)

@app.route('/edit', methods = ['GET', 'POST'])
def edit():
    if request.method == 'POST':
        
        flash('post successful')
        return redirect(url_for('index'))
    return render_template('edit.html', title = 'edit')

@app.errorhandler(404)
def page_not_found(error):
    title = unicode(error)
    message = error.description
    return render_template('errors.html', title=title, message=message)

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

开头看到

app.route('/')
@app.route('/index')
def index():
    return render_template('index.html', title = 'hctf')

说明用了模板渲染,用的是index.html,查看index.html的代码:

{% 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') %}

显示flag的条件是:
current_user.is_authenticated and session[‘name’] == ‘admin’
session的那么需要修改,当前的用户还需要得到授权,当然admin用户是有授权的。

2、flask session伪造

关于flask,我们知道flask 的session是存在于客户端(浏览器)的cookie中的,我们在请求头中可以看到,而在安全方面,flask对数据仅仅是进行了签名,防止数据被篡改,但是数据仍然可以被读取。

而用户的身份信息在也存在于session中,可以对session进行修改来达到伪造身份的目的。

我们需要的是对session进行加解密来进行session修改。
拿到session:

.eJw9UE2LwkAM_StLzh7aai8FDy61RSFTWkZK5iLdWrWZGReqUjvif9_BBQ8hHy95vJcn7I9Ddz1Dchvu3Qz2_QGSJ3z9QAIqVRplG2IuWMhTKPJ1QFFmyZUPJTNDvBlVWjE51WMquEg3C5GXC-F0hLyKKSpjvxsTn-YojcY60ySFRda-1zFamitJI6Y4Vz78zVjk1ZlYGcVrz91Ofh4p1hNFgol3EzpfOQqFax_E31qkqxHrzRJeM2ivw3F_-9Xd5WMB2ZxJZqzs1svDgNzW-ByRPFgvpfcWAuI2RlcGoq50IZWhcvmm621z6j5McndbVOM_cmmsB6BpYAb3aze8nwZhAK8_y-pr_w.XYzBwA.8riiXn6Rgx5ONsRDxM5CJMp_9r8

然后进行解密:
在这里插入图片描述解密之后的session结构就是:

{’_fresh’: True, ‘_id’: b’d6d1750cc5854a4cafc41e1eb20d4cc6b03c8284d8796209cd9c49b8719d1ada3f2971992f7e60037d372008dab6ef10d72d36f92cccb52366765771b0d4001b’, ‘csrf_token’: b’29aa1cfbc834c2e836a7fa3bb24b793445dd96ea’, ‘image’: b’MKxG’, ‘name’: ‘aa’, ‘user_id’: ‘10’}

然后把name修改为admin再进行加密:
在这里插入图片描述然后把session修改为我们伪造的加密结果:
在这里插入图片描述然后就拿到flag了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值