| Solves | 70 |
|---|
The challenge involves a WordPress plugin named "AI Trust Score" (located in wp-content/plugins/ai-badbots/ai-badbots.php). This plugin uses AI heuristics to assign a "trust score" to incoming requests, blocking those that appear to be bots.
The core logic is found in the evaluate_request function, which is hooked to init. It only triggers if the GET parameter ai-trust-check is present.
public function evaluate_request()
{
if (!isset($_GET['ai-trust-check'])) {
return;
}
$this->collect_signals();
$this->calculate_score();
$this->validate_score();
}
The scoring mechanism relies on collecting various "signals" in collect_signals(). One interesting signal is ip_entropy, which is calculated by subtracting the length of a forwarded IP header (e.g., X-Forwarded-For) from the length of the remote IP address.
$xff = 0;
// ... (checks various headers like HTTP_X_FORWARDED_FOR)
$this->signals['ip_entropy'] = strlen($ip) - strlen($xff);
After collection, each signal is "normalized" using a logarithmic scale:
private function normalize($value)
{
// ...
return log($value) / log(10);
}
Finally, the validate_score() method determines if access should be granted.
private function validate_score()
{
if (($this->score * 0) != 0 || $this->score > 0.95) {
$this->grant_access();
return;
}
$this->deny_access();
}
The vulnerability stems from the handling of negative numbers in the ip_entropy calculation and how PHP's log() function behaves.
X-Forwarded-For header, we can make strlen($xff) much larger than strlen($ip), resulting in a negative value for ip_entropy.normalize(), log(negative_number) returns NAN (Not A Number).