diff --git a/modules/vulnerabilities/unix/http/librenms_rce/files/composer.phar b/modules/vulnerabilities/unix/http/librenms_rce/files/composer.phar new file mode 100644 index 000000000..decd0873c Binary files /dev/null and b/modules/vulnerabilities/unix/http/librenms_rce/files/composer.phar differ diff --git a/modules/vulnerabilities/unix/http/librenms_rce/files/distro.txt b/modules/vulnerabilities/unix/http/librenms_rce/files/distro.txt new file mode 100644 index 000000000..da06f943a --- /dev/null +++ b/modules/vulnerabilities/unix/http/librenms_rce/files/distro.txt @@ -0,0 +1,161 @@ +#!/usr/bin/env sh +# Detects which OS and if it is Linux then it will detect which Linux Distribution. + +OS=$(uname -s) +REV=$(uname -r) +#MACH=$(uname -m) + +if [ "${OS}" = "SunOS" ] ; then + OS=Solaris + ARCH=$(uname -p) + OSSTR="${OS} ${REV}(${ARCH} $(uname -v))" + +elif [ "${OS}" = "AIX" ] ; then + OSSTR="${OS} $(oslevel) ($(oslevel -r))" + +elif [ "${OS}" = "Linux" ] ; then + #KERNEL=$(uname -r) + + if [ -f /etc/fedora-release ]; then + DIST=$(cat /etc/fedora-release | awk '{print $1}') + REV=$(cat /etc/fedora-release | sed s/.*release\ // | sed s/\ .*//) + + elif [ -f /etc/redhat-release ] ; then + DIST=$(cat /etc/redhat-release | awk '{print $1}') + if [ "${DIST}" = "CentOS" ]; then + DIST="CentOS" + IGNORE_OS_RELEASE=1 # https://bugs.centos.org/view.php?id=8359 + elif [ "${DIST}" = "CloudLinux" ]; then + DIST="CloudLinux" + elif [ "${DIST}" = "Mandriva" ]; then + DIST="Mandriva" + #PSEUDONAME=$(cat /etc/mandriva-release | sed s/.*\(// | sed s/\)//) + REV=$(cat /etc/mandriva-release | sed s/.*release\ // | sed s/\ .*//) + elif [ -f /etc/oracle-release ]; then + DIST="Oracle" + elif [ -f /etc/rockstor-release ]; then + DIST="Rockstor" + elif [ -f /etc/rocky-release ]; then + DIST="Rocky" + else + DIST="RedHat" + fi + + #PSEUDONAME=$(cat /etc/redhat-release | sed s/.*\(// | sed s/\)//) + REV=$(cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//) + + elif [ -f /etc/almalinux-release ] ; then + DIST='AlmaLinux' + #PSEUDONAME=$(cat /etc/almalinux-release | sed s/.*\(// | sed s/\)//) + REV=$(cat /etc/almalinux-release | sed s/.*release\ // | sed s/\ .*//) + + elif [ -f /etc/mandrake-release ] ; then + DIST='Mandrake' + #PSEUDONAME=$(cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//) + REV=$(cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//) + + elif [ -f /etc/devuan_version ] ; then + DIST="Devuan $(cat /etc/devuan_version)" + REV="" + + elif [ -f /etc/debian_version ] ; then + DIST="Debian $(cat /etc/debian_version)" + REV="" + IGNORE_OS_RELEASE=1 + if [ -f /usr/bin/lsb_release ] ; then + ID=$(lsb_release -i | awk -F ':' '{print $2}' | sed 's/\s//g') + fi + if [ "${ID}" = "Raspbian" ] ; then + DIST="Raspbian $(cat /etc/debian_version)" + fi + if [ -f /usr/bin/pveversion ]; then + DIST="${DIST}/PVE $(/usr/bin/pveversion | cut -d '/' -f 2)" + fi + if [ -f /usr/bin/pmgversion ]; then + # pmgversion requires root permissions to run, please add NOPASSWD setting to visudo. + DIST="${DIST}/PMG $(sudo /usr/bin/pmgversion | cut -d '/' -f 2)" + fi + if [ -f /etc/dogtag ]; then + DIST=$(cat /etc/dogtag) + fi + + elif [ -f /etc/gentoo-release ] ; then + DIST="Gentoo" + REV=$(tr -d '[[:alpha:]]' /dev/null 2>&1 + fi + fi + + # try standardized os version methods + if [ -f /etc/os-release ] && [ "${IGNORE_OS_RELEASE}" != 1 ] ; then + . /etc/os-release + STD_DIST="$NAME" + STD_REV="$VERSION_ID" + elif [ -f /etc/lsb-release ] && [ "${IGNORE_LSB}" != 1 ] ; then + STD_DIST=$(lsb_release -si) + STD_REV=$(lsb_release -sr) + fi + if [ -n "${STD_DIST}" ]; then + DIST="${STD_DIST}" + fi + if [ -n "${STD_REV}" ]; then + REV="${STD_REV}" + fi + + if [ -n "${REV}" ]; then + OSSTR="${DIST} ${REV}" + else + OSSTR="${DIST}" + fi + +elif [ "${OS}" = "Darwin" ] ; then + if [ -f /usr/bin/sw_vers ] ; then + OSSTR=$(/usr/bin/sw_vers|grep -v Build|sed 's/^.*:.//'| tr "\n" ' ') + fi + +elif [ "${OS}" = "FreeBSD" ] ; then + if [ -f /etc/version ] ; then + DIST=$(cat /etc/version | cut -d'-' -f 1) + if [ "${DIST}" = "FreeNAS" ]; then + OSSTR=$(cat /etc/version | cut -d' ' -f 1) + fi + else + OSSTR=$(/usr/bin/uname -mior) + fi +fi + +if [ -f /etc/vpp/startup.conf ]; then + OSSTR="VPP ${OSSTR}" +fi + +echo "${OSSTR}" diff --git a/modules/vulnerabilities/unix/http/librenms_rce/files/librenms-1.43.zip b/modules/vulnerabilities/unix/http/librenms_rce/files/librenms-1.43.zip new file mode 100644 index 000000000..85b4bbf2f Binary files /dev/null and b/modules/vulnerabilities/unix/http/librenms_rce/files/librenms-1.43.zip differ diff --git a/modules/vulnerabilities/unix/http/librenms_rce/librenms_rce.pp b/modules/vulnerabilities/unix/http/librenms_rce/librenms_rce.pp new file mode 100644 index 000000000..ee0db04d1 --- /dev/null +++ b/modules/vulnerabilities/unix/http/librenms_rce/librenms_rce.pp @@ -0,0 +1,8 @@ +# begining of puppet code execution + +contain librenms_rce::install +contain librenms_rce::librenms +contain librenms_rce::webserver +Class['librenms_rce::install'] -> +Class['librenms_rce::librenms'] -> +Class['librenms_rce::webserver'] \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/librenms_rce/manifests/install.pp b/modules/vulnerabilities/unix/http/librenms_rce/manifests/install.pp new file mode 100644 index 000000000..400ae817a --- /dev/null +++ b/modules/vulnerabilities/unix/http/librenms_rce/manifests/install.pp @@ -0,0 +1,33 @@ +class librenms_rce::install { + $releasename = 'librenms-1.43' + $docroot = '/opt/librenms' + # sets the default paths to use + Exec { path => ['/bin', '/usr/bin', '/usr/local/bin', '/sbin', '/usr/sbin'] } + #TESTING ONLY make sure to run apt-get update before running module + #TODO remove package redundencies + #ensure_packages(['acl','composer','curl','fping','git','graphviz','imagemagick','mariadb-server','mtr-tiny','nginx-full','nmap','php7.3-cli','php7.3-curl','php7.3-fpm','php7.3-gd','php7.3-json','php7.3-mysql','php7.3-snmp','php7.3-xml','php7.3-zip','php7.3-mbstring','php-mysqli','python-memcache','python-mysqldb','rrdtool','snmp','snmpd','whois','php-xml','php-gd','php-mbstring','php-json','libapache2-mod-php','php','python3-pymysql','python3-dotenv','python3-redis','python3-setuptools','software-properties-common']) + #ensure_packages(['php','php-common','php-cli','php-fpm','php-json','php-pdo','php-mysql','php-zip','php-gd','php-mbstring','php-curl','php-xml','php-pear','php-bcmath']) + + ensure_packages(['software-properties-common']) + ensure_packages(['curl','acl','composer','fping','git','graphviz','imagemagick','mariadb-server','mtr-tiny','nginx-full','nmap','python-memcache','python-mysqldb','python-pip','rrdtool','snmp','snmpd','whois']) + ensure_packages(['php-common','php-cli','php-fpm','php-json','php-pdo','php-mysql','php-zip','php-gd','php-mbstring','php-curl','php-xml','php-pear','php-bcmath']) + + # copy and unzip archive + file { 'librenms': + ensure => file, + path => "/usr/local/src/${releasename}.zip", + source => "puppet:///modules/librenms_rce/${releasename}.zip" + } + exec { 'unzip-librenms': + cwd => '/usr/local/src', + command => "unzip ${releasename}.zip -d /opt", + require => File['librenms'] + } -> + exec {'rename-directory': + cwd => '/opt', + command => "mv ${releasename} librenms", + logoutput => true + } + + +} \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/librenms_rce/manifests/librenms.pp b/modules/vulnerabilities/unix/http/librenms_rce/manifests/librenms.pp new file mode 100644 index 000000000..26d95374d --- /dev/null +++ b/modules/vulnerabilities/unix/http/librenms_rce/manifests/librenms.pp @@ -0,0 +1,90 @@ +class librenms_rce::librenms { + #TODO Make SecGen parameter? + $username = 'librenms' ##TODO $secgen_parameters + $password = 'password' ##TODO $secgen_parameters + #TODO make same as librenms user? + $db_name = 'librenms'##$secgen_parameters['db_name'][0] + $host = 'localhost' + $charset = 'utf8mb4' + $collate ='utf8mb4_unicode_ci' + + Exec { path => ['/bin', '/usr/bin', '/usr/local/bin', '/sbin', '/usr/sbin'] } + + #create system user + user { $username: + ensure => present, + password => pw_hash($password, 'SHA-512', 'mysalt'), + groups => 'www-data', + home => '/opt/librenms', + managehome => false, + system => true, + notify => Exec['chown-librenms'], + + } + + #set folder permissions + exec { 'chown-librenms': + command => "chown -R ${username}:${username} /opt/librenms", + logoutput => true + }-> + exec { 'chmod-librenms': + command => 'chmod 770 /opt/librenms', + logoutput => true + }-> + exec { 'deafult-acl-librenms': + command => 'setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/', + logoutput => true + }-> + exec { 'recursive-acl-librenms': + command => 'setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/', + logoutput => true + }-> + #install composer manually + file { 'composer': + ensure => file, + path => '/usr/bin/composer', + source => 'puppet:///modules/librenms_rce/composer.phar', + } -> + exec{ 'chmod-composer': + cwd => '/usr/bin/', + command => 'chmod +x /usr/bin/composer', + logoutput => true + } + + + #set up librenms database + mysql::db { 'librenms_database': + user => $username, + password => $password, + dbname => $db_name, + charset => $charset, + collate => $collate, + host => $host, + grant => ['ALL'] + } + file_line{ '50-server.cnf-innodb': + ensure => present, + path => '/etc/mysql/mariadb.conf.d/50-server.cnf', + line => 'innodb_file_per_table=1', + match => '^innodb_file_per_table=', + after => '# * InnoDB' + + } + + file_line{ '50-server.cnf-lowercase': + ensure => present, + path => '/etc/mysql/mariadb.conf.d/50-server.cnf', + line => 'lower_case_table_names=0', + match => '^lower_case_table_names=', + after => '#skip-external-locking' + } + + exec{'restart-mysql': + command => 'service mysql restart', + logoutput => true, + require => [ File_line['50-server.cnf-lowercase'], File_line['50-server.cnf-innodb'] ] + + } + + +} \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/librenms_rce/manifests/webserver.pp b/modules/vulnerabilities/unix/http/librenms_rce/manifests/webserver.pp new file mode 100644 index 000000000..36e0c2d0c --- /dev/null +++ b/modules/vulnerabilities/unix/http/librenms_rce/manifests/webserver.pp @@ -0,0 +1,103 @@ +class librenms_rce::webserver{ + $timezone ='Europe/London' + $port = '80' + $host = 'localhost' + $username = 'librenms' ##TODO $secgen_parameters + $password = 'password' ##TODO $secgen_parameters + #$nginx_server_name = www.librenms_example.com ##SECGEN parameter + $community_string = fqdn_rand_string(20, 'ABCDEF!@$%^') ##secgen? + #TODO FIX NGIX server (virtual host or permissions issues) + Exec { path => ['/bin', '/usr/bin', '/usr/local/bin', '/sbin', '/usr/sbin'] } + #Configure and Start PHP-FPM + #set time zones + exec{'set-system-timezone': + command => "timedatectl set-timezone ${timezone}", + logoutput => true, + }-> + file_line{ 'set-timezone-fpm': + ensure => present, + path => '/etc/php/7.3/fpm/php.ini', + line => "date.timezone =${timezone}", + match => '^date.timezone =', + } -> + file_line{ 'set-timezone-cli': + ensure => present, + path => '/etc/php/7.3/cli/php.ini', + line => "date.timezone =${timezone}", + match => '^date.timezone =', + }-> + exec{'restart-php-fpm': + command => 'service php7.3-fpm restart', + logoutput => true, + + } + #configure nginx + + file{'nginx-deafult': + ensure => absent, + path => '/etc/nginx/sites-enabled/default', + + + }-> + file { 'librenms.conf': + ensure => present, + path => '/etc/nginx/sites-available/librenms.vhost', + content => template('librenms_rce/librenms.vhost.erb'), + }-> + exec {'restart-nginx': + command => 'systemctl restart nginx', + logoutput => true, + require => Exec['restart-php-fpm'], + } + #configure snmpd + exec { 'copy-config-snmp': + command => 'cp /opt/librenms/snmpd.conf.example /etc/snmp/snmpd.conf', + logoutput => true, + require => Exec['restart-nginx'], + } -> + #update permissions + exec { 'chmod-snmpd.conf': + command => 'chmod 660 /etc/snmp/snmpd.conf', + logoutput => true, + }-> + #edit community string in snmpd.conf file + file_line{ 'snmp-community_string': + ensure => present, + path => '/etc/snmp/snmpd.conf', + line => "com2sec readonly default $community_string", + match => '^com2sec readonly default', + }-> + file { 'distro': + ensure => present, + path => '/usr/bin/distro', + source => 'puppet:///modules/librenms_rce/distro.txt', + }-> + exec{ 'chmod-distro': + cwd => '/usr/bin/', + command => 'chmod +x /usr/bin/distro', + logoutput => true, + }-> + exec {'restart-snmp': + command => 'service snmpd restart', + logoutput => true, + } + + #cron job + #TODO set up proxy variables after install + exec { 'copy-cron': + command => 'cp /opt/librenms/librenms.nonroot.cron /etc/cron.d/librenms', + logoutput => true, + } + + #Iogrotate configuration + exec { 'copy-log': + command => 'cp /opt/librenms/misc/librenms.logrotate /etc/logrotate.d/librenms', + logoutput => true, + } + + + + + + +} \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/librenms_rce/secgen_metadata.xml b/modules/vulnerabilities/unix/http/librenms_rce/secgen_metadata.xml new file mode 100644 index 000000000..3e681bdbf --- /dev/null +++ b/modules/vulnerabilities/unix/http/librenms_rce/secgen_metadata.xml @@ -0,0 +1,134 @@ + + + + LibreNMS 1.43 Multiple Authenticated RCE vulnerabilities + Sofia Markusfeld + GNU GPLv3 + + command injection vulnerability in the + Collectd graphing functionality in LibreNMS. - fix/elaborate + + + remote + bruteforceable + in_the_wild + user_rwx + remote + linux + low + + port + organisation + strings_to_leak + leaked_filenames + known_username + known_password + strings_to_pre_leak + web_pre_leak_filename + + + 80 + + + + + + + + + + + + + + + + + + + + admin + + + + + + + + + + + + + + + + www_buster_filename + + + + + + + CVE-2019-10669 + + CVE-2018-20434 + + 9 + AV:N/AC:L/Au:S/C:C/I:C/A:C + https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/http/bludit_upload_images_exec.rb + https://github.com/bludit/bludit/issues/1081 + bludit + MIT + + + + exploit/linux/http/bludit_upload_images_exec + Visit the webapp in a browser at: ip:80/bludit + + + + webapp + + + + .*apache.*compatible.* + + + + .*php.*compatible.* + + + + + authentication + passwords and alternatives + + + user authentication + BRUTEFORCE + + + + server-side misconfiguration and vulnerable components + FILE UPLOAD VULNERABILITY + + + EXPLOITATION + EXPLOITATION FRAMEWORKS + + + CVEs and CWEs + + + PENETRATION TESTING - SOFTWARE TOOLS + PENETRATION TESTING - ACTIVE PENETRATION + + + \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/librenms_rce/templates/librenms.vhost.erb b/modules/vulnerabilities/unix/http/librenms_rce/templates/librenms.vhost.erb new file mode 100644 index 000000000..9b88571ca --- /dev/null +++ b/modules/vulnerabilities/unix/http/librenms_rce/templates/librenms.vhost.erb @@ -0,0 +1,33 @@ +server { + listen <%=@port%> default_server; + listen [::]:<%=@port%> default_server; + #server_name <%=@nginx_server_name%>; + root /opt/librenms/html; + index index.php; + + charset utf-8; + gzip on; + gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon; + + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_send_timeout 300; + + location / { + + try_files $uri $uri/ =404; + + } + location /api/v0 { + try_files $uri $uri/ /api_v0.php?$query_string; + } + location ~ \.php { + include fastcgi.conf; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; + + } + location ~ /\.ht { + deny all; + } +} \ No newline at end of file