Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deparsing/Decomposing - step-by-step this obfuscated perl script

As the title - please can anyone explain how the next scripts works

this prints the text: "Perl guys are smart"

''=~('(?{'.('])@@^{'^'-[).*[').'"'.('-[)@{:__({:)[{(-:)^}'^'}>[,[]*&[[[[>[[@[[*_').',$/})')

this prints only "b"

use strict;
use warnings;
''=~('(?{'.('_/).+{'^'/]@@_[').'"'.('=^'^'_|').',$/})')

the perl -MO=Deparse shows only this:

use warnings;
use strict 'refs';
'' =~ m[(?{print "b",$/})];

but havent any idea why... ;(

What is the recommended way decomposing like scripts? How to start?

so, tried this:

'' =~
(
        '(?{'
        .
        (
                '])@@^{' ^ '-[).*['
        )
        .
        '"'
        .
        (
                 '-[)@{:__({:)[{(-:)^}' ^ '}>[,[]*&[[[[>[[@[[*_'
        )
        .
        ',$/})'
)

several parts are concatenated by .. And the result of the bitwise ^ probably gives the text parts. The:

perl -e "print '-[)@{:__({:)[{(-:)^}' ^ '}>[,[]*&[[[[>[[@[[*_'"

prints "Perl guys are smart" and the first ^ generating "print".

But when, i rewrite it to:

'' =~
(
    '(?{'
    .
    (
        'print'
    )
    .
    '"'
    .
    (
         'Perl guys are smart'
    )
    .
    ',$/})'
)

My perl told me:

panic: top_env

Strange, first time i saw like error message...

Thats mean: it isn't allowed replace the 'str1' ^ 'str2' with the result, (don't understand why) and why the perl prints the panic message?

my perl:

This is perl 5, version 12, subversion 4 (v5.12.4) built for darwin-multi-2level

Ps: examples are generated here

like image 468
cajwine Avatar asked Jun 16 '12 10:06

cajwine


2 Answers

In the line

.('_/).+{' ^ '/]@@_[

when you evaluate ']' ^ '-', the result will be the letter p. ^ is a bitwise string operation, so after that we follow letter by letter to get result string.

Check my script, it works like your example. I hope it will help you.

use v5.14;

# actually we obfuscated print and your word + "
# it looks like that (print).'"'.(yor_word")
my $print  = 'print';
my $string = 'special for stackoverflow by fxzuz"';

my $left  = get_obfuscated($print);
my $right = get_obfuscated($string);

# prepare result regexp
my $result = "'' =~ ('(?{'.($left).'\"'.($right).',\$/})');";

say 'result obfuscated ' .  $result;
eval $result;

sub get_obfuscated {

    my $string = shift;
    my @letters = split //, $string;

    # all symbols like :,&? etc (exclude ' and \)
    # we use them for obfuscation
    my @array = (32..38, 40..47, 58..64, 91, 93..95, 123..126);

    my $left_str = '';
    my $right_str = '';

    # obfuscated letter by letter
    for my $letter (@letters) {

        my @result;
        # get right xor letters
        for my $symbol (@array) {

            # prepare xor results
           my $result = ord $letter ^ $symbol;
           push @result, { left => $result, right => $symbol } if $result ~~ @array;
        }

        my $rand_elem = $result[rand $#result];
        $left_str  .= chr $rand_elem->{left};
        $right_str .= chr $rand_elem->{right};
    }

    my $obfuscated = "'$left_str' ^ '$right_str'";
    say "$string => $obfuscated";

    return $obfuscated;
}
like image 158
Pavel Vlasov Avatar answered Nov 10 '22 16:11

Pavel Vlasov


The trick to understanding what's going on here is to look at the string being constructed by the XORs and concatenations:

(?{print "Perl guys are smart",$/})

This is an experimental regular expression feature of the form (?{ code }). So what you see printed to the terminal is the result of

print "Perl guys are smart",$/

being invoked by ''=~.... $/ is Perl's input record separator, which by default is a newline.

like image 3
flesk Avatar answered Nov 10 '22 15:11

flesk