17
\$\begingroup\$

The point of this puzzle is to learn how a malicious code can be hidden and discovered in a program.

A person is asking the question:

Plz give me some code that how can I search a file may be in Present Directory or in its Sub-Directories.

(This is a variant of a real question I've seen posted on one site.)

To be more specific: The OP wants you to write a program that accepts a string and a directory. It will traverse all files in the directory and recursively all its subdirectories. For each file it will check if the file contains the string, and if it does, will print the name of the file. (The program can have additional features as long as they are relevant to the main goal, if you wish.) There are no requirements on the traversal order.

However, the main task of this puzzle is to hide into the program additional code that will make a fool of the person that asks for the program in the eyes of its users/colleagues/boss/etc. For example, print a humiliating text at some point, such as: The author of the program doesn't know how to program, should return his/her diploma and get fired. Be creative.

Rules:

  • The solution must not be harmful (except making fool of the OP, of course). It must not do any irreversible damage to end users (no stuff like rm -rf)! Such solutions will be disqualified.
  • The trolling stuff should be hidden so that the OP won't find it easily.
  • It shouldn't be obvious that you're trolling the OP. The code should look genuine.
  • The solution must come with a proper explanation how it trolls the OP so that everybody can learn something from your solution. The explanation should be hidden in a hidden-until-you-click text (spoilers). When judging, try to discover the trolling without looking at the explanation and vote for those that are difficult to discover.
  • Also try to hide the trolling from the OP if (s)he tries to run the code a few times. Perhaps start trolling only after a particular date, or under some conditions that a sloppy programmer won't test. Be creative and don't forget to explain the trick.
  • Don't just create a script using existing tools such as grep or find. Write the program from scratch. Better avoid libraries and prefer low-level calls - this will make the code more complex and gives you the opportunity to hide the evil stuff there.

This is a . Please judge according the above points.

\$\endgroup\$

closed as off-topic by Erik the Outgolfer, NoOneIsHere, Michael Klein, DJMcMayhem, nimi Jun 7 '16 at 17:48

  • This question does not appear to be about programming puzzles or code golf within the scope defined in the help center.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 6
    \$\begingroup\$ How does "will make a fool of the person that asks for the program in the eyes of its users/colleagues/boss." and "should return his/her diploma and get fired." square with "The solution must not be harmful, must not do any damage to its users"? \$\endgroup\$ – emory Jan 1 '14 at 21:34
  • \$\begingroup\$ I appreciate that you've put in more effort than most posters of "trolling" questions, but all questions on this site should have a clear specification and "how can I search a file may be in present directory" is nowhere near meeting that standard. (Whether any code-trolling question can meet that standard is a separate issue). \$\endgroup\$ – Peter Taylor Jan 1 '14 at 22:01
  • \$\begingroup\$ @PeterTaylor I tried to give a more specific assignment. If you have more specific suggestions, I'll appreciate them. \$\endgroup\$ – Petr Pudlák Jan 1 '14 at 22:42
  • 2
    \$\begingroup\$ @emory the coder is not the user. Humiliating the coder in front of his fellow coders without effecting the clients is possible. \$\endgroup\$ – Cruncher Jan 2 '14 at 18:10
  • 3
    \$\begingroup\$ I'm voting to close this question as off-topic because it is underhanded. \$\endgroup\$ – Erik the Outgolfer Jun 7 '16 at 15:17
42
\$\begingroup\$

Here is my solution (in 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 : $!";
    }
}

The first argument of the program is the directory and the second argument is the string we are looking for. The program also show the number of matches in each file.

Here is how to search "VGA" in /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
$

And now, here is the trick :

The program works exactly as advised as long as it doesn't encounter itself in the files. As soon as it encounters itself, it starts to prefix each file found with insanity. Let's copy some files in the current directory and try again :

$ 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 matches
/tmp/mygrep/english.0 : 1 match
Fuck you /tmp/mygrep/mygrep.pl : 9 matches
Fuck you /tmp/mygrep/xorg.conf.nouveau : 2 matches
Fuck you /tmp/mygrep/xorg.conf.nvidia : 2 matches
$
This is due to this code:
$F eq $k && /y .([F c-y])/
It tests if the current file is the running program, and if it is, it extract some part of the program with a regexp and affects it to $c with
$c = $c.$1
What is extracted by the regexp are the variable declarations (variables are named $F, @u, $c, $k, $y, $o, $u) and two spaces from the comments. I had to do that to keep it hidden, even if the program is relatively short.

\$\endgroup\$
  • \$\begingroup\$ Haha, this is epic. \$\endgroup\$ – Soham Chowdhury Sep 9 '14 at 15:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.