PluginProbe ʕ •ᴥ•ʔ
Wordfence Security – Firewall, Malware Scan, and Login Security / 3.0.3
Wordfence Security – Firewall, Malware Scan, and Login Security v3.0.3
8.2.2 8.2.1 8.2.0 3.7.1 3.7.2 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.8.8 3.8.9 3.9.1 4.0.1 4.0.2 4.0.3 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.0.9 5.1.1 5.1.2 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.2.1 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.1 5.3.10 5.3.11 5.3.12 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.3.8 5.3.9 6.0.1 6.0.10 6.0.11 6.0.12 6.0.14 6.0.15 6.0.16 6.0.17 6.0.18 6.0.19 6.0.2 6.0.20 6.0.21 6.0.22 6.0.23 6.0.24 6.0.25 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.0.8 6.0.9 6.1.1 6.1.10 6.1.11 6.1.12 6.1.14 6.1.15 6.1.16 6.1.17 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6 6.1.7 6.1.8 6.1.9 6.2.0 6.2.1 6.2.10 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.2.8 6.2.9 6.3.0 6.3.1 6.3.10 6.3.11 6.3.12 6.3.14 6.3.15 6.3.16 6.3.17 6.3.18 6.3.19 6.3.2 6.3.20 6.3.21 6.3.22 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.3.8 6.3.9 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1.0 7.1.1 7.1.10 7.1.11 7.1.12 7.1.14 7.1.15 7.1.16 7.1.17 7.1.18 7.1.19 7.1.2 7.1.20 7.1.3 7.1.4 7.1.5 7.1.6 7.1.7 7.1.8 7.1.9 7.10.0 7.10.1 7.10.2 7.10.3 7.10.4 7.10.5 7.10.6 7.10.7 7.11.0 7.11.1 7.11.2 7.11.3 7.11.4 7.11.5 7.11.6 7.11.7 7.2.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3.1 7.3.2 7.3.3 7.3.4 7.3.5 7.3.6 7.4.0 7.4.1 7.4.10 7.4.11 7.4.12 7.4.14 7.4.2 7.4.3 trunk 7.4.4 1.1 7.4.5 1.2 7.4.6 1.3 7.4.7 1.3.1 7.4.8 1.3.2 7.4.9 1.3.3 7.5.0 1.4.2 7.5.1 1.4.3 7.5.10 1.4.4 7.5.11 1.4.5 7.5.2 1.4.6 7.5.3 1.4.7 7.5.4 1.4.8 7.5.5 1.5.1 7.5.6 1.5.2 7.5.7 1.5.3 7.5.8 1.5.4 7.5.9 1.5.5 7.6.0 1.5.6 7.6.1 2.0.1 7.6.2 2.0.2 7.7.0 2.0.3 7.7.1 2.0.5 7.8.0 2.0.6 7.8.1 2.0.7 7.8.2 2.1.0 7.9.0 2.1.1 7.9.1 2.1.2 7.9.2 2.1.3 7.9.3 2.1.4 8.0.0 2.1.5 8.0.1 3.0.2 8.0.2 3.0.3 8.0.3 3.0.4 8.0.4 3.0.5 8.0.5 3.0.6 8.1.0 3.0.7 8.1.1 3.0.8 8.1.2 3.0.9 8.1.3 3.1.0 8.1.4 3.1.1 v1.4.1 3.1.2 3.1.4 3.1.6 3.2.1 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.1 3.4.4 3.4.5 3.5.1 3.5.2 3.6.1 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.6.9
wordfence / lib / wordfenceURLHoover.php
wordfence / lib Last commit date
Diff 13 years ago .htaccess 14 years ago Diff.php 13 years ago IPTraf.php 13 years ago diffResult.php 13 years ago email_genericAlert.php 13 years ago email_newIssues.php 14 years ago email_unlockRequest.php 14 years ago menu_activity.php 14 years ago menu_blockedIPs.php 13 years ago menu_options.php 13 years ago menu_scan.php 13 years ago sysinfo.php 13 years ago viewFullActivityLog.php 13 years ago wf503.php 13 years ago wfAPI.php 13 years ago wfAction.php 14 years ago wfArray.php 13 years ago wfBrowscap.php 14 years ago wfBrowscapCache.php 14 years ago wfConfig.php 13 years ago wfCrawl.php 13 years ago wfDB.php 13 years ago wfDict.php 14 years ago wfIssues.php 13 years ago wfLockedOut.php 14 years ago wfLog.php 13 years ago wfModTracker.php 14 years ago wfRate.php 14 years ago wfScanEngine.php 13 years ago wfSchema.php 13 years ago wfUnlockMsg.php 14 years ago wfUtils.php 13 years ago wfViewResult.php 13 years ago wordfenceClass.php 13 years ago wordfenceConstants.php 13 years ago wordfenceHash.php 13 years ago wordfenceScanner.php 13 years ago wordfenceURLHoover.php 13 years ago
wordfenceURLHoover.php
198 lines
1 <?php
2 require_once('wfAPI.php');
3 require_once('wfArray.php');
4 class wordfenceURLHoover {
5 private $debug = false;
6 public $errorMsg = false;
7 private $hostsToAdd = false;
8 private $table = '';
9 private $apiKey = false;
10 private $wordpressVersion = false;
11 private $dRegex = 'aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|xn--lgbbat1ad8j|xn--fiqs8s|xn--fiqz9s|xn--wgbh1c|xn--j6w193g|xn--h2brj9c|xn--mgbbh1a71e|xn--fpcrj9c3d|xn--gecrj9c|xn--s9brj9c|xn--xkc2dl3a5ee0h|xn--45brj9c|xn--mgba3a4f16a|xn--mgbayh7gpa|xn--mgbc0a9azcg|xn--ygbi2ammx|xn--wgbl6a|xn--p1ai|xn--mgberp4a5d4ar|xn--90a3ac|xn--yfro4i67o|xn--clchc0ea0b2g2a9gcd|xn--3e0b707e|xn--fzc2c9e2c|xn--xkc2al3hye2a|xn--mgbtf8fl|xn--kprw13d|xn--kpry57d|xn--o3cw4h|xn--pgbs0dh|xn--mgbaam7a8h|xn--54b7fta0cc|xn--90ae|xn--node|xn--4dbrk0ce|xn--80ao21a|xn--mgb9awbf|xn--mgbai9azgqp6j|xn--j1amh|xn--mgb2ddes|xn--kgbechtv|xn--hgbk6aj7f53bba|xn--0zwm56d|xn--g6w251d|xn--80akhbyknj4f|xn--11b5bs3a9aj6g|xn--jxalpdlp|xn--9t4b11yi5a|xn--deba0ad|xn--zckzah|xn--hlcj6aya9esc7a';
12 private $api = false;
13 private $db = false;
14 public function __sleep(){
15 $this->writeHosts();
16 return array('debug', 'errorMsg', 'table', 'apiKey', 'wordpressVersion', 'dRegex');
17 }
18 public function __wakeup(){
19 $this->hostsToAdd = new wfArray(array('owner', 'host', 'path', 'hostKey'));
20 $this->api = new wfAPI($this->apiKey, $this->wordpressVersion);
21 $this->db = new wfDB();
22 }
23 public function __construct($apiKey, $wordpressVersion){
24 $this->hostsToAdd = new wfArray(array('owner', 'host', 'path', 'hostKey'));
25 $this->apiKey = $apiKey;
26 $this->wordpressVersion = $wordpressVersion;
27 $this->api = new wfAPI($apiKey, $wordpressVersion);
28 $this->db = new wfDB();
29 global $wpdb;
30 $this->table = $wpdb->base_prefix . 'wfHoover';
31 $this->db->query("truncate table $this->table");
32 }
33 public function hoover($id, $data){
34 if(strpos($data, '.') === false){
35 return;
36 }
37 if(! preg_match('/[a-zA-Z0-9\-]+\.(?:' . $this->dRegex . ')/i', $data)){
38 return;
39 }
40 try {
41 @preg_replace("/(?<=^|[^a-zA-Z0-9\-])((?:[a-zA-Z0-9\-]+\.)+)(" . $this->dRegex . ")((?:$|[^a-zA-Z0-9\-\.\'\"])[^\r\n\s\t\"\'\$\{\}<>]*)/ie", "\$this->" . "addHost(\$id, '$1$2', '$3')", $data);
42 } catch(Exception $e){ error_log("Regex error 1: $e"); }
43 preg_replace("/(?<=[^\d]|^)(\d{8,10}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})([^\d\'\"][^\r\n\s\t\"\'\$\{\}<>]*)/e", "\$this->" . "addIP(\$id, \"$1\",\"$2\")", $data);
44 $this->writeHosts();
45 }
46 private function dbg($msg){ if($this->debug){ error_log("DEBUG: $msg\n"); } }
47 public function addHost($id, $host, $path){
48 $path = preg_replace_callback('/([^A-Za-z0-9\-\.\_\~:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,;\=]+)/', 'wordfenceURLHoover::urlenc', $path);
49 $host = strtolower($host);
50 $this->intAddHost($id, $host, $path);
51 }
52 public function addIP($id, $ipdata, $path){
53 $path = preg_replace_callback('/([^A-Za-z0-9\-\.\_\~:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,;\=]+)/', 'wordfenceURLHoover::urlenc', $path);
54 if(strstr($ipdata, '.') === false && $ipdata >= 16777216 && $ipdata <= 4026531840){
55 $ipdata = long2ip($ipdata);
56 }
57 $parts = explode('.', $ipdata);
58 $isValid = true;
59 if($parts[0] >= 240 || $parts[0] == '10' || $parts[0] == '172' || $parts[0] == '192' || $parts[0] == '127'){
60 $isValid = false;
61 }
62 if($isValid){
63 foreach($parts as $part){
64 if($part < 1 || $part > 255){
65 $isValid = false;
66 }
67 }
68 }
69 if($isValid && $ipdata){
70 $this->intAddHost($id, $ipdata, $path);
71 }
72 }
73 public static function urlenc($m){
74 return urlencode($m[1]);
75 }
76 private function intAddHost($id, $host, $path){
77 if(strpos($path, '/') !== 0){
78 $path = '/';
79 }
80 $this->hostsToAdd->push(array('owner' => $id, 'host' => $host, 'path' => $path, 'hostKey' => $this->makeHostKey($host)));
81 if($this->hostsToAdd->size() > 1000){ $this->writeHosts(); }
82 return true;
83 }
84 private function writeHosts(){
85 if($this->hostsToAdd->size() < 1){ return; }
86 $sql = "insert into " . $this->table . " (owner, host, path, hostKey) values ";
87 while($elem = $this->hostsToAdd->shift()){
88 $sql .= sprintf("('%s', '%s', '%s', '%s'),",
89 mysql_real_escape_string($elem['owner']),
90 mysql_real_escape_string($elem['host']),
91 mysql_real_escape_string($elem['path']),
92 mysql_real_escape_string($elem['hostKey'])
93 );
94 }
95 $sql = rtrim($sql, ',');
96 $this->db->query($sql);
97 }
98 private function makeHostKey($host){
99 $hostParts = explode('.', $host);
100 $hostKey = '';
101 if(sizeof($hostParts) == 2){
102 $hostKey = substr(hash('sha256', $hostParts[0] . '.' . $hostParts[1] . '/', true), 0, 4);
103 } else if(sizeof($hostParts) > 2){
104 $hostKey = substr(hash('sha256', $hostParts[sizeof($hostParts) - 3] . '.' . $hostParts[sizeof($hostParts) - 2] . '.' . $hostParts[sizeof($hostParts) - 1] . '/', true), 0, 4);
105 }
106 return $hostKey;
107 }
108 public function getBaddies(){
109 $allHostKeys = array();
110 $stime = microtime(true);
111 $allHostKeys = array();
112 $q1 = $this->db->query("select distinct hostKey as hostKey from $this->table");
113 while($hRec = mysql_fetch_assoc($q1)){
114 array_push($allHostKeys, $hRec['hostKey']);
115 }
116 //Now call API and check if any hostkeys are bad.
117 //This is a shortcut, because if no hostkeys are bad it saves us having to check URLs
118 if(sizeof($allHostKeys) > 0){ //If we don't have any hostkeys, then we won't have any URL's to check either.
119 //Hostkeys are 4 byte sha256 prefixes
120 //Returned value is 2 byte shorts which are array indexes for bad keys that were passed in the original list
121 $this->dbg("Checking " . sizeof($allHostKeys) . " hostkeys");
122 $resp = $this->api->binCall('check_host_keys', implode('', $allHostKeys));
123 $this->dbg("Done hostkey check");
124
125 $badHostKeys = array();
126 if($resp['code'] == 200){
127 if(strlen($resp['data']) > 0){
128 $dataLen = strlen($resp['data']);
129 if($dataLen % 2 != 0){
130 $this->errorMsg = "Invalid data length received from Wordfence server: " . $dataLen;
131 return false;
132 }
133 for($i = 0; $i < $dataLen; $i += 2){
134 $idxArr = unpack('n', substr($resp['data'], $i, 2));
135 $idx = $idxArr[1];
136 if(isset($allHostKeys[$idx]) ){
137 array_push($badHostKeys, $allHostKeys[$idx]);
138 } else {
139 $this->errorMsg = "Bad allHostKeys index: $idx";
140 return false;
141 }
142 }
143 }
144 } else {
145 $this->errorMsg = "Wordfence server responded with an error. HTTP code " . $resp['code'] . " and data: " . $resp['data'];
146 return false;
147 }
148 if(sizeof($badHostKeys) > 0){
149 $urlsToCheck = array();
150 //need to figure out which id's have bad hostkeys
151 //need to feed in all URL's from those id's where the hostkey matches a URL
152 foreach($badHostKeys as $badHostKey){
153 $q1 = $this->db->query("select owner, host, path from $this->table where hostKey='%s'", $badHostKey);
154 while($rec = mysql_fetch_assoc($q1)){
155 $url = 'http://' . $rec['host'] . $rec['path'];
156 if(! isset($urlsToCheck[$rec['owner']])){
157 $urlsToCheck[$rec['owner']] = array();
158 }
159 if(! in_array($url, $urlsToCheck[$rec['owner']])){
160 $urlsToCheck[$rec['owner']][] = $url;
161 }
162 }
163 }
164
165 if(sizeof($urlsToCheck) > 0){
166 $this->dbg("Checking " . sizeof($urlsToCheck) . " URLs");
167 $badURLs = $this->api->call('check_bad_urls', array(), array( 'toCheck' => json_encode($urlsToCheck)) );
168 $this->dbg("Done URL check");
169 if(is_array($badURLs) && sizeof($badURLs) > 0){
170 $finalResults = array();
171 foreach($badURLs as $file => $badSiteList){
172 if(! isset($finalResults[$file])){
173 $finalResults[$file] = array();
174 }
175 foreach($badSiteList as $badSite){
176 array_push($finalResults[$file], array(
177 'URL' => $badSite[0],
178 'badList' => $badSite[1]
179 ));
180 }
181 }
182 return $finalResults;
183 } else {
184 return array();
185 }
186 } else {
187 return array();
188 }
189 } else {
190 return array();
191 }
192 } else {
193 return array();
194 }
195 }
196 }
197 ?>
198