Buscando en un backup acabo de encontrar este script y lo dejo por si a alguien le sirve.
Hace un tiempo programé un wargame y necesitaba una manera de comprobar que nadie hubiese comprometido los archivos de la web. Las opciones eran verificar los arhivos de más de 20 retos a mano y comprobar que no hubiesen subido una shell o incrustado código en algún php existente. Así que decidí codear un script que me indicara si se creó o modificó algún archivo.
Funcionamiento de script: El script crawlea un directorio y guarda en una "base de datos" (en este caso un diccionario serializado) la ruta de los archivos y sus respectivos hash md5. Para comprobar si un archivo a sido modificado, simplemente se compara su hash md5 con el que está en la BD y obviamente si el archivo no se encuentra en la BD es porque fue creado despues.
Además indica los archivos de backup (.*~) que encuentra.
# -*- coding: utf-8 -*-
#11Sep
import os
import sys
import hashlib
import cPickle
recursividad = False
diccionario = {}
COLORES = {
"archivo": "\033[91m\t[Archivo nuevo] %s\033[0m", # Rojo
"carpeta": "\033[94m\t[Carpeta nueva] %s\033[0m", # Azul
"modificado": "\033[93m\t[Modificado] %s\033[0m", # Amarillo
"backup": "\033[91m\t[BACKUP] %s\033[0m", # Rojo
}
MENU = """Modo de uso:
%s ruta [parametros]
-r Modo recursivo
-a Actualiza la BD
-v Para ver archivos y hashes
"""
def imprimir(data, color):
if its_linux:
print COLORES[color] % data
else:
print data
def es_archivo(ruta):
if os.path.isfile(ruta):
return True
def es_directorio(ruta):
if os.path.isdir(ruta):
return True
def guardar():
with open("./data.sf", "wb") as archivo:
cPickle.dump(diccionario, archivo, 2)
def cargar():
global diccionario
try:
with open("./data.sf", "rb") as archivo:
diccionario = cPickle.load(archivo)
return True
except:
return False
def get_md5(ruta):
md5 = hashlib.md5()
with open(ruta, "r") as hash:
for linea in hash.readlines():
md5.update(linea)
return md5.hexdigest()
def recorrer(path, opt):
if es_directorio(path):
if not diccionario.has_key(path):
diccionario[path] = {}
imprimir(path, "carpeta")
archivos = os.listdir(path)
for archivo in archivos:
ruta_completa = os.path.join(path, archivo)
if es_archivo(ruta_completa):
extension = os.path.splitext(ruta_completa)[1]
if extension.endswith("~"):
imprimir(ruta_completa, "backup")
if opt == 1:
diccionario[path][archivo] = get_md5(ruta_completa)
else:
md5 = get_md5(ruta_completa)
md5_bd = diccionario[path].get(archivo)
if md5_bd:
if md5_bd != md5:
imprimir(ruta_completa, "modificado")
else:
imprimir(ruta_completa, "archivo")
elif es_directorio(ruta_completa) and recursividad:
recorrer(ruta_completa, opt)
its_linux = (os.name == "posix")
argumentos = sys.argv
if len(argumentos) > 1:
parametros = []
ruta = argumentos[1]
parametros = argumentos[2:]
if "-r" in parametros:
recursividad = True
if not es_directorio(ruta):
print "Ruta no valida"
exit()
else:
if "-a" in parametros:
diccionario = {}
recorrer(ruta, 1)
guardar()
exit()
if cargar():
recorrer(ruta, 2)
else:
recorrer(ruta, 1)
guardar()
if "-v" in parametros:
for x, y in diccionario.iteritems():
print x
for archivo, hash in sorted(y.iteritems()):
print "\t", archivo, hash
else:
print MENU % os.path.split(argumentos[0])[-1]
Las opciones son:
-v: para ver la BD de los archivos y hashes md5
-a: para actualizar la BD
-r: para recorrer las carpetas en modo recursivo
(http://i.imgur.com/qqyiERt.png)
(http://i.imgur.com/PwOnx9W.png)
(http://i.imgur.com/z8CsEo1.png)
(http://i.imgur.com/Oo1nzBl.png)
Saludos!
Muy útil! Gracias.
Saludos.