Changeset 1087

Show
Ignore:
Timestamp:
12/30/07 14:50:17 (11 months ago)
Author:
xkovah
Message:

still underway…just checking in to save

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • honeyclient/branches/exp/xkovah-priority_interrupt/etc/honeyclient.xml

    r1083 r1087  
    377377            3 
    378378        </max_agent_error_count> 
     379        <priority_links_file description="File path (absolute, or relative to manager) to a file which can contain links which should be visited ASAP, by interrupting the existing agent which is running" default="../../../priority_links.txt"> 
     380        ../../../priority_links.txt 
     381        </priority_links_file> 
    379382        <!-- HoneyClient::Manager::FW Options --> 
    380383        <FW> 
  • honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Agent.pm

    r1012 r1087  
    11891189} 
    11901190 
     1191 
     1192sub setPriorityLinksStatus{ 
     1193    my ($junk, $val) = @_; 
     1194    my $data = _lock(); 
     1195 
     1196     
     1197    _unlock($data); 
     1198} 
     1199 
    11911200# XXX: Document this. 
    11921201# XXX: Do we really need this? 
  • honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Agent/Driver/Browser.pm

    r1082 r1087  
    451451# 
    452452# When getting the next link, 'next_link_to_visit' is checked first. 
    453 # If that value is undef, then the 'relative_links_to_visit' hashtable 
     453# If that value is undef, then the 'priority_links' hashtable is  
     454# checked next. If that is empty, then 'relative_links_to_visit' 
    454455# is checked next.  If that hashtable is empty, then finally the 
    455456# 'links_to_visit' hashtable is checked. 
     
    898899        links_timed_out         => { }, 
    899900 
     901        # 
     902        priority_links  => { }, 
     903 
     904 
    900905        # If this parameter is a defined scalar, then the browser 
    901906        # will also never attempt to revisit any links that caused 
     
    16481653    return (!(defined($self->next_link_to_visit) or 
    16491654              scalar(%{$self->relative_links_to_visit}) or 
     1655              scalar(%{$self->priority_links}) or 
    16501656              scalar(%{$self->links_to_visit}))) 
    16511657 
     
    17271733                                          $next_link_is_set; 
    17281734 
     1735    # Figure out how many priority links are left to process. 
     1736    #FIXME: Should this have + $next_link_is_set? 
     1737    $status->{priority_links_remaining} = scalar(keys(%{$self->priority_links})) + $next_link_is_set; 
     1738     
    17291739    # Figure out how many total links are left to process. 
    1730     $status->{links_remaining} = $status->{relative_links_remaining} + 
    1731                                  scalar(keys(%{$self->links_to_visit})); 
    1732   
     1740    if($status->{priority_links_remaining} > 0){ 
     1741        #NOTE: This is tied to the assumption that we always want to visit priority links  
     1742        #by themselves (with the equivalent of limit_spidering on) before finishing that run 
     1743        $status->{links_remaining} = $status->{priority_links_remaining}; 
     1744    } 
     1745    else{ 
     1746        $status->{links_remaining} = $status->{relative_links_remaining} +  
     1747                                scalar(keys(%{$self->links_to_visit})); 
     1748    } 
    17331749    # Set the total number of links in the object's state. 
    17341750    $status->{links_total} = $status->{links_processed} + 
  • honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Manager.pm

    r1086 r1087  
    2828####################################################################### 
    2929 
    30 =pod 
    31  
    32 =head1 NAME 
    33  
    34 HoneyClient::Manager - Perl extension to manage Agent VMs on the 
    35 host system. 
    36  
    37 =head1 VERSION 
    38  
    39 This documentation refers to HoneyClient::Manager version 1.00. 
    40  
    41 =head1 SYNOPSIS 
    42  
    43   use HoneyClient::Manager; 
    44   use Data::Dumper; 
    45  
    46   # Utility functions to encode configuration data. 
    47   use Storable qw(nfreeze thaw); 
    48   use MIME::Base64 qw(encode_base64 decode_base64); 
    49  
    50   # Note: Make sure only one of these "my driver =" lines 
    51   # is uncommented. 
    52  
    53   # Use Internet Explorer as the instrumenting application. 
    54   my $driver = "HoneyClient::Agent::Driver::Browser::IE"; 
    55  
    56   # Use Mozilla Firefox as the instrumenting application. 
    57   #my $driver = "HoneyClient::Agent::Driver::Browser::FF"; 
    58  
    59   # Start the Manager. 
    60   HoneyClient::Manager->run( 
    61  
    62       driver => $driver, 
    63  
    64       agent_state => encode_base64(nfreeze({ 
    65  
    66           $driver => { 
    67  
    68               # Specify the next link for the Agent VM to visit. 
    69               next_link_to_visit => "http://www.mitre.org", 
    70  
    71               # If you have more than one link, you can also 
    72               # set this type of hashtable: 
    73               links_to_visit => { 
    74                   'http://www.google.com' => 1, 
    75               }, 
    76           }, 
    77  
    78       })), 
    79   ); 
    80  
    81 =head1 DESCRIPTION 
    82  
    83 This module provides centralized control over provisioning, initializing, 
    84 running, and suspending all Agent VMs.  Upon calling the run() function, 
    85 the Manager will proceed to create a new clone of the master Honeyclient VM 
    86 (aka. an Agent VM) and feed this Agent VM a new list of URLs to crawl. 
    87  
    88 While the Agent VM is crawling, the Manager will check to make sure the 
    89 Agent VM has not been compromised.  If no compromise was found, then the 
    90 Manager will signal the Firewall to allow the Agent VM to contact the 
    91 next set of network resources (i.e., a webserver). 
    92  
    93 If the Manager discovers the Agent VM has been compromised, then the 
    94 Manager will suspend the clone VM, log the incident, and create a new Agent 
    95 VM clone -- where this new clone picks up with the next set of URLs to 
    96 crawl. 
    97  
    98 If there are no URLs left for the Agent VM to visit OR if the user 
    99 presses CTRL+C while the Manager is running, then the Manager will 
    100 suspend the currently running Agent VM and write its state information 
    101 out to the filesystem on the host system.  This file is usually 
    102 called 'Manager.dump'; however, the name can be changed by editing 
    103 the <HoneyClient/><Manager/><manager_state/> section of the 
    104 etc/honeyclient.xml file. 
    105  
    106 This 'Manager.dump' file contains the set of URLs that the Honeyclients 
    107 have visited, ignored, or tried to visit.  In order to determine 
    108 which URLs were identified as malicious, you will need to check 
    109 the syslog on the host system and search for the keyword of "FAILED". 
    110  
    111 By default, all cloned VMs that the Manager suspends will have been 
    112 flagged as compromised -- unless the set of URLs has been exhausted 
    113 or the user prematurely terminates the process (by pressing CTRL+C). 
    114  
    115 =cut 
    11630 
    11731package HoneyClient::Manager; 
     
    16175our (@EXPORT_OK, $VERSION); 
    16276 
    163 =pod 
    164  
    165 =begin testing 
    166  
    167 # Make sure ExtUtils::MakeMaker loads. 
    168 BEGIN { 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."); } 
    169 require_ok('ExtUtils::MakeMaker'); 
    170 can_ok('ExtUtils::MakeMaker', 'prompt'); 
    171 use ExtUtils::MakeMaker qw(prompt); 
    172  
    173 # Make sure Log::Log4perl loads 
    174 BEGIN { use_ok('Log::Log4perl', qw(:nowarn)) 
    175         or diag("Can't load Log::Log4perl package. Check to make sure the package library is correctly listed within the path."); 
    176         
    177         # Suppress all logging messages, since we need clean output for unit testing. 
    178         Log::Log4perl->init({ 
    179             "log4perl.rootLogger"                               => "DEBUG, Buffer", 
    180             "log4perl.appender.Buffer"                          => "Log::Log4perl::Appender::TestBuffer", 
    181             "log4perl.appender.Buffer.min_level"                => "fatal", 
    182             "log4perl.appender.Buffer.layout"                   => "Log::Log4perl::Layout::PatternLayout", 
    183             "log4perl.appender.Buffer.layout.ConversionPattern" => "%d{yyyy-MM-dd HH:mm:ss} %5p [%M] (%F:%L) - %m%n", 
    184         }); 
    185 } 
    186 require_ok('Log::Log4perl'); 
    187 use Log::Log4perl qw(:easy); 
    188  
    189 # Make sure HoneyClient::Util::Config loads. 
    190 BEGIN { use_ok('HoneyClient::Util::Config', qw(getVar)) 
    191         or diag("Can't load HoneyClient::Util::Config package.  Check to make sure the package library is correctly listed within the path."); 
    192  
    193         # Suppress all logging messages, since we need clean output for unit testing. 
    194         Log::Log4perl->init({ 
    195             "log4perl.rootLogger"                               => "DEBUG, Buffer", 
    196             "log4perl.appender.Buffer"                          => "Log::Log4perl::Appender::TestBuffer", 
    197             "log4perl.appender.Buffer.min_level"                => "fatal", 
    198             "log4perl.appender.Buffer.layout"                   => "Log::Log4perl::Layout::PatternLayout", 
    199             "log4perl.appender.Buffer.layout.ConversionPattern" => "%d{yyyy-MM-dd HH:mm:ss} %5p [%M] (%F:%L) - %m%n", 
    200         }); 
    201 } 
    202 require_ok('HoneyClient::Util::Config'); 
    203 can_ok('HoneyClient::Util::Config', 'getVar'); 
    204 use HoneyClient::Util::Config qw(getVar); 
    205  
    206 # Suppress all logging messages, since we need clean output for unit testing. 
    207 Log::Log4perl->init({ 
    208     "log4perl.rootLogger"                               => "DEBUG, Buffer", 
    209     "log4perl.appender.Buffer"                          => "Log::Log4perl::Appender::TestBuffer", 
    210     "log4perl.appender.Buffer.min_level"                => "fatal", 
    211     "log4perl.appender.Buffer.layout"                   => "Log::Log4perl::Layout::PatternLayout", 
    212     "log4perl.appender.Buffer.layout.ConversionPattern" => "%d{yyyy-MM-dd HH:mm:ss} %5p [%M] (%F:%L) - %m%n", 
    213 }); 
    214  
    215 # Make sure the module loads properly, with the exportable 
    216 # functions shared. 
    217 BEGIN { use_ok('HoneyClient::Manager', qw(init destroy)) or diag("Can't load HoneyClient::Manager package.  Check to make sure the package library is correctly listed within the path."); } 
    218 require_ok('HoneyClient::Manager'); 
    219 can_ok('HoneyClient::Manager', 'init'); 
    220 can_ok('HoneyClient::Manager', 'destroy'); 
    221 use HoneyClient::Manager qw(init destroy); 
    222  
    223 # Make sure HonyClient::Manager::VM::Clone loads. 
    224 BEGIN { use_ok('HoneyClient::Manager::VM::Clone') or diag("Can't load HoneyClient::Manager::VM::Clone package.  Check to make sure the package library is correctly listed within the path."); } 
    225 require_ok('HoneyClient::Manager::VM::Clone'); 
    226 use HoneyClient::Manager::VM::Clone; 
    227  
    228 # Make sure HoneyClient::Util::SOAP loads. 
    229 BEGIN { use_ok('HoneyClient::Util::SOAP', qw(getServerHandle getClientHandle)) or diag("Can't load HoneyClient::Util::SOAP package.  Check to make sure the package library is correctly listed within the path."); } 
    230 require_ok('HoneyClient::Util::SOAP'); 
    231 can_ok('HoneyClient::Util::SOAP', 'getServerHandle'); 
    232 can_ok('HoneyClient::Util::SOAP', 'getClientHandle'); 
    233 use HoneyClient::Util::SOAP qw(getServerHandle getClientHandle); 
    234  
    235 # Make sure HoneyClient::Util::Config loads. 
    236 BEGIN { use_ok('HoneyClient::Util::Config', qw(getVar)) or diag("Can't load HoneyClient::Util::Config package.  Check to make sure the package library is correctly listed within the path."); } 
    237 require_ok('HoneyClient::Util::Config'); 
    238 can_ok('HoneyClient::Util::Config', 'getVar'); 
    239 use HoneyClient::Util::Config qw(getVar); 
    240  
    241 # Check if HoneyClient::DB support is enabled.  
    242 my $DB_ENABLE = getVar(name      => "enable", 
    243                        namespace => "HoneyClient::DB"); 
    244  
    245 if ($DB_ENABLE) { 
    246     # Make sure HoneyClient::DB::Fingerprint loads.  
    247     require_ok('HoneyClient::DB::Fingerprint'); 
    248     require HoneyClient::DB::Fingerprint; 
    249 } 
    250  
    251 # Make sure Storable loads. 
    252 BEGIN { use_ok('Storable', qw(nfreeze thaw)) or diag("Can't load Storable package.  Check to make sure the package library is correctly listed within the path."); } 
    253 require_ok('Storable'); 
    254 can_ok('Storable', 'nfreeze'); 
    255 can_ok('Storable', 'thaw'); 
    256 use Storable qw(nfreeze thaw); 
    257  
    258 # Make sure MIME::Base64 loads. 
    259 BEGIN { use_ok('MIME::Base64', qw(encode_base64 decode_base64)) or diag("Can't load MIME::Base64 package.  Check to make sure the package library is correctly listed within the path."); } 
    260 require_ok('MIME::Base64'); 
    261 can_ok('MIME::Base64', 'encode_base64'); 
    262 can_ok('MIME::Base64', 'decode_base64'); 
    263 use MIME::Base64 qw(encode_base64 decode_base64); 
    264  
    265 =end testing 
    266  
    267 =cut 
    26877 
    26978####################################################################### 
     
    28190use HoneyClient::Util::Config qw(getVar); 
    28291 
    283 # Include the VM Utility Libraries 
    284 use HoneyClient::Manager::VM::Clone; 
    285  
    286 # XXX: Remove this, eventually. 
    287 # TODO: Include unit tests. 
    288 use HoneyClient::Manager::VM qw(); 
    289  
    290 # Check if HoneyClient::DB support is enabled.  
    291 our $DB_ENABLE = getVar(name      => "enable", 
    292                         namespace => "HoneyClient::DB"); 
    293 our $clientDbId = 0; 
    29492our %link_categories; 
    29593 
    296 if ($DB_ENABLE) { 
    297     # Include HoneyClient::DB Utility Libraries 
    298     # TODO: Include unit tests. 
    299     require HoneyClient::DB::Fingerprint; 
    300     require HoneyClient::DB::Client; 
    301     require HoneyClient::DB::Url::History; 
    302     require HoneyClient::DB::Time; 
    303     %link_categories = ( 
    304         $HoneyClient::DB::Url::History::STATUS_VISITED => 'links_visited', 
    305         $HoneyClient::DB::Url::History::STATUS_TIMED_OUT => 'links_timed_out', 
    306 # For the time being, ignored links will not be inserted. 
    307 #       $HoneyClient::DB::Url::History::STATUS_IGNORED => 'links_ignored', 
    308     ); 
    309 } 
    31094 
    31195# XXX: Remove this, eventually. 
     
    325109use Storable qw(nfreeze thaw); 
    326110 
    327 # Include VmPerl Constants. 
    328 # TODO: Include unit tests. 
    329 use VMware::VmPerl qw(VM_EXECUTION_STATE_ON 
    330                       VM_EXECUTION_STATE_OFF 
    331                       VM_EXECUTION_STATE_STUCK 
    332                       VM_EXECUTION_STATE_SUSPENDED); 
    333  
    334111# TODO: Include unit tests. 
    335112use IO::File; 
     
    339116 
    340117# TODO: Include unit tests. 
    341 use Sys::Hostname::Long; 
     118#use Sys::Hostname::Long; 
    342119 
    343120# TODO: Include unit tests. 
    344 use Sys::HostIP; 
     121#use Sys::HostIP; 
    345122 
    346123# Include Logging Library 
    347 use Log::Log4perl qw(:easy); 
    348  
    349 # The global logging object. 
    350 our $LOG = get_logger(); 
     124#use Log::Log4perl qw(:easy); 
    351125 
    352126# Complete URL of SOAP server, when initialized. 
     
    357131our $DAEMON_PID     : shared = undef; 
    358132 
    359 # XXX: These will be migrated somewhere else, eventually. 
    360 our $vmCloneConfig      = undef; 
    361133 
    362134# This is a temporary, shared variable, used to print out the 
     
    365137# eventually. 
    366138our $globalAgentState   = undef; 
    367  
    368 #This variable is used to count how many times stubAgent's fault 
    369 #handler has been called, so that special actions can be taken if 
    370 #it is called too many times (for instance when Manager loses  
    371 #connectivity with the Agent it would otherwise loop and get errors 
    372 #forever if some action isn't taken) 
    373 #NOTE: This will have to be changed to be agent/vm-specific in the 
    374 #future when we have multiple Agents interacting with a single  
    375 #Manager. 
    376 our $globalAgentErrorCount = 0
     139our $globalAgentStateInWaiting   = undef; 
     140 
     141#our $priority_links_to_visit = 0; 
     142#our %priority_links = (); 
     143#FIXME: This should by putting the links into the agent driver state 
     144#Global error count for determining when to stop trying to contact the agent 
     145our $G_error_count = 0; 
     146 
     147#The file which is checked to see if there are priority links to visit 
     148our $priority_links_file = getVar(name => "priority_links_file")
    377149 
    378150# Temporary variable, used to indicate to the fault handler whether 
     
    468240 
    469241 
    470     #NOTE: In the future we may want to have this check first to see if 
    471     #the error is specific to a failed connection (by regexing the error 
    472     #message. But for now, we have no evidence that multiple errors will 
    473     #occur in other circumstances. 
    474     $globalAgentErrorCount++; 
    475  
     242    $G_error_count++; 
     243    print "G_error_count = $G_error_count\n"; 
    476244    # Construct error message. 
    477245    # Figure out if the error occurred in transport or over 
     
    484252 
    485253    if (!$SUPPRESS_ERRORS) { 
    486         $LOG->warn("Error occurred during processing. " . $errMsg); 
    487254        Carp::carp __PACKAGE__ . "->_handleFault(): Error occurred during processing.\n" . $errMsg; 
    488255    } 
     
    504271 
    505272    if (!$SUPPRESS_ERRORS) { 
    506         $LOG->warn("Error occurred during processing. " . $errMsg); 
    507273        Carp::carp __PACKAGE__ . "->_handleFault(): Error occurred during processing.\n" . $errMsg; 
    508274    } 
     
    523289sub _cleanup { 
    524290 
    525     $LOG->info("Cleaning up."); 
    526291 
    527292    # Mask all possible signals, so that we don't call this function multiple times. 
     
    533298    $SIG{TERM}    = sub { }; 
    534299 
    535     # XXX: Need to clean this up. 
    536     my $stubFW = getClientHandle(namespace     => "HoneyClient::Manager::FW"); 
    537  
    538     # XXX: Change this to installDefaultRules(), eventually. 
    539     # Reset the firewall, to allow everything open. 
    540     $stubFW->allowAllTraffic(); 
    541300 
    542301    # This variable may contain a filename that the Manager 
     
    547306    if (length($STATE_FILE) > 0 && 
    548307        defined($globalAgentState)) { 
    549         $LOG->info("Saving state to '" . $STATE_FILE . "'."); 
    550308        my $dump_file = new IO::File($STATE_FILE, "a"); 
    551309 
     
    556314        $dump_file->close(); 
    557315    } 
    558     #XXX: Insert Urls. To be moved eventually. 
    559     if ($DB_ENABLE && ($clientDbId > 0)) { 
    560         $LOG->info("Saving Url History to Database."); 
    561         insert_url_history(agent_state => $globalAgentState); 
    562         HoneyClient::DB::Client->update( 
    563             '-set' => { 
    564                 status => $HoneyClient::DB::Client::STATUS_CLEAN, 
    565             }, 
    566             '-where' => { 
    567                 id => $clientDbId, 
    568             } 
    569         ); 
    570     } 
    571316 
    572317    # XXX: There is an issue where if we try to quit but are in the 
     
    630375    # set. 
    631376    my $argsExist = scalar(%args); 
    632     if (!$argsExist || 
    633         !exists($args{'master_vm_config'}) || 
    634         !defined($args{'master_vm_config'})) { 
    635         # Get the master_vm_config from the configuration file. 
    636         $args{'master_vm_config'} = getVar(name      => "master_vm_config", 
    637                                            namespace => "HoneyClient::Manager::VM"); 
    638     } 
     377 
     378    print "I am the ALPHA\n"; 
     379    print Dumper($args{'agent_state'}); 
    639380 
    640381    for (;;) { 
     
    642383        $agentState = $class->runSession(%args); 
    643384        $args{'agent_state'} = $agentState; 
    644  
    645385        # XXX: Delete this, eventually. 
    646386        $globalAgentState = $agentState; 
    647387 
    648         #$Data::Dumper::Terse = 0; 
    649         #$Data::Dumper::Indent = 2; 
    650         #print Dumper(thaw(decode_base64($agentState))); 
     388        $Data::Dumper::Terse = 0; 
     389        $Data::Dumper::Indent = 1; 
     390        print "agentState in run()\n"; 
     391        print Dumper(thaw(decode_base64($agentState))); 
    651392    } 
    652393} 
     394 
    653395 
    654396sub runSession { 
     
    661403 
    662404# XXX: Remove some of these, eventually. 
    663     my $stubVM    = undef; 
    664     my $stubFW    = undef; 
    665405    my $stubAgent = undef; 
    666406    my $som       = undef; 
    667407    my $ret       = undef; 
    668     #DELETE ME UNUSED my $vmName    = undef; 
    669     #DELETE ME UNUSED my $URL       = undef; 
    670     #DELETE ME UNUSED my $vmState   = undef; 
     408    my $vmName    = undef; 
     409    my $URL       = undef; 
     410    my $vmState   = undef; 
    671411    my $vmCompromised = 0; 
    672     my $vmStateTable = { }; 
    673  
    674     # Temporary variable to hold each cloned VM. 
    675     my $vm        = undef; 
    676  
    677     # Get a stub connection to the firewall. 
    678     $stubFW = getClientHandle(namespace     => "HoneyClient::Manager::FW", 
    679                               fault_handler => \&_handleFaultAndCleanup); 
    680  
    681     # Open up the firewall initially, to allow the Agent to do an SVN update. 
    682     #FIXME: This needs to be more limited for the multi-vm case, and should probably  
    683     # just be included by making the default rules require no action 
    684     $stubFW->allowAllTraffic(); 
    685  
    686     # Create a new cloned VM. 
    687     $vm = HoneyClient::Manager::VM::Clone->new(master_vm_config => $args{'master_vm_config'}); 
    688  
    689     #Register Client with the Honeyclient Database 
    690     if ($DB_ENABLE) { 
    691         eval { 
    692             $clientDbId = dbRegisterClient($vm->name); 
    693         }; 
    694         if ($@) { 
    695             $clientDbId = 0; #$DB_FAILURE 
    696             $LOG->warn("Failure Inserting Client Object:\n$@"); 
    697         } 
    698     } 
     412    my %vmStateTable; 
    699413 
    700414    # Build our VM's connection table. 
    701415    # Note: We assume our VM has a single MAC address 
    702416    # and a single IP address. 
    703     $vmStateTable->{$vm->name}->{sources}->{$vm->mac_address}->{$vm->ip_address} = { 
     417    $vmStateTable{"127.0.0.1"} = { 
    704418        # XXX: We assume we can't pinpoint what source TCP ports the 
    705419        # corresponding driver will need.  (We may want to get this 
     
    712426    $Data::Dumper::Terse = 0; 
    713427    $Data::Dumper::Indent = 2; 
    714     print Dumper($vmStateTable) . "\n"; 
     428    print Dumper(\%vmStateTable) . "\n"; 
    715429   
    716     # Initialize the firewall. 
    717     $stubFW->installDefaultRules(); 
    718  
    719     # Add new chain, per cloned VM. 
    720     $stubFW->addChain($vmStateTable); 
    721     
    722430    sleep (2); 
    723431 
    724432    # Recreate the client stub; handle faults. 
    725433    $stubAgent = getClientHandle(namespace     => "HoneyClient::Agent", 
    726                                  address       => $vm->ip_address
     434                                 address       => "127.0.0.1"
    727435                                 fault_handler => \&_handleFaultAndCleanup); 
    728436 
     
    731439    # from user input. 
    732440    print "Calling updateState()...\n"; 
     441    print "YOU MUST BE AT LEAST THIS COMPLETE TO RIDE THE UPDATESTATE\n"; 
     442    print Dumper($args{'agent_state'}); 
    733443    $som = $stubAgent->updateState($args{'agent_state'}); 
    734444 
    735445    # Recreate the client stub; ignore faults. 
    736446    $stubAgent = getClientHandle(namespace     => "HoneyClient::Agent", 
    737                                  address       => $vm->ip_address
     447                                 address       => "127.0.0.1"
    738448                                 fault_handler => \&_agentHandleFault); 
    739  
    740     # Recreate the firewall stub; ignore faults. 
    741     $stubFW = getClientHandle(namespace     => "HoneyClient::Manager::FW", 
    742                               fault_handler => \&_handleFault); 
    743449 
    744450    for (my $counter = 1;; $counter++) { 
     
    748454        # assume that the Agent's watchdog process will recover. 
    749455        eval { 
     456 
    750457            print "Calling getState()...\n"; 
    751458            $som = $stubAgent->getState(); 
     
    761468            # Make Dumper format more verbose. 
    762469            $Data::Dumper::Terse = 0; 
    763             $Data::Dumper::Indent = 2; 
    764             print Dumper($ret->{$args{'driver'}}->{status}); 
    765             #print Dumper($ret); 
     470            $Data::Dumper::Indent = 1; 
     471            #print Dumper($ret->{$args{'driver'}}->{status}); 
     472            print "This is the full driverData\n"; 
     473            print Dumper($ret); 
     474 
     475            #Check if there are any priority links to start using 
     476            #TODO: In the future, this should also poll on the DB or other sources 
     477            _updatePriorityLinks($ret->{$args{'driver'}}); 
     478 
     479            #At this point, the driver could still be running, but we want to interrupt as soon 
     480            #as possible even though we may lose a little state. 
     481            if(scalar(keys %priority_links) > 0 && !$priority_links_to_visit){ 
     482                #The agent is still running, and is not compromised, but there are priority links 
     483                #to process. This means we need to save off the state of the running VM, and   
     484                #then suspend the VM, and start a new one with the priority links as targets 
     485                $globalAgentStateInWaiting = $globalAgentState; 
     486  
     487                print "Suspending VM ;)"; 
     488                return; # Return out of eval block. 
     489            } 
     490 
    766491 
    767492            # Check to see if Agent::run() thread has stopped 
     
    771496                    # Check to see if the VM has been compromised. 
    772497                    print "WARNING: VM HAS BEEN COMPROMISED!\n"; 
    773 #                    $LOG->info("Calling suspendVM(config => " . $vmCloneConfig . ")."); 
    774 #                    $som = $stubVM->suspendVM(config => $vmCloneConfig); 
    775 #                    HoneyClient::Manager::VM->destroy(); 
    776                     my $vmName = $vm->name; 
     498                    my $vmName = "1234"; 
    777499                    $vmCompromised = 1; 
    778500 
    779501                    my $fingerprint = $ret->{$args{'driver'}}->{status}->{fingerprint}; 
    780                     $LOG->warn("VM Compromised. Last Resource (" . $fingerprint->{'last_resource'} . ")"); 
    781502 
    782503                    # Dump the fingerprint to the compromise file, if needed. 
     
    785506                    if (length($COMPROMISE_FILE) > 0 && 
    786507                        defined($fingerprint)) { 
    787                         $LOG->info("Saving fingerprint to '" . $COMPROMISE_FILE . "'."); 
    788508                        my $dump_file = new IO::File($COMPROMISE_FILE, "a"); 
    789509 
     
    796516                    } 
    797517 
    798                     # Archive the VM. 
    799                     $LOG->info("Archiving VM..."); 
    800                     $vm->archive(); 
    801                     $vm = undef; 
    802  
    803                     # Insert Compromised Fingerprint into DB. 
    804                     if ($DB_ENABLE && ($clientDbId > 0)) { 
    805                         #XXX: This should occurr as a resource is accessed and will be moved. Also should be in Browser code. 
    806                         # Put Honeyclient Link History in database. 
    807                         $LOG->info("Saving Url History to Database."); 
    808                         $args{'agent_state'} = insert_url_history(agent_state => $args{'agent_state'}); 
    809                         $globalAgentState = $args{'agent_state'}; 
    810  
    811                         # Remove the compromise time from the fingerprint. This is to be added to the Client Object 
    812                         delete $fingerprint->{last_resource}; 
    813                         my $compromise_time = HoneyClient::DB::Time->new(delete($fingerprint->{'compromise_time'})); 
    814                         $LOG->info("Inserting Fingerprint Into Database."); 
    815                         my $fp = HoneyClient::DB::Fingerprint->new($fingerprint); 
    816                         my $fpId = $fp->insert(); 
    817                         my $ctId = $compromise_time->insert(); 
    818                         HoneyClient::DB::Client->update( 
    819                             '-set' => { 
    820                                 status => $HoneyClient::DB::Client::STATUS_COMPROMISED, 
    821                                 fingerprint => $fpId, 
    822                                 compromise_time => $ctId, 
    823                             }, 
    824                             '-where' => { 
    825                                 id => $clientDbId, 
    826                             } 
    827                         ); 
    828                         $LOG->info("Database Insert Successful."); 
    829                     } 
     518 
    830519                    return; # Return out of eval block. 
    831                 } else { 
     520                } 
     521                else { 
    832522                    print "VM Integrity Check: OK!\n"; 
    833523 
     
    836526                    if (!$ret->{$args{'driver'}}->{status}->{links_remaining}) { 
    837527 
    838                         $LOG->info("All URLs exhausted.  Shutting down Manager."); 
    839                         $vm = undef; 
    840528                        # Get a local copy of the configuration and kill the global copy. 
    841 #                        my $vmCfg = $vmCloneConfig; 
    842 #                        $vmCloneConfig = undef; 
    843 #                        $LOG->info("Calling suspendVM(config => " . $vmCfg . ")."); 
    844 #                        $stubVM->suspendVM(config => $vmCfg); 
    845529                        print "Done!\n"; 
    846530                        _cleanup(); 
     
    851535                        # to allow access to the new targets. 
    852536                 
    853                         # Delete the old firewall rules, based upon existing 
    854                         # targets. 
    855                         $stubFW->deleteRules($vmStateTable); 
    856537 
    857538                        # Get the new targets from the Agent. 
    858                         $vmStateTable->{$vm->name}->{targets} = $ret->{$args{'driver'}}->{next}->{targets}; 
    859                         #$vmStateTable->{$vm->name}->{targets} = '0.0.0.0'; 
     539                        $vmStateTable{targets} = $ret->{$args{'driver'}}->{next}->{targets}; 
    860540 
    861541                        print "VM State Table:\n"; 
     
    863543                        $Data::Dumper::Terse = 0; 
    864544                        $Data::Dumper::Indent = 2; 
    865                         print Dumper($vmStateTable) . "\n"; 
    866  
    867                         # Add the new targets from the Agent. 
    868                         $stubFW->addRules($vmStateTable); 
     545                        print Dumper(\%vmStateTable) . "\n"; 
    869546 
    870547                        print "Calling run()...\n"; 
     
    884561                    # the daemon, in which case, we indefinately try to reset the 
    885562                    # firewall accordingly. 
    886                     $stubFW->installDefaultRules(); 
    887                     $stubFW->addChain($vmStateTable); 
    888                     $stubFW->addRules($vmStateTable); 
    889563                }; 
    890564                if (!$@) { 
     
    897571        if ($vmCompromised) { 
    898572            # Reset the FW state table.  
    899             $vmStateTable = ( ); 
     573            %vmStateTable = ( ); 
    900574            return $args{'agent_state'}; 
    901575        } 
    902         if ($globalAgentErrorCount >= getVar(name => "max_agent_error_count")) { 
    903             $globalAgentErrorCount = 0; 
     576        if ($G_error_count >= 3) { 
     577            $G_error_count = 0; 
    904578            # Reset the FW state table.  
    905             $vmStateTable = ( ); 
     579            %vmStateTable = ( ); 
    906580            return $args{'agent_state'}; 
    907581        } 
     582        if(scalar(keys %priority_links) > 0){ 
     583            %vmStateTable = ( ); 
     584            #In this case, we want to suspend the VM and we need to build a  
     585            #new agentState which has only the links from the %priority_links 
     586            $args{agent_state}->links_to_visit = \%priority_links; 
     587 
     588  
     589        } 
     590 
    908591        print "Sleeping for 2s...\n"; 
    909592        sleep (2); 
     593    } #end infinite for loop 
     594} 
     595 
     596#helper for checking for priority links to interrupt the current run session 
     597sub _updatePriorityLinks { 
     598 
     599    $driverRef = shift; 
     600    $priority_links = $driverRef->{'state'}->{'priority_links'}; 
     601 
     602    if(-f $priority_links_file && -s $priority_links_file){ 
     603        open(PRIORITY, $priority_links_file); 
     604        while(<PRIORITY>){ 
     605            my $tmp = $_; 
     606            chomp($tmp); 
     607            $tmp =~ s/\r$//; 
     608            $priority_links{$tmp} = 1;  
     609        } 
     610        close(PRIORITY); 
     611        system("rm $priority_links_file"); #FIXME: make more generic 
    910612    } 
    911 
    912  
    913 sub insert_url_history { 
    914  
    915     # Extract arguments. 
    916     my %args = @_; 
    917  
    918     my $agent_state = thaw(decode_base64($args{'agent_state'})); 
    919  
    920     my $state; 
    921     my $agent_driver; 
    922     foreach my $driver (keys %$agent_state) { 
    923         if ($agent_state->{$driver}) { 
    924             $state = $agent_state->{$driver}; 
    925             $agent_driver = $driver; 
    926             last; 
    927         } 
    928     } 
    929  
    930     foreach my $i (keys %link_categories) { 
    931         my @url_history; 
    932         while (my ($url,$url_time) = each(%{$state->{$link_categories{$i}}})) { 
    933             # Don't insert already inserted URLs into DB. 
    934             if (!$url_time) { 
    935                 next; 
    936             } 
    937             # Some ignored links are the result of invalid Urls. Preprocess to avoid errors. 
    938             my $url_obj = HoneyClient::DB::Url->new($url); 
    939             next if (!$url_obj); 
    940             my $u = HoneyClient::DB::Url::History->new({ 
    941                 url => $url_obj, 
    942                 visited => $url_time, 
    943                 status => $i, 
    944             }); 
    945             push @url_history,$u; 
    946             # For all sucessfully inserted URLs, set their timestamps to 0. 
    947             $agent_state->{$agent_driver}->{$link_categories{$i}}->{$url} = 0; 
    948         } 
    949  
    950 # Update the History item to reflect the Client it belongs to. 
    951 # get_col_name is used to get the foreign key column associated w/ the url_history array 
    952         HoneyClient::DB::Client->append_children( 
    953             '-parent_id' => $clientDbId, 
    954             'url_history' => \@url_history, 
    955         ); 
    956         $LOG->info("Inserted Urls of type ".$link_categories{$i}); 
    957     } 
    958  
    959     return encode_base64(nfreeze($agent_state)); 
    960 
    961  
    962 sub dbRegisterClient { 
    963     my $vmName = shift; 
    964     my $dt = DateTime::HiRes->now(); 
    965  
    966     $LOG->info("Attempting to Register Client $vmName."); 
    967  
    968     # Register the VM with the DB 
    969     my $clientObj = HoneyClient::DB::Client->new({ 
    970         system_id => $vmName, 
    971         status => $HoneyClient::DB::Client::STATUS_RUNNING, 
    972         # TODO: Collect host,application, and config through automation/config files 
    973         host => { 
    974             organization => 'MITRE', 
    975             host_name => Sys::Hostname::Long::hostname_long, 
    976             ip_address => Sys::HostIP->ip, 
    977         }, 
    978         client_app => { 
    979             manufacturer => 'Microsoft', 
    980             name => 'Internet Explorer', 
    981             major_version => '6', 
    982         }, 
    983         config => { 
    984             name => 'Default Windows XP SP2', 
    985             os_name => 'Microsoft Windows', 
    986             os_version => 'XP Professional', 
    987             os_patches => [{ 
    988                 name => 'Service Pack 2', 
    989             }], 
    990         }, 
    991         start_time => $dt->ymd('-').'T'.$dt->hms(':'), 
    992     }); 
    993     return $clientObj->insert(); 
     613    my $num_keys = keys %{$priority_links}; 
     614    $driverRef->{'status'}->{'priority_links_remaining'} = $num_keys; 
     615  
     616    return $num_keys; 
    994617} 
    995618