HoneyClient::Manager::FW - Perl module to remotely handle firewall rule/chain creation and deletion


HoneyClient-Manager documentation  | view source Contained in the HoneyClient-Manager distribution.

Index


NAME

Top

HoneyClient::Manager::FW - Perl module to remotely handle firewall rule/chain creation and deletion which will provide network connectivity for the honeyclients during crawling. Additionally, it will provide protection when the honeyclients become compromised by enabling static rate limiting(tcp/udp/icmp) and MAC address filtering.

VERSION

Top

This documentation refers to HoneyClient::Manager::FW version 0.99.

SYNOPSIS

Top

CREATING THE SOAP SERVER

  # Make sure HoneyClient::Util::Config loads properly
use HoneyClient::Util::Config qw(getVar);

# Make sure IPTables::IPv4 loads use IPTables::IPv4;

# Make sure HoneyClient::Manager::FW can load use HoneyClient::Manager::Firewall::FW;

# Make sure HoneyClient::Util::SOAP loads properly require_ok('HoneyClient::Util::SOAP');

package HoneyClient::Manager::Firewall::FW; use HoneyClient::Util::SOAP qw(getClientHandle getServerHandle); my $daemon = getServerHandle(); $daemon->handle;

The SOAP firewall server will boot up when the honeywall is started by the HoneyClient manager. The main directory that holds all the listener code is the /hc directory. startFWListener.pl is located in the /etc/rc.d/rc3.d directory and will boot up when the honeywall starts up in run level three. After start up, the firewall listener will await calls from the HoneyClient manager so that the firewall may be configured properly and dynamically updated when crawling begins.

Steps to get honeyclient listening:

1. Boot up honeyclient honeywall vmware image. 2. Start up our SOAP firewall and SOAP log listener /usr/bin/perl /hc/startFWListener.pl > /dev/null 2> /dev/null & These will start upon boot of the honeywall so you will not have to do anything except boot the image. 3. Now the firewall is listening for all SOAP client calls 4. Do a "ps -xf" to confirm that your firewall is listening It should show something like: 7580 pts/0 S 0:01 /usr/bin/perl /hc/startFWListener.pl 5. Make your FW calls now from honeyclient-client.pl.

INTERACTING WITH SOAP SERVER

 use HoneyClient::Util::SOAP qw(getClientHandle);
 use HoneyClient::Util::Config qw(getVar);

After the honeywall boots up, startFWListerner.pl will be executed and begin listening. From here we want to start interacting with our SOAP FW server.

 # Create a new SOAP client, to talk to the HoneyClient::Manager::FW module
 # @initlist will contain all the return values sent back from the server (PID of startFWListerner.pl on server and status message)
 #  Lets set our default honeyclient ruleset:
  my $stub = getClientHandle(namespace => "HoneyClient::Manager::FW");
  my $som = $stub->fwInit();
  my @initlist = $som->paramsall;
  print "$_\n" foreach (@initlist);

 # To dynamically append new rules to the iptables ruleset, do the following
$hashref = this data structure will be passed from the manager to the HoneyClient::Manager::FW

 $som = $stub->addRule( $hashref );
 print $stub->result;
 print "\n";

# To dynamically delete rules, all you need to do is delete the user-defined chain that was originally created.

$som = $stub->deleteChain( $hashref ); print $stub->result; print "\n";

# To get the status of the current iptables ruleset, this function prints to hard disk the working iptables ruleset $som = $stub->getStatus(); print $stub->result; print "\n";

# For all new VM's that we plan to add later on, we will have to add new VM chains: $som = $stub->addChain( $hashref); print $stub->result; print "\n";

 # To shutdown the Firewall SOAP listner on the Honeywall
$som = $stub->FWShutdown();
print $stub->result;
print "\n";

DESCRIPTION

Top

Once created, the daemon acts as a stand-alone SOAP server, processing individual requests from the HoneyClient manager and manipulating the IPTables ruleset on the transparent virtual honeywall.

# This package name. our $PACKAGE = __PACKAGE__; our $DAEMON_PID : shared = undef; # Complete URL of SOAP server, when initialized. our $URL_BASE; our $URL; our $UPTIME = "/usr/bin/uptime";

BEGIN {

	# Defines which functions can be called externally.
	require Exporter;
	our ( @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION );

	# Set our package version.
	$VERSION = 0.99;

	@ISA = qw(Exporter);

	# Symbols to export automatically
	@EXPORT =
	  qw( _parseHash _validateInit init_fw destroy_fw _doFullBackup _flushChains _setAcceptPolicy _setDefaultDeny _set_log_rules _setstaticrate _setDefaultRules _remoteConnection _set_ip_forwarding _getpid);

	# Items to export into callers namespace by default. Note: do not export
	# names by default without a very good reason. Use EXPORT_OK instead.
	# Do not simply export all your public functions/methods/constants.

	# This allows declaration use HoneyClient::Manager::FW ':all';
	# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
	# will save memory.

	%EXPORT_TAGS = ( 'all' => [qw(init_fw destroy_fw)], );

	# Symbols to autoexport (when qw(:all) tag is used)
	@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

	$SIG{PIPE} = 'IGNORE';    # Do not exit on broken pipes.
}




EXTERNAL SOAP FUNCTIONS

Top

_getVMName($hashref);

This function extracts the VM name from the hash reference and will use it in the addChain() function later.

Inputs: $hashrefis the hash reference sent from the HoneyClient::Agent->HoneyClient::Manager->HoneyClient::Manager::FW

Output: Returns the VM name.

init_fw()

The following init_fw() and destroy_fw() functions are the only direct calls required to startup and shutdown the SOAP server.

Input: $class, $localAddr, $localPort

Output: n/a

destroy_fw()

Terminates the SOAP server within the child process.

_load_interfaces()

Loads the interfaces listed in the /etc/interfaces.conf file (function not active yet)

Input: filename

Output: n/a

_flushChains()

Gets the current list of chains within the IPTables ruleset and flushes all corresponding rules, then deletes the actual chain.

Input: No input

Output: Return true if success for the flushing and deleting, returns false if unsuccessful

_setAcceptPolicy()

Grabs the current list of chains within the IPTables ruleset and sets the policy to ACCEPT.

Input: No input

Output: Return true if the commit was successful, returns false if unsuccessful. $table->commit() attempts to commit all changes made to the IP chains in the table that $table points to, and closes the connection to the kernel-level netfilter subsystem. If you wish to apply your changes back to the kernel, you must call this.

_setDefaultDeny()

Gets the current list of chains and sets the firewall policy to DROP.

Input: No input

Output: Return true if successful commit, returns false if unsuccessful commit

_setDefaultRules()

This function parses the /etc/resolv.conf file and grabs the DNS settings, then creates iptables rules on the INPUT/FORWARD and OUTPUT chains from thoses DNS settings. Additionally, we create rules to allow the firewall to talk to itself via the localhost.

Additionally, at the end of the opendefault function are two rules:

"iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT" "iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT"

These rules track state and allow traffic to be forwarded in both directions. It also only allows initiated 10.0.0.0/24 outbound traffic to be sent. This is necessary since we only want our honeyclients to recieve traffic that they initiated and no other. For starters, our honeyclients will just be examining HTTP traffic but might be examining other protocols in the future. Either way, all established and initiated connections that match this rule and be allowed out.

Input: No input

Output: Return true if successful commit, returns false if unsuccessful commit

_createNat()

Create a NAT rule that allows for all HoneyClient VM's to have access through the Honeywall. We are using a Masquerading rule, masquerading is a simplified form of SNAT (source NAT) in which packets receive the IP address of the output interface as their source address.

Input: No input

Output: Output is a bolean value for succes or failure during the rule insertion.

_createPreroutingLogging()

Create a logging rule for the NAT table (PREROUTING chain) in which we log all traffic that does match the specified rule.

Input: No input

Output: Output is a boolean value for succes or failure during the rule insertion.

_getdns()

This function grabs the DNS settings from the /etc/resolv.conf file. It assumes that the default location for these settings will be in that file. However, it does check and make sure that it is a linux box first.

Input: No input

Output: Returns a complete list of nameservers if true, if not true, returns value of linux variable which should be 0

_createDropLog()

Create a user-defined chain called Drop_Log which logs and drops all rules that do not match rules within the INPUT and OUTPUT chains.

Input: No input

Output: Return true if successful , returns false if unsuccessful append.

_doFullBackup()

Does a complete backup to hard disk of the current active iptables ruleset.

Input: Requires the $outputdir where the file will be written to.

Output: Returns void; dies if failure.

_setstaticrate()

This function creates a static rate limiting rule for our default honeyclient default ruleset. For testing purposes, I allow an initial burst of 10 tcp/udp/icmp packets, then gives you 5 packets per minute thereafter.

Input: Requires the $outputdir where the file will be written to.

Output: Return true if commit success or false if commit failure

_remoteConnection()

This function opens a few remote connection holes within our honeyclient firewall, more specifically ssh and 8082/tcp (used for connection to/from GSX server manager module)

Input: No input

Output: Return true if successful commit, returns false if unsuccessful commit

_set_ip_forwarding()

Set the /proc/sys/net/ipv4/ip_forward file to a value supplied by the user

Input: $value which will be either 0 or 1

Output: nothing

_checkRoot()

Checks to make sure FW.pm is running as root user (uid 0).

Input: No input

Output: Return true if success or false if failure

[NOT IMPLEMENTED AT THIS TIME]: _rule_exists() function checks for the existance of rules within our IPTables ruleset. Within this function, we are checking the rules within the user-defined chains that we have created. If there is a match within the "input" VM, we consider that a match since when the rule is initially appended, it is appended to both the VM#-in and VM#-out chains. Here, I am only testing against the VM#-in chain since if the rule is in one, it has to be in both.

Inputs: $tableis the object type of IPTables::IPv4::Table. $vin is the VM input chain name. $vout is the VM output chain name. %rule is a hash containing source, destination, and protocol values.

Output: Return true if success or false if failure

[NOT IMPLEMENTED AT THIS TIME]: _translate($url);

The translate function converts a host name to dotted quad format.

Inputs: $urlis the domain name that will be converted to dotted quad format.

Output: Return the domain name as an IP address.

getStatus();

Gets the current iptables ruleset for all the chains (both default and user-defined) and writes them to hard disk. Loop through each chain which gets you the list of chain names. The function list_rules() returns an array of hash references, which contain descriptions of each rule in the chain chainname. Below is the core of the function FWStatus().

        foreach $chainname(@chainlist){
                print "\n$chainname\n";
                my @chainrules = $table->list_rules($chainname);
                for my $href (@chainrules){
                        for $line (keys %$href){
                                print FWSTATUS "$line=$href->{$line} ";
                        }
                print "\n";
                }
        }

Inputs: $classis the name of the package.

Output: nothing

_iplookup();

_iplookup takes a domain name ($dest) and performs a DNS query to find an IP address or IP addresses corresponding to that domain name. Currently, _resolveHost() is being used.

Inputs: $dest is a domain name that will be queried to retrieve corresponding IP addresses.

Output: An array of resolved IP addresses. If the array only contains one value, then just the one value is in the array.

[NOT IMPLEMENTED AT THIS TIME]: insertMac();

insertMac function add mac address filtering (Anti-spoofing) rules after the VM user-chains are created. They must be remotely called after the vm_add_chain() function.

Inputs: $chain is the name of the chain that you will be applying the Mac filtering to. $ip is the VM ip address that will be filtered. $mac is the mac address of the VM honeyclient.

Output: returns nothing

_chain_exists();

_chain_exists tests to see if the chain already exists within the IPTables ruleset.

Inputs: $vmindex is the Virtual Machine index number that will be used for comparing to the array of existing chains.

Output: returns true if chain exists, fales if it does not exist.

[NOT IMPLEMENTED AT THIS TIME]: isAlive();

Tests for existance of a file to verify if firewall has been started (not currently active)

Inputs: $pidfile is the name of the created PID file.

Output: creation of file with resolved IP addresses.

_getLogtime();

gets the time based on the OS time

Inputs: nothing

Output: current time

FWShutdown();

This function first flushes and deletes all the chains in the IPTables ruleset, then sets the ACCEPT policy to all the default chains (INPUT, FORWARD, and OUTPUT). Additionally, the function then loops through the process table and kills all processes with "startFWListener.sh" in the process commandline (of which there should only be one).

Inputs: nothing Output: process will be killed

starttestProcess() - system command to start the SOAP FW listener. This function is used strictly for pod2test purposes.

Inputs: nothing Output: nothing

findProcess() - used for test purposes only to find a started SOAP server listener.

Inputs: class name Output: returns the boolean value, true or false

_getpid();

_getpid() takes in 1 argument and returns the $pid of the SOAP firewall listener.

Inputs: Takes in the process name (name of the listener) Output: returns the process ID number

[NOT IMPLEMENTED AT THIS TIME]: _sendMail() is a helper function that sends email to other systems informing them of various actions with the firewall.

_sendMail will send mail to the root account at localhost informing the root user of various firewall actions Inputs: $from is where the user is sending from $to is where the user is sending to $subject is the subject of the email $body is content of the email Output: returns nothing for now

[NOT IMPLEMENTED AT THIS TIME]: getcpuload is a function that gives you the cpuload of the OS firewall. This should help give a better understanding of how the firewall OS is running.

Inputs: nothing Output: cpu load of the OS FW

_getip gets the current IP address and mask of the specified interface.

Inputs: Requires the interface so that it can find the IP address of that interface Output: IP address and Mask of that interface

_getmac gets the current MAC address of the specified interface.

Inputs: Requires the interface so that it can find the MAC address of that interface Output: returns the mac address of the interface

_resolveHost() is a helper function that takes in destination domain name and spits out an array list of resolved ip addresses

Inputs: Requires domain name ($host) Output: returns array list of resolved IP addresses

fwOff() opens up our firewall.

Inputs: n/a Output: nothing

killProcess();

This is a function kills all systems process based on the command line name give via the remote call. It looks through the process table and removes all processes with that key name.

<Inputs>: no input

Output: destruction of all Process IDs.

[NOT IMPLEMENTED AT THIS TIME]: checkDiskSize();

checkDiskSize() checks the size of the honeywall partitions and makes sure the disk does not fill up. If it reaches a certain level (90%), then it shoots off an email to root and logs it to hard disk.

Inputs: no inputs

Output: outputs the percentage of hard disk that is filled per partition.

[NOT IMPLEMENTED AT THIS TIME]: isCompromised();

isCompromised() checks the iptables log files to see if there has been a compromise to one of the VM images.

Inputs: hash reference($hashref)

Output: none

checkLog();

checkLog() checks for network anomalies (MAC address spoofing) or any blocked outbound traffic that orginates from anywhere from the VM subnet.

Inputs: hash reference($hashref)

Output: none

runTcpdump() - starts a tcpdump procces for a specified VM machine.

Inputs: VM name and the source IP address of the image.

Output: none

clearTcpdump() - Deletes the corresponding tcpdump .pcap file, then creates a new file for logging.

Inputs: none

Output: none

removeTcpdump() - removes the corresponding tcpdump .pcap file

Inputs: VM name and the source IP address of the image.

Output: none

_getSourceIP() - gets the source IP address from the hash table sent from the HoneyClient Manager

Inputs: hash reference Output: source ip address

testConnect() - will allow the user to test connectivity for all their VM's sitting on the backend network behind the honeywall.

Inputs: package name is passed by default

Output: $success; boolean value to determine if iptables inserted the rules or not.

SEE ALSO

Top

http://www.honeyclient.org/trac

SOAP::Lite, SOAP::Transport::HTTP

http://www.soaplite.com

IPTables::IPv4

Net::DNS

IPTables Perl API http://sourceforge.net/projects/iptperl/

Data::Dumper, English, Proc::ProcessTable, FileHandle

http://www.honeyclient.org/trac

REPORTING BUGS

Top

http://www.honeyclient.org/trac/newticket

ACKNOWLEDGEMENTS

Top

Derrik Pates for providing the IPTables perl API code and to the sourceforge perl API mailing list for providing detailed support about the IPTables::IPv4 module.

AUTHOR

Top

JD Durick, <jdurick@mitre.org>

Xeno Kovah, <xkovah@mitre.org>

COPYRIGHT AND LICENSE

Top


HoneyClient-Manager documentation  | view source Contained in the HoneyClient-Manager distribution.