Page cover

Airplane

Are you ready to fly?

Room Link

This work by Manav G Krishna is licensed under CC BY-NC 4.0

Machine IP: 10.10.116.253

Nmap Scan:

From the scan, we can see ports 22, 6048, and 8000 open and also there is a domain named airplane.thm which can be seen in the http-title part.

Hosts file entry: echo '10.10.116.253 airplane.thm' | sudo tee -a /etc/hosts

Checking out port 6048:

The Nmap Scan says that the service running on this port might be x11. It is not certain as it gives a question mark (x11?). Let us now check out resources to pentest this service anyways.

Ports 6000-6063 is where we typically find the x11 service:

SpeedGuide also mentions: Known Unauthorized Use on port 6003.

Pentesting X11:

HackTricks mentions that we could check if we can connect anonymously to the x11 port. From the information that we got from SpeedGuide, only port 6003 has been identified as being susceptible to unauthorized access, but in our case x11 might be running on port 6048, but we can still try to check for anonymous connection via the scanner auxiliary module present in Metasploit to see what we get.

This shows we can't connect anonymously to the port 6048. This is pretty much a dead end now. HackTricks didn't have anything else that was worth testing out for x11.

Now we can look at port 8000.

Checking out port 8000:

From the Nmap Scan we can see that server running on this port is a Python web server utilizing Werkzeug.

We can do some directory busting:

Command:

There is a path named /airplane. Checking it out:

Nothing interesting here.

Upon browsing http://airplane.thm:8000 we are redirected to http://airplane.thm:8000/?page=index.html.

There is a parameter in the URL named page (?page=) and the first thing that comes to mind is LFI (Local File Inclusion).

We can now try to traverse/climb the directory tree to fetch files such as /etc/passwd etc. and doing it via the terminal would be a lot more easier:

Command:

We indeed have successful LFI.

From the /etc/passwd file contents we have two users other than root having a console, that is hudson and carlos. Trying to fetch the ssh private key (id_rsa) of these users, the user.txt flag etc. didn't yield any results.

Now let us try to fetch some files from the /proc file system (It provides detailed information about kernel, processes, and configuration parameters in a structured manner under the /proc directory):

  1. /proc/self/cmdline: It is a file that contains the command line arguments that were used to start the current process.

Command:

It outputs: /usr/bin/python3app.py. This shows that, the current process that is running is app.py.

We can now try to fetch the app.py file:

Command:

There is nothing of interest in here.

  1. /proc/sched_debug: It is a file that can be used to retrieve running processes. It provides information about the state of the Linux scheduler.

Command:

The file contents has a section labeled runnable tasks which lists all the tasks (processes or threads) that are considered runnable by the scheduler. The S column shows the Process status (S: Sleeping, R: Running, I: Idle).

Extracting information from these processes (PIDs):

We can try to fetch the command line arguments for the various processes by substituting the PIDs within: /proc/[pid]/cmdline. Manually doing so is practically not possible as we have lots of processes based on the sched_debug file content. Writing a script is what would help.

The script:

This is a simple script written in bash:

Explanation:

This fetches the contents of the sched_debug file:

/^runnable tasks:/,/^$/: This part tells awk to look for lines starting with runnable tasks: and continue until it finds an empty line.

{if ($3 ~ /^[0-9]+$/) print $3}: Inside the runnable tasks section, it checks if the third column ($3) is a number (PID) and then it prints that number:

This takes each PID found by awk and loops through them:

For each PID, it then fetches and display its cmdline:

Running the script:

We then come across this cmdline that stands out:

/usr/bin/gdbserver0.0.0.0:6048airplane

Finally we now know what exactly is running on port 6048. It is gdbserver. This is a tool that enables the debugging of programs remotely.

Based on the command gdbserver is listening on all network interfaces (0.0.0.0) on port 6048 and the executable program that gdbserver is said to debug is airplane.

This executable can also be found running as a process:

This binary can be downloaded via LFI as we have it's location, and it can be run:

Command:

Nothing interesting could be found post reverse engineering it. Let us go back to check out the gdbserver and find ways to exploit it.

Metasploit Exploit:

We have to set the RHOSTS, RPORT, LPORT and the target architecture, on which the payload will be based.

First up, we have to find the target machine's arch. We can do the same by fetching the /proc/version file:

Command:

This file specifies the version of the Linux kernel, the version of gcc used to compile the kernel, and the time of kernel compilation.

It says amd64, so it is a 64-bit machine. The target can be now set to x86_64 (Id - 1).

Setting up the options:

Running the exploit:

We have got a shell as the user hudson. The same can be done without using Metasploit too.

Exploitation w/o Metasploit:

Commands:

Now set up a listener on port 5555:

We can place the binary in the /tmp directory as it is universally writeable:

The moment we type in run, we can see we have got a connection on the listener on port 5555:

Now we can upgrade the shell a little by running this:

Commands:

The user flag is within carlos's home directory:

Command:

So now we have to laterally move to carlos from hudson, unless we directly get to root.

Enumeration:

Checking for binaries that have the SUID bit set:

Command:

The find binary has the SUID bit set. Files which have SUID permissions run with higher privileges.

Searching in GTFOBins:

Command:

The EUID (Effective User ID) bit is now set to carlos. This means that the shell that we got has the effective permissions and privileges associated with the user carlos, but the shell session itself is running as the user hudson. So the shell is still in the context of hudson.

The user flag can be found it carlos's home directory:

We can now generate a ssh key pair and the public key can be placed on the target machine inside the /.ssh directory within carlos's home directory as authorized_keys:

Command:

Now we can SSH in as carlos:

Command:

Now we have a full fledged shell as carlos.

Privilege Escalation: We can now check for carlos's sudo rights/privs:

This command: /usr/bin/ruby /root/*.rb can be run as any user without us being prompted to enter a password. By making use of that command we would be able to get to root.

The security risk:

The problem here is, the command: /usr/bin/ruby /root/*.rb has a wildcard character (*) in the path argument and this command can be run by us with sudo rights, basically with elevated privs. * matches any character (including whitespaces), so we can modify the path as needed via a simple path traversal. We can get a root shell this way.

Command:

The file when run with elevated privs, will set the SUID bit on the bash binary.

The command can be run within carlos's home directory as we as carlos will have write permissions on it:

Getting a root shell:

Command:

Now let us check out the bash binary:

The SUID bit has been indeed set.

Now we can just type in this to get a root shell:

Command:

When bash is invoked with the -p option, it starts in privileged mode. Normally, when bash starts, it drops certain privileges for security reasons. The -p flag prevents bash from doing this.

We are root.

A simpler way to do the same would be directly spawning a bash shell, like so:

Now we can fetch the root flag from the /root directory.

Room solved!!

Profile Link

Last updated