HACKVent 2020 – Day 8

  • by

Challenge – The game

Let’s play another little game this year. Once again, as every year, I promise it is hardly obfuscated.

Solution

The file contained an obfuscated Perl script, neatly formatted to look like tetris. Of couse, when ran, it really was a tetris game. Since I am bad at tetris, but good in programming I chose to deobfuscate it.

eval eval '"'.
('['^'.').('['^'(').('`'|'%').('{'^
'^'^('`'|'+')).';'.'\\'.'$'.'|'.'='
.('`'|',').'\\'.'\\'.('`'|'%').'['.
'['^'(').('['^'+').('`'|',').('`'|'
'#'.('['^',').'#'.('['^',').'#'.('[
'`'|"\#").                         
'(')."\#".                         
'['^"\-").                         
'#'.("\`"|                         
'{'^"\*").                         
',').'#'.(                         
'*')).'#'.                         
'#'.("\;"&                         
'{'^"\,").                         
"'").'#'.(                         
'#'.("\`"|                         
'{'^"\*").                                             

Obfuscation was done by replacing the first eval with print to get sane code. Next I used perltidy to format the code. It was much better now:

use Term::ReadKey;
ReadMode 5;
$| = 1;
print "\ec\e[2J\e[?25l\e[?7l\e[1;1H\e[0;0r";
@FF = split //,
'####H#V#2#0#{#h#t#t#p#s#:#/#/#w#w#w#.#y#o#u#t#u#b#e#.#c#o#m#/#w#a#t#c#h#?#v#=#d#Q#w#4#w#9#W#g#X#c#Q#}####';
@BB = ( 89, 51, 30, 27, 75, 294 );
$w  = 11;
$h  = 23;
print(  "\e[1;1H\e[103m"
      . ( ' ' x ( 2 * $w + 2 ) )
      . "\e[0m\r\n"
      . (
        ( "\e[103m \e[0m" . ( ' ' x ( 2 * $w ) ) . "\e[103m \e[0m\r\n" ) x $h )
      . "\e[103m"
      . ( ' ' x ( 2 * $w + 2 ) )
      . "\e[2;1H\e[0m" );

sub bl {
    ( $b, $bc, $bcc, $x, $y ) = @_;
    for $yy ( 0 .. 2 ) {
        for $xx ( 0 .. 5 ) {
            print(  "\e[${bcc}m\e["
                  . ( $yy + $y + 2 ) . ";"
                  . ( $xx + $x * 2 + 2 )
                  . "H${bc}" )
              if ( ( ( $b & ( 0b111 << ( $yy * 3 ) ) ) >> ( $yy * 3 ) ) &
                ( 4 >> ( $xx >> 1 ) ) );
        }
    }
}

<...>

It even got a flag in it, HV20{https://www.youtube.com/watch?v=dQw4w9WgXcQ}, but that did not work. At least the video was a classic. I even paused my CTF attempt to watch it fully 🙂

Next steps were to understand the code and see where the real flag was supposed to be. After a while I noticed that each building block was made out of a character from the fake flag. A bit more deciphering later, it occured to me that maybe the characters in the blocks will reveal the real flag. Meaning, the program might transform the fake flag into the real flag.

But again, I am bad at tetris. However in the meanwhile my understanding of the code was good enough to tweak it a litte. I changed all blocks to just a single square and removed the logic that clears completed lines. This way, I could easily play the game until the whole flag is shown and wouldn’t even need to remember the past blocks.

The modified parts

# rig the building blocks
# @BB = ( 89, 51, 30, 27, 75, 294 );
@BB = ( 2, 2, 2, 2, 2, 2 );

<...>

sub _s {
    ( $b, $bc, $x, $y ) = @_;
    for $yy ( 0 .. 2 ) {
        for $xx ( 0 .. 5 ) {
         <...>
        }
    }
    $Q = 'QcXgWw9d4';
    # don't clear lines
    # @f = grep { / / } @f;
    # unshift @f, ( " " x $w ) while ( @f < $h );
    p();
}

The rigged playthrough

Read it LTR, skip the # and you’ll see the flag
HV20{https://www.youtube.com/watch?v=Alw5hs0chj0}
Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *