Hackvent 2019: Day 14

Hackvent 2019130

Challenge

HV19.14 Achtung das Flag

Introduction
Let's play another little game this year. Once again, I promise it is hardly obfuscated.

Resources:

use Tk;use MIME::Base64;chomp(($a,$a,$b,$c,$f,$u,$z,$y,$r,$r,$u)=<DATA>);sub M{$M=shift;##
@m=keys %::;(grep{(unpack("%32W*",$_).length($_))eq$M}@m)[0]};$zvYPxUpXMSsw=0x1337C0DE;###
/_help_me_/;$PMMtQJOcHm8eFQfdsdNAS20=sub{$zvYPxUpXMSsw=($zvYPxUpXMSsw*16807)&0xFFFFFFFF;};
($a1Ivn0ECw49I5I0oE0='07&3-"11*/(')=~y$!-=$`-~$;($Sk61A7pO='K&:P3&44')=~y$!-=$`-~$;m/Mm/g;
($sk6i47pO='K&:R&-&"4&')=~y$!-=$`-~$;;;;$d28Vt03MEbdY0=sub{pack('n',$fff[$S9cXJIGB0BWce++]
^($PMMtQJOcHm8eFQfdsdNAS20->()&0xDEAD));};'42';($vgOjwRk4wIo7_=MainWindow->new)->title($r)
;($vMnyQdAkfgIIik=$vgOjwRk4wIo7_->Canvas("-$a"=>640,"-$b"=>480,"-$u"=>$f))->pack;@p=(42,42
);$cqI=$vMnyQdAkfgIIik->createLine(@p,@p,"-$y"=>$c,"-$a"=>3);;;$S9cXJIGB0BWce=0;$_2kY10=0;
$_8NZQooI5K4b=0;$Sk6lA7p0=0;$MMM__;$_=M(120812).'/'.M(191323).M(133418).M(98813).M(121913)
.M(134214).M(101213).'/'.M(97312).M(6328).M(2853).'+'.M(4386);s|_||gi;@fff=map{unpack('n',
$::{M(122413)}->($_))}m:...:g;($T=sub{$vMnyQdAkfgIIik->delete($t);$t=$vMnyQdAkfgIIik->#FOO
createText($PMMtQJOcHm8eFQfdsdNAS20->()%600+20,$PMMtQJOcHm8eFQfdsdNAS20->()%440+20,#Perl!!
"-text"=>$d28Vt03MEbdY0->(),"-$y"=>$z);})->();$HACK;$i=$vMnyQdAkfgIIik->repeat(25,sub{$_=(
$_8NZQooI5K4b+=0.1*$Sk6lA7p0);;$p[0]+=3.0*cos;$p[1]-=3*sin;;($p[0]>1&&$p[1]>1&&$p[0]<639&&
$p[1]<479)||$i->cancel();00;$q=($vMnyQdAkfgIIik->find($a1Ivn0ECw49I5I0oE0,$p[0]-1,$p[1]-1,
$p[0]+1,$p[1]+1)||[])->[0];$q==$t&&$T->();$vMnyQdAkfgIIik->insert($cqI,'end',\@p);($q==###
$cqI||$S9cXJIGB0BWce>44)&&$i->cancel();});$KE=5;$vgOjwRk4wIo7_->bind("<$Sk61A7pO-n>"=>sub{
$Sk6lA7p0=1;});$vgOjwRk4wIo7_->bind("<$Sk61A7pO-m>"=>sub{$Sk6lA7p0=-1;});$vgOjwRk4wIo7_#%"
->bind("<$sk6i47pO-n>"=>sub{$Sk6lA7p0=0 if$Sk6lA7p0>0;});$vgOjwRk4wIo7_->bind("<$sk6i47pO"
."-m>"=>sub{$Sk6lA7p0=0 if $Sk6lA7p0<0;});$::{M(7998)}->();$M_decrypt=sub{'HACKVENT2019'};
__DATA__
The cake is a lie!
width
height
orange
black
green
cyan
fill
Only perl can parse Perl!
Achtung das Flag! --> Use N and M
background
M'); DROP TABLE flags; -- 
Run me in Perl!
__DATA__

Solution

We are provided with some Perl code so we decide to run it. We realise we need the Tk module which seems to be some GUI library for Perl.
After running the code we are presented with a game which allows us to control the direction of a line with the letters N and M. We also see letters on the screen which look like parts of the flag!

Perl Line Game

So we start playing this game for fun but realise its very difficult to win the game ends when we hit the line or borders. Therefore, we give ourselves god mode by replacing $i->cancel(); with 1. However, even if we cheat at the game there are just too many characters and it all gets too messy so we don't peruse this avenue any further:

Perl Line Game Messy

Instead, we try to manually deobfuscate the Perl code. We don't need to deobfuscate the whole program, only the parts that spit the cyan coloured text.
Before we do this we use PerlTidy to clean up our code a little.

We follow the word cyan in the __DATA__ segment which we discover is tied to the $z variable. In the call to createText, we see that $d28Vt03MEbdY0 is variable holding the code reference with the flag text components. We'll use built in B::Deparse to deparse this. However, it seems like the code actually mutates data so we cannot simply evaluate $d28Vt03MEbdY0 code twice. Therefore, we replace it with an empty string in the actual text to be displayed and print the text to the console instead. We also replace $q==$t&&$T->() with $T->() to ensure that the next component is displayed each frame regardless of any checks (i.e. interception check). Finally, we change the FPS in the repeat loop to 1 so the program executes and ends quickly.

Our new code looks like this (with new lines marked with a # new comment):

use Tk;
use MIME::Base64;
use B::Deparse (); # new
my $deparse = B::Deparse->new; # new

chomp( ( $a, $a, $b, $c, $f, $u, $z, $y, $r, $r, $u ) = <DATA> );

sub M {
    $M = shift;      ##
    @m = keys %::;
    ( grep { ( unpack( "%32W*", $_ ) . length($_) ) eq $M } @m )[0];
}
$zvYPxUpXMSsw = 0x1337C0DE;    ###
/_help_me_/;
$PMMtQJOcHm8eFQfdsdNAS20 =
  sub { $zvYPxUpXMSsw = ( $zvYPxUpXMSsw * 16807 ) & 0xFFFFFFFF; };
( $a1Ivn0ECw49I5I0oE0 = '07&3-"11*/(' ) =~ y$!-=$`-~$;
( $Sk61A7pO           = 'K&:P3&44' )    =~ y$!-=$`-~$;
m/Mm/g;
( $sk6i47pO = 'K&:R&-&"4&' ) =~ y$!-=$`-~$;
$d28Vt03MEbdY0 = sub {
    pack( 'n',
        $fff[ $S9cXJIGB0BWce++ ] ^ ( $PMMtQJOcHm8eFQfdsdNAS20->() & 0xDEAD ) );
};
'42';
( $vgOjwRk4wIo7_ = MainWindow->new )->title($r);
( $vMnyQdAkfgIIik =
      $vgOjwRk4wIo7_->Canvas( "-$a" => 640, "-$b" => 480, "-$u" => $f ) )->pack;
@p             = ( 42, 42 );
$cqI           = $vMnyQdAkfgIIik->createLine( @p, @p, "-$y" => $c, "-$a" => 3 );
$S9cXJIGB0BWce = 0;
$_2kY10        = 0;
$_8NZQooI5K4b  = 0;
$Sk6lA7p0      = 0;
$MMM__;
$_ =
    M(120812) . '/'
  . M(191323)
  . M(133418)
  . M(98813)
  . M(121913)
  . M(134214)
  . M(101213) . '/'
  . M(97312)
  . M(6328)
  . M(2853) . '+'
  . M(4386);
s|_||gi;
@fff = map { unpack( 'n', $::{ M(122413) }->($_) ) } m:...:g;
(
    $T = sub {
        $vMnyQdAkfgIIik->delete($t);
        $t = $vMnyQdAkfgIIik->    #FOO
          createText(
            $PMMtQJOcHm8eFQfdsdNAS20->() % 600 + 20,
            $PMMtQJOcHm8eFQfdsdNAS20->() % 440 + 20,    #Perl!!
            "-text" => "", # new
            "-$y"   => $z
          );
        print eval( $deparse->coderef2text($d28Vt03MEbdY0) ); # new
    }
)->();
$HACK;
$i = $vMnyQdAkfgIIik->repeat(
    1, # new
    sub {
        $_ = ( $_8NZQooI5K4b += 0.1 * $Sk6lA7p0 );
        $p[0] += 3.0 * cos;
        $p[1] -= 3 * sin;
        ( $p[0] > 1 && $p[1] > 1 && $p[0] < 639 && $p[1] < 479 )
          || $i->cancel();
        00;
        $q = (
            $vMnyQdAkfgIIik->find(
                $a1Ivn0ECw49I5I0oE0,
                $p[0] - 1,
                $p[1] - 1,
                $p[0] + 1,
                $p[1] + 1
              )
              || []
        )->[0];
        $T->(); # new
        $vMnyQdAkfgIIik->insert( $cqI, 'end', \@p );
        (
            $q ==    ###
              $cqI || $S9cXJIGB0BWce > 44
        ) && $i->cancel();
    }
);
$KE = 5;
$vgOjwRk4wIo7_->bind(
    "<$Sk61A7pO-n>" => sub {
        $Sk6lA7p0 = 1;
    }
);
$vgOjwRk4wIo7_->bind( "<$Sk61A7pO-m>" => sub { $Sk6lA7p0 = -1; } );
$vgOjwRk4wIo7_       #%"
  ->bind( "<$sk6i47pO-n>" => sub { $Sk6lA7p0 = 0 if $Sk6lA7p0 > 0; } );
$vgOjwRk4wIo7_->bind(
    "<$sk6i47pO" . "-m>" => sub { $Sk6lA7p0 = 0 if $Sk6lA7p0 < 0; } );
$::{ M(7998) }->();
$M_decrypt = sub { 'HACKVENT2019' };
__DATA__
The cake is a lie!
width
height
orange
black
green
cyan
fill
Only perl can parse Perl!
Achtung das Flag! --> Use N and M
background
M'); DROP TABLE flags; -- 
Run me in Perl!
__DATA__

We run the Perl program again and it prints out an interesting but working flag!

PS C:\Users\Mo\Desktop> perl .\day14.pl.tdy
HV19{s@@jSfx4gPcvtiwxPCagrtQ@,y^p-za-oPQ^a-z\x20\n^&&s[(.)(..)][\2\1]g;s%4(...)%"p$1t"%ee}

Flag:

HV19{s@@jSfx4gPcvtiwxPCagrtQ@,y^p-za-oPQ^a-z\x20\n^&&s[(.)(..)][\2\1]g;s%4(...)%"p$1t"%ee}

Bonus

This challenge also contained the solution to HV19.H4 Hidden Four.


Leave a comment

(required)(will not be published)(required)

Comments

There are no comments yet. Be the first to add one!