Audite el código fuente y agregue algunos comentarios
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) ) :
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
@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' )
Un breve resumen del código después de la auditoría
Hay tres rutas en el marco de Flask
/geneSign:
La página de prueba devuelta está cifrada por md5 secert_key + param + action
/De1ta:
La parte central del tema
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
task = Task( action, param, sign, ip)
return json. dumps( task. Exec( ) )
Obtenga una serie de datos, filtros de parámetros, gopher y archivo, genere el objeto Task, llame al comando Exec () para ejecutar la función para leer el archivo
/:
Regrese al código fuente, nada es útil y el problema se le da al lugar de descarga.
En el primer paso de ejecutar la función Exec (), hay un if(self.checkSign())
def checkSign ( self) :
if ( getSign( self. action, self. param) == self. sign) :
return True
else :
eturn False
def getSign ( action, param) :
return hashlib. md5( secert_key + param + action) . hexdigest( )
Entonces, el signo que pasamos debe ser consistente con el signo generado por getSign ()
Entonces visitamos el /geneSign
enrutamiento get upload? Param = flag.txtread
adf80ee5dfe9c60c8575ebd2c8baacf1
Página atrás
Este es el valor encriptado md5 devuelto por la página cuando action = readscan param = flag.txt
Debido a que la acción se ha corregido para escanear cuando se genera, solo se requiere param = readscan
def geneSign ( ) :
param = urllib. unquote( request. args. get( "param" , "" ) )
action = "scan"
return getSign( action, param)