web-dev-qa-db-fra.com

PHP malware / Shell continue de ressusciter

Donc, je lutte contre ce problème depuis des mois maintenant et j'ai décidé que cela dépassait mes compétences de serveur limitées (voire pas du tout) et que j'avais besoin de l'aide des pros.

J'ai un VPS (avec accès root) qui héberge plusieurs sites Web différents PHP, dont certains sont basés sur WordPress. Certains sites ont été infectés par le n malware à la suite de la vulnérabilité MailPoet . J'ai nettoyé les sites infectés, complètement supprimé MailPoet, les comptes de porte dérobée et les choses connexes, mais le malware continue de ressusciter de temps en temps. Voici ce que je peux décrire à ce sujet :

  • Il existe deux signatures de logiciels malveillants (désolé si j'utilise le mauvais terme), les deux sont injectés tout en haut de PHP. Une fois ressemble à ceci <?php $ozufdqjmhx = '7825h!>!%x5c%x7825tdz)%x5c%x7825bbT-%x5c%x782vg}... Avec la variable $ozufdqjmhx Change de temps en temps, l'autre commence par <?php if(!isset($GLOBALS[\'\a\e\0... etc etc
  • Le malware revient à intervalles aléatoires . Parfois, il revient un jour après le nettoyage, parfois une semaine ou plusieurs semaines.
  • Seuls les fichiers/répertoires/sites Web précédemment infectés sont à nouveau infectés . Les nouveaux répertoires, ou les anciens non affectés, sont toujours propres. Cependant, les nouveaux fichiers dans les anciens répertoires infectés sont infectés.
  • maldet (en utilisant ClamAV je crois) ne peut détecter aucun malware. PHP Shell Detector le peut, mais il ne peut pas le réparer car il s'agit uniquement d'un détecteur.

Pouvez-vous m'aider ou donner une direction vers laquelle je devrais me diriger? Un million de mercis d'avance!

(Je suis également désolé si cette question ne correspond pas aux réglementations du site. Lorsque je suis un utilisateur quotidien de StackOverflow, c'est ma première visite sur ce sous-site de sécurité).

EDIT: J'apprécie vraiment toute recommandation de votre part, mais essuyer le serveur et recommencer à zéro n'est pas une option. Si c'était le cas, pourquoi devrais-je poser cette question pour commencer, non? :)

EDIT 2: Suite à la réponse de @ Mints97, j'ai vérifié tous les ports ouverts - semble normal:

21/tcp    open  ftp
22/tcp    open  ssh
25/tcp    open  smtp
53/tcp    open  domain
80/tcp    open  http
110/tcp   open  pop3
143/tcp   open  imap
443/tcp   open  https
465/tcp   open  smtps
587/tcp   open  submission
993/tcp   open  imaps
995/tcp   open  pop3s
3000/tcp  open  ppp
3306/tcp  open  mysql
5432/tcp  open  postgresql
8000/tcp  open  http-alt
8080/tcp  open  http-proxy
8082/tcp  open  blackice-alerts
10000/tcp open  snet-sensor-mgmt
20000/tcp open  dnp

EDIT 3: C'est pour @QuestionOverflow: Lors de la recherche des 4 domaines que vous avez mentionnés dans votre autre réponse , je suis tombé sur un script pour éliminer le malware ici . Dans le code, nous pouvons voir if (preg_match('/^<\?php \$[a-z]{10} = \'/', $fh_str)) {, qui cible EXACTEMENT la première signature. Je dirais maintenant que c'est le même malware, ou du moins du même gars via la même vulnérabilité. Assez intéressant.

EDIT 4: Le deuxième malware a déjà été discuté ici si cela peut aider, et oui, apparemment, les deux récupèrent une charge utile au hasard dans 4 domaines: "33db9538.com", "9507c4e8.com", "e5b57288 .com "," 54dfa1cb.com ". J'ai ajouté les 4 dans mes fichiers hosts, pointant vers 127.0.0.1. Voyons quelle est la prochaine étape.

EDIT 5: Plusieurs suggèrent que cette question a déjà été répondue ici à Comment expliquez-vous la nécessité de la "neutraliser depuis l'orbite" à la direction et aux utilisateurs? . Honnêtement, je ne vois pas comment l'autre question répond à la mienne. Je demande comment éliminer un malware, sans expliquer à mon patron pourquoi je devrais réinstaller un serveur.

22
An Phan

J'activerais auditd pour surveiller les modifications apportées aux fichiers que vous attendez à être détournés. Vous pourrez déterminer le compte et le processus responsables de ces modifications.

Après avoir installé auditd (non installé par défaut sur tous les systèmes), vous pouvez commencer à surveiller les modifications dans les fichiers. Pour ce faire, exécutez simplement la commande:

auditctl -w /var/www -p wa

Cette commande enregistre toutes les modifications de fichier dans le fichier journal d'auditd. Habituellement, vous le trouverez dans/var/log/audit /, mais il dépend du système.

Si vous pensez que l'attaquant pourrait remarquer cela (et peut-être supprimer la règle), vous pouvez le verrouiller en exécutant la commande:

auditctl -e 2

Aucune autre modification ne peut être apportée aux règles d'audit avant le redémarrage du système. Avant de faire cela, assurez-vous que la règle d'audit ci-dessus ne génère pas une quantité insensée de journaux.

Enfin, les journaux d'audit sont un peu cryptiques. Une fois que vous avez constaté que le système est à nouveau détourné, vous pouvez rechercher la piste d'audit à l'aide de la commande:

ausearch -f /var/www/backdoored_file.php

J'espère que cela vous fournira des indices sur ce qui se passe. Bonne chance!

Additionnel:

Pour que les règles d'audit survivent au redémarrage, vous devez les définir dans /etc/audit/audit.rules

22
Dog eat cat world

J'ai initialement posté cela en tant que commentaire, mais je pense que cela pourrait faire avec une petite explication.

D'après mon expérience avec les scénarios de prise de contrôle de sites Web, lorsqu'un shell est téléchargé sur un site Web, le pirate parvient à exploiter une vulnérabilité dans le serveur, à obtenir un accès root, à dérober votre SSH et à compromettre tous les autres sites du serveur, ou il ne le fait tout simplement pas. t gérer cela et se contenter d'un simple Shell. Je pense que, dans votre cas, c'est le deuxième scénario, étant donné que vous dites qu'un seul site Web sur le VPS a été infecté.

Maintenant, comment le Shell "ressuscite". Si votre serveur n'était pas "rooté", cela ne laisse que quatre autres options auxquelles je peux penser:

  1. a "bindport" porte dérobée
  2. a "backconnect" backdoor (rare)
  3. un porte dérobée personnalisée ou "téléchargeur" dans l'un de vos fichiers PHP
  4. un compte MySQL compromis avec accès aux fichiers et privilèges de connexion à distance.

Parlons des deux premiers et comment les traiter en premier. "bindport" et "backconnect" sont deux petits programmes, généralement des scripts Perl, qui sont traditionnellement livrés avec des shells web. Ils sont généralement créés dans (et exécutés depuis) ​​le /tmp dossier, qui est accessible en écriture pour tout. Pour les trouver, vous pouvez surveiller tous vos processus à la recherche de scripts ou de programmes étranges et jeter un œil dans le /tmp dossier. Il est également conseillé de mettre en place un pare-feu.

"Bindport" ouvre un nouveau port pour les connexions entrantes et fournit un accès au shell Unix à quiconque se connecte (il est généralement protégé par mot de passe). Pour le trouver, recherchez des ports ouverts étranges (de nombreux pirates l'ont juste ouvert le port 31337 ou quelque chose comme ça).

"Backconnect" fait exactement ce qu'on appelle - il ouvre une connexion à un serveur distant, accordant également un accès Shell. Il est utilisé plus rarement que "bindport", principalement parce que la plupart des pirates informatiques sont trop paresseux pour se soucier de l'utiliser. Ils ne recourent normalement à cette méthode que si "bindport" échoue pour une raison quelconque (comme les paramètres du pare-feu).

Maintenant, à propos des backdoors personnalisés et "téléchargeurs". Celles-ci sont rarement utilisées, car l'attaquant a besoin de savoir PHP au moins un peu pour l'utiliser (et la plupart des site-jackers aujourd'hui ne sont rien de plus que des skriptkiddies ou des bots mal faits). Ils sont principalement des fichiers autonomes comme des shells simplistes ou quelques lignes de code supplémentaires injectées dans l'un de vos scripts. Ils exécutent soit les commandes qui leur sont données (code PHP, commandes Shell), soit effectuent une simple écriture de fichier avec des données qui leur sont transmises ( qui peut être une autre porte dérobée). Vous pouvez essayer de rechercher des fichiers qui ont PHP comme eval, preg_replace avec le modificateur e, exec, system, fopen/fwrite et d'autres fonctions de fichier, etc. Cependant, le le meilleur et le moyen le plus sûr de gérer ce genre de choses est simplement restaurer tout le site Web à partir d'une sauvegarde. Si vous décidez de le faire, assurez-vous d'effacer tous les autres fichiers du site du serveur au préalable, au cas où vous auriez manqué un shell ou une porte dérobée autonome.

Et le dernier cas hautement improbable, mais toujours possible. Si vous avez exécuté WordPress avec l'utilisateur racine MySQL (ou simplement un utilisateur avec des droits d'écriture de fichier), ou simplement avec un utilisateur qui avait suffisamment de droits pour afficher le hachage de mot de passe d'un autre utilisateur avec les droits d'écriture de fichiers, et cet utilisateur avec les droits d'écriture de fichiers a le privilège de se connecter à la base de données de n'importe où, eh bien ... vous l'obtenez. Je vous recommande de changer tous vos mots de passe MySQL.

Passons maintenant à pourquoi seul un certain ensemble de répertoires est infecté. Il y a deux cas possibles: soit le pirate informatique, ayant échoué à "rooter" le serveur, se débrouille avec le nombre limité de répertoires disponibles (probablement tous les répertoires de votre site Web), soit il a accès à d'autres répertoires, mais il suffit de ne pas '' t les utiliser.

Si c'est le dernier cas, je parierais que vous avez affaire à un idiot ou à quelqu'un de très paresseux. Ou avec un bot. Oui, cela peut vous décevoir, mais je doute que votre site soit vraiment assez important pour un pirate expérimenté: il pourrait être utilisé pour récupérer quelques clics de vos utilisateurs, pour héberger des logiciels malveillants ou simplement produire une tonne métrique de spam quelques fois. Vous avez affaire à un scriptkiddie, ou à un imbécile inexpérimenté essayant de récupérer quelques centimes de clics et de spam, ou avec un bot. Cependant, je pense qu'il s'agit plutôt d'une personne vivante: cela expliquerait l'irrégularité des "résurections" du Shell.

9
Mints97

J'ai eu une chose très similaire à un site que je gère. Après beaucoup de frustration de supprimer le code malveillant, puis d'apparaître environ 2 semaines plus tard, j'ai découvert ceci:

J'ai pris note de l'horodatage de la date à laquelle tous les fichiers ont été modifiés, puis j'ai recherché le journal d'accès pendant cette minute. J'ai vu une certaine page demandée qui semblait suspecte, car c'était un 404.php d'un thème wordpress qui n'était pas actif. J'ai vérifié cette page et j'ai vu une ligne qui était essentiellement eval($_POST['php']) codé en base64.

Je n'ai donc pas supprimé le code, au lieu de cela, je l'ai changé pour enregistrer un journal de tout ce qui est envoyé au message de cette page. Effectivement, 2 semaines plus tard, mon site est resté en sécurité, mais un fichier journal a enregistré un code intéressant qui lui a été envoyé.

7
scrollup

On dirait que les attaquants ont installé un rootkit sur votre serveur. Un rootkit peut fournir une porte dérobée même si tout semble propre.

À mon avis, la meilleure approche consiste à effacer le serveur et à réinstaller à partir de zéro. Corrigez les sites Web pour éliminer la vulnérabilité. Si vous avez besoin de restaurer à partir d'une sauvegarde (vous avez des sauvegardes, non? :)) assurez-vous qu'elle est propre.

Configurez un script pour rechercher les traces d'infection (par exemple l'utilisateur ID 10001) au cas où il y aurait d'autres vulnérabilités en plus du problème MailPoet.

4
Vegard

Cela peut sembler être une question simple, mais avez-vous vérifié tout élément suspect en vous /tmp répertoire? Alors que différentes variantes de logiciels malveillants sont partout, beaucoup profitent généralement des bogues d'accès au système, tels que le bogue Shellshock bash, pour planter du code exécutable directement dans le /tmp répertoire.

Si vous ne savez pas ce qui devrait/ne devrait pas être dans /tmp/ il y a une chose simple, mais extrême, que vous pouvez faire pour éliminer les mauvaises choses. Exécutez simplement ceci en ligne dans la ligne de commande:

rm -rf /tmp && mkdir /tmp && chown root:root /tmp && chmod 1777 /tmp

Ou exécutez chaque commande individuellement comme ceci:

Sudo rm -rf /tmp 
Sudo mkdir /tmp
Sudo chown root:root /tmp
Sudo chmod 1777 /tmp

Redémarrez ensuite le serveur pour voir si cela clarifie les choses. Si c'est le cas, félicitations! Mais vous n'êtes pas encore sorti du bois, car ce qui a causé l'infection du système d'origine pourrait toujours pénétrer votre système, ce n'est qu'une question de temps avant qu'ils ne vous réinfectent à nouveau. Ce qui signifie, espérons-le, que cela nettoiera le gâchis causé par une faiblesse de votre système que vous avez, espérons-le, déjà branché. Mais vous devez être sûr de découvrir ce qu'aurait pu être ce point faible et de le durcir.

Je recommanderais également de vérifier les entrées crontab pour l'utilisateur root via un simple crontab -l comme ça:

Sudo crontab -l

Et peut-être même en exécutant le script bash tiré de cette réponse sur Stack Overflow qui vous donnera un bon rapport d'ensemble de tous les crontabs installés sur le système:

#!/bin/bash

# System-wide crontab file and cron job directory. Change these for your system.
CRONTAB='/etc/crontab'
CRONDIR='/etc/cron.d'

# Single tab character. Annoyingly necessary.
tab=$(echo -en "\t")

# Given a stream of crontab lines, exclude non-cron job lines, replace
# whitespace characters with a single space, and remove any spaces from the
# beginning of each line.
function clean_cron_lines() {
    while read line ; do
        echo "${line}" |
            egrep --invert-match '^($|\s*#|\s*[[:alnum:]_]+=)' |
            sed --regexp-extended "s/\s+/ /g" |
            sed --regexp-extended "s/^ //"
    done;
}

# Given a stream of cleaned crontab lines, echo any that don't include the
# run-parts command, and for those that do, show each job file in the run-parts
# directory as if it were scheduled explicitly.
function lookup_run_parts() {
    while read line ; do
        match=$(echo "${line}" | egrep -o 'run-parts (-{1,2}\S+ )*\S+')

        if [[ -z "${match}" ]] ; then
            echo "${line}"
        else
            cron_fields=$(echo "${line}" | cut -f1-6 -d' ')
            cron_job_dir=$(echo  "${match}" | awk '{print $NF}')

            if [[ -d "${cron_job_dir}" ]] ; then
                for cron_job_file in "${cron_job_dir}"/* ; do  # */ <not a comment>
                    [[ -f "${cron_job_file}" ]] && echo "${cron_fields} ${cron_job_file}"
                done
            fi
        fi
    done;
}

# Temporary file for crontab lines.
temp=$(mktemp) || exit 1

# Add all of the jobs from the system-wide crontab file.
cat "${CRONTAB}" | clean_cron_lines | lookup_run_parts >"${temp}" 

# Add all of the jobs from the system-wide cron directory.
cat "${CRONDIR}"/* | clean_cron_lines >>"${temp}"  # */ <not a comment>

# Add each user's crontab (if it exists). Insert the user's name between the
# five time fields and the command.
while read user ; do
    crontab -l -u "${user}" 2>/dev/null |
        clean_cron_lines |
        sed --regexp-extended "s/^((\S+ +){5})(.+)$/\1${user} \3/" >>"${temp}"
done < <(cut --fields=1 --delimiter=: /etc/passwd)

# Output the collected crontab lines. Replace the single spaces between the
# fields with tab characters, sort the lines by hour and minute, insert the
# header line, and format the results as a table.
cat "${temp}" |
    sed --regexp-extended "s/^(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(.*)$/\1\t\2\t\3\t\4\t\5\t\6\t\7/" |
    sort --numeric-sort --field-separator="${tab}" --key=2,1 |
    sed "1i\mi\th\td\tm\tw\tuser\tcommand" |
    column -s"${tab}" -t

rm --force "${temp}"

Aussi complexe que puissent paraître les infections de logiciels malveillants, une fois que vous savez où se trouvent les points d'étranglement communs, vous pouvez concentrer vos efforts pour purger votre système de ces fichiers indésirables une fois pour toutes.

1
JakeGould

Si vous ne savez pas comment vous avez été infecté en premier lieu, alors je suppose que la résurrection vient de vous, frappé par le même scanner de vulnérabilité qui vous a frappé la première fois - si tel est le cas, en suivant @ scrollup's des conseils pour comparer les horodatages des fichiers au trafic Web devraient vous trouver le script vulnérable, ainsi que de bonnes adresses IP à bloquer sur votre site.

D'après mon expérience, au moins lors du ciblage d'Apache, les scripts de modification de page cibleront un sous-ensemble très spécifique des dossiers sur votre machine: ceux qu'ils peuvent trouver dans votre dossier /etc/httpd/conf/httpd.conf. J'avais d'autres dossiers Web définis dans les fichiers inclus, mais le script qui recherchait les dossiers à injecter était clairement uniquement intéressé à saluer les dossiers d'un seul fichier.

Alors, voyez s'il y a quelque chose de significativement différent dans votre configuration Apache entre les sites qui ont été impactés et ceux qui ne l'ont pas été. Il peut vous donner une bonne approche pour en protéger la plupart de vos sites à l'avenir, tout en laissant un site "canari" ou "pot de miel" que vous pouvez surveiller pour les récidives.

1
Dewi Morgan

Pourquoi ne pas surveiller la création du nouvel utilisateur? Et une fois que cela se produit, vous envoyez un mail hors site pour vous informer de la création.

0
deelink

Il n'y a pas assez d'informations dans votre message pour déterminer la cause de cela. Vous devrez faire des recherches. La première chose à vérifier est l'heure de création/modification des fichiers, puis comparez-la à vos journaux d'accès et ftp à peu près en même temps afin de déterminer comment les fichiers ont été modifiés. J'espère que cela vous mènera à un fichier /plugin/.Shell.php qui est la porte dérobée de l'infection initiale. Si vos journaux ne semblent pas contenir quoi que ce soit d'utile, il est possible qu'un compte de porte dérobée ait été créé dans votre WP installation et ce que vous voyez est le résultat des "opérations normales" par un malveillant utilisateur.

0
wireghoul