in reply to Locking PERL code another way

Hmmm... you're using a Perl program to make sure that the Perl program is correct? If someone can change the original program, surely someone can change the test-program in such a way that it will produce the expected result?

Which, by the way, would be a problem with _any_ interpreted programming language that has the equivalent of eval, not just of Perl.

The least you would need would be an externally running program / process that would inspect the Perl program running in memory. Not an easy task, I would think.

Liz

Replies are listed 'Best First'.
Re: Re: Locking PERL code another way
by Anonymous Monk on Sep 25, 2003 at 05:10 UTC
    Thank you for thinking about this. This is how it works

    1. OK, I've parsed. Now, get my tree.
    2. When called, give out my tree MD5, say I keep running as a server process
    3. Something else has all the MD5s and "pings" me pretty regularly

    Since the inherited PMs, get-my-tree etc are all in the tree, (excepting ///o and others as other submitters have suggested) our MD5 seems to "lock" up everything that matters.

    With regards to changing the code on disk, I assume something conventional watches the .pl file and that other security is in place for other compromises. This would help us trust the PERL binary etc.

    We then want to prevent foo-root-user being able to fiddle with the executable image in memory. At the PERL level at least.

    So, you are right; something has to watch something - it's not "self-auditing" :-).

    But is it the case that something could be injected into the memory image which issues fake MD5s for us? How hard is it to fiddle with execution tree in the Perl state machine?

    I'll also follow up what other people have posted, thank you.
      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

        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?"
        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.