Monthly Archives: March 2010

( unix/linux = !safe ) unless ( security == holistic )

There is a long held misbelief in the unix / linux crowd that their systems are inherently secure. Whereas it is the case that windows based systems are severely encumbered in the security field, their  unix cousins  have a whole set of issues all by themselves, as the perlism in the title tries to show.

One such issue that I will deal with here is the notorious ability to audit/monitor the usage of the terminal. OK let’s call it with its proper name, it is eavesdropping. In the windows world there a are a number of companies offering applications to that extent, including the author of this here blog with his project rautor. If you would think that such a thing is not possible in the unix world, sorry to disappoint you, it is patently easy!

While toying with the idea of a unix screen grabber to complement my project rautor, I came across to much forgotten legacy lost in the mists of project Athena, X11 for the rest of us mere mortals. Yes X11 has had the ability to grab the terminal’s screen since time immemorial, so after adapting some of my rautor code I came up with a remote console eavedropper  for linux and other unix systems. Run it on the target host and from another terminal,  using only a  browser, request a url like http://the_target_ip:420000/. Whammo you get the console screen. If you want another screen adjust the DISPLAY variable in the code.

The moral of the above snippet is that ( unix/linux != safe )   unless ( security == holistic ). One must have a complete outlook on what IT security is not just buy into the promises of a vendor. IT Security is an attitude, not a product and it must be holistic. Little known tricks or utilities  of each platform, like the xwd utility that dumps X11 screens, can wreak havoc with a poorly envisioned IT security modus operandi.

and here is the code

#!/usr/bin/perl -w
#
# A screen grabber with an embedded Web Server
# Angelos Karageorgiou
# angelos@unix.gr
#

package Rautor; # look for it under sourceforge

use common::sense;

use HTTP::Daemon;
use HTTP::Response;
use HTTP::Status;
use HTTP::Request;
use Getopt::Long;
use IO::Socket::INET;
use IO::Select;
use File::Temp qw|tempdir|;
use Fcntl qw |:flock|;
use Carp;

my $PORT=42000;
my $VERBOSE='';
my $format="png";
my $imgFname="screen.$format";
my $SLEEP=5;
#my $CMDLINE="/usr/bin/import -silent -window root";
my $CMDLINE="/usr/bin/xwd -root -silent | /usr/bin/xwdtopnm -quiet | /usr/bin/pnmtopng";

$ENV{"DISPLAY"}=":0.0";	# just in case

GetOptions (
        'verbose'   => $VERBOSE,
);

print "Port is $PORTn" if ( $VERBOSE);

my $RepeatHeader="<HEAD><META HTTP-EQUIV=REFRESH CONTENT=$SLEEP></HEAD>rn
<table width="100%" height="100%" border="0" cellpadding="2" cellspacing="2" style="position:relative">rn
";

my $sessdir = tempdir ( "sessXXXXXX", TMPDIR => 1 , CLEANUP => 1);

open(my $LOCKFILE ,">/tmp/sesslock") || carp("cannot create lock file");

$HTTP::Daemon::PROTO = "HTTP/1.0";
my $daemon  = HTTP::Daemon->new(Listen=>3,LocalPort=>$PORT, ReuseAddr=>1) || die "cannot spawn http server";
my $sel= IO::Select->new();
$sel->add($daemon);

while(my @ready = $sel->can_read()) { # 1 sec timeout
     foreach my $fh (@ready) {
         if($fh == $daemon) {
            # Create a new socket
            my $new = $daemon->accept;
            $sel->add($new);	# add it to the select list
         } else {
		my @ip = unpack("C4",$fh->peeraddr);
		my $ip=join(".",@ip);
		print "Connection from $ipn" if ( $VERBOSE);
		process_one_req($fh,$ip);
		$sel->remove($fh);
		$fh->close;
        }
    }
  }

1;

########################################################################################
sub process_one_req {
my $connection = shift;
#my $SESSIONID=shift;
my $IP=shift;

	my $RepeatHTML=$RepeatHeader;

 	my $receiver = $connection->get_request;
	if ( ! $receiver ) {
		return;
	}
	if (! ($receiver->method eq 'GET') ){					# Method GET
       		$connection->send_error(RC_FORBIDDEN);
			return;
	}
	$receiver->url->path =~ m/^/(.*)$/mi;
	my $path=$1;

	if ( ($path eq "monitor" ) || ($path eq "" ) ) 	{
		domonitor($connection,$RepeatHTML,$IP);
		return;
	}

    if  ($path =~ /^screen([1-9]*).$format$/ )  {	# Screen[1-9].$format

		my $scrnum=1;
		if ( $1 ) {
			$scrnum=$1;
		}
		my $res=screendumper_UNIX($scrnum);
		my $fname="screen".$scrnum.".$format";
		if ( $fname eq "screen.$format" ) {
			$fname="screen1.$format";
		}
		if ( ! -f "$sessdir/$fname" )  {
          		$connection->send_error(404,"Could not grab the screen num $scrnum");
			$connection->close;
			undef($connection);
			return;
		}
       	my $response = HTTP::Response->new(200);
       	$response->push_header('Content-Type','image/$format');
		$connection->send_response($response);
		$connection->send_file("$sessdir/$fname");
		unlink $fname;
	return;
	}

	# no matches
	$connection->send_error(RC_FORBIDDEN);
}

######################################################################
sub domonitor{
	my ($connection,$RepeatHTML,$SESSIONID,$IP)=@_;
	my $span=2;
	my $NumScreens=1;
	my $KEYLOG="";
	for (my $i=1;$i<=$NumScreens;$i++){
		my $fname="screen".$i.".$format";
		$RepeatHTML .= "<tr><td colspan=$span>";
		$RepeatHTML .= "<img src="/$fname" width="100%" height="100%" align=center></td>rn";
		if ( ( $i % 2 ) == 0 ) {
			$RepeatHTML .= "</tr>rn<tr>";
		}
	}

	$RepeatHTML .= "</tr>";

	$RepeatHTML .= "</table>";

    my $response = HTTP::Response->new(length($RepeatHTML));
    $response->content($RepeatHTML);
	$connection->send_response($response);
	$KEYLOG=""; # reset untill next call
}

############################################################
sub screendumper_UNIX{
	my $scrnum=shift;
	lock($LOCKFILE);
	print "Calling systemn" if ( $VERBOSE );
#	system("/usr/bin/import -silent -window root $sessdir/screen".$scrnum.".$format");
	system($CMDLINE . ">" .  $sessdir . "/screen" . $scrnum . ".". $format);
	print "Import donen" if ( $VERBOSE );
	unlock($LOCKFILE);
	return 1;
}

############################################################
sub lock {
	my ($fh) = @_;
	flock($fh, LOCK_EX) or die "Cannot lock session - $!n";
}

############################################################
sub unlock {
	my ($fh) = @_;
	flock($fh, LOCK_UN) or die "Cannot unlock session - $!n";
}
Advertisements

Hiring for talent

I have been having a discussion over on linkedin about how one goes about hiring people for talent, so I am reposting my answer as a blog entry.

I can only talk about the IT industry so here is my 2c worth. The really cool companies in IT are looking for capable hands on generalists with team leading abilities in a particular field and a yen for creativity. What the previous mouthful asks of the prospective employee is: “are you knowledgeable,capable and mature enough to tackle just about anything novel I can throw at you without throwing a fit?” Don’t forget to mention that your budget for support is limited therefore your prospect should be a tool maker too.

If they flinch on the idea on operating on unknown landscapes on a large scope with limited resources while maintaining rank morale, then chances are that they are not talented.

Caveats: Beware of divas.