ACC SHELL
<?php
class wfGrant
{
public $select = false;
public $update = false;
public $insert = false;
public $delete = false;
public $alter = false;
public $create = false;
public $drop = false;
public static function get()
{
static $instance;
if ($instance === null) {
$instance = new self;
}
return $instance;
}
private function __construct()
{
global $wpdb;
$rows = $wpdb->get_results("SHOW GRANTS FOR current_user()", ARRAY_N);
foreach ($rows as $row) {
preg_match("/GRANT (.+) ON (.+) TO/", $row[0], $matches);
foreach (explode(",", $matches[1]) as $permission) {
$permission = str_replace(" ", "_", trim(strtolower($permission)));
if ($permission === 'all_privileges') {
foreach ($this as $key => $value) {
$this->$key = true;
}
break 2;
}
$this->$permission = true;
}
}
}
}
class wfDiagnostic
{
protected $minVersion = array(
'PHP' => '5.2.4',
'cURL' => '1.0',
);
protected $description = array(
'Filesystem' => array(
'isTmpReadable' => 'Checking if web server can read from <code>~/plugins/wordfence/tmp</code>',
'isTmpWritable' => 'Checking if web server can write to <code>~/plugins/wordfence/tmp</code>',
'isWAFReadable' => 'Checking if web server can read from <code>~/wp-content/wflogs</code>',
'isWAFWritable' => 'Checking if web server can write to <code>~/wp-content/wflogs</code>',
),
'Config' => array(
'configWritableSet' => 'Checking basic config reading/writing',
'configWritableSetSer' => 'Checking serialized config reading/writing',
),
'MySQL' => array(
'userCanDelete' => 'Checking if MySQL user has <code>DELETE</code> privilege',
'userCanInsert' => 'Checking if MySQL user has <code>INSERT</code> privilege',
'userCanUpdate' => 'Checking if MySQL user has <code>UPDATE</code> privilege',
'userCanSelect' => 'Checking if MySQL user has <code>SELECT</code> privilege',
'userCanCreate' => 'Checking if MySQL user has <code>CREATE TABLE</code> privilege',
'userCanAlter' => 'Checking if MySQL user has <code>ALTER TABLE</code> privilege',
'userCanDrop' => 'Checking if MySQL user has <code>DROP</code> privilege',
'userCanTruncate' => 'Checking if MySQL user has <code>TRUNCATE</code> privilege',
),
'PHP' => array(
'phpVersion' => 'PHP version >= PHP 5.2.4<br><em> (<a href="https://wordpress.org/about/requirements/" target="_blank" rel="noopener noreferrer">Minimum version required by WordPress</a>)</em>',
'processOwner' => 'Process Owner',
'hasOpenSSL' => 'Checking for OpenSSL support',
'hasCurl' => 'Checking for cURL support',
),
'Connectivity' => array(
'connectToServer1' => 'Connecting to Wordfence servers (http)',
'connectToServer2' => 'Connecting to Wordfence servers (https)',
'connectToSelf' => 'Connecting back to this site',
),
// 'Configuration' => array(
// 'howGetIPs' => 'How does get IPs',
// ),
);
protected $results = array();
public function __construct()
{
foreach ($this->description as $title => $tests) {
$this->results[$title] = array();
foreach ($tests as $name => $description) {
$result = $this->$name();
if (is_bool($result)) {
$result = array(
'test' => $result,
'message' => $result ? 'OK' : 'FAIL',
);
}
$result['label'] = $description;
$this->results[$title][] = $result;
}
}
}
public function getResults()
{
return $this->results;
}
public function isTmpReadable() {
return is_readable(WORDFENCE_PATH . 'tmp');
}
public function isTmpWritable() {
return is_writable(WORDFENCE_PATH . 'tmp');
}
public function isWAFReadable() {
if (!is_readable(WFWAF_LOG_PATH)) {
return array('test' => false, 'message' => 'No files readable');
}
$files = array(
WFWAF_LOG_PATH . 'attack-data.php',
WFWAF_LOG_PATH . 'ips.php',
WFWAF_LOG_PATH . 'config.php',
WFWAF_LOG_PATH . 'rules.php',
WFWAF_LOG_PATH . 'wafRules.rules',
);
$unreadable = array();
foreach ($files as $f) {
if (!file_exists($f)) {
$unreadable[] = 'File "' . basename($f) . '" does not exist';
}
else if (!is_readable($f)) {
$unreadable[] = 'File "' . basename($f) . '" is unreadable';
}
}
if (count($unreadable) > 0) {
return array('test' => false, 'message' => implode(', ', $unreadable));
}
return true;
}
public function isWAFWritable() {
if (!is_writable(WFWAF_LOG_PATH)) {
return array('test' => false, 'message' => 'No files writable');
}
$files = array(
WFWAF_LOG_PATH . 'attack-data.php',
WFWAF_LOG_PATH . 'ips.php',
WFWAF_LOG_PATH . 'config.php',
WFWAF_LOG_PATH . 'rules.php',
WFWAF_LOG_PATH . 'wafRules.rules',
);
$unwritable = array();
foreach ($files as $f) {
if (!file_exists($f)) {
$unwritable[] = 'File "' . basename($f) . '" does not exist';
}
else if (!is_writable($f)) {
$unwritable[] = 'File "' . basename($f) . '" is unwritable';
}
}
if (count($unwritable) > 0) {
return array('test' => false, 'message' => implode(', ', $unwritable));
}
return true;
}
public function userCanInsert() {
return wfGrant::get()->insert;
}
public function userCanUpdate() {
return wfGrant::get()->update;
}
public function userCanDelete() {
return wfGrant::get()->delete;
}
public function userCanSelect() {
return wfGrant::get()->select;
}
public function userCanCreate() {
return wfGrant::get()->create;
}
public function userCanDrop() {
return wfGrant::get()->drop;
}
public function userCanTruncate() {
return wfGrant::get()->drop && wfGrant::get()->delete;
}
public function userCanAlter() {
return wfGrant::get()->alter;
}
public function phpVersion()
{
return array(
'test' => version_compare(phpversion(), $this->minVersion['PHP'], '>='),
'message' => phpversion(),
);
}
public function configWritableSet() {
global $wpdb;
$show = $wpdb->hide_errors();
$val = md5(time());
wfConfig::set('configWritingTest', $val, wfConfig::DONT_AUTOLOAD);
$testVal = wfConfig::get('configWritingTest');
$wpdb->show_errors($show);
return array(
'test' => ($val === $testVal),
'message' => 'Basic config writing'
);
}
public function configWritableSetSer() {
global $wpdb;
$show = $wpdb->hide_errors();
$val = md5(time());
wfConfig::set_ser('configWritingTest_ser', array($val), false, wfConfig::DONT_AUTOLOAD);
$testVal = @array_shift(wfConfig::get_ser('configWritingTest_ser', array(), false));
$wpdb->show_errors($show);
return array(
'test' => ($val === $testVal),
'message' => 'Serialized config writing'
);
}
public function processOwner() {
$disabledFunctions = explode(',', ini_get('disable_functions'));
if (is_callable('posix_geteuid')) {
if (!is_callable('posix_getpwuid') || in_array('posix_getpwuid', $disabledFunctions)) {
return array(
'test' => false,
'message' => 'Unavailable',
);
}
$processOwner = posix_getpwuid(posix_geteuid());
if ($processOwner !== null)
{
return array(
'test' => true,
'message' => $processOwner['name'],
);
}
}
$usernameOrUserEnv = getenv('USERNAME') ? getenv('USERNAME') : getenv('USER');
if (!empty($usernameOrUserEnv)) { //Check some environmental variable possibilities
return array(
'test' => true,
'message' => $usernameOrUserEnv,
);
}
$currentUser = get_current_user();
if (!empty($currentUser)) { //php.net comments indicate on Windows this returns the process owner rather than the file owner
return array(
'test' => true,
'message' => $currentUser,
);
}
if (!empty($_SERVER['LOGON_USER'])) { //Last resort for IIS since POSIX functions are unavailable, Source: https://msdn.microsoft.com/en-us/library/ms524602(v=vs.90).aspx
return array(
'test' => true,
'message' => $_SERVER['LOGON_USER'],
);
}
return array(
'test' => false,
'message' => 'Unknown',
);
}
public function hasOpenSSL() {
return is_callable('openssl_open');
}
public function hasCurl() {
if (!is_callable('curl_version')) {
return false;
}
$version = curl_version();
return array(
'test' => version_compare($version['version'], $this->minVersion['cURL'], '>='),
'message' => $version['version'],
);
}
public function connectToServer1() {
return $this->_connectToServer('http');
}
public function connectToServer2() {
return $this->_connectToServer('https');
}
public function _connectToServer($protocol) {
$cronURL = admin_url('admin-ajax.php');
$cronURL = preg_replace('/^(https?:\/\/)/i', '://noc1.wordfence.com/scanptest/', $cronURL);
$cronURL .= '?action=wordfence_doScan&isFork=0&cronKey=47e9d1fa6a675b5999999333';
$cronURL = $protocol . $cronURL;
$result = wp_remote_post($cronURL, array(
'timeout' => 10, //Must be less than max execution time or more than 2 HTTP children will be occupied by scan
'blocking' => true, //Non-blocking seems to block anyway, so we use blocking
// This causes cURL to throw errors in some versions since WordPress uses its own certificate bundle ('CA certificate set, but certificate verification is disabled')
// 'sslverify' => false,
'headers' => array()
));
if( (! is_wp_error($result)) && $result['response']['code'] == 200 && strpos($result['body'], "scanptestok") !== false){
return true;
}
ob_start();
if(is_wp_error($result)){
echo "wp_remote_post() test to noc1.wordfence.com failed! Response was: " . $result->get_error_message() . "<br />\n";
} else {
echo "wp_remote_post() test to noc1.wordfence.com failed! Response was: " . $result['response']['code'] . " " . $result['response']['message'] . "<br />\n";
echo "This likely means that your hosting provider is blocking requests to noc1.wordfence.com or has set up a proxy that is not behaving itself.<br />\n";
echo "This additional info may help you diagnose the issue. The response headers we received were:<br />\n";
foreach($result['headers'] as $key => $value){
echo "$key => $value<br />\n";
}
}
return array(
'test' => false,
'message' => ob_get_clean()
);
}
public function connectToSelf() {
$adminAJAX = admin_url('admin-ajax.php?action=wordfence_testAjax');
$result = wp_remote_post($adminAJAX, array(
'timeout' => 10, //Must be less than max execution time or more than 2 HTTP children will be occupied by scan
'blocking' => true, //Non-blocking seems to block anyway, so we use blocking
'headers' => array()
));
if ((!is_wp_error($result)) && $result['response']['code'] == 200 && strpos($result['body'], "WFSCANTESTOK") !== false) {
$host = parse_url($adminAJAX, PHP_URL_HOST);
if ($host !== null) {
$ips = wfUtils::resolveDomainName($host);
$ips = implode(', ', $ips);
return array('test' => true, 'message' => 'OK - ' . $ips);
}
return true;
}
ob_start();
if (is_wp_error($result)) {
echo "wp_remote_post() test back to this server failed! Response was: " . $result->get_error_message() . "<br />\n";
}
else {
echo "wp_remote_post() test back to this server failed! Response was: " . $result['response']['code'] . " " . $result['response']['message'] . "<br />\n";
echo "This additional info may help you diagnose the issue. The response headers we received were:<br />\n";
foreach($result['headers'] as $key => $value){
echo "$key => $value<br />\n";
}
}
return array(
'test' => false,
'message' => ob_get_clean()
);
}
public function howGetIPs()
{
$howGet = wfConfig::get('howGetIPs', false);
if ($howGet) {
if (empty($_SERVER[$howGet])) {
return array(
'test' => false,
'message' => 'We cannot read $_SERVER[' . $howGet . ']',
);
}
return array(
'test' => true,
'message' => $howGet,
);
}
foreach (array('HTTP_CF_CONNECTING_IP', 'HTTP_X_REAL_IP', 'HTTP_X_FORWARDED_FOR') as $test) {
if (!empty($_SERVER[$test])) {
return array(
'test' => false,
'message' => 'Should be: ' . $test
);
}
}
return array(
'test' => true,
'message' => 'REMOTE_ADDR',
);
}
}
ACC SHELL 2018