Friday, December 19, 2014

knock know who's there?

sometimes you just want to set up a virtual system to see if there are any scans going on your network.
 
on an ubuntu 14.04 lts server...
   
 # apt-get install build-essential mail-utils perl

   
run cpan get the following cpan dependencies:  
   
 # cpan  
 > install Net::DNS  
 > install Net::Server  
 > install YAML  
 > install MIME::Lite::TT  
 > install Data::Dumper  
 > install Getopt::Long  
 > install Net::IP::Match::Regexp  
 > exit  
   
place perl script and conf in /usr/local/bin/honey or wherever   
do a little ln action.  
   
 # ln -s /usr/local/honey/honey.conf /etc/honey.conf  
   
set background to 1 in honey.conf to make it turn into a background process.  
   
and... when putting in your ports, if any ports happen to be open when 
honey.pl is called, honey.pl will die.  
 figure them out?  
   
 # netstat -tpln  
   
speaking of which look at the honey.conf below, we're going to be opening 
a scad of ports. tune the system:  
   
 # ulimit -n 70000  
 # echo "32768 65535" >/proc/sys/net/ipv4/ip_local_port_range  
   
test it  
   
 # perl -c honey.pl should return 'OK'  
   
start with  
 # perl /usr/local/honey.pl --config /etc/honey.conf  
   
if running via /etc/rc.local :  
 # chmod +x /etc/rc.local  
   
add the line before exit 0:  
   
perl /usr/local/honey.pl --config /etc/honey.conf  
   
 ##########  
 # honey.pl  
   
 #!/usr/bin/perl  
 # version 1.3  
 package Honey;  
 use MIME::Lite::TT;  
 use Net::DNS;  
 use strict;  
 use warnings;  
 use Data::Dumper;  
 use base qw(Net::Server::PreForkSimple);  
 use YAML;  
 use Getopt::Long;  
 use Net::IP::Match::Regexp qw( create_iprange_regexp match_ip );  
 sub logger($);  
   
 my $configfile = "./honey.conf";  
 GetOptions ("config=s" => \$configfile);  
 my ($hashref, $arrayref, $string) = YAML::LoadFile( $configfile );  
   
 print Dumper($hashref);  
 my %config = %$hashref;  
   
   
 #############################  
 ### CONFIG   
 #############################  
 my $from_email = $config{'from_email'};  
 my $subject   = $config{'subject'};  
 my $to_email  = $config{'to_email'};  
 my $mailserver = $config{'mailserver'};  
 my $mail_thres = $config{'mail_thres'};  
 my $tempfolder = $config{'tempfolder'};  
 my $lp_ref   = $config{'listenports'};  
 my $background = $config{'background'};  
 my $ih_ref   = $config{'ignorehosts'};  
 my $logpath   = $config{'logpath'};  
   
 unless ( 1 &&  
     defined($from_email) &&   
     defined($subject) &&   
     defined($to_email) &&   
     defined($mailserver) &&   
     defined($mail_thres) &&   
     defined($tempfolder) &&   
     defined($lp_ref) &&   
     defined($background) &&   
     defined($ih_ref) &&   
     1 ) {  
     die "invalid configuration\n";  
 }  
   
 unless (defined($logpath)) {  
     print STDERR "No logpath given, will default to /var/log/honey.log";    
     $logpath = "/var/log/honey.log";  
 }  
   
 logger("honey init");  
   
 #############################  
 ### VARS  
 #############################  
 my ($i);  
 my @lports   = @$lp_ref;  
 my @ih     = split(",",$ih_ref);  
 my $ignorehosts = create_iprange_regexp(@ih);  
 my $tempcache  = $tempfolder . "honeycache";  
 my $tempports  = $tempfolder . "honeyports";  
   
   
 my $template = <<TEMPLATE;  
 Unauthorized connection noted \n\r  
 Connection details: [% connection_string %] \n\r  
 Source details: [% srcip %] ([% srcip_dns %]) \n\r  
 Timestamp: [% timestamp %]  
 TEMPLATE  
   
   
 ############################################  
   
   
 sub post_accept {  
     #print STDERR "post accept in $$\n";  
 }   
   
 sub process_request {  
     my $self = shift;  
   
     #print STDERR "process request in $$\n";  
   
     my $connection_info = $self->{'server'}->{'peeraddr'} . ":" . $self->{'server'}->{'peerport'};  
     $connection_info = $connection_info . " --> " . $self->{'server'}->{'sockaddr'} . ":" . $self->{'server'}->{'sockport'};  
     connection_identified( $self->{'server'}->{'peeraddr'}, $connection_info);  
       
 }  
   
   
 sub connection_identified ($$) {  
     my $srcIP        = $_[0];  
     my $connection_info   = $_[1];  
   
     logger("ok we got a connection from $srcIP");  
   
     # RESTORE HASH  
     my $ref = restore_hash();  
     my %last_email_timestamp = %$ref;  
     my $skip_email = 0;  
   
     # check if we should ignore this IP  
     if (match_ip($srcIP, $ignorehosts)) {  
         logger("ignoring $srcIP!");  
         $skip_email = 1;  
         return 0;  
     }  
   
     # email max every $mail_thres secs   
     my $current_timestamp = time();  
     if (defined($last_email_timestamp{$srcIP})) {  
         logger("We have already seen a connection from the host before");  
       
         my $diff = $current_timestamp - $last_email_timestamp{$srcIP};  
         if ( $diff < $mail_thres) {  
             logger("OK so we saw a connection less than $mail_thres secs ago .. skippin email");  
             $skip_email = 1;  
         } else {  
             logger("but it was a long time ago, diff is $diff");  
         }  
     } else {  
         logger("we have not seen this IP before");  
     }  
     $last_email_timestamp{$srcIP} = $current_timestamp;  
     save_hash(\%last_email_timestamp);  
   
     if ($skip_email) { return; };  
     logger("ok gonna send an email using $mailserver, timeout 60");  
   
     # reverse dns  
     my $srcip_dns = PTR_lookup($srcIP);  
   
     # timestamp  
     my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);  
     my $timestamp = sprintf("%4d-%02d-%02d %02d:%02d:%02d\n",$year+1900,$mon+1,$mday,$hour,$min,$sec);  
   
     # SEND EMAIL?  
     my %params;  
     $params{connection_string}  = $connection_info;  
     $params{srcip_dns}   = $srcip_dns;  
     $params{srcip}     = $srcIP;  
     $params{timestamp}   = $timestamp;  
   
     my $msg = MIME::Lite::TT->new(  
       From     => $from_email,  
       To      => $to_email,  
       Subject   => $subject,  
       Template   => \$template,  
       TmplParams  => \%params,  
     );  
   
     $msg->send('smtp', $mailserver, Timeout => 60 );  
     logger("email sent using $mailserver");  
 }  
   
 sub PTR_lookup {  
     my $tname = shift;  
     my $type = "Reverse (PTR)";  
   
     my $rr;  
   
     my $res = new Net::DNS::Resolver;  
     my $query = $res->query("$tname","PTR");  
   
     if ($query) {  
         foreach $rr ($query->answer) {  
             next unless $rr->type eq "PTR";  
             my $ip = $rr->ptrdname;  
             return ($ip);  
         }  
     } else {  
         my $logstring = "Reverse lookup query failed for $tname : " . $res->errorstring . "\n";  
         logger($logstring);  
         return ($tname);  
     }  
 }   
   
 sub restore_hash() {  
   
     my %thash = ();  
     if (-e $tempcache) {  
         open(FOO,"<$tempcache") or die;  
         foreach my $line (<FOO>) {  
             chomp($line);  
             my ($ip,$time) = split(":",$line);  
             $thash{$ip} = $time;  
         }  
         close(FOO);  
     }  
   
     return \%thash;  
 }  
   
 sub save_hash($) {  
     my $hash_ref = $_[0];  
   
     my %thash = %$hash_ref;  
   
     open(FOO,">$tempcache") or die;  
     foreach my $key (keys %thash) {  
         if (defined($thash{$key})) {  
             print FOO $key . ":" . $thash{$key} . "\n";  
         }  
     }  
     close(FOO);  
   
 }  
   
 sub logger($) {  
     my $message = $_[0];  
   
     # LOG  
     open(POO,">>$logpath") or die;  
     print POO get_date() . ": $message\n";  
     close(POO);   
   
     # STDERR  
     print STDERR get_date() . ": $message\n";  
   
 }  
   
 sub get_date () {  
     my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);  
     my $timestamp = sprintf("%4d-%02d-%02d %02d:%02d:%02d\n",$year+1900,$mon+1,$mday,$hour,$min,$sec);  
     chop($timestamp);  
     return $timestamp;  
 }  
   
   
 open(FOO,">$tempports") or die;  
 foreach my $lport (@lports) {  
       
     if ($lport =~ /(\d+)-(\d+)/) {  
         my $startport = $1;  
         my $stopport = $2;  
         if ($stopport < $startport) { die "Invalid config, check the range\n"; };  
         for ($i=$startport;$i<=$stopport;$i++) {  
             print FOO "port $i\n";  
         }  
     } elsif ($lport =~ /^(\d+)/) {  
         print FOO "port $lport\n";  
     } else {  
         logger("Invalid port $lport specified");  
     }  
 }  
 close(FOO);  
   
 if ($background) {  
     Honey->run(   background => 1,  
         conf_file => "$tempports");  
 } else {  
     Honey->run(conf_file => "$tempports");  
 }  
   
 ##########  
 # honey.conf  
   
 from_email: me@here  
 to_email: you@there  
 mailserver: smtpserver  
 ignorehosts: 10.10.10.10, 0.0.0.0  
 mail_thres: 60  
 tempfolder: /tmp/  
 subject: Unauthorized connection to knockknock  
 background: 1  
 logpath: /var/log/honeylog.log  
 listenports:  
   - 1-21  
   - 23-24  
   - 26-65500  
   

apache logs to syslog

the other day i flipped out. well, flipped out in my own quiet way. i heard about some apache access issues and it gave me a slight headache. the super cool thing about linux boxes is that the "truth is in the logs". and i heart logs and log aggregation.

the cool thing about apache is that if configured correctly it will log all access and all errors. sadly, apache, by default, writes its logs on the local system and not via syslog processes. crap.
i really really don't want to go to each of my boxes and grep through /var/log/apache/blah.txt, how do i throw the logs access the network?

well, most linux boxes have tee and logger. tee is a nice program that basically say, do this and this. logger can send arbitrary data to syslog. yay.

in my enabled site, i changed my ErrorLog and CustomLog sections from this:

ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
to this:

ErrorLog "|/usr/bin/tee -a /var/log/apache2/error.log | /usr/bin/logger -thttpd -plocal6.err"
CustomLog "|/usr/bin/tee -a /var/log/apache2/access.log | /usr/bin/logger -thttpd -plocal6.notice" combined
i'm calling local6 and sending it off to syslog in httpd format. neat.

since i'm using rsyslogd, i edited my /etc/rsyslog.d/50-default conf to pipe off my logs to my remote syslog server:
auth,authpriv.*;local6.* @remotesyslogserver
if you'd rather not log to /var/log/syslog, add: local6.none to the -/var/log/messages stanza.

reload your daemons and voila.

Wednesday, December 17, 2014

openvas v7 create a new user

well. there are so many ways to create a user. this allows for integration with greenbone security desktop; a scanner user.
root@openvas:~#  openvasmd --create-user younotme
User created with password 'd25d4c66-5f7a-4156-84ee-f3ee101381fa'.

root@openvas:~# openvasmd --user=younotme --new-password=notcreatedhere
that was easy.

Monday, December 8, 2014

create a user via commandline in osx

 create a local user with local user group in macos x  
   
 list existing local gids:  
 # dscl . -list /Groups PrimaryGroupID | awk '{print $2}' | sort -n  
   
 for new group, choose numeric id not in list; above 1000 is good.  
 # dscl . -create /Groups/localgroup  
 # dscl . -create /Groups/localgroup PrimaryGroupID 1001  
   
 did you press enter?  
   
 # dscl . -read /Groups/localgroup  
   
 AppleMetaNodeLocation: /Local/Default  
 GeneratedUID: 00A738DA-21B7-4CD2-B5D9-7873C77205D1  
 PrimaryGroupID: 1001  
 RecordName: localgroup 
 RecordType: dsRecTypeStandard:Groups  
   
 list existing local uids:  
 # dscl . -list /Users UniqueID | awk '{print $2}' | sort -n  
   
 for new user, choose numberic id not in lists; above 1000 is good.  
 # dscl . -create /Users/localuser  
 # dscl . -create /Users/localuser UserShell /bin/bash  
 # dscl . -create /Users/localuser RealName "Local Users"  
 # dscl . -create /Users/localuser UniqueID "1001"  
 # dscl . -create /Users/localuser PrimaryGroupID 1001  
 # dscl . -create /Users/localuser NFSHomeDirectory /Users/localuser  
   
 did you really do all that?  
   
 # dscl . -read /Users/localuser  
   
 AppleMetaNodeLocation: /Local/Default  
 NFSHomeDirectory: /Users/localuser  
 GeneratedUID: 47D6D841-C7F1-4962-9F7E-167E8BFC3A91  
 PrimaryGroupID: 1001  
 RealName: localuser  
 RecordName: localuser  
 RecordType: dsRecTypeStandard:Users  
 UniqueID: 1001  
 UserShell: /usr/bash  
   
 create home directory.  
 # mkdir /Users/localuser  
 # chown localuser:localgroup /Users/localuser  
   
 give localuser a password:  
 # password localuser  
   
 # su - localuser  
   
 $  
   
 neat!  
   

Friday, December 5, 2014

netapp exports and hate

 i have a netapp on premises.  
it has a couple vfilers. i wanted to create an additional vfiler. sadly, i couldn't.  hate.  i hate.
 
i created a volume and i needed to make it have special non-nfsv4 settings cause that's just how the world goes.  

but! for whatever reason the netapp won't let me edit /etc/exports via a mount on a management host. it just won't.  

so, here's what you do, and you'll see what this is a pain.  

ssh root@freakonetapp  

rdfile /etc/exports  

(and out spits a lot of stuff)  

/vol/crap     -sec=sys,rw,root=10.6.6.66,nosuid  
/vol/crap2     -sec=sys,rw,root=10.6.6.66,nosuid  

i need to change /vol/crap2 and add yet another management host.  

so, copy all the lines that spit out on the screen. make your spiffy changes on an editor somewhere and issue:  

wrfile /etc/export  

(copy your spiffy changes you had in an editor elsewhere)  

/vol/crap     -sec=sys,rw,root=10.6.6.66,nosuid  
#/vol/crap2     -sec=sys,rw,root=10.6.6.66,nosuid  
/unix-crap     -actual=/vol/crap2,sec=sys,rw,root=10.6.6.66:10.6.66.6,nosuid  

Ctrl-C  
And reexport nfs:  

exportfs -a  

Thursday, December 4, 2014

am i slob or am i lazy? let's find -exec chown

 le sigh. LE SIGH. sometimes people like to do things on their own out of expediency or   
 because their local sysadmin is a lazy lazy lazy slob.
  
 i'm not a slob.  

 the issue was that someonenotme updated ubuntu and nfs was broke. or rather,   
 their home dir wasn't mounted.  

 this had been the case for months.   

 sure, i could put this line in /etc/fstab and go my merry way:  

 slobberserver:/home     /home     nfs   rsize=8192,wsize=8192,soft,_netdev   0 0  

 but, i'm not a slob.  

 see that _netdev? that's an awesome directive that says, "hey linuxbox  
 do not mount me till the network stack it up". awesome.  

 here's what you do:  

 record someonenotme's local system uid & gid  
 # id someonenotme  
 uid=1000(someonenotme) gid=1000(someonenotme)  

 kill all someonenotme processes  
 # kill -9 `ps -ef|grep someonenotme| awk '{print $2}'`  

 really really?  
 # lsof |grep someonenotme  
 ... nada ...  

 ldap & nfs-ize the system  
 # apt-get install nscd autofs ldap-client  

 put all your specially conf'd ldap conf files in /etc  

 refresh the name service  
 # /etc/init.d/nscd restart  

 # id someonenotme  
 uid=15288(someonenotme) gid=101(someonenotme) groups=100(users)  

 edit passwd and change someonenotme's uid and gid to that in ldap.  

 oh, and make sure the homedir matches, too.  
 # vipasswd  

 now we change all the uids and gids so that someonenotme matches what we have in ldap.  
 to prevent an unfun time, first umount all nfs mounts of interest.  
 # umount /home  

 now we look and change:  
 # find / -uid 1000 -gid 1000 -exec chown 15288:101 {} \;   

 after this is complete, mount -a and go about your business.  

 but wait! you cd'd into their dir, didn't you?  you saw they've done stuff as root 
 in the past.  crud.  why did you ls -la?
 # find /home/someonenotme -uid 0 -gid 0 -exec chown 15288:101 {} \;

 still not a slob.