AI BadBots

Solves 70

Recon

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();
    }

Solver

The vulnerability stems from the handling of negative numbers in the ip_entropy calculation and how PHP's log() function behaves.

  1. Negative Input: By providing a very long string in the X-Forwarded-For header, we can make strlen($xff) much larger than strlen($ip), resulting in a negative value for ip_entropy.
  2. NaN Generation: When this negative value is passed to normalize(), log(negative_number) returns NAN (Not A Number).