Ukryj zły kod - drukuj pliki zawierające dany ciąg w dowolnym miejscu w drzewie katalogów [zamknięte]

17

Zagadka polega na tym, aby dowiedzieć się, w jaki sposób złośliwy kod może być ukryty i wykryty w programie.

Osoba zadaje pytanie:

Plz daj mi kod, w jaki sposób mogę przeszukać plik w katalogu bieżącym lub w jego podkatalogach.

(Jest to wariant prawdziwego pytania, które widziałem na jednej stronie).

Aby być bardziej szczegółowym: OP chce, abyś napisał program, który akceptuje ciąg i katalog. Przejdzie wszystkie pliki w katalogu i rekurencyjnie wszystkie jego podkatalogi. Dla każdego pliku sprawdzi, czy plik zawiera ciąg, a jeśli tak, wydrukuje nazwę pliku. (Program może mieć dodatkowe funkcje, o ile są one zgodne z głównym celem, jeśli chcesz). Nie ma żadnych wymagań dotyczących kolejności przejścia.

Jednak głównym zadaniem tej układanki jest ukrywanie w programie dodatkowego kodu, który będzie głupcem osoby, która prosi o program w oczach użytkowników / współpracowników / szefa itp. Na przykład w pewnym momencie wydrukuj upokarzający tekst, na przykład: Autor programu nie wie, jak programować, powinien zwrócić swój dyplom i zostać zwolniony. Bądź kreatywny.

Zasady:

  • Rozwiązanie nie może być szkodliwe (oczywiście z wyjątkiem głupstwa PO), oczywiście. Nie może wyrządzić żadnych nieodwracalnych szkód użytkownikom końcowym (nic podobnego rm -rf)! Takie rozwiązania zostaną zdyskwalifikowane.
  • Trollingowe rzeczy powinny być ukryte, aby OP nie mógł ich łatwo znaleźć.
  • Nie powinno być oczywiste, że trollujesz PO. Kod powinien wyglądać autentycznie.
  • Rozwiązanie musi pochodzić z właściwego wyjaśnienia, jak to trolle OP tak, że każdy może nauczyć się czegoś od swojego rozwiązania. Wyjaśnienie powinno być ukryte w tekście ukrytym aż do kliknięcia (spoilery) . Oceniając, spróbuj odkryć trolling bez patrzenia na wyjaśnienia i głosuj na tych, których trudno odkryć.
  • Spróbuj także ukryć trollowanie przed OP, jeśli spróbuje uruchomić kod kilka razy. Być może zacznij trolling dopiero po określonej dacie lub pod pewnymi warunkami, których niechlujny programista nie przetestuje. Bądź kreatywny i nie zapomnij wyjaśnić sztuczki.
  • Nie twórz po prostu skryptu przy użyciu istniejących narzędzi, takich jak greplub find. Napisz program od zera. Lepiej unikaj bibliotek i preferuj połączenia niskopoziomowe - sprawi to, że kod będzie bardziej złożony i da ci możliwość ukrycia tam złych rzeczy.

To . Oceniaj zgodnie z powyższymi punktami.

Petr Pudlák
źródło
6
W jaki sposób „zrobi z głupca osobę, która prosi o program w oczach użytkowników / współpracowników / szefa”. i „powinien zwrócić swój dyplom i zostać zwolniony”. kwadrat z „Rozwiązanie nie może być szkodliwe, nie może wyrządzać szkód użytkownikom”?
emory
Rozumiem, że włożyłeś więcej wysiłku niż większość plakatów z pytaniami „trollingowymi”, ale wszystkie pytania na tej stronie powinny mieć jasną specyfikację, a „jak mogę przeszukać plik w obecnym katalogu” nie jest wcale bliskie spełnienia tego standardu . (Czy pytanie trollowania kodu może spełniać ten standard, jest osobną kwestią ).
Peter Taylor
@PeterTaylor Próbowałem podać bardziej szczegółowe zadanie. Jeśli masz bardziej szczegółowe sugestie, docenię je.
Petr Pudlák
2
@ emory programista nie jest użytkownikiem. Możliwe jest upokorzenie programisty przed innymi programistami bez wywierania wpływu na klientów.
Cruncher
3
Głosuję za zamknięciem tego pytania jako nie na temat, ponieważ jest ono niepełne .
Erik the Outgolfer

Odpowiedzi:

42

Oto moje rozwiązanie (w Perlu):

#! /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 : $!";
    }
}

Pierwszym argumentem programu jest katalog, a drugim argumentem jest szukany ciąg. Program pokazuje również liczbę dopasowań w każdym pliku.

Oto jak wyszukać „VGA” w / 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
$

A teraz oto sztuczka:

Program działa dokładnie tak, jak zalecany, o ile nie napotyka się w plikach. Jak tylko się zorientuje, zaczyna szaleć przed każdym znalezionym plikiem. Skopiujmy niektóre pliki z bieżącego katalogu i spróbuj ponownie:

$ 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 dopasowania
/tmp/mygrep/english.0: 1 dopasowanie
Pierdol się /tmp/mygrep/mygrep.pl: 9 meczów
Pierdol się /tmp/mygrep/xorg.conf.nouveau: 2 mecze
Pierdol się /tmp/mygrep/xorg.conf.nvidia: 2 mecze
$
Wynika to z tego kodu:
$ F eq $ k && / y. ([F cy]) /
Sprawdza, czy bieżący plik jest uruchomionym programem, a jeśli tak, to wypakowuje część programu za pomocą wyrażenia regularnego i wpływa na $ c za pomocą
$ c = $ c. $ 1
Wyrażenie regularne wyodrębnia deklaracje zmiennych (zmienne mają nazwy $ F, @u, $ c, $ k, $ y, $ o, $ u) i dwie spacje od komentarzy. Musiałem to zrobić, aby go ukryć, nawet jeśli program jest stosunkowo krótki.

Florent Bayle
źródło
Haha, to jest epickie.
Soham Chowdhury,