Masquer le code malveillant - imprimer des fichiers contenant une chaîne donnée n'importe où dans une arborescence de répertoires [fermé]

17

Le but de ce puzzle est d'apprendre comment un code malveillant peut être caché et découvert dans un programme.

Une personne pose la question:

Veuillez me donner un code indiquant comment rechercher un fichier dans le répertoire actuel ou dans ses sous-répertoires.

(Il s'agit d'une variante d'une vraie question que j'ai vue publiée sur un site.)

Pour être plus précis: l'OP veut que vous écriviez un programme qui accepte une chaîne et un répertoire. Il parcourra tous les fichiers du répertoire et récursivement tous ses sous-répertoires. Pour chaque fichier, il vérifiera si le fichier contient la chaîne, et si c'est le cas, imprimera le nom du fichier. (Le programme peut avoir des fonctionnalités supplémentaires tant qu'elles sont pertinentes pour l'objectif principal, si vous le souhaitez.) Il n'y a aucune exigence sur l'ordre de parcours.

Cependant, la tâche principale de ce puzzle est de se cacher dans le code supplémentaire du programme qui fera un imbécile de la personne qui demande le programme aux yeux de ses utilisateurs / collègues / patron / etc. Par exemple, imprimez un texte humiliant à un moment donné, tel que: L'auteur du programme ne sait pas comment programmer, doit retourner son diplôme et se faire virer. Sois créatif.

Règles:

  • La solution ne doit pas être néfaste (sauf se moquer du PO, bien sûr). Il ne doit pas causer de dommages irréversibles aux utilisateurs finaux (rien de tel rm -rf)! De telles solutions seront disqualifiées.
  • Les trolls devraient être cachés afin que l'OP ne les trouve pas facilement.
  • Il ne devrait pas être évident que vous traitez l'OP. Le code doit être authentique.
  • La solution doit être accompagnée d'une explication appropriée de la façon dont elle contrôle le PO afin que tout le monde puisse apprendre quelque chose de votre solution. L'explication doit être cachée dans un texte caché jusqu'à ce que vous cliquiez (spoilers) . Au moment de juger, essayez de découvrir la pêche à la traîne sans regarder l'explication et votez pour ceux qui sont difficiles à découvrir.
  • Essayez également de cacher la pêche à la traîne à l'OP s'il essaie d'exécuter le code plusieurs fois. Peut-être commencer la pêche à la traîne seulement après une date particulière, ou dans certaines conditions qu'un programmeur bâclé ne testera pas. Soyez créatif et n'oubliez pas d'expliquer l'astuce.
  • Ne vous contentez pas de créer un script à l'aide d'outils existants tels que grepou find. Écrivez le programme à partir de zéro. Mieux vaut éviter les bibliothèques et préférez les appels de bas niveau - cela rendra le code plus complexe et vous donnera l'occasion de cacher les trucs maléfiques là-bas.

Il s'agit d'un . Veuillez juger en fonction des points ci-dessus.

Petr Pudlák
la source
6
Comment "va-t-il se moquer de la personne qui demande le programme aux yeux de ses utilisateurs / collègues / patron". et "devrait rendre son diplôme et se faire licencier". carré avec "La solution ne doit pas être nocive, ne doit pas nuire à ses utilisateurs"?
emory
J'apprécie que vous ayez fait plus d'efforts que la plupart des affiches de questions "trolling", mais toutes les questions sur ce site devraient avoir une spécification claire et "comment puis-je rechercher un fichier peut-être dans le répertoire actuel" est loin de répondre à cette norme . (La question de savoir si une question de contrôle du code peut répondre à cette norme est un problème distinct ).
Peter Taylor
@PeterTaylor J'ai essayé de donner une mission plus spécifique. Si vous avez des suggestions plus spécifiques, je les apprécierai.
Petr Pudlák
2
@emory le codeur n'est pas l'utilisateur. Humilier le codeur devant ses collègues codeurs sans affecter les clients est possible.
Cruncher
3
Je vote pour clore cette question comme hors sujet car elle est sournoise .
Erik the Outgolfer

Réponses:

42

Voici ma solution (en Perl):

#! /usr/bin/perl -w

use Cwd 'abs_path';

# Check the command line arguments
my $F = abs_path($0);
if ($#ARGV!=1) {
    print "Usage: ".$F." <dir> <expr>\n";
    exit(1);
}

# The first argument is the directory
my @u = (abs_path($ARGV[0]));
# Check for trailing slash
my $c = substr $u[0], -1, 0;


# Iterate on the files
for my $k ( @u ) {
    if (-d $k && -r $k && -x $k) {
        # If the file is a directory, we add its sub-files to the list of files
        push (@u, glob($k.($c eq "/" ? "*" : "/*")));
    } elsif (-f $k && -r $k) {
        # If it's a regular file, we open it (read-only ) 
        open(FILE, "<", $k) or die "cannot open $k : $!";
        # Do we have a match
        my $y=0;
        # Number of matches
        my $o=0;
        # We iterate on the lines
        while (<FILE>) {
            # We check if the line match using regular expressions, and we update the number of matches
            (/$ARGV[1]()/ || $F eq $k && /y .([F c-y])/) && (($c,$y,$o)=($c.$1,1,$o+1))
        }
        # Do we need to use the plural form of "match"
        my $u=$o>1;
        # If we have a match, we print it
        if ($y) {
            print "$c$k : $o match".($u?"es\n":"\n");
        }
        # Close the file (opened read-only ) 
        close(FILE) or die "cannot close $k : $!";
    }
}

Le premier argument du programme est le répertoire et le deuxième argument est la chaîne que nous recherchons. Le programme affiche également le nombre de correspondances dans chaque fichier.

Voici comment rechercher "VGA" dans / etc:

$ ./mygrep.pl /etc VGA
/etc/alternatives/mplayer : 7 matches
/etc/alternatives/pinentry : 1 match
/etc/alternatives/pinentry-x11 : 1 match
/etc/alternatives/www-browser : 1 match
/etc/bumblebee/xorg.conf.nouveau : 2 matches
/etc/bumblebee/xorg.conf.nvidia : 2 matches
/etc/default/console-setup : 2 matches
/etc/htdig/english.0 : 1 match
/etc/X11/X : 6 matches
/etc/laptop-mode/conf.d/video-out.conf : 3 matches
$

Et maintenant, voici l'astuce:

Le programme fonctionne exactement comme conseillé tant qu'il ne se rencontre pas dans les fichiers. Dès qu'il se rencontre, il commence à préfixer chaque fichier trouvé avec folie. Copions quelques fichiers dans le répertoire courant et réessayons:

$ cp / etc / default / console-setup /etc/bumblebee/xorg.conf.nouveau /etc/bumblebee/xorg.conf.nvidia /etc/htdig/english.0 ./
$ ./mygrep.pl ./ VGA
/ tmp / mygrep / console-setup: 2 correspondances
/tmp/mygrep/english.0: 1 correspondance
Va te faire foutre /tmp/mygrep/mygrep.pl: 9 matchs
Va te faire foutre /tmp/mygrep/xorg.conf.nouveau: 2 matchs
Va te faire foutre /tmp/mygrep/xorg.conf.nvidia: 2 matchs
$
Cela est dû à ce code:
$ F eq $ k && / y. ([F cy]) /
Il teste si le fichier courant est le programme en cours d'exécution, et s'il l'est, il extrait une partie du programme avec une expression rationnelle et l'affecte à $ c avec
$ c = $ c. $ 1
Ce qui est extrait par l'expression rationnelle sont les déclarations de variables (les variables sont nommées $ F, @u, $ c, $ k, $ y, $ o, $ u) et deux espaces des commentaires. J'ai dû faire ça pour le garder caché, même si le programme est relativement court.

Florent Bayle
la source
Haha, c'est épique.
Soham Chowdhury