[HCTF 2018]admin

来到题目的主页面,看到主页右面有一个下拉框,有登陆,注册功能,注册个用户再说,登陆后有编辑、更改密码、登出功能。

在这里插入图片描述
源码中hint提示不是admin,题目肯定是想让我们登陆admin用户,在更改密码页面源码中有一个github地址,去看一下github

在这里插入图片描述
是一个flask项目下载下来审计一下,先看下路由routes.py
index函数

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

在这里插入图片描述
当用户为admin时才输出falg,看下登陆注册其它函数

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

Unicode欺骗

简单的代码审计后发现登陆、注册、更改密码函数都使用了strlower函数,在末尾定义了strlower函数,这突破口不就来了

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

nodeprep.prepare函数从twisted

from twisted.words.protocols.jabber.xmpp_stringprep import nodeprep

requirements.txt中看一下版本吧

在这里插入图片描述
百度了一下twisted已经22.4.0版本,nodeprep.prepare函数对unicode编码处理后得到正常的字符
也就是说nodeprep.prepare函数对unicode的ᴬ转换为A,当再次调用nodeprep.prepare函数时就会转换为a
这样先创建个ᴬdmin用户,当登陆时调用nodeprep.prepare函数将用户名转换为Admin。
在修改密码中同样也调用了nodeprep.prepare函数,我们将其修改密码,就是修改了admin用户的密码

注册ᴬdmin用户主页显示的为Admin用户

在这里插入图片描述
登陆admin账号密码为刚才修改的密码,拿到flag

弱口令

此非预期解
直接登陆用户admin密码为123
此题还可以使用flask的session伪造但也是非预期解,github上有flask的加解密脚本跑一下也可以得到flag

专注,勤学,慎思。戒骄戒躁,谦虚谨慎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值