Скрыть злой код - печатать файлы, содержащие данную строку, в любом месте дерева каталогов [закрыто]

17

Цель этой головоломки - узнать, как вредоносный код может быть скрыт и обнаружен в программе.

Человек задает вопрос:

Пожалуйста, дайте мне некоторый код, который, как я могу искать файл, может быть в Present Directory или в его подкаталогах.

(Это вариант реального вопроса, который я видел на одном сайте.)

Чтобы быть более конкретным: OP хочет, чтобы вы написали программу, которая принимает строку и каталог. Он будет проходить по всем файлам в каталоге и рекурсивно по всем его подкаталогам. Для каждого файла он проверит, содержит ли файл строку, и если это так, напечатает имя файла. (Программа может иметь дополнительные функции, если они имеют отношение к главной цели, если вы хотите.) Нет никаких требований к порядку обхода.

Однако главная задача этой головоломки - скрыть в программе дополнительный код, который сделает дурака человеком, который просит программу в глазах ее пользователей / коллег / босса / и т.д. Например, напечатайте унизительный текст в какой-то момент, например: Автор программы не знает, как программировать, должен вернуть свой диплом и быть уволенным. Будь креативным.

Правила:

  • Раствор не должен быть вредным (за исключением, конечно, дурака из ОП). Он не должен наносить необратимый ущерб конечным пользователям (ничего подобного rm -rf)! Такие решения будут дисквалифицированы.
  • Троллинг должен быть спрятан, чтобы ОП не мог легко его найти.
  • Не должно быть очевидно, что вы троллируете ОП. Код должен выглядеть подлинно.
  • Решение должно прийти с надлежащим объяснением того, как оно контролирует OP, чтобы каждый мог узнать что-то из вашего решения. Объяснение должно быть скрыто в скрытом тексте (спойлеры) . При оценке попробуйте обнаружить троллинг, не глядя на объяснение, и проголосуйте за тех, кого трудно обнаружить.
  • Также попытайтесь скрыть троллинг от OP, если он попытается выполнить код несколько раз. Возможно, начните троллинг только после определенной даты или при некоторых условиях, которые не будет проверять неаккуратный программист. Будьте изобретательны и не забудьте объяснить трюк.
  • Не просто создайте сценарий, используя существующие инструменты, такие как grepили find. Напишите программу с нуля. Лучше избегать библиотек и предпочитать низкоуровневые вызовы - это сделает код более сложным и даст вам возможность скрывать там злые вещи.

Это . Пожалуйста, судите по вышеуказанным пунктам.

Петр Пудлак
источник
6
Как это «сделает глупцом человека, который просит программу в глазах ее пользователей / коллег / начальника». и «должен вернуть свой диплом и быть уволенным». квадрат с надписью "Решение не должно быть вредным, не должно наносить ущерб его пользователям"?
Эмори
Я ценю, что вы приложили больше усилий, чем большинство постеров с «троллингом», но все вопросы на этом сайте должны иметь четкую спецификацию, и «как я могу найти файл в текущем каталоге» далеко не соответствует этому стандарту , (Может ли какой-либо вопрос о кодовом контроле соответствовать этому стандарту - это отдельная проблема ).
Питер Тейлор
@PeterTaylor Я пытался дать более конкретное задание. Если у вас есть более конкретные предложения, я буду признателен за них.
Петр Пудлак
2
@emory кодер не пользователь. Унижение кодера перед его коллегами по кодированию без влияния на клиентов возможно.
Cruncher
3
Я голосую, чтобы закрыть этот вопрос как не по теме, потому что он закулисный .
Эрик Outgolfer

Ответы:

42

Вот мое решение (на 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 : $!";
    }
}

Первый аргумент программы - это каталог, а второй аргумент - искомая строка. Программа также показывает количество совпадений в каждом файле.

Вот как искать "VGA" в / 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
$

А теперь вот трюк:

Программа работает точно так, как было рекомендовано, если она не встречает себя в файлах. Как только он сталкивается с самим собой, он начинает префикс каждого файла, найденного с безумством. Давайте скопируем некоторые файлы в текущий каталог и попробуем снова:

$ 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 совпадения
/tmp/mygrep/english.0: 1 совпадение
Трахни тебя /tmp/mygrep/mygrep.pl: 9 совпадений
Трахни тебя /tmp/mygrep/xorg.conf.nouveau: 2 совпадения
Пошел на хуй /tmp/mygrep/xorg.conf.nvidia: 2 совпадения
$
Это связано с этим кодом:
$ F eq $ k && / y. ([F cy]) /
Он проверяет, является ли текущий файл работающей программой, и если это так, извлекает некоторую часть программы с помощью регулярного выражения и переводит ее в $ c с помощью
$ c = $ c. $ 1
Регулярное выражение извлекает объявления переменных (переменные имеют имена $ F, @u, $ c, $ k, $ y, $ o, $ u) и два пробела из комментариев. Я должен был сделать это, чтобы скрыть это, даже если программа относительно короткая.

Флоран Бэйл
источник
Ха-ха, это эпично.
Сохам Чоудхури