BUUCTF WEB [De1CTF 2019]SSRF Me
Buuctf tengo que decir es un sitio bueno, el juego tiene una gran cantidad de problemas para reproducir! !
A reserva de la fuente:
#! /usr/bin/env python
#encoding=utf-8
from flask import Flask
from flask import request
import socket
import hashlib
import urllib
import sys
import os
import json
reload(sys)
sys.setdefaultencoding('latin1')
app = Flask(__name__)
secert_key = os.urandom(16)
class Task:
def __init__(self, action, param, sign, ip):
self.action = action
self.param = param
self.sign = sign
self.sandbox = md5(ip)
if(not os.path.exists(self.sandbox)): #SandBox For Remote_Addr
os.mkdir(self.sandbox)
def Exec(self):
result = {}
result['code'] = 500
if (self.checkSign()):
if "scan" in self.action:
tmpfile = open("./%s/result.txt" % self.sandbox, 'w')
resp = scan(self.param)
if (resp == "Connection Timeout"):
result['data'] = resp
else:
print resp
tmpfile.write(resp)
tmpfile.close()
result['code'] = 200
if "read" in self.action:
f = open("./%s/result.txt" % self.sandbox, 'r')
result['code'] = 200
result['data'] = f.read()
if result['code'] == 500:
result['data'] = "Action Error"
else:
result['code'] = 500
result['msg'] = "Sign Error"
return result
def checkSign(self):
if (getSign(self.action, self.param) == self.sign):
return True
else:
return False
#generate Sign For Action Scan.
@app.route("/geneSign", methods=['GET', 'POST'])
def geneSign():
param = urllib.unquote(request.args.get("param", ""))
action = "scan"
return getSign(action, param)
@app.route('/De1ta',methods=['GET','POST'])
def challenge():
action = urllib.unquote(request.cookies.get("action"))
param = urllib.unquote(request.args.get("param", ""))
sign = urllib.unquote(request.cookies.get("sign"))
ip = request.remote_addr
if(waf(param)):
return "No Hacker!!!!"
task = Task(action, param, sign, ip)
return json.dumps(task.Exec())
@app.route('/')
def index():
return open("code.txt","r").read()
def scan(param):
socket.setdefaulttimeout(1)
try:
return urllib.urlopen(param).read()[:50]
except:
return "Connection Timeout"
def getSign(action, param):
return hashlib.md5(secert_key + param + action).hexdigest()
def md5(content):
return hashlib.md5(content).hexdigest()
def waf(param):
check=param.strip().lower()
if check.startswith("gopher") or check.startswith("file"):
return True
else:
return False
if __name__ == '__main__':
app.debug = False
app.run(host='0.0.0.0')
También hay un tema pista:
auditoría en la fuente! El marco pitón frasco, tres rutas
índice para obtener el código fuente, geneSign llamado método getSign para generar MD5,
De1ta debe ser la clave de la página! Se puede ver llegar tres parámetros, dos de los cuales se obtienen de una cookie:
action = urllib.unquote(request.cookies.get("action"))
param = urllib.unquote(request.args.get("param", ""))
sign = urllib.unquote(request.cookies.get("sign"))
Como parámetro pasado a la clase de tareas, y llama al método Exec () en la clase de tareas, lo que debería ser la clave! !
El análisis de tres parámetros:
El primer parámetro es la acción de lectura entrante y exploración, el
segundo argumento debe ser visto pasar a un nombre de archivo,
el tercer parámetro es un valor MD5 señal,
para dar seguimiento a la tarea Exec ( ) método se puede encontrar que hay también una checkSign (), y no llama getSign () método, los resultados se compararon con el signo
mirada más cercana método getSign (), encontramos una secert_key se desconoce ,,,, ,
después de leer el código tendrá una cierta comprensión! ! Su objetivo debe ser leído el contenido de Flag.txt nosotros en!
Por lo que necesitamos para construir parámetros! La primera acción argumento debe contener leer ,, parámetro de nombre de fichero segundo parámetro debe ser
el más importante es el tercer argumento, porque no conocemos el valor de secert_key, que no es su propia encriptación, sitios de prueba debería estar aquí!
Acceso qué página geneSign y pasar parámetros PARAM = Flag.txt obtener una cadena de valor MD5: ea25b05cf3918f0728b123883e59f93c
de esta manera obtenemos el valor MD5 (secert_key + flag.txtscan) de! !
Miró y vio que MD5 es un personaje costura! ! Nosotros configurado parámetro PARAM = flag.txtread parámetros
para que podamos obtener el valor MD5 MD5 (secert_key + flag.txtreadscan): el a8bda0fcca126badfc8483ee6b3623cc
acceso a la página re-De1ta paso de parámetros, obtener la bandera:
Debido a que somos capaces de derivación a través de la concatenación de cadenas checkSign () método! ! Así que podemos conseguir amigos ~ ~ bandera
De hecho, hay una manera, es MD5Hash ataque extensión de la longitud! ! !
De hecho, este método es relativamente insípido, pero el título CTF aún es posible, que no aparece! ! !
medios de hash de ataque extensión de la longitud para permitir alguna función hash criptográfica (MD5, SHA1 y similares) contienen información adicional de los ataques
a entender el proceso de cifrado se puede apreciar que el ataque extensión porque cifrado MD5 se cifra paquete de
principio: la Hash la extensión de la Longitud ataque
El anterior artículo fue muy bien escrito! Dijo muy claramente, lo que es el ataque extensión de hash ,,
aquí nos limitamos a usar la herramienta, no utilice herramientas pueden hacer, usted mismo, entender el principio debe ser capaz de lograr salir! !
kali HashPump instalación:
git clone https://github.com/bwall/HashPump
apt-get install g++ libssl-dev
cd HashPump
make
make install
Operación, y la cadena md5 valor obtenido:
e4310fe8dd373052d4e304f725f683f1
scan\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00read
Parámetro de pasar a dar a bandera: