Jump to content


Photo
- - - - -

obfuscation

perl obfuscation coding complex

  • Please log in to reply
12 replies to this topic

#1 flyingpoptartcat

flyingpoptartcat

    Hak5 Fan +

  • Active Members
  • PipPipPip
  • 49 posts
  • Gender:Male
  • Interests:PERL, obfuscation, networking, coding, reverse engineering

Posted 24 December 2012 - 10:21 AM

how's my obfuscation?
my($a, $b, $c);($a,$b,$c) =	 floor();local $d=					 "\x53\x54\x44\x4f\x55\x54";my @z=('0','5','6','4',rand(10),'0','','3','8','4');
for($i=$z[int(4+(.714287*7))];$i<25;$i++){$c=	 $a+$b ;$a=$b;$b=$c;syswrite		 $d,"$c\x0A";}
sub floor{return ("\x30"+ (	 "\x31")*(((1-1)+1)/(1*1))		 -(int(48*0.020833333))),
$b=(int((20+1)*("0.0434782" ) )),$c = "\x".(4						 +("\x2D". 1)).(0),,,,,,,,,,,,,};

this perl script simply prints the fibonachi sequence.
alright perl writers how did i do?

post you own obfuscated Fibonachi sequence. interested in what techniques i have not thought of. an tips?
purely accedmic.

Edited by flyingpoptartcat, 24 December 2012 - 10:26 AM.


#2 Pwnd2Pwnr

Pwnd2Pwnr

    Hak5 Ninja

  • Active Members
  • PipPipPipPipPipPipPip
  • 599 posts
  • Gender:Male
  • Location:Michigan
  • Interests:Arduino, Tech, Internet Policy, Development, Learning.

Posted 24 December 2012 - 01:09 PM

Well, far from being my own... this was a good one I found (I am useless in Perl). Tried Pasting it... looks like shit.

http://pastebin.com/m8xBrAgx

Edited by Pwnd2Pwnr, 24 December 2012 - 01:12 PM.


#3 flyingpoptartcat

flyingpoptartcat

    Hak5 Fan +

  • Active Members
  • PipPipPip
  • 49 posts
  • Gender:Male
  • Interests:PERL, obfuscation, networking, coding, reverse engineering

Posted 24 December 2012 - 03:26 PM

well the sh*tier code the better. as long as it still works

#4 flyingpoptartcat

flyingpoptartcat

    Hak5 Fan +

  • Active Members
  • PipPipPip
  • 49 posts
  • Gender:Male
  • Interests:PERL, obfuscation, networking, coding, reverse engineering

Posted 24 December 2012 - 05:14 PM

3rd revision:
my($a,$b,$c,$r);($a,$b,$c)=f();sub t{$r=caller if eval{ord(71)};};local $d="\xAA\x79\x53\x54\x44\x4f\x55\x54";"\xAA\x79"=~m/\xAA\x79/;
t($&);my @z=('0','5','6','4',rand(10),'0','','3','8','4');$d=~s///;for($i=$z[int(4+(.714287*7))];$i<125;$i=$i+5){$c=$a+=$b;$a=$b;$b=$c;__("\x0A");}
sub __{$xz=pop;syswrite $d,"$c$xz"};sub f{return("\x30"+("\x31")*(((1-1)+1)/(1*1)-1)-(int(48*0.020833333))),
$b=(int(((ord " ")+1)*("0.0434782" ))),$c="\x5C\x78".(4+("\x2D". 1)).(0),,,,,,,,,,,,,};

UPDATED

Edited by flyingpoptartcat, 26 December 2012 - 11:22 AM.


#5 Pwnd2Pwnr

Pwnd2Pwnr

    Hak5 Ninja

  • Active Members
  • PipPipPipPipPipPipPip
  • 599 posts
  • Gender:Male
  • Location:Michigan
  • Interests:Arduino, Tech, Internet Policy, Development, Learning.

Posted 26 December 2012 - 07:09 AM

LOL.. I wish I could write code like that; but it would look like shredded cheese with no flavor. I have a list of obsufication commands and "how to's"... but it is, humbly put, way over my head.. :D

#6 Jason Cooper

Jason Cooper

    Hak5 Pirate

  • Active Members
  • PipPipPipPipPipPip
  • 461 posts
  • Gender:Male
  • Location:Great Britain
  • Interests:Cards,
    Computers,
    Cryptography,
    Hacking,
    Lock Picking,
    Programming,
    And many more

Posted 26 December 2012 - 09:13 AM

As it is Perl then there is always more than one way to do it. So here is my one liner (Not overly obfuscated so that people have a hope of figuring it out quickly :) )

@a=(240&15,length(@a)>>length(@a));$_=join(',',map{push(@a,shift(@a)+$a[0]||1);$a[1]}1..100)."\n";print;


#7 flyingpoptartcat

flyingpoptartcat

    Hak5 Fan +

  • Active Members
  • PipPipPip
  • 49 posts
  • Gender:Male
  • Interests:PERL, obfuscation, networking, coding, reverse engineering

Posted 26 December 2012 - 11:32 AM

thats not to bad. had to think about >>

#8 Jason Cooper

Jason Cooper

    Hak5 Pirate

  • Active Members
  • PipPipPipPipPipPip
  • 461 posts
  • Gender:Male
  • Location:Great Britain
  • Interests:Cards,
    Computers,
    Cryptography,
    Hacking,
    Lock Picking,
    Programming,
    And many more

Posted 26 December 2012 - 01:35 PM

For those that need a bit of practice with deobfuscation, let's work through it for first post.

The original looks like:

my($a, $b, $c);($a,$b,$c) = floor();local $d= "\x53\x54\x44\x4f\x55\x54";my @z=('0','5','6','4',rand(10),'0','','3','8','4');
for($i=$z[int(4+(.714287*7))];$i<25;$i++){$c= $a+$b ;$a=$b;$b=$c;syswrite $d, "$c\x0A";}
sub floor{return ("\x30"+ ( "\x31")*(((1-1)+1)/(1*1)) -(int(48*0.020833333))),
$b=(int((20+1)*("0.0434782" ) )),$c = "\x".(4 + ("\x2D". 1)).(0),,,,,,,,,,,,,};

First we will start by fixing the formatting

my($a, $b, $c);
($a,$b,$c) = floor();

local $d="\x53\x54\x44\x4f\x55\x54";
my @z=('0','5','6','4',rand(10),'0','','3','8','4');
for($i=$z[int(4+(.714287*7))];$i<25;$i++){
$c=$a+$b;
$a=$b;
$b=$c;
syswrite $d,"$c\x0A";
}

sub floor{
return ("\x30"+("\x31")*(((1-1)+1)/(1*1))-(int(48*0.020833333))),$b=(int((20+1)*("0.0434782" ))),$c = "\x".(4+("\x2D". 1)).(0),,,,,,,,,,,,,
};

Now lets remove some of the obfuscated constants.

perl -e 'print "\x53\x54\x44\x4f\x55\x54";'

Shows that we can replace it with "STDOUT". The only place that $d is used is in the syswrite line, and after reading up on syswrite we see that a write to STDOUT is effecitvely a print statement so we can rewrite that line to (Replacing the "\x0A" line with the more common "\n")

print "$c\n";

and throw away the declaration of $d.

perl -e 'print int(4+(.714287*7));'

Shows that we can replace it with 9, and we can then replace the whole array lookup with 4. As the z array isn't used anywhere else we can throw it away.

We now have the following.

my($a, $b, $c);
($a,$b,$c) = floor();

for($i=4;$i<25;$i++){
$c=$a+$b;
$a=$b;
$b=$c;
print "$c\n";
}

sub floor{
return ("\x30"+("\x31")*(((1-1)+1)/(1*1))-(int(48*0.020833333))),$b=(int((20+1)*("0.0434782" ))),$c = "\x".(4+("\x2D". 1)).(0),,,,,,,,,,,,,
};

Now lets look at that floor subroutine. We know it returns a tuple of at least 3 elements and we only care about the first three elements (Unless we find it is updating global variables)

Counting brackets gives us the first three elements which, as they all consist of constants, can be simply evaluated.

perl -e 'print ("\x30"+("\x31")*(((1-1)+1)/(1*1))-(int(48*0.020833333)));'
perl -e 'print $b=(int((20+ 1)*("0.0434782" )));'
perl -e 'print $c = "\x".(4+("\x2D". 1)).(0);'

Which gives us a value of 1,0 and 30, so we can throw away the whole the floor subroutine, which leaves us with

my($a, $b, $c);
($a,$b,$c) = (1,0,30);

for($i=4;$i<25;$i++){
$c=$a+$b;
$a=$b;
$b=$c;
print "$c\n";
}

Finally $c is only overwitten before it is used so we can throw the first definition of it away.

my($a, $b, $c);
($a,$<img src='http://forums.hak5.org/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' /> = (1,0);

for($i=4;$i<25;$i++){
$c=$a+$b;
$a=$b;
$b=$c;
print "$c\n";
}


#9 Pwnd2Pwnr

Pwnd2Pwnr

    Hak5 Ninja

  • Active Members
  • PipPipPipPipPipPipPip
  • 599 posts
  • Gender:Male
  • Location:Michigan
  • Interests:Arduino, Tech, Internet Policy, Development, Learning.

Posted 26 December 2012 - 02:00 PM

Nice... who the hell says you don't learn something everyday?

#10 flyingpoptartcat

flyingpoptartcat

    Hak5 Fan +

  • Active Members
  • PipPipPip
  • 49 posts
  • Gender:Male
  • Interests:PERL, obfuscation, networking, coding, reverse engineering

Posted 27 December 2012 - 06:52 PM


jason, have you tried cracking the harder version i posted afterwards?


#11 Jason Cooper

Jason Cooper

    Hak5 Pirate

  • Active Members
  • PipPipPipPipPipPip
  • 461 posts
  • Gender:Male
  • Location:Great Britain
  • Interests:Cards,
    Computers,
    Cryptography,
    Hacking,
    Lock Picking,
    Programming,
    And many more

Posted 29 December 2012 - 09:57 AM

OK, deobfuscating the 3rd revision. The starting code is:

my($a,$b,$c,$r);($a,$b,$c)=f();sub t{$r=caller if eval{ord(71)};};local $d="\xAA\x79\x53\x54\x44\x4f\x55\x54";"\xAA\x79"=~m/ \xAA\x79/;t($&);my @z=('0','5','6','4',rand(10),'0','','3','8','4');$d=~s///;for($i=$z[int(4+(.714287*7))];$i<125;$i=$i+5){$c=$a+=$b; $a=$b;$b=$c;__("\x0A");}sub __{$xz=pop;syswrite $d,"$c$xz"};sub f{return("\x30"+("\x31")*(((1-1)+1)/(1*1)-1)-(int(48*0.020833333))), $b=(int(((ord " ")+1)*("0.0434782" ))),$c="\x5C\x78".(4+("\x2D". 1)).(0),,,,,,,,,,,,,};

Let's start again by putting in some formatting.

my($a,$b,$c,$r);
($a,$b,$c)=f();

sub t{
$r=caller if eval{ord(71)};
};

local $d="\xAA\x79\x53\x54\x44\x4f\x55\x54";
"\xAA\x79"=~m/\xAA\x79/;
t($&);
my @z=('0','5','6','4',rand(10),'0','','3','8','4');
$d=~s///;

for($i=$z[int(4+(.714287*7))];$i<125;$i=$i+5){
$c=$a+=$b;
$a=$b;
$b=$c;
__("\x0A");
}

sub __{
$xz=pop;
syswrite $d,"$c$xz"
};

sub f{
return("\x30"+("\x31")*(((1-1)+1)/(1*1)-1)-(int(48*0.020833333))),$b=(int(((ord " ")+1)*("0.0434782" ))),$c="\x5C\x78".(4+("\x2D". 1)).(0),,,,,,,,,,,,,
};

Now lets remove the obfuscated constant in $d. We can evaluate it just like last time

perl -e 'print "\xAA\x79\x53\x54\x44\x4f\x55\x54";'

This time though we see that it contains the value two odd characters before the constant "STDOUT". Lets look for the next place that $d is used to see if those characters are removed. The next line that $d is used is

$d=~s///;

This is where a bit of obscure perl knowledge is required. If an pattern in a substitution regular expression is empty then it uses the last pattern used in a match, which in this case is the regular expression in the line

"\xAA\x79"=~m/\xAA\x79/;

So it actually substitutes the "\xAA\x79" at the start of $d with nothing, leaving us with "STDOUT".

The next place we find $d is in the line

syswrite $d,"$c$xz"

Which we know that, as $d is "STDOUT", we can replace it with a print. Just before we tidy up by removing those lines we have decided aren't needed anymore lets look at the single call to the subroutine "t". Its parameter is $& which is a perl special variable that refers to the string matched by the last pattern in a regular expression. Looking inside the subroutine we see that it never makes use of its parameter, instead it always sets the global variable $r to "main" as that is the value returned by "caller" when used in this context, and the if statement is checking a constant value so it is always going to be true. As $r is never used elsewhere we can throw the whole of the subroutine away and the one call to it.

This now leaves us with the following code

my($a,$b,$c);
($a,$b,$c)=f();

my @z=('0','5','6','4',rand(10),'0','','3','8','4');
for($i=$z[int(4+(.714287*7))];$i<125;$i=$i+5){
$c=$a+=$b;
$a=$b;
$b=$c;
__("\x0A");
}
sub __{
$xz=pop;
print "$c$xz"
};

sub f{
return("\x30"+("\x31")*(((1-1)+1)/(1*1)-1)-(int(48*0.020833333))),$b=(int(((ord " ")+1)*("0.0434782" ))),$c="\x5C\x78".(4+("\x2D". 1)).(0),,,,,,,,,,,,,
};

We can tackle the for loop in a similar way to last time. As it is still all constants used to calculate the index we can calculate it and then remove the whole array lookup.

perl -e 'print int(4+(.714287*7))';

returns the value of 9 which is the last entry in the array @z, which is the value 4. So we can replace the initial assignment of $i in the for loop to 4 and throw the @z array away as it isn't used elsewhere. Also looking at the re-initialisation part of the for loop we can see that it is incrementing in steps of 5 and as $i isn't used elsewhere we can simplify the for loop to loop for the same number of times. Which gives us now

my($a,$b,$c);
($a,$b,$c)=f();

for($i=0;$i<25;$i++){
$c=$a+=$b;
$a=$b;
$b=$c;
__("\x0A");
}
sub __{
$xz=pop;
print "$c$xz"
};

sub f{
return("\x30"+("\x31")*(((1-1)+1)/(1*1)-1)-(int(48*0.020833333))),$b=(int(((ord " ")+1)*("0.0434782" ))),$c="\x5C\x78".(4+("\x2D". 1)).(0),,,,,,,,,,,,,
};

Now lets look at the double underscore subroutine. It is called in one location and passes a single constant parameter through. We know that we can replace the "\x0A" with a more common "\n", but looking in the subroutine itself we see that all it does is take that parameter, by using the pop command to pop it off the array of parameters passed to the subroutine,and then it prints out the global variable $c and then the parameter. Knowing this we can remove the whole double underscore subroutine and replace it with a simple print statement.

my($a,$b,$c);
($a,$b,$c)=f();

for($i=0;$i<25;$i++){
$c=$a+=$b;
$a=$b;
$b=$c;
print "$c\n";
}

sub f{
return("\x30"+("\x31")*(((1-1)+1)/(1*1)-1)-(int(48*0.020833333))),$b=(int(((ord " ")+1)*("0.0434782" ))),$c="\x5C\x78".(4+("\x2D". 1)).(0),,,,,,,,,,,,,
};

we can remove the subroutine f as we know it simply returns a group of constants to set $a, $b and $c. Looking through the rest of the code we see that the next reference to $c is it being assigned an new value so we only really need the first two.

perl -e 'print "\x30"+("\x31")*(((1-1)+1)/(1*1)-1)-(int(48*0.020833333));'
perl -e 'print (int(((ord " ")+1)*("0.0434782" )));'

Having evaluated the two constants we need (as 0 and 1) we can remove the f subroutine and the call to it.

my($a,$b,$c);
($a,$b)=(0,1);

for($i=0;$i<25;$i++){
$c=$a+=$b;
$a=$b;
$b=$c;
print "$c\n";
}

Now we are almost there, but to make it read a little better lets look at the line

$c=$a+=$b;

As we can see the next line assigns a new value to $a so we don't need to use the "+=" operator we can just use "+" instead. This now leaves us with

my($a,$b,$c);
($a,$b)=(0,1);

for($i=0;$i<25;$i++){
$c=$a+$b;
$a=$b;
$b=$c;
print "$c\n";
}

This seems a reasonable place to stop as we can clearly see now what the code does.

Edited by Jason Cooper, 29 December 2012 - 10:57 AM.


#12 digip

digip

    -we're all just neophytes-

  • Active Members
  • PipPipPipPipPipPipPipPipPipPipPipPip
  • 7,653 posts
  • Gender:Male
  • Location:RnVjayBPZmYh 192.168.100.1

Posted 29 December 2012 - 10:27 AM

So we get like 21 lines of 0, each on their own line? lol

Running his code as is, I get:


1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025
121393

But I cheated. I used this - http://codepad.org/

Edited by digip, 29 December 2012 - 10:31 AM.

@xxdigipxx http://www.attack-scanner.com/ | I'm the resident dick around here, or so I am told. Don't take it personally, I just give a shit too much sometimes. respect to all, its the Internet, don't take it to heart.
"Staying quiet doesn't mean I have nothing to say, it means I don't think you're ready to hear my thoughts..."

#13 Jason Cooper

Jason Cooper

    Hak5 Pirate

  • Active Members
  • PipPipPipPipPipPip
  • 461 posts
  • Gender:Male
  • Location:Great Britain
  • Interests:Cards,
    Computers,
    Cryptography,
    Hacking,
    Lock Picking,
    Programming,
    And many more

Posted 29 December 2012 - 10:55 AM

Ok, one minor fix in the simplfying the loop I missed altering the start of the counter to 0 (to get the same number of loops). Now one issue that isn't so minor. It appears that the forum is capitalizing one of the variables from $b to $B when it is initially assigned. Interestingly it doesn't always seem to do it, it just alters the last two.

At first I thought I had made a mistake but when I went back to text file that I wrote it in and cut and pasted from the mistake wasn't there, so I went back and tried to edit the post to correct it but it doesn't want to let that character be lowercase.

The final de-obfuscated version should be (assuming the forum lets this through without altering it)

my($a,$b,$c);
($a,$b)=(0,1);
for($i=0;$i<25;$i++){
$c=$a+$b;
$a=$b;
$b=$c;
print "$c\n";
}

edit: I have now figured it out the forum was trying to do something with emoticons. If I disable them for the post it works.

Edited by Jason Cooper, 29 December 2012 - 10:58 AM.






Also tagged with one or more of these keywords: perl, obfuscation, coding, complex

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users