spaceout has asked for the wisdom of the Perl Monks concerning the following question:

I'm attempting to create a simple cgi script that will display the output from nmap.
#!/usr/bin/perl use strict; my $output = `/usr/bin/nmap -sU -p 2300,6500 $ENV{'REMOTE_ADDR'}`; print "Content-type: text/html\n\n"; print $output;
Since nmap needs to run as root I keep getting permission problems. Is there an easy way around this? Thanks

Replies are listed 'Best First'.
Re: Capturing the output of nmap from within a Perl script
by Tanktalus (Canon) on Aug 08, 2005 at 23:53 UTC

    First, I'm not really sure what nmap is. That's probably not too important.

    Second, I'm not sure what a root-only binary is doing in /usr/bin. It should be in /usr/sbin. So that's a bit odd.

    Finally, you want sudo. It provides the ability to allow a user (e.g., "wwwrun" or "apache" or whatever your server drops privileges to) to become another user (e.g., 'root') to run specific programs (e.g., "/usr/bin/nmap"), optionally (well, mandatory for you) without providing a password.

    my $output = `sudo /usr/bin/nmap -sU -p 2300,6500 $ENV{'REMOTE_ADDR'}` +;

    Note that setting the suid bit is not enough unless the program is written to take advantage of the bit.

    Update: Not sure what I'm on. I still prefer sudo to set-uid.

      nmap is in /usr/bin because there are things that the user are allowed to do with nmap, and it is a user runable program. However, if you want to do some of the advanced things, one of which that I can think of is sending a SYN packet, listening for a SYN/ACK, and then not sending the ACK packet back (somehow it tricks some OS's / services so that they don't log that they were nmap'ed), then you need root privileges. I think almost all of the -s options require root privileges. The point being, though, that the user can do a limited number of things with nmap.

          -Bryan

      I agree that sudo is probably a better solution, but why do you say that the setuid bit is not enough? If the EUID of a process is zero, then that process will bypass permission checks, which should allow it to function exactly as if root had run it. Unless the program is peversely written to explicitly check it's RUID and implements its own permissions based on that, there shouldn't be a problem.

      You made a good point - what's it doing in /usr/bin? But on my box, that's where nmap lives.

      I believe the answer is that nmap isn't root-only. It can be run by ordinary mortals, although some functionality is unavailable to them.

Re: Capturing the output of nmap from within a Perl script
by izut (Chaplain) on Aug 08, 2005 at 23:49 UTC
    You can change nmap permissions to +s to enable setuid. Then if you want to process the text returned from nmap you can execute it like this:
    my $cmd = "/usr/bin/nmap -sU -p 2300,6500 $ENV{'REMOTE_ADDR'}"; open NMAP, "$cmd|" or die $!; foreach (<NMAP>) { # process here ... }
    Hope this helps :)

    Update: I think you can have security issues by enabling setuid root to nmap. Be careful. :)


    Igor S. Lopes - izut
    surrender to perl. your code, your rules.
Re: Capturing the output of nmap from within a Perl script
by ikegami (Patriarch) on Aug 09, 2005 at 03:51 UTC

    You effectively have print `...`. That can be simplified to system '...'. Furthermore, since that's the last command of the script, using exec '...' would be even more efficient.

    Particularly if system is used, it wouldn't hurt to auto-flush STDOUT to make sure the header gets sent out at the right time.

    No matter whether ``, system or exec is used, you might want to display what nmap sends to STDERR (if anything). Append 2>&1 to your command to do so.

    #!/usr/bin/perl $| = 1; # Make sure the header gets sent first. print "Content-type: text/html\n\n"; exec "... 2>&1"; # We only get here if exec failed. my $error = "Error executing nmap: $!"; $error =~ s/&/&amp;/g; $error =~ s/</&lt;/g; print("$error\n");
Re: Capturing the output of nmap from within a Perl script
by ghenry (Vicar) on Sep 21, 2005 at 07:28 UTC

    Nmap::Scanner will do all this for you.

    Walking the road to enlightenment... I found a penguin and a camel on the way.....
    Fancy a yourname@perl.me.uk? Just ask!!!