35C3 CTF Write-up: php

php (web)

PHP’s unserialization mechanism can be exceptional. Guest challenge by jvoisin.

Files at https://35c3ctf.ccc.ac/uploads/php-ff2d1f97076ff25c5d0858616c26fac7.tar. Challenge running at: nc 35.242.207.13 1

This challenge exposes a service written in PHP, and as you can guess, it has something to do with unserialization.

The single source file is straightforward to understand:

<?php

$line = trim(fgets(STDIN));

$flag = file_get_contents('/flag');

class B {
  function __destruct() {
    global $flag;
    echo $flag;
  }
}

$a = @unserialize($line);

throw new Exception('Well that was unexpected…');

echo $a;

Your goal is to get the flag printed by somehow getting the destructor of class B to execute.

Continue reading

Flare-On 2017 Write-up: “pewpewboat.exe”

Flare-On 2017 Challenge #5 — pewpewboat.exe

As usual, the first thing to do when tackling the challenge is to run the binary first, to see what it does. You will soon learn that it’s not actually a Windows executable, but rather a 64-bit Linux ELF.

$ ./pewpewboat.exe
Loading first pew pew map...
   1 2 3 4 5 6 7 8
  _________________
A |_|_|_|_|_|_|_|_|
B |_|_|_|_|_|_|_|_|
C |_|_|_|_|_|_|_|_|
D |_|_|_|_|_|_|_|_|
E |_|_|_|_|_|_|_|_|
F |_|_|_|_|_|_|_|_|
G |_|_|_|_|_|_|_|_|
H |_|_|_|_|_|_|_|_|

Rank: Seaman Recruit

Welcome to pewpewboat! We just loaded a pew pew map, start shootin'!

Enter a coordinate:

So this is a Battleship game. Playing manually for a bit, I see the “ships” form up in the shape what looked like a letter. Hmm could this be the flag?

It’s now time to read the code.

Continue reading

LabyREnth 2017 Write-up: “EzDroid”

Mobile track #1 – EzDroid

Provided is an Android app package EzDroid.apk.

I typically use an Android emulator for testing, it’s free and easy to install on all major platforms, so it’s pretty much a no brainer.

After installation, it looks like it maanges to start but exits shortly after, for some unknown reason. Looks like it is time to inspect the code.

I like looking at high-level languages, so let’s start with that first.

My preferred method is to use dex2jar for decompilation, then using JD-GUI to explore the produced JAR file. You should have something that looks like the following screen:

JD-GUI app, exploring the decompiled JAR file

There’s only 2 packages, one of which is the Support Library, so the package with app code is likely com.labyrenth.manykeys.manykeys, with 4 classes inside:

  • BuildConfig
  • EZMain
  • R
  • onoes

BuildConfig and R are compile-time Android-generated classes, so ignore those.

EZMain looks to be the main Activity class. If you are unfamiliar with Android, that’s where the action happens.

Continue reading

LabyREnth 2016 Write-up: “bowie.pl”

Unix track #1 – bowie.pl

This is a Perl script which is really large (3MB). When you open it up, you’ll see it request input from STDIN, then compares it against these concatenated chars like so:

my $input = <STDIN>;
$input = trim($input); 
if ($input eq (chr(5156 - 5035) . chr(-4615 - -4716) . chr(3162 - 3047))) {
  ...

It then has a lot of MIME::Base64::decode() statements, which seem to be building up data in variable $a. Only if the input matches does it go further into the nested if‘s and performs more decoding. Otherwise it just borks.

If you follow further, you’ll notice that at some point it calls eval() with even more Base64-decoded code.

Perl’s Debugging Hooks

One interesting thing I learnt while solving this challenge was that Perl internally has some mechanisms for debugging, allowing you to easily write your own debugger. How easy? You can fit a tracer into a one-liner like so:

PERL5DB='sub DB::DB {my @c=caller;print STDERR qq|@c[1,2] ${"::_<$c[1]"}[$c[2]]|}' \
perl -d my-script.pl

So the gist of solving this challenge would be to check what $input is being compared to, set that into the $input variable, and let ‘er rip. The beauty of this method is, it will even handle the eval() for you. You don’t need to separately decode it and put it back in, or run it as a separate script.

You can find my solver script here. Everything happens in the DB::DB function, which is called before a statement is executed. It then waits for if ($input eq ...) statement, transforms that into an assignment statement and evals it in the program’s context. The rest of the code are just stolen from the Perl debugger to save and restore program context (or something like that).

Save the script as Devel/Tracer.pm, then run the bowie.pl script like so:

perl -d:Tracer bowie.pl < /dev/null

After the script is done, you should get a entrevue.gif dropped in the current directory. That image is a picture of David Bowie with the flag written over him.

I learn new things every time I play CTF.

If you found this Perl debugger thing interesting, you can take a look at these links:

LabyREnth 2016 Write-up: “Regex”

Random track #2 – Regex

This is a challenge involving regular expressions. It reads the huge expression from the file omglob_what_is_dis_crap.txt. The code that reads and evaluates this expression will only provide you with the key if you provide it with an input that doesn’t match this expression. Of course the program runs on a remote server, so you don’t have direct access to the flag.

Inspecting the expression, there’s a lot of “OR” conditions, and splitting them into lines gets you something like this:

^(
.*[^0mglo8sc1enC3].*|
.{,190}|
.{192,}|
.{97}[cgClm]|
.{135}[so1l803]|
   .
   .
   .

If this looks familiar to you, it’s because a similar challenge appeared in PlaidCTF 2015. I solved and wrote about the challenge here using Z3 (an SMT solver).

Basically the first 3 lines of expressions at the start dictate what characters can appear in the input, as well its length (191, in this case). This, however, is a watered-down challenge compared to the PlaidCTF one. You do not need to use Z3 in this case. To illustrate what I mean, if you sort each of the regex part in numeric order using sort -k 1.3n, you get this:

.{0}[eo1Cnsc0lm38]
.{1}[3]
.{1}[8l0osm]
.{1}[c1C]
.{1}[en]
.{2}[18]
.{2}[3omsglcn]
.{2}[C]
.{2}[e]
.{3}[3]
.{3}[com8negC]
   .
   .
   .

Using a script, you can easily piece together what characters should (not) go into each position, and thus, construct the correct input to feed to the server.

Because I’m lazy, I decided to re-use my solver script from last time. At that time, the character set was "plaidctf" but this time round it’s "0mglo8sc1enC3", the length of which is unable to fit exactly into N bits (not a power of 2). So I made a few modifications to make it use Z3 Ints instead of a BitVec to support arbitrary string lengths. Fortunately I did a good enough regex parser the last time, so that worked out of the box. (Never did I imagine that it would ever be re-used again.) Now all you need to do is to change the valid character set and length of the flag at the top of the solver script, and off it goes!

I said this was watered-down because Z3 took about 20 minutes the last time to solve PlaidCTF’s constraints. This, on the other hand, took less than one second.