Ocultar código maligno: imprima archivos que contengan una cadena dada en cualquier lugar de un árbol de directorios [cerrado]

17

El objetivo de este rompecabezas es aprender cómo se puede ocultar y descubrir un código malicioso en un programa.

Una persona hace la pregunta:

Por favor, dame un código que indique cómo puedo buscar un archivo en el presente directorio o en sus subdirectorios.

(Esta es una variante de una pregunta real que he visto publicada en un sitio).

Para ser más específico: El OP quiere que escriba un programa que acepte una cadena y un directorio. Recorrerá todos los archivos en el directorio y recursivamente todos sus subdirectorios. Para cada archivo, verificará si el archivo contiene la cadena y, si lo tiene, imprimirá el nombre del archivo. (Si lo desea, el programa puede tener características adicionales siempre que sean relevantes para el objetivo principal). No hay requisitos en el orden transversal.

Sin embargo, la tarea principal de este rompecabezas es esconderse en el código adicional del programa que hará el ridículo a la persona que solicita el programa a los ojos de sus usuarios / colegas / jefe / etc. Por ejemplo, imprima un texto humillante en algún momento, como: El autor del programa no sabe cómo programar, debe devolver su diploma y ser despedido. Ser creativo.

Reglas:

  • La solución no debe ser dañina (excepto hacer el ridículo al OP, por supuesto). ¡No debe causar ningún daño irreversible a los usuarios finales (nada parecido rm -rf)! Dichas soluciones serán descalificadas.
  • El curricán debe estar oculto para que el OP no lo encuentre fácilmente.
  • No debería ser obvio que estás controlando el OP. El código debe verse genuino.
  • La solución debe venir con una explicación adecuada de cómo controla el OP para que todos puedan aprender algo de su solución. La explicación debe estar oculta en un texto oculto hasta que haga clic (spoilers) . Al juzgar, trate de descubrir el curricán sin mirar la explicación y vote por aquellos que son difíciles de descubrir.
  • También intente ocultar el trolling del OP si intenta ejecutar el código varias veces. Quizás comience a cursar solo después de una fecha en particular, o bajo ciertas condiciones que un programador descuidado no probará. Sé creativo y no olvides explicar el truco.
  • No solo cree un script usando herramientas existentes como grepo find. Escribe el programa desde cero. Mejor evite las bibliotecas y prefiera las llamadas de bajo nivel: esto hará que el código sea más complejo y le dará la oportunidad de ocultar las cosas malvadas allí.

Este es un . Por favor juzgue de acuerdo con los puntos anteriores.

Petr Pudlák
fuente
66
¿Cómo "hará el ridículo a la persona que solicita el programa a los ojos de sus usuarios / colegas / jefe". y "debería devolver su diploma y ser despedido". cuadrado con "La solución no debe ser dañina, no debe hacer ningún daño a sus usuarios"?
emory
Le agradezco que haya puesto más esfuerzo que la mayoría de los pósters de preguntas de "curricán", pero todas las preguntas en este sitio deben tener una especificación clara y "cómo puedo buscar un archivo puede estar en el directorio actual" no está cerca de cumplir ese estándar . (Si alguna pregunta de arrastre de código puede cumplir ese estándar es un tema aparte ).
Peter Taylor
@PeterTaylor Intenté dar una tarea más específica. Si tienes sugerencias más específicas, te las agradeceré.
Petr Pudlák
2
@emory el codificador no es el usuario. Es posible humillar al codificador frente a sus compañeros codificadores sin afectar a los clientes.
Cruncher el
3
Estoy votando para cerrar esta pregunta como fuera de tema porque está oculta .
Erik the Outgolfer

Respuestas:

42

Aquí está mi solución (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 : $!";
    }
}

El primer argumento del programa es el directorio y el segundo argumento es la cadena que estamos buscando. El programa también muestra el número de coincidencias en cada archivo.

Aquí es cómo buscar "VGA" en / 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
$

Y ahora, aquí está el truco:

El programa funciona exactamente como se recomienda, siempre y cuando no se encuentre en los archivos. Tan pronto como se encuentra, comienza a prefijar cada archivo encontrado con locura. Copiemos algunos archivos en el directorio actual e intentemos de nuevo:

$ 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 coincidencias
/tmp/mygrep/english.0: 1 partido
Jódete /tmp/mygrep/mygrep.pl: 9 partidos
Jódete /tmp/mygrep/xorg.conf.nouveau: 2 partidos
Jódete /tmp/mygrep/xorg.conf.nvidia: 2 partidos
PS
Esto se debe a este código:
$ F eq $ k && / a. ([F cy]) /
Comprueba si el archivo actual es el programa en ejecución y, si lo es, extrae alguna parte del programa con una expresión regular y lo afecta a $ c con
$ c = $ c. $ 1
Lo que extrae la expresión regular son las declaraciones de variables (las variables se denominan $ F, @u, $ c, $ k, $ y, $ o, $ u) y dos espacios de los comentarios. Tenía que hacer eso para mantenerlo oculto, incluso si el programa es relativamente corto.

Florent Bayle
fuente
Jaja, esto es épico.
Soham Chowdhury