2

I have been working on a project that uses PIDs, /proc and command line analysis to validate processes on a system. My code had to be checked by the security guys who manage to break it with a single line... embarrassing!

#!/usr/bin/env perl

$0="I am running wild"; # I had no clue you can do this!

system("cat /proc/$$/cmdline");
print("\n");
system("ps -ef | grep $$");

# do bad stuff here...

My questions:

  1. I see some uses cases for the above, like hiding passwords given on the command line (also bad practice) but I see a lot more problems/issues when one can hide processes and spoof cmdline. Is there a reason it is allowed? Isn't it a system vulnerability?

  2. How can I prevent or detect this? I have looked into /proc mount options. I also know that one can use lsof to identify spoofed processes based on unexpected behavior, but this won't work in my case. At the moment I am using a simple method to detect if the cmdline contains at least one null (\0) character which assumes that at least one argument is present. In the above code, spaces need to be replaced with nulls to bypass that check which is something I couldn't find how to implement in Perl - writes up to the first \0.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
urban
  • 5,392
  • 3
  • 19
  • 45

1 Answers1

6

To answer 1:

It's because of how starting a new process actually works.

You fork() to spawn a duplicate instance of your current process, and then you exec() to start the new thing - it replaces your current process with the 'new' process, and as a result - it has to rewrite $0.

This is actually quite useful though when running parallel code - I do it fairly frequently when fork()ing code, because it makes it easy to spot which 'thing' is getting stuck/running hot.

E.g.:

use Parallel::ForkManager;
my $manager = Parallel::ForkManager -> new ( 10 ); 

foreach my $server ( @list_of_servers ) {
    $manager -> start and next;
    $0 = "$0 child: ($server)";
    #do stuff;
    $manager -> finish;
}

You can instantly see in your ps list what's going on. You'll see this sort of behaviour with many multiprocessing services like httpd.

But it isn't a vulnerability, unless you assume it's something that it's not (as you do). No more than being able to 'mv' a binary anyway.

Anyway, to answer 2... prevent or detect what? I mean, you can't tell what a process is doing from the command line, but you can't tell what it's doing otherwise anyway (there's plenty of ways to make a piece of code do something 'odd' behind the scenes).

The answer is - trust your security model. Don't run untrusted code in a privileged context, and it's largely irrelevant what they call it. Sure, you could write rude messages in the process list, but it's pretty obvious who's doing it.

Sobrique
  • 52,974
  • 7
  • 60
  • 101
  • Hi Sobrique. I see what you are saying and I admit I am using the `cmdline` probably for something I shouldn't (see [this one](http://stackoverflow.com/questions/34380618/password-management-for-non-interactive-process)). I also see the usefulness of it in parallel processing. My second question is more about if I can detect that the cmdline has been modified to something other than the first/original value – urban Mar 04 '16 at 10:22
  • But that's every process. The "parent" of every process on your system is ultimately `init`. Everything else did a fork and exec from there - and in the process, changed its name. Files don't know their own name, names are just how the directory structure finds a particular inode. So processes don't know their own name either, aside from setting $0 to something appropriate. – Sobrique Mar 04 '16 at 11:50
  • I see... makes sense... and I was afraid that it would be the case - I accept your answer since you cover both questions. The technical info you provide is also very much appreciated - cheers for that :) – urban Mar 04 '16 at 12:02