Skip to content

Instantly share code, notes, and snippets.

@sharmashivanand
Last active July 9, 2018 03:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sharmashivanand/2d8307f130feb62ad909ff93ac042aee to your computer and use it in GitHub Desktop.
Save sharmashivanand/2d8307f130feb62ad909ff93ac042aee to your computer and use it in GitHub Desktop.
Adding meta-boxes to plugin settings page. (Doesn't work)
<?php
/**
* WP Malware Removal
*
* @package WP Malware Removal
* @author Shivanand Sharma
* @copyright 2018 ConverticaCommerce.Com
* @license MIT
*
* @wordpress-plugin
* Plugin Name: WP Malware Removal
* Plugin URI: https://www.converticacommerce.com/
* Description: Malware scanner for your WP website.
* Version: 0.1
* Author: Shivanand Sharma
* Author URI: https://www.converticacommerce.com/
* Text Domain: wpmr
* License: MIT
* License URI: https://opensource.org/licenses/MIT
*/
define( 'WPMR_PLUGIN_DIR', trailingslashit(plugin_dir_url( __FILE__ )));
class WPMR_Init {
private $status = array(
'start_time' => false,
'end_time' => false,
'altered'=>array(), // changed files
'altered'=>array(), // changed files
'skipped' => array(), // skipped files
'matched' => array(), // good files
'errors' => array(), // any errors
'empty' => array(), // total number of empty directories
'dirs' => array(), // total number of directories
'files' => array(), // total number of files
'notices' => array(), // any notices encountered like no files to scan etc.
'state' => false
);
/* Get the engine going */
public function __construct() {
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'plugin_styles' ) );
add_action( 'admin_menu', array( $this, 'settings_menu' ) );
add_action( 'wp_ajax_wpmr_clear_log', array( $this, 'wpmr_clear_log' ));
add_action( 'wp_ajax_wpmr_init_scan', array( $this, 'wpmr_init_scan' ));
add_action( 'wp_ajax_wpmr_get_progress', array( $this, 'wpmr_get_progress' ));
add_action( 'wp_ajax_nopriv_wpmr_clear_log', '__return_false' );
add_action( 'wp_ajax_nopriv_wpmr_init_scan', '__return_false' );
add_action( 'wp_ajax_nopriv_wpmr_check_files', '__return_false' );
add_action( 'admin_footer', array( $this, 'scripts'));
/* Load the results meta boxes. */
add_action( "load-toplevel_page_wpmr", array($this, 'load_meta_boxes' ));
/* Create a hook for adding meta boxes. */
add_action( 'load-toplevel_page_wpmr', array($this, 'add_meta_boxes' ));
}
function load_meta_boxes(){
add_action( 'add_meta_boxes', array($this, 'wpmr_add_results' ));
}
function wpmr_add_results(){
add_meta_box( 'wpmr-results-box', 'Title', array($this, 'meta_box_results'), 'toplevel_page_wpmr', 'main', 'high' );
}
function add_meta_boxes(){
do_action( 'add_meta_boxes', 'toplevel_page_wpmr' );
}
function meta_box_results(){ ?>
meta_box_results
<?php
}
/* Add links below the plugin name on the plugins page */
function plugin_action_links($links){
$links[] = '<a href="'. esc_url( get_admin_url(null, 'options-general.php?page=wpmr') ) .'">Run Site Scan</a>';
return $links;
}
/* Enqueue the styles for admin page */
function plugin_styles(){
$screen = get_current_screen();
if( $screen->id == 'toplevel_page_' . basename( __FILE__ , '.php') ) {
wp_enqueue_style( 'wpmr-stylesheet', WPMR_PLUGIN_DIR . 'assets/admin-styles.css' );
}
}
/* Outputs any variable / php objects / arrays in a clear visible frmat */
function llog($str, $echo = true) {
if($echo){
echo '<pre>';
print_r($str);
echo '</pre>';
}
else {
return print_r($str, 1);
}
}
/* Add the settings menu to WP Admin */
function settings_menu(){
$hook_suffix = add_menu_page(
'Malware Removal',
'Malware Removal',
'manage_options',
'wpmr',
array( $this, 'settings_page' )
);
//$this->llog($hook_suffix);
//die();
add_submenu_page( 'wpmr', 'Tools', 'Tools', 'manage_options' , 'wpmr-tools', array($this, 'wpmrtools'));
}
/* Render the settings page */
function settings_page(){
?>
<div class="wrap">
<h1>WP Malware Removal</h1>
<div class="container-wrap">
<div class="container">
<div class="gauge-a"></div>
<div class="gauge-c"></div>
<div class="gauge-data">
<h1 id="percent"></h1>
</div>
</div>
<div id="lcd"></div>
</div>
<div id="ux">
<input type="submit" value="Start Scan" id="scan-control" data-state="0" class="button-primary"/>
</div>
<div class="scan-results">
<h3>Results:</h3>
<p>Core WordPress files will be checked for integrity. Core themes &amp; plugins may show altered after updating. Non-WordPress files will be skipped.</p>
<div id="scan-results"></div>
</div>
<div id="postbox-container-1" class="postbox-container">
<?php do_meta_boxes( 'toplevel_page_wpmr', 'main', null ); ?>
</div><!-- #postbox-container-1 -->
</div>
<?php
}
/* Ajax request handler for triggering scan */
function wpmr_init_scan(){
$this->status['state'] = 'initializing';
$this->status['start_time'] = microtime(true);
$this->run_tests();
wp_die();
}
function save_progress($progress){
update_option("WPMR_scan_log", $progress);
}
function wpmr_get_progress(){
wp_die(json_encode(get_option('WPMR_scan_log')));
}
function wpmr_clear_log(){
wp_die(delete_option("WPMR_scan_log"));
}
function file_integrity_check($local_file){
$checksums = $this->get_checksums();
$install_path = get_home_path();
$file = array();
//foreach($local_files as $local) {
$match_path = str_replace($install_path,'', $local_file );
if(array_key_exists($match_path, $checksums)) {
if($checksums[$match_path] != md5_file($local_file)){
//$this->status['altered'][] = $file;
//$this->status['files'][$file]['altered'];
return 'altered';
}
else{
//$this->status['matched'][] = $file;
//$this->status['files'][$file]['matched'];
return 'matched';
}
}
else{
//$this->status['skipped'][] = $file;
//$this->status['files'][$file]['skipped'];
return 'skipped';
}
//}
}
/* Collect all files to scan */
function get_all_files($path = false) {
if(!$path) {
$path = untrailingslashit( get_home_path() );
}
$this->get_checksums();
if(is_dir($path)) {
$children = @scandir($path);
if(is_array($children)) {
if($path == '/var/www/html/dev/wp-sandbox/wp-content/plugins/advanced-wp-reset') {
//$this->llog(is_array($children));
}
$children = array_diff($children, array('..', '.'));
$dirs = array();
$files = array();
foreach( $children as $child ) {
$target = trailingslashit($path) . $child;
if(is_dir($target)) {
$elements = $this->get_all_files($target);
if($elements) { // check for read/write errors
foreach($elements as $element) {
$files[] = $element;
}
}
}
if(is_file($target)) {
$files[] = $target;
}
}
return $files;
}
}
}
function run_tests() {
$files = $this->get_all_files();
$tests = array();
$i = 0;
$current = 0;
$percent = 0;
$total = count($files);
$start = microtime(true);
foreach($files as $file) {
$i++;
$current++;
$percent = round(( $current / $total ) * 100, 2);
$tests[$file]['md5'] = $this->file_integrity_check($file);
//if($i = 8) {
// break;
//}
if( ($current % 5) == 0 || $percent == 100) {
$time_lapse = (microtime(TRUE) - $start );
$this->save_progress(array('percent' => $percent, 'scanned' => $current, 'total' => $total, 'time' => $time_lapse, 'memory' => (memory_get_peak_usage(true)/1024/1024), 'math' => "$current:$total", 'result' => $tests));
usleep(10000);
}
}
}
/* Update hashes for all WP core files */
function get_checksums(){
$checksums = get_transient( 'WPMR_checksums' );
if(! $checksums) {
global $wp_version;
$checksums = get_core_checksums( $wp_version, get_locale() );
if($checksums) {
set_transient( 'WPMR_checksums',$checksums, 12 * HOUR_IN_SECONDS );
return $checksums;
}
return;
}
else {
return $checksums;
}
}
function read_error($path) {
if (!file_exists($path)) {
return 'are you sure this file exists?: '. $path;
}
if (!is_readable($path) ) {
return 'are you sure this file is readable?:' . $path;
}
return (is_array($error) && isset($error["message"])?preg_replace('/[\r\n]/', ' ', print_r($error["message"],1)):"readable?");
}
/* JS routine to handle user-events and reporting */
function scripts(){
?>
<script type="text/javascript" >
jQuery(document).ready(function ($) { //wrapper
$("#scan-control").click(function () { //event
$('.container .gauge-c').css('transform', 'rotate( 0turn)');
$('#scan-results').html('');
switch ($("#scan-control").attr('data-state')) {
case '1':
$("#scan-control").attr('data-state', '0');
break;
default:
total_files = 0;
$("#scan-control").attr('disabled', 'disabled');
wpmr_clear_log = {
_ajax_nonce: '<?php echo wp_create_nonce( 'wpmr' ); ?>',
action: "wpmr_clear_log",
};
$.post(ajaxurl, wpmr_clear_log, function (response) { //initialize and setup everything
console.log()
wpmr_init_scan = {
_ajax_nonce: '<?php echo wp_create_nonce( 'wpmr' ); ?>',
action: "wpmr_init_scan",
};
$.post(ajaxurl, wpmr_init_scan, function (response) { //initialize and setup everything
}); // ajax post
//interval = setInterval(get_progress, 1000); // get recurring progress
get_progress();
function get_progress() {
wpmr_get_progress = {
_ajax_nonce: '<?php echo wp_create_nonce( 'wpmr' ); ?>',
action: "wpmr_get_progress", //action
};
$.post(ajaxurl, wpmr_get_progress, function (progress) {
result = JSON.parse(progress);
if(result == false) {
return get_progress();
}
//console.log(result)
progress = result.percent;
scan_output = result.result;
//console.log(scan_output.length);
html = '';
Object.keys(scan_output).forEach(function(key) {
if(scan_output[key].md5 == 'altered'){
html += '<p class="record"><span class="result md5 altered">altered</span>' + key + '</p>';
}
if(scan_output[key].md5 == 'skipped'){
//html += '<p class="record"><span class="result md5 non-wp">non-wp</span>' + key + '</p>';
}
});
$('#scan-results').html(html);
$('#percent').html('<span class="percentage">' + parseFloat(progress).toFixed(0) + '%</span><br /><span class="time">' + Math.round(result.time) + ' sec</span>' );
$('#lcd').html('<span class="stats"><span class="speed"><span class="digits">' + parseFloat((result.scanned) / result.time).toFixed(1) + '</span><span class="rate">&nbsp;files / sec</span></span><span class="ram">'+result.memory+'mb ram</span>' ).fadeIn(2000);
$('.container .gauge-c').css('transform', 'rotate( ' + (.005 * progress) + 'turn)');
if (progress < 100) {
return get_progress();
} else {
console.log(progress);
$("#scan-control").val('Re-Scan');
$("#scan-control").removeAttr('disabled');
}
});
}
});
} // switch
}); //click
}); //ready
</script>
<?php
}
function wpmrtools() { ?>
<div class="wrap">
<h1>Diagnostic Tools</h1>
<?php
$this->status['state'] = 'initializing';
$start = microtime(true);
$this->status['start_time'] = $start;
//$this->llog($this->get_all_files());
$this->wpmr_init_scan();
$this->llog( "Mem peak usage: " . (memory_get_peak_usage(true)/1024/1024)." MiB" );
$time = (microtime(true) - $start);
$this->llog( "Completed in: $time micro-seconds" );
$this->llog($this->status);
//$this->get_all_files();
echo '
<h2>Test these first</h2>
<b>Click on any of the links below to run your site through the tool.</b><br>
<div id="toolscol1">
<a id="tool" target="_blank" href="https://www.google.com/transparencyreport/safebrowsing/diagnostic/index.html#url='.get_site_url().'">Google Safe Browsing Tool</a><br>
<a id="tool" target="_blank" href="https://sitecheck.sucuri.net/results/'.get_site_url().'">Sucuri Website Malware Scanner</a><br>
</div>
<div id="toolscol2">
<a id="tool" target="_blank" href="https://www.virustotal.com/#/domain/'.get_site_url().'">VirusTotal Analyzer</a><br>
<a id="tool" target="_blank" href="https://tools.geekflare.com/report/screenshot/'.get_site_url().'">Geek Flare Screenshot Checker</a>
<a id="tool" target="_blank" href="https://tools.geekflare.com/report/screenshot/'.get_site_url().'">Geek Flare Blacklist Test</a>
</div>
<div id="toolscol3">
<a id="tool" target="_blank" href="https://geopeeker.com/fetch/?url='.get_site_url().'">GeoPeeker Peek Results</a><br>
<a id="tool" target="_blank" href="https://tools.geekflare.com/report/https-test/'.get_site_url().'">Geek Flare DNSSEC Test</a>
<a id="tool" target="_blank" href="https://tools.geekflare.com/report/https-test/'.get_site_url().'">Geek Flare HTTP/2 Test</a>
</div>
'; ?>
</div>
<?php
}
}
$wpmr_init = new WPMR_Init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment