in reply to Re: Re: Locking PERL code another way
in thread Locking PERL code another way

There must be a routine that returns the MD5. Let's call this "giveMD5" in package Foo. Then the following code will replace that routine by another routine, without the outside world knowing about it.
{ my $giveMD5 = \&Foo::giveMD5; my %givenMD5; *Foo::giveMD5 = sub { my $md5 = $givenmd5{@_} ||= $giveMD5->( @_ ); # execute old to obt +ain "real" MD5 # do evil things to op tree for given parameters if first time return $md5; # the "right" value }; }

Of course, this is more or less pseudo-code to give you the idea.

By the way, this "wrapping" technique is used in all sorts of Perl modules, so disabling this feature in Perl is basically impossible.

Liz

Replies are listed 'Best First'.
Re: Re: Re: Re: Locking PERL code another way
by Anonymous Monk on Sep 26, 2003 at 04:06 UTC
    Thanks Liz,
    I was pretty sure there'd be something like that possible, but do you know how your example could be executed so that it affects my program _while its running_?

    I assume I am protected by *NIX protected memory... but I wonder if there is some debug mode for Perl that lets one inspect running code...or poke at a Perl process...? Cheers,
    Craig.
    PS My idea is getting some function creep, or worse, creep creep. However, to compromise the running process would require your hack above being able to affect my running process. I hope you haven't lost patience with this idea. The question then becomes "does this fangled idea really add any more security than tripwire etc?"
      You need to watch out for string eval's during execution. Now you might say, I'm not doing any string eval's. That may be true, but the modules that you've used at compile time, may do require at run-time. Many times this is done to reduce the memory footprint of the module and/or to reduce startup time.

      This is also the mechanism that AutoLoader type modules use.

      So you need to make sure that the files that are being required, can not be changed to include trojan horses. One way of doing that is with tripwire.

      Then there is also the possibility of programs changing @INC and/or @ISA of a module. That would also offer ways of introducing executable code.

      So basically, I think that if all of your explicit string eval's are covered, and you are sure that the modules that you use do not contain backdoors that would allow a string eval, and you're monitoring the files with tripwire, then maybe your idea makes sense as the final check on everything else. With a high chance on false positives, as Perl does its rearranging and changing of optrees with runtime requires anyway.

      I don't think it is worth the trouble given all the other security features that Perl has. But please don't take my word for it, as I am not a security professional, just someone with some experience.

      Liz

Re: Re: Re: Re: Locking PERL code another way
by Anonymous Monk on Dec 19, 2003 at 02:25 UTC
    Liz, a late reply here after some meditation. Your code snippet to steal the getMD5 routine would itself become part of the syntax tree for the program. This changes the MD5, even before you get to it. Anything calling us for the MD5 will get a bad MD5. This is, unless you can call getMD5 before the Perl code fully parses.

    Another way would be to somehow obtain the MD5 from our live script by copying the script elsewhere and executing it under debug. Presumably we can then observe the variable that handles the MD5 and grab it on its way through without modifying the syntax tree for the script. With the MD5, we can pretend to be the script.

    I know little about Debug. Does debug modify the syntax tree for a script by, say, instrumenting the code (the way some profilers do at run time?) if so, Debug could not help an attacker. Also, we could peek the memory for the data segment used by the script/Perl and try to find the MD5. However, with protected memory we would presumably be somewhat prevented from doing this.

    Presumably Perl has some Debug/Devel feature that lets one "watch" the state machine and so obtain the values of of any SV at any time? Or does it have security to prevent this?

    I think my idea is doomed, however. Trust requires secrets. If my script can be read, I have naught that can't be copied and used to pretend to be me to a remote entity. The Devel::opprof idea just attempts to prove all's well on-the-fly with a schroedinger's cat and a remote entity watching the door on the cat's box.

    This doesn't prevent someone from copying the cat/box and then putting up a picture of the cat/box for the remote observer.

    Cheers
    Craig.