Changeset 1008

Show
Ignore:
Timestamp:
11/16/07 16:20:26 (10 months ago)
Author:
kindlund
Message:

Merging kindlund-dynamic_updates branch back into trunk.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • honeyclient/trunk/bin/StartAgent.pl

    r409 r1008  
    6060    $URL = HoneyClient::Agent->init(); 
    6161 
     62    # Recreate a new stub handle, in case the global configuration has 
     63    # changed. 
     64    $stub = getClientHandle(address   => 'localhost', 
     65                            namespace => 'HoneyClient::Agent', 
     66                            fault_handler => \&_watchdogFaultHandler); 
     67 
    6268    # Restore state information. 
    63     $som = $stub->updateState(encode_base64(nfreeze($agentState))); 
     69    if (defined($agentState)) { 
     70        $som = $stub->updateState(encode_base64(nfreeze($agentState))); 
     71    } 
    6472} 
    6573 
  • honeyclient/trunk/bin/StartManager.pl

    r942 r1008  
    77use Carp (); 
    88 
     9# Include Dumper Library 
    910use Data::Dumper; 
    1011 
     
    1819use Getopt::Long; 
    1920 
     21# Include utility access to global configuration. 
     22use HoneyClient::Util::Config qw(getVar); 
     23 
     24# Include Manager Library 
    2025use HoneyClient::Manager; 
    2126 
     27# Include Logging Library 
     28use Log::Log4perl qw(:easy); 
     29 
     30# The global logging object. 
     31our $LOG = get_logger(); 
     32 
    2233# We expect that the user will supply a single argument to this script. 
    23 # Namely, the initial URL that they want the Agent to use. 
    24 # They can however supply multiple urls which will be processed in order 
     34# Namely, the initial set of URLs that they want the Agent to use. 
    2535 
    2636# Change to 'HoneyClient::Agent::Driver::Browser::IE' or 
    2737#           'HoneyClient::Agent::Driver::Browser::FF' 
    28 my $driver = "HoneyClient::Agent::Driver::Browser::IE"
     38my $driver = undef
    2939my $config = undef; 
    30 my $maxrel = 5
     40my $maxrel = undef
    3141my $nexturl = ""; 
    3242my $urllist= ""; 
     
    3848           'url_list=s'           => \$urllist, 
    3949           'max_relative_links:i' => \$maxrel); 
     50 
     51# Sanity Check.  Make sure $driver is set. 
     52unless (defined($driver)) { 
     53    $driver = getVar(name      => "default_driver", 
     54                     namespace => "HoneyClient::Agent"); 
     55} 
     56 
     57# Sanity Check.  Make sure $max_relative_links is set. 
     58unless (defined($maxrel)) { 
     59    $maxrel = getVar(name      => "max_relative_links_to_visit", 
     60                     namespace => "HoneyClient::Agent::Driver::Browser"); 
     61} 
    4062 
    4163# Go through the list of urls to create the array 
  • honeyclient/trunk/etc/honeyclient.xml

    r986 r1008  
    7272            <name>HoneyClient::Agent::Driver::Browser::FF</name> 
    7373        </allowed_drivers> 
     74        <default_driver description="If no driver is manually specified, then this Driver will be used as the default by the Agent." default="HoneyClient::Agent::Driver::Browser::IE"> 
     75            HoneyClient::Agent::Driver::Browser::IE 
     76        </default_driver> 
    7477        <!-- HoneyClient::Agent::Driver Options --> 
    7578        <Driver> 
     
    9497                    1 
    9598                </ignore_links_timed_out> 
    96                 <!-- TODO: Update this. --> 
    97                 <process_name description="The name of the Internet Explorer application process, as it appears in the Task Manager." default="iexplore.exe"> 
    98                     iexplore.exe 
    99                 </process_name> 
    10099                <max_relative_links_to_visit description="An integer, representing the maximum number of relative links that the browser should visit, before moving onto another website.  If negative, then the browser will exhaust all possible relative links found, before moving on.  This functionality is best effort; it's possible for the browser to visit new links on previously visited websites." default="-1"> 
    101                     -1 
     100                    5 
    102101                </max_relative_links_to_visit> 
    103102                <positive_words description="If a link contains any number of these words, then its probability of being visited (its score) will increase."> 
     
    123122                    <word>jobs</word> 
    124123                    <word>careers</word> 
     124                    <word>term</word> 
    125125                </negative_words> 
    126126                <IE> 
     
    155155            </changes_found_file> 
    156156            <realtime_changes_file description="When an integrity check fails, all changes will be written to this file within the compromized honeyclient VM's filesystem." default="/tmp/realtime-changes.txt"> 
    157             /tmp/realtime-changes.txt 
     157                /tmp/realtime-changes.txt 
    158158            </realtime_changes_file> 
    159159            <!-- HoneyClient::Agent::Integrity::Filesystem Options --> 
     
    329329    <DB> 
    330330        <enable description="Enables database operations. 1 enables, 0 disables." default="0"> 
    331             1 
     331            0 
    332332        </enable> 
    333333        <host description="The system providing the HoneyClient database.  If the database is installed on the same host system as the Manager, then localhost should be used." default="127.0.0.1"> 
     
    349349    <Manager> 
    350350        <!-- TODO: Update this. --> 
    351         <manager_state description="Upon termination, the Manager will attempt to save a complete copy of its state into this file, if specified." default=""> 
     351        <manager_state description="Upon termination, the Manager will attempt to append a complete copy of its state into this file, if specified." default=""> 
    352352            Manager.dump 
    353353        </manager_state> 
     354        <compromise_dump description="When the Manager encounters a compromised VM, it will attempt to append a complete copy of the compromised information to this file, if specified."> 
     355            Compromise.dump 
     356        </compromise_dump> 
    354357        <!-- TODO: Update this. --> 
    355358        <address description="The IP or hostname that all Manager modules should use, when accepting SOAP requests." default="localhost"> 
  • honeyclient/trunk/etc/honeyclient_log.conf

    r937 r1008  
    6565#log4perl.logger.HoneyClient.Manager=INFO, Screen, Syslog 
    6666#log4perl.logger.HoneyClient.DB=DEBUG, Screen, Syslog 
     67#log4perl.logger.HoneyClient.Manager.VM.Clone=DEBUG, Screen 
    6768# Suppress Parser Debugging Messages 
    6869#log4perl.logger.HoneyClient.Agent.Integrity.Registry.Parser=INFO, Screen 
  • honeyclient/trunk/lib/HoneyClient/Agent.pm

    r994 r1008  
    346346        Carp::croak "Error: " . __PACKAGE__ . " daemon is already running (PID = $DAEMON_PID)!\n"; 
    347347    } 
     348 
     349    # Reinitialize global constants (for dynamic updates). 
     350    $PERFORM_INTEGRITY_CHECKS = getVar(name => "perform_integrity_checks"); 
    348351 
    349352    # Figure out what our list of allowed Drivers are.  
     
    896899        my $driverTargetsChanged = 0; 
    897900 
     901        # Boolean to indicate that the driver has been compromised. 
     902        my $isCompromised = 0; 
     903 
     904        # Variable to hold any changes found in a compromise. 
     905        my $changes = undef; 
     906 
    898907        while (!$driver->isFinished() && !$driverTargetsChanged) { 
    899908            # XXX: Debug.  Remove this. 
     
    907916            # If the operation fails, then an exception will be generated. 
    908917            $driver->drive(); 
    909     
     918   
     919            # Perform an integrity check, if needed. 
     920            if (defined($integrity)) { 
     921                # For now, we update a scalar called 'is_compromised' within 
     922                # the $data->{$driverName}->{'status'} sub-hashtable. 
     923                $LOG->info($driverName . " - Performing Integrity Checks."); 
     924                $changes = $integrity->check(); 
     925                if (scalar(@{$changes->{processes}})) {  
     926                    $LOG->warn($driverName . " - Integrity Check: FAILED"); 
     927                    $isCompromised = 1; 
     928                    $changes->{'last_resource'} = $lastResource; 
     929         
     930                    # Release our copy of the integrity object, but do not destroy  
     931                    # any internal references. 
     932                    $integrity = undef; 
     933 
     934                    # Exit the while block. 
     935                    last; 
     936 
     937                } else { 
     938                    $LOG->info($driverName . " - Integrity Check: PASSED"); 
     939                } 
     940            } 
     941 
    910942            # Acquire lock on stored driver state. 
    911943            $data = _lock(); 
     
    928960            $data->{$driverName}->{'next'} = $driver->next(); 
    929961            $data->{$driverName}->{'status'} = $driver->status(); 
    930             $data->{$driverName}->{'status'}->{'is_compromised'} = 0
     962            $data->{$driverName}->{'status'}->{'is_compromised'} = $isCompromised
    931963            $data->{$driverName}->{'status'}->{'is_running'} = 1; 
    932964            $data->{$driverName}->{'state'} = $driver; 
     
    935967            _unlock($data); 
    936968        } 
    937                  
    938         # Perform Integrity Check 
    939         # XXX: We may want this logic moved out of the child thread, 
    940         # in case we ever have more than one worker thread simultaneously going. 
    941         # (We wouldn't want to have 2 worker threads simultaneously performing 
    942         # this check, as VM performance would slow to a crawl.) 
    943         my $isCompromised = 0; 
    944         my $changes = undef; 
    945         if (defined($integrity)) { 
    946             # For now, we update a scalar called 'is_compromised' within 
    947             # the $data->{$driverName}->{'status'} sub-hashtable. 
    948             $LOG->info($driverName . " - Performing Integrity Checks."); 
    949             $changes = $integrity->check(); 
    950             if (scalar(@{$changes->{processes}})) {  
    951                 $LOG->warn($driverName . " - Integrity Check: FAILED"); 
    952                 $isCompromised = 1; 
    953                 $changes->{'last_resource'} = $lastResource; 
    954             } else { 
    955                 $LOG->info($driverName . " - Integrity Check: PASSED"); 
    956             } 
    957         } 
     969         
     970        # XXX: This code may come in handy again, if we decide to keep the 
     971        # old-style integrity checks. 
     972        # Perform an integrity check, if needed. 
     973        # if (defined($integrity)) { 
     974        #     # For now, we update a scalar called 'is_compromised' within 
     975        #     # the $data->{$driverName}->{'status'} sub-hashtable. 
     976        #     $LOG->info($driverName . " - Performing Integrity Checks."); 
     977        #     $changes = $integrity->check(); 
     978        #     if (scalar(@{$changes->{processes}})) {  
     979        #         $LOG->warn($driverName . " - Integrity Check: FAILED"); 
     980        #         $isCompromised = 1; 
     981        #         $changes->{'last_resource'} = $lastResource; 
     982        #     } else { 
     983        #         $LOG->info($driverName . " - Integrity Check: PASSED"); 
     984        #     } 
     985        # } 
     986 
    958987        # Release our copy of the integrity object, but do not destroy  
    959988        # any internal references. 
  • honeyclient/trunk/lib/HoneyClient/Agent/Driver/Browser.pm

    r994 r1008  
    438438 
    439439=cut 
    440  
    441 my %PARAMS = ( 
    442  
    443     # This is a hashtable of fully qualified URLs 
    444     # to visit by the browser.  Specifically, the 'key' is 
    445     # the absolute URL and the 'value' is always 1. 
    446     links_to_visit          => { }, 
    447  
    448     # This is a hashtable of fully qualified URLs that the 
    449     # browser has already visited.  Specifically, the 
    450     # 'key' is the absolute URL and the 'value' is a string 
    451     # representing the date and time of when the link was visited. 
    452     # 
    453     # Note: See _getTimestamp() for the corresponding date/time 
    454     # format. 
    455     links_visited           => { }, 
    456  
    457     # This is a hashtable of URLs that the browser has found 
    458     # during its traversal process, but the browser could not 
    459     # access the link. 
    460     # 
    461     # Links could be added to this list if access requires any type of 
    462     # authentication, or if the link points to a non-HTTP or HTTPS 
    463     # resource (i.e., "javascript:doNetDetect()"). 
    464     # 
    465     # The 'key' is the absolute URL and the 'value' is a string 
    466     # representing the date and time of when the link was visited. 
    467     # 
    468     # Note: See _getTimestamp() for the corresponding date/time 
    469     # format. 
    470     links_ignored           => { }, 
    471  
    472     # This is a hashtable of fully qualified URLs 
    473     # that all share a common *hostname*.  This hashtable should be 
    474     # initially empty.  As the driver extracts and removes new URLs 
    475     # off the 'links_to_visit' hashtable, driving the browser to each URL, 
    476     # any *relative* links found are added into this hashtable; any 
    477     # *external* links found are added back into the 'links_to_visit' 
    478     # hashtable. 
    479     # 
    480     # When navigating to the next link, this hashtable is exhausted prior 
    481     # to the main 'links_to_visit' hashtable.  This allows a 
    482     # browser to navigate to all links hosted on the same server, prior 
    483     # to contacting a different server. 
    484     # 
    485     # Specifically, the 'key' is the absolute URL and the 'value' 
    486     # is always 1. 
    487     relative_links_to_visit => { }, 
    488  
    489     # This is a scalar that contains the next URL to visit. 
    490     # It is updated dynamically, any time getNextLink() is called. 
    491     # When the browser is ready to drive to the next link, 
    492     # 'next_link_to_visit' is checked.  If that value is undef, then 
    493     # the 'relative_links_to_visit' hashtable is checked next. 
    494     # If that hashtable is empty, then finally the 'links_to_visit' 
    495     # hashtable is checked. 
    496     next_link_to_visit      => undef, 
    497  
    498     # This is a hashtable of URLs that the browser has found 
    499     # during its traversal process, but the browser could not 
    500     # access the resource due to the operation timing out. 
    501     # 
    502     # The 'key' is the absolute URL and the 'value' is a string 
    503     # representing the date and time of when the link was visited. 
    504     # 
    505     # Note: See _getTimestamp() for the corresponding date/time 
    506     # format. 
    507     links_timed_out         => { }, 
    508  
    509     # If this parameter is a defined scalar, then the browser 
    510     # will also never attempt to revisit any links that caused 
    511     # the browser to time out. 
    512     ignore_links_timed_out  => getVar(name => "ignore_links_timed_out"), 
    513  
    514     # A string containing the process name of the browser application, 
    515     # as it appears in the Task Manager. 
    516     process_name            => getVar(name => "process_name"), 
    517  
    518     # An integer, representing how many relative links the browser 
    519     # should continue to drive to, before moving onto another 
    520     # website.  If negative, then the browser will exhaust all possible 
    521     # relative links, before moving on.  (This internal variable should 
    522     # never be modified externally.) 
    523     _remaining_number_of_relative_links_to_visit => getVar(name => "max_relative_links_to_visit"), 
    524  
    525     # An integer, representing the maximum number of relative links that 
    526     # the browser should visit, before moving onto another website.  If 
    527     # negative, then the browser will exhaust all possible relative links 
    528     # found, before moving on.  This functionality is best effort; it's 
    529     # possible for the browser to visit new links on previously visited 
    530     # websites. 
    531     max_relative_links_to_visit => getVar(name => "max_relative_links_to_visit"), 
    532  
    533     # An array of positive words, where a link's probability of being 
    534     # visited (its score) will increase, if the link contains any of these 
    535     # words. 
    536     positive_words => getVar(name => "positive_words")->{word}, 
    537  
    538     # An array of negative words, where a link's probability of being 
    539     # visited (its score) will decrease, if the link contains any of these 
    540     # words. 
    541     negative_words => getVar(name => "negative_words")->{word}, 
    542  
    543     # If set to 1, then the code will attempt to parse and extract links 
    544     # within active content (e.g., Flash animations).  Otherwise, the 
    545     # code will ignore all active content.  
    546     parse_active_content => getVar(name      => "enable", 
    547                                    namespace => "HoneyClient::Agent::Driver::ActiveContent"), 
    548 ); 
    549440 
    550441####################################################################### 
     
    907798    # 
    908799    # - For each parameter given, it overwrites any corresponding 
    909     #   parameters specified within the default hashtable, %PARAMS
     800    #   parameters specified within the default hashtable, %params
    910801    #   with custom entries that were given as parameters. 
    911802    # 
     
    926817 
    927818    # Initialize default parameters. 
    928     my %params = %{dclone(\%PARAMS)}; 
     819    my %params = ( 
     820 
     821        # This is a hashtable of fully qualified URLs 
     822        # to visit by the browser.  Specifically, the 'key' is 
     823        # the absolute URL and the 'value' is always 1. 
     824        links_to_visit          => { }, 
     825 
     826        # This is a hashtable of fully qualified URLs that the 
     827        # browser has already visited.  Specifically, the 
     828        # 'key' is the absolute URL and the 'value' is a string 
     829        # representing the date and time of when the link was visited. 
     830        # 
     831        # Note: See _getTimestamp() for the corresponding date/time 
     832        # format. 
     833        links_visited           => { }, 
     834 
     835        # This is a hashtable of URLs that the browser has found 
     836        # during its traversal process, but the browser could not 
     837        # access the link. 
     838        # 
     839        # Links could be added to this list if access requires any type of 
     840        # authentication, or if the link points to a non-HTTP or HTTPS 
     841        # resource (i.e., "javascript:doNetDetect()"). 
     842        # 
     843        # The 'key' is the absolute URL and the 'value' is a string 
     844        # representing the date and time of when the link was visited. 
     845        # 
     846        # Note: See _getTimestamp() for the corresponding date/time 
     847        # format. 
     848        links_ignored           => { }, 
     849 
     850        # This is a hashtable of fully qualified URLs 
     851        # that all share a common *hostname*.  This hashtable should be 
     852        # initially empty.  As the driver extracts and removes new URLs 
     853        # off the 'links_to_visit' hashtable, driving the browser to each URL, 
     854        # any *relative* links found are added into this hashtable; any 
     855        # *external* links found are added back into the 'links_to_visit' 
     856        # hashtable. 
     857        # 
     858        # When navigating to the next link, this hashtable is exhausted prior 
     859        # to the main 'links_to_visit' hashtable.  This allows a 
     860        # browser to navigate to all links hosted on the same server, prior 
     861        # to contacting a different server. 
     862        # 
     863        # Specifically, the 'key' is the absolute URL and the 'value' 
     864        # is always 1. 
     865        relative_links_to_visit => { }, 
     866 
     867        # This is a scalar that contains the next URL to visit. 
     868        # It is updated dynamically, any time getNextLink() is called. 
     869        # When the browser is ready to drive to the next link, 
     870        # 'next_link_to_visit' is checked.  If that value is undef, then 
     871        # the 'relative_links_to_visit' hashtable is checked next. 
     872        # If that hashtable is empty, then finally the 'links_to_visit' 
     873        # hashtable is checked. 
     874        next_link_to_visit      => undef, 
     875 
     876        # This is a hashtable of URLs that the browser has found 
     877        # during its traversal process, but the browser could not 
     878        # access the resource due to the operation timing out. 
     879        # 
     880        # The 'key' is the absolute URL and the 'value' is a string 
     881        # representing the date and time of when the link was visited. 
     882        # 
     883        # Note: See _getTimestamp() for the corresponding date/time 
     884        # format. 
     885        links_timed_out         => { }, 
     886 
     887        # If this parameter is a defined scalar, then the browser 
     888        # will also never attempt to revisit any links that caused 
     889        # the browser to time out. 
     890        ignore_links_timed_out  => getVar(name => "ignore_links_timed_out"), 
     891 
     892        # A string containing the process name of the browser application, 
     893        # as it appears in the Task Manager. 
     894        process_name            => getVar(name => "process_name"), 
     895 
     896        # An integer, representing how many relative links the browser 
     897        # should continue to drive to, before moving onto another 
     898        # website.  If negative, then the browser will exhaust all possible 
     899        # relative links, before moving on.  (This internal variable should 
     900        # never be modified externally.) 
     901        _remaining_number_of_relative_links_to_visit => getVar(name => "max_relative_links_to_visit"), 
     902 
     903        # An integer, representing the maximum number of relative links that 
     904        # the browser should visit, before moving onto another website.  If 
     905        # negative, then the browser will exhaust all possible relative links 
     906        # found, before moving on.  This functionality is best effort; it's 
     907        # possible for the browser to visit new links on previously visited 
     908        # websites. 
     909        max_relative_links_to_visit => getVar(name => "max_relative_links_to_visit"), 
     910 
     911        # An array of positive words, where a link's probability of being 
     912        # visited (its score) will increase, if the link contains any of these 
     913        # words. 
     914        positive_words => getVar(name => "positive_words")->{word}, 
     915 
     916        # An array of negative words, where a link's probability of being 
     917        # visited (its score) will decrease, if the link contains any of these 
     918        # words. 
     919        negative_words => getVar(name => "negative_words")->{word}, 
     920 
     921        # If set to 1, then the code will attempt to parse and extract links 
     922        # within active content (e.g., Flash animations).  Otherwise, the 
     923        # code will ignore all active content.  
     924        parse_active_content => getVar(name      => "enable", 
     925                                       namespace => "HoneyClient::Agent::Driver::ActiveContent"), 
     926    ); 
     927 
    929928    $self = $class->SUPER::new(); 
    930929    @{$self}{keys %params} = values %params; 
  • honeyclient/trunk/lib/HoneyClient/Agent/Integrity.pm

    r994 r1008  
    6161  } 
    6262 
    63 $changes refers to an array of hashtable references, where 
    64 each hashtable has the format given in the METHODS IMPLEMENTED section related to 
    65 check(). 
    66  
    67 =head2 INITIALIZATION 
    68  
    69 No initialization is currently necessary, as realtime changes are read in from 
     63  # $changes refers to an array of hashtable references, where 
     64  # each hashtable has the format given in the METHODS IMPLEMENTED section related to 
     65  # check(). 
     66 
     67  # Once you're finished with the $integrity object, be sure to destroy it. 
     68  $integrity->destroy(); 
     69 
     70=head1 DESCRIPTION 
     71 
     72This library allows the Agent module to easily baseline and perform subsequent 
     73checks of different aspects of the Windows OS for any changes that may occur, 
     74while Agent instruments a target application. 
     75 
     76Currently, the Integrity module performs the following checks, using the 
     77listed sub-modules.  Please refer to the sub-module documentation for 
     78further details about how each check is implemented. 
     79 
     80No initialization is currently necessary, as real-time changes are read in from 
    7081a list exported by the Capture C code. However, in the future it may become  
    71 deisrable to perform an initial baseline of the system in order to automatically 
    72 determine the original value for things which were changed. This is because the 
     82desirable to perform an initial baseline of the system, in order to automatically 
     83determine the original value for things which were changed. This is because the 
    7384mechanisms that Capture code uses to record events, may in some cases be unable 
    74 to record the initial value for a registry key for instance. 
     85to record the initial value (e.g., a registry key). 
     86 
     87=over 4 
     88 
     89=item * 
     90 
     91Checks Windows OS Registry.  See L<HoneyClient::Agent::Integrity::Registry>. 
     92 
     93=item * 
     94 
     95Checks Windows OS Filesystem.  See L<HoneyClient::Agent::Integrity::Filesystem>. 
     96 
     97=back 
    7598 
    7699=cut 
     
    250273=back 
    251274 
     275=head2 changes_found_file 
     276 
     277A string to the absolute path of a file on the VM's filesystem. 
     278When an integrity check fails, all changes will be written to this 
     279file within the compromized honeyclient VM's filesystem. 
     280 
     281=back 
     282 
    252283=cut 
    253  
    254 my %PARAMS = ( 
    255     # When set to 1, the object will forgo any type of initial baselining 
    256     # process, upon initialization.  Otherwise, baselining will occur 
    257     # as normal, upon initialization. 
    258     # XXX: Bypass static baselining, for now. 
    259     # XXX: Baselining will not be used with the current version which includes Capture 
    260     bypass_baseline => 1, 
    261  
    262     # Contains the Registry object, once initialized. 
    263     # (For internal use only.) 
    264     _registry => undef, 
    265  
    266     # Contains the Filesystem object, once initialized. 
    267     # (For internal use only.) 
    268     _filesystem => undef, 
    269  
    270     # XXX: comment this 
    271     _changes_found_file => getVar(name => 'changes_found_file'), 
    272  
    273     # XXX: comment this 
    274     _realtime_changes_file => getVar(name => 'realtime_changes_file'), 
    275  
    276 ); 
    277284 
    278285####################################################################### 
     
    289296    # the Registry object creates new files that must exist to be added to the 
    290297    # Filesystem's baseline list of files that exist on the system. 
    291    $self->{'_registry'} = HoneyClient::Agent::Integrity::Registry->new(); 
     298    $self->{'_registry'} = HoneyClient::Agent::Integrity::Registry->new(); 
    292299    $self->{'_filesystem'} = HoneyClient::Agent::Integrity::Filesystem->new(); 
    293300} 
     
    334341diag("Performing baseline check of the system; this may take some time..."); 
    335342 
    336 # XXX: Uncomment this next check, eventually.  (It's commented out right now, in order to save some time). 
    337343# Perform baseline. 
    338344$integrity = HoneyClient::Agent::Integrity->new(); 
    339345isa_ok($integrity, 'HoneyClient::Agent::Integrity', "new()") or diag("The new() call failed."); 
     346$integrity->destroy(); 
    340347 
    341348=end testing 
     
    349356    # 
    350357    # - For each parameter given, it overwrites any corresponding 
    351     #   parameters specified within the default hashtable, %PARAMS,  
     358    #   parameters specified within the default hashtable, %params,  
    352359    #   with custom entries that were given as parameters. 
    353360    # 
     
    369376    # Initialize default parameters. 
    370377    $self = { }; 
    371     my %params = %{dclone(\%PARAMS)}; 
     378    my %params = ( 
     379        # When set to 1, the object will forgo any type of initial baselining 
     380        # process, upon initialization.  Otherwise, baselining will occur 
     381        # as normal, upon initialization. 
     382        # XXX: Bypass static baselining, for now. 
     383        # XXX: Baselining will not be used with the current version which includes Capture 
     384        bypass_baseline => 1, 
     385 
     386        # Contains the Registry object, once initialized. 
     387        # (For internal use only.) 
     388        _registry => undef, 
     389 
     390        # Contains the Filesystem object, once initialized. 
     391        # (For internal use only.) 
     392        _filesystem => undef, 
     393 
     394        # A string to the absolute path of a file on the VM's filesystem. 
     395        # When an integrity check fails, all changes will be written to this 
     396        # file within the compromized honeyclient VM's filesystem. 
     397        changes_found_file => getVar(name => 'changes_found_file'), 
     398     
     399        # XXX: comment this 
     400        realtime_changes_file => getVar(name => 'realtime_changes_file'), 
     401    ); 
     402 
    372403    @{$self}{keys %params} = values %params; 
    373404 
     
    404435hashtable has the following format: 
    405436 
    406 $changes = { 
     437  $changes = { 
    407438    #A reference to an anonymous array of process objects 
    408439    processes => [ { 
     
    456487        file_system => [ { 
    457488            #The full path and name of the file which was effected 
    458            'name'  => 'C:\WINDOWS\SYSTEM32...', 
     489            'name'  => 'C:\WINDOWS\SYSTEM32...', 
    459490 
    460491            'event_type' => { Deleted | Read | Write }, #TODO: add created & renamed/moved 
    461492 
    462493            'time' => ISO 8601 Timestamp,  
    463             
     494             
    464495            #OPTIONAL, this will not exist for deleted files 
    465            'content' => { 
    466                'size' => 1234,                                       # size of new content 
    467                'type' => 'application/octect-stream',                # type of new content 
    468                'md5'  => 'b1946ac92492d2347c6235b4d2611184',         # md5  of new content 
    469                'sha1' => 'f572d396fae9206628714fb2ce00f72e94f2258f', # sha1 of new content 
    470            }, 
     496            'content' => { 
     497                'size' => 1234,                                       # size of new content 
     498                'type' => 'application/octect-stream',                # type of new content 
     499                'md5'  => 'b1946ac92492d2347c6235b4d2611184',         # md5  of new content 
     500                'sha1' => 'f572d396fae9206628714fb2ce00f72e94f2258f', # sha1 of new content 
     501            }, 
    471502        },] 
    472503    },] 
    473 
     504 
    474505 
    475506I<Notes>: 
    476507 
    477508=back 
    478  
    479 #=begin testing 
    480 # 
    481 # TODO: 
    482 # 
    483 #=end testing 
    484509 
    485510=cut 
     
    506531    }); 
    507532 
    508 #  my $changes = { 
     533#    my $changes = { 
    509534#        'registry' => $self->{'_registry'}->check(), 
    510535#        'filesystem' => $self->{'_filesystem'}->check(), 
    511536#    }; 
    512537#XENO - BEGIN REPLACEMENT WITH CAPTURE-READING CODE 
    513     my $change_file_name = $self->{_realtime_changes_file}; 
     538    my $change_file_name = $self->{realtime_changes_file}; 
    514539    my %changes; 
    515540    my @capdump; 
     
    670695                        }; 
    671696                        my $tmp_name = $toks[$F_NAME]; 
    672                        eval{ 
     697                        eval{ 
    673698                            if(-f $tmp_name){ 
    674699                                my $md5_ctx  = Digest::MD5->new(); 
     
    680705                                my $size = 0; 
    681706                                my $fh = IO::File->new($tmp_name, "r"); 
    682                                #print "md5ing $tmp_name\n"; 
    683                                # Compute MD5 Checksum. 
    684                                $md5_ctx->addfile($fh); 
    685                                $md5 = $md5_ctx->hexdigest(); 
    686      
    687                                # Rewind file handle. 
    688                                seek($fh, 0, 0); 
    689      
    690                                #print "sha1ing $tmp_name\n"; 
    691                                # Compute SHA1 Checksum. 
    692                                $sha1_ctx->addfile($fh); 
    693                                $sha1 = $sha1_ctx->hexdigest(); 
    694         
    695                                #Compute file size 
    696                                $size = -s $tmp_name; 
    697         
    698                                # Compute File Type. 
    699                                $type = $type_ctx->mime_type($tmp_name); 
    700         
    701                                # Close the file handle. 
    702                                undef $fh; 
     707                                #print "md5ing $tmp_name\n"; 
     708                                # Compute MD5 Checksum. 
     709                                $md5_ctx->addfile($fh); 
     710                                $md5 = $md5_ctx->hexdigest(); 
     711     
     712                                # Rewind file handle. 
     713                                seek($fh, 0, 0); 
     714     
     715                                #print "sha1ing $tmp_name\n"; 
     716                                # Compute SHA1 Checksum. 
     717                                $sha1_ctx->addfile($fh); 
     718                                $sha1 = $sha1_ctx->hexdigest(); 
     719         
     720                                #Compute file size 
     721                                $size = -s $tmp_name; 
     722         
     723                                # Compute File Type. 
     724                                $type = $type_ctx->mime_type($tmp_name); 
     725         
     726                                # Close the file handle. 
     727                                undef $fh; 
    703728                                $file_obj->{'contents'}->{'size'} = $size; 
    704729                                $file_obj->{'contents'}->{'md5'} = $md5; 
     
    738763    # filesystem. 
    739764    if (scalar($changes{'processes'})){ 
    740         if (!open(CHANGE_FILE, ">>" . $self->{_changes_found_file})) { 
    741             $LOG->error("Unable to write changes to file '" . $self->{_changes_found_file} . "'."); 
     765        if (!open(CHANGE_FILE, ">>" . $self->{changes_found_file})) { 
     766            $LOG->error("Unable to write changes to file '" . $self->{changes_found_file} . "'."); 
    742767        } else { 
    743768            $Data::Dumper::Terse = 1; 
     
    749774    } 
    750775 
    751    return \%changes; 
     776    return \%changes; 
    752777} 
    753778 
     779# TODO: Comment this. 
    754780# This function looks for if there is already a process object with the given pid and name 
    755781# and if it exists, returns its index in the processes array 
     
    777803} 
    778804 
    779  
    780  
    781 # TODO: Comment this. 
     805=pod 
     806 
     807=head2 $object->closeFiles() 
     808 
     809=over 4 
     810 
     811Closes any temporary files that may have been created by any 
     812of the Integrity::* sub-modules.  By performing this operation, 
     813the Integrity B<$object> can become serializable. 
     814 
     815=back 
     816 
     817=cut 
     818 
    782819sub closeFiles { 
    783820    my $self = shift; 
     
    796833} 
    797834 
    798 # TODO: Comment this. 
     835=pod 
     836 
     837=head2 $object->destroy() 
     838 
     839=over 4 
     840 
     841Destroys any temporary files that have been created by any 
     842of the Integrity::* sub-modules.  By performing this operation, 
     843the Integrity B<$object> can be released from memory without 
     844leaving any residual temporary files on the filesystem. 
     845 
     846=back 
     847 
     848=cut 
     849 
    799850sub destroy { 
    800851    my $self = shift; 
     
    819870=head1 BUGS & ASSUMPTIONS 
    820871 
    821 We assume that because of the short time in which malware is allowed to run 
    822 we can never see the same name:pid pair twice, because there will not have been 
    823 enough processes created in order to wrap the pid numbers back around. 
     872When performing an integrity check, this library assumes that it will never 
     873see the same process name and process ID (PID) pair twice, because the malware 
     874will not have had enough time to create processes that cause the OS to reissue 
     875the same PIDs again. 
     876 
     877For a complete list of when these checks may fail, see the following sections: 
     878 
     879=over 4 
     880 
     881=item * 
     882 
     883L<HoneyClient::Agent::Integrity::Registry/"BUGS & ASSUMPTIONS"> 
     884 
     885=item * 
     886 
     887L<HoneyClient::Agent::Integrity::Filesystem/"BUGS & ASSUMPTIONS"> 
     888 
     889=back 
     890 
     891=head1 TODO 
     892 
     893The following sub-modules are still a work-in-progress: 
     894 
     895=over 4 
     896 
     897=item * 
     898 
     899Real-time filesystem detection. 
     900 
     901=item * 
     902 
     903Real-time registry detection. 
     904 
     905=item * 
     906 
     907Static and/or real-time rogue process detection. 
     908 
     909=item * 
     910 
     911Static and/or real-time memory alteration detection. 
     912 
     913=back 
    824914 
    825915=head1 SEE ALSO 
     
    833923=head1 ACKNOWLEDGEMENTS 
    834924 
    835 The Capture client-side honeypot team is responsible for creating the code which outputs 
    836 the system events that this reads in in the event of a compromise. 
     925Christian Seifert E<lt>cseifert@mcs.vuw.ac.nzE<gt> and Ramon Steenson 
     926E<lt>rsteenson@gmail.comE<gt> from the Victoria University of Wellington, 
     927for their work on the Capture Client-Side Honeypot, which is used to 
     928obtain kernel-level system events from Windows in the event of a compromise. 
     929 
     930L<http://www.client-honeynet.org/capture.html> 
    837931 
    838932=head1 AUTHORS 
     
    845939 
    846940Brad Stephenson, E<lt>stephenson@mitre.orgE<gt> 
    847  
    848 Thanh Truong, E<lt>ttruong@mitre.orgE<gt> 
    849941 
    850942=head1 COPYRIGHT & LICENSE 
  • honeyclient/trunk/lib/HoneyClient/Agent/Integrity/Filesystem.pm

    r994 r1008  
    175175=begin testing 
    176176 
     177# Make sure ExtUtils::MakeMaker loads. 
     178BEGIN { use_ok('ExtUtils::MakeMaker', qw(prompt)) or diag("Can't load ExtUtils::MakeMaker package.  Check to make sure the package library is correctly listed within the path."); } 
     179require_ok('ExtUtils::MakeMaker'); 
     180can_ok('ExtUtils::MakeMaker', 'prompt'); 
     181use ExtUtils::MakeMaker qw(prompt); 
     182 
    177183# Make sure Log::Log4perl loads 
    178184BEGIN { use_ok('Log::Log4perl', qw(:nowarn)) 
     
    358364 
    359365=cut 
    360  
    361 my %PARAMS = ( 
    362     # When set to 1, the object will forgo any type of initial baselining 
    363     # process, upon initialization.  Otherwise, baselining will occur