add admin cookie check
This commit is contained in:
@@ -4,13 +4,17 @@ class FilterTrapRule implements RuleInterface
|
||||
{
|
||||
public function execute()
|
||||
{
|
||||
$ip = BotLogger::getRealIp();
|
||||
if (BotLogger::isWhitelisted($ip)) {
|
||||
return true;
|
||||
}
|
||||
// 1. Only analyze heavy requests (filters/sorting)
|
||||
if (!Tools::getIsset('q') && !Tools::getIsset('order')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$context = Context::getContext();
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
|
||||
// 2. Allow whitelisted Bots (Google/Bing)
|
||||
// We trust them not to spam. If they do, use robots.txt.
|
||||
@@ -52,17 +56,17 @@ class FilterTrapRule implements RuleInterface
|
||||
|
||||
// 5. If we are here: Heavy request + No Cookie + No Token.
|
||||
// Redirect to the Trap (Verify Controller)
|
||||
|
||||
|
||||
$current_url = $_SERVER['REQUEST_URI'];
|
||||
// Remove existing bot_token if present to avoid loops
|
||||
$current_url = preg_replace('/([?&])bot_token=[^&]+(&|$)/', '$1', $current_url);
|
||||
|
||||
// Encode target URL safely
|
||||
$target = urlencode($current_url);
|
||||
|
||||
|
||||
$link = $context->link->getModuleLink('botlimiter', 'verify', ['return_url' => $target]);
|
||||
|
||||
|
||||
Tools::redirect($link);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,19 @@ class HeadRequestRule implements RuleInterface
|
||||
{
|
||||
public function execute()
|
||||
{
|
||||
$ip = BotLogger::getRealIp();
|
||||
if (BotLogger::isWhitelisted($ip)) {
|
||||
return true;
|
||||
}
|
||||
// Detect HEAD request with Filter parameters
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'HEAD' && (Tools::getIsset('q') || Tools::getIsset('order'))) {
|
||||
|
||||
|
||||
// Log for Fail2Ban
|
||||
BotLogger::logBan($_SERVER['REMOTE_ADDR'], 'HEAD_REQUEST_SPAM');
|
||||
BotLogger::logBan($ip, 'HEAD_REQUEST_SPAM');
|
||||
|
||||
header('HTTP/1.1 405 Method Not Allowed');
|
||||
die('Method Not Allowed');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
68
classes/rules/RateLimitRule.php
Normal file
68
classes/rules/RateLimitRule.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
|
||||
class RateLimitRule implements RuleInterface
|
||||
{
|
||||
const MAX_404_REQUESTS = 20; // Allow a maximum of 20 dead links...
|
||||
const TIME_WINDOW = 300; // ...within 300 seconds (5 minutes)
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$ip = BotLogger::getRealIp();
|
||||
if (BotLogger::isWhitelisted($ip)) {
|
||||
return true;
|
||||
}
|
||||
$context = Context::getContext();
|
||||
|
||||
// 1. Instantly skip if this is NOT a 404 error page.
|
||||
// During the hookActionFrontControllerInitBefore hook, PrestaShop has already
|
||||
// resolved the route. If it failed, the controller is set to PageNotFoundController.
|
||||
if (!($context->controller instanceof PageNotFoundController)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 2. Safely check if the Cache module is installed and enabled
|
||||
if (!Module::isInstalled('dbmemorycache') || !Module::isEnabled('dbmemorycache')) {
|
||||
return true; // Pass gracefully if the module is missing or disabled
|
||||
}
|
||||
|
||||
/** @var DbMemoryCache $cache */
|
||||
$cache = Module::getInstanceByName('dbmemorycache');
|
||||
if (!$cache) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3. Generate a unique hash for this specific IP's 404 traffic
|
||||
$cacheKey = hash('sha256', '404_spam_limiter_' . $ip);
|
||||
|
||||
// 4. Lookup their current 404 hit count in the memory table
|
||||
$currentCount = 0;
|
||||
if ($cache->existsValue($cacheKey)) {
|
||||
$currentCount = (int) $cache->getValue($cacheKey);
|
||||
}
|
||||
|
||||
// 5. Increment their strike counter
|
||||
$currentCount++;
|
||||
|
||||
// 6. Have they triggered too many 404s?
|
||||
if ($currentCount > self::MAX_404_REQUESTS) {
|
||||
|
||||
// Log it so Fail2ban can block them at the server firewall level
|
||||
BotLogger::logBan($ip, '404_RATE_LIMIT_EXCEEDED');
|
||||
|
||||
// Drop the connection instantly to save server resources
|
||||
header('HTTP/1.1 429 Too Many Requests');
|
||||
die('429 Too Many Requests - Stop Scanning');
|
||||
}
|
||||
|
||||
// 7. Save the new strike count back to the cache
|
||||
// Note: Because we overwrite it here, this creates a "Sliding Window".
|
||||
// If a bot keeps spamming, the 300s timer resets every time, keeping them trapped!
|
||||
$cache->setValue($cacheKey, $currentCount, self::TIME_WINDOW);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
200
classes/rules/ScanBotsRule.php
Normal file
200
classes/rules/ScanBotsRule.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
class ScanBotsRule implements RuleInterface
|
||||
{
|
||||
// 1. Exact matches using Keys for O(1) Instant Lookup
|
||||
// Redundant wp-content/ and wp-includes/ files were removed because the prefix scanner catches them all!
|
||||
private static $exact_targets = [
|
||||
'/database.php' => true,
|
||||
'/acp.php' => true,
|
||||
'/gettest.php' => true,
|
||||
'/4h.php' => true,
|
||||
'/flower.php' => true,
|
||||
'/styll.php' => true,
|
||||
'/re.php' => true,
|
||||
'/alfashell.php' => true,
|
||||
'/axx.php' => true,
|
||||
'/X57.php' => true,
|
||||
'/erty.php' => true,
|
||||
'/miansha.php' => true,
|
||||
'/bengi.php' => true,
|
||||
'/bs1.php' => true,
|
||||
'/motu.php' => true,
|
||||
'/gssdd.php' => true,
|
||||
'/in.php' => true,
|
||||
'/bal.php' => true,
|
||||
'/dev.php' => true,
|
||||
'/k.php' => true,
|
||||
'/prv8.php' => true,
|
||||
'/lb.php' => true,
|
||||
'/hi.php' => true,
|
||||
'/f35.php' => true,
|
||||
'/update/f35.php' => true,
|
||||
'/a1.php' => true,
|
||||
'/fi.php' => true,
|
||||
'/init.php' => true,
|
||||
'/abcd.php' => true,
|
||||
'/av.php' => true,
|
||||
'/kj.php' => true,
|
||||
'/fe5.php' => true,
|
||||
'/about.php' => true,
|
||||
'/ok.php' => true,
|
||||
'/w4.php' => true,
|
||||
'/assets/css/index.php' => true,
|
||||
'/wp.php' => true,
|
||||
'/BDKR28WP.php' => true,
|
||||
'/wp-the.php' => true,
|
||||
'/wp-michan.php' => true,
|
||||
'/makeasmtp.php' => true,
|
||||
'/alpha.php' => true,
|
||||
'/we.php' => true,
|
||||
'/155.php' => true,
|
||||
'/goat.php' => true,
|
||||
'/fff.php' => true,
|
||||
'/ff1.php' => true,
|
||||
'/cgi-bin/index.php' => true,
|
||||
'/plugins.php' => true,
|
||||
'/222.php' => true,
|
||||
'/ms-edit.php' => true,
|
||||
'/goods.php' => true,
|
||||
'/adminfuns.php' => true,
|
||||
'/166.php' => true,
|
||||
'/test1.php' => true,
|
||||
'/wp-blog.php' => true,
|
||||
'/sbhu.php' => true,
|
||||
'/wp-update.php' => true,
|
||||
'/ms.php' => true,
|
||||
'/x.php' => true,
|
||||
'/tinyfilemanager.php' => true,
|
||||
'/classwithtostring.php' => true,
|
||||
'/aaa.php' => true,
|
||||
'/plss3.php' => true,
|
||||
'/06.php' => true,
|
||||
'/a.php' => true,
|
||||
'/xqq.php' => true,
|
||||
'/class-t.api.php' => true,
|
||||
'/wp-act.php' => true,
|
||||
'/wp9.php' => true,
|
||||
'/bless.php' => true,
|
||||
'/file59.php' => true,
|
||||
'/file.php' => true,
|
||||
'/sc.php' => true,
|
||||
'/1.php' => true,
|
||||
'/aa.php' => true,
|
||||
'/bgymj.php' => true,
|
||||
'/style.php' => true,
|
||||
'/inputs.php' => true,
|
||||
'/f6.php' => true,
|
||||
'/ol.php' => true,
|
||||
'/xmlrpc.php' => true,
|
||||
'/gifclass.php' => true,
|
||||
'/66.php' => true,
|
||||
'/ioxi-o.php' => true,
|
||||
'/edit.php' => true,
|
||||
'/3.php' => true,
|
||||
'/wsvvs.php' => true,
|
||||
'/pass2.php' => true,
|
||||
'/maxro.php' => true,
|
||||
'/mga.php' => true,
|
||||
'/2.php' => true,
|
||||
'/wdf.php' => true,
|
||||
'/path.php' => true,
|
||||
'/txets.php' => true,
|
||||
'/sys.php' => true,
|
||||
'/pp.php' => true,
|
||||
'/g.php' => true,
|
||||
'/h.php' => true,
|
||||
'/xxxx.php' => true,
|
||||
'/sty.php' => true,
|
||||
'/a2.php' => true,
|
||||
'/fvvff.php' => true,
|
||||
'/claw.php' => true,
|
||||
'/swallowable.php' => true,
|
||||
'/foxr.php' => true,
|
||||
'/w2025.php' => true,
|
||||
'/cs.php' => true,
|
||||
'/kk.php' => true,
|
||||
'/rithin.php' => true,
|
||||
'/h2h.php' => true,
|
||||
'/wo.php' => true,
|
||||
'/jocundly.php' => true,
|
||||
'/rere.php' => true,
|
||||
'/bafFz.php' => true,
|
||||
'/elabel.php' => true,
|
||||
'/teee.php' => true,
|
||||
'/no1.php' => true,
|
||||
'/akses.php' => true,
|
||||
'/lp6.php' => true,
|
||||
'/eee.php' => true,
|
||||
'/asw.php' => true,
|
||||
'/sf.php' => true,
|
||||
'/by.php' => true,
|
||||
'/x12.php' => true,
|
||||
'/uuu.php' => true,
|
||||
'/fsgdjkl.php' => true,
|
||||
'/settings.php' => true,
|
||||
'/utky.php' => true,
|
||||
'/yos.php' => true,
|
||||
'/albin.php' => true,
|
||||
'/invisi.php' => true,
|
||||
'/ty.php' => true,
|
||||
'/wziar1.php' => true,
|
||||
'/742.php' => true,
|
||||
'/wp-p2r3q9c8k4.php' => true,
|
||||
'/cash.php' => true,
|
||||
'/nw_ok.php' => true,
|
||||
'/filefuns.php' => true,
|
||||
'/leon.php' => true,
|
||||
'/199.php' => true,
|
||||
'/aifa.php' => true,
|
||||
'/gptsh.php' => true,
|
||||
];
|
||||
|
||||
// 2. Prefix Targets (Folders/Directories)
|
||||
// ANY traffic accessing these folders immediately triggers the ban.
|
||||
private static $prefix_targets = [
|
||||
'/wp-content/',
|
||||
'/wp-includes/',
|
||||
'/wp-admin/',
|
||||
'/x/'
|
||||
];
|
||||
|
||||
public function execute()
|
||||
{
|
||||
if (empty($_SERVER['REQUEST_URI'])) {
|
||||
return true;
|
||||
}
|
||||
$ip = BotLogger::getRealIp();
|
||||
|
||||
if (BotLogger::isWhitelisted($ip)) {
|
||||
return true;
|
||||
}
|
||||
// 1. Strip Query Strings (e.g. ?id=1) so bots cannot bypass the exact match
|
||||
$path = strtok($_SERVER['REQUEST_URI'], '?');
|
||||
|
||||
// 2. O(1) Instant RAM-speed check for exact files
|
||||
if (isset(self::$exact_targets[$path])) {
|
||||
$this->blockRequest($ip);
|
||||
}
|
||||
|
||||
// 3. Prefix Check for WordPress & Malicious Directories
|
||||
foreach (self::$prefix_targets as $prefix) {
|
||||
if (strpos($path, $prefix) === 0) {
|
||||
$this->blockRequest($ip);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable trigger to log and drop connection
|
||||
*/
|
||||
private function blockRequest($ip)
|
||||
{
|
||||
BotLogger::logBan($ip, 'SCAN_BOT');
|
||||
|
||||
header('HTTP/1.1 405 Method Not Allowed');
|
||||
die('Method Not Allowed');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user