Changeset 1087
- Timestamp:
- 12/30/07 14:50:17 (11 months ago)
- Files:
-
- honeyclient/branches/exp/xkovah-priority_interrupt/etc/honeyclient.xml (modified) (1 diff)
- honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Agent.pm (modified) (1 diff)
- honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Agent/Driver/Browser.pm (modified) (4 diffs)
- honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Manager-local.pm (added)
- honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Manager-orig.pm (added)
- honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Manager.pm (modified) (29 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
honeyclient/branches/exp/xkovah-priority_interrupt/etc/honeyclient.xml
r1083 r1087 377 377 3 378 378 </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> 379 382 <!-- HoneyClient::Manager::FW Options --> 380 383 <FW> honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Agent.pm
r1012 r1087 1189 1189 } 1190 1190 1191 1192 sub setPriorityLinksStatus{ 1193 my ($junk, $val) = @_; 1194 my $data = _lock(); 1195 1196 1197 _unlock($data); 1198 } 1199 1191 1200 # XXX: Document this. 1192 1201 # XXX: Do we really need this? honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Agent/Driver/Browser.pm
r1082 r1087 451 451 # 452 452 # 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' 454 455 # is checked next. If that hashtable is empty, then finally the 455 456 # 'links_to_visit' hashtable is checked. … … 898 899 links_timed_out => { }, 899 900 901 # 902 priority_links => { }, 903 904 900 905 # If this parameter is a defined scalar, then the browser 901 906 # will also never attempt to revisit any links that caused … … 1648 1653 return (!(defined($self->next_link_to_visit) or 1649 1654 scalar(%{$self->relative_links_to_visit}) or 1655 scalar(%{$self->priority_links}) or 1650 1656 scalar(%{$self->links_to_visit}))) 1651 1657 … … 1727 1733 $next_link_is_set; 1728 1734 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 1729 1739 # 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 } 1733 1749 # Set the total number of links in the object's state. 1734 1750 $status->{links_total} = $status->{links_processed} + honeyclient/branches/exp/xkovah-priority_interrupt/lib/HoneyClient/Manager.pm
r1086 r1087 28 28 ####################################################################### 29 29 30 =pod31 32 =head1 NAME33 34 HoneyClient::Manager - Perl extension to manage Agent VMs on the35 host system.36 37 =head1 VERSION38 39 This documentation refers to HoneyClient::Manager version 1.00.40 41 =head1 SYNOPSIS42 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 =" lines51 # 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 also72 # set this type of hashtable:73 links_to_visit => {74 'http://www.google.com' => 1,75 },76 },77 78 })),79 );80 81 =head1 DESCRIPTION82 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 VM86 (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 the89 Agent VM has not been compromised. If no compromise was found, then the90 Manager will signal the Firewall to allow the Agent VM to contact the91 next set of network resources (i.e., a webserver).92 93 If the Manager discovers the Agent VM has been compromised, then the94 Manager will suspend the clone VM, log the incident, and create a new Agent95 VM clone -- where this new clone picks up with the next set of URLs to96 crawl.97 98 If there are no URLs left for the Agent VM to visit OR if the user99 presses CTRL+C while the Manager is running, then the Manager will100 suspend the currently running Agent VM and write its state information101 out to the filesystem on the host system. This file is usually102 called 'Manager.dump'; however, the name can be changed by editing103 the <HoneyClient/><Manager/><manager_state/> section of the104 etc/honeyclient.xml file.105 106 This 'Manager.dump' file contains the set of URLs that the Honeyclients107 have visited, ignored, or tried to visit. In order to determine108 which URLs were identified as malicious, you will need to check109 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 been112 flagged as compromised -- unless the set of URLs has been exhausted113 or the user prematurely terminates the process (by pressing CTRL+C).114 115 =cut116 30 117 31 package HoneyClient::Manager; … … 161 75 our (@EXPORT_OK, $VERSION); 162 76 163 =pod164 165 =begin testing166 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 loads174 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 exportable216 # 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 testing266 267 =cut268 77 269 78 ####################################################################### … … 281 90 use HoneyClient::Util::Config qw(getVar); 282 91 283 # Include the VM Utility Libraries284 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;294 92 our %link_categories; 295 93 296 if ($DB_ENABLE) {297 # Include HoneyClient::DB Utility Libraries298 # 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 }310 94 311 95 # XXX: Remove this, eventually. … … 325 109 use Storable qw(nfreeze thaw); 326 110 327 # Include VmPerl Constants.328 # TODO: Include unit tests.329 use VMware::VmPerl qw(VM_EXECUTION_STATE_ON330 VM_EXECUTION_STATE_OFF331 VM_EXECUTION_STATE_STUCK332 VM_EXECUTION_STATE_SUSPENDED);333 334 111 # TODO: Include unit tests. 335 112 use IO::File; … … 339 116 340 117 # TODO: Include unit tests. 341 use Sys::Hostname::Long;118 #use Sys::Hostname::Long; 342 119 343 120 # TODO: Include unit tests. 344 use Sys::HostIP;121 #use Sys::HostIP; 345 122 346 123 # 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); 351 125 352 126 # Complete URL of SOAP server, when initialized. … … 357 131 our $DAEMON_PID : shared = undef; 358 132 359 # XXX: These will be migrated somewhere else, eventually.360 our $vmCloneConfig = undef;361 133 362 134 # This is a temporary, shared variable, used to print out the … … 365 137 # eventually. 366 138 our $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 if370 # it is called too many times (for instance when Manager loses371 # connectivity with the Agent it would otherwise loop and get errors372 # 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;139 our $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 145 our $G_error_count = 0; 146 147 #The file which is checked to see if there are priority links to visit 148 our $priority_links_file = getVar(name => "priority_links_file"); 377 149 378 150 # Temporary variable, used to indicate to the fault handler whether … … 468 240 469 241 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"; 476 244 # Construct error message. 477 245 # Figure out if the error occurred in transport or over … … 484 252 485 253 if (!$SUPPRESS_ERRORS) { 486 $LOG->warn("Error occurred during processing. " . $errMsg);487 254 Carp::carp __PACKAGE__ . "->_handleFault(): Error occurred during processing.\n" . $errMsg; 488 255 } … … 504 271 505 272 if (!$SUPPRESS_ERRORS) { 506 $LOG->warn("Error occurred during processing. " . $errMsg);507 273 Carp::carp __PACKAGE__ . "->_handleFault(): Error occurred during processing.\n" . $errMsg; 508 274 } … … 523 289 sub _cleanup { 524 290 525 $LOG->info("Cleaning up.");526 291 527 292 # Mask all possible signals, so that we don't call this function multiple times. … … 533 298 $SIG{TERM} = sub { }; 534 299 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();541 300 542 301 # This variable may contain a filename that the Manager … … 547 306 if (length($STATE_FILE) > 0 && 548 307 defined($globalAgentState)) { 549 $LOG->info("Saving state to '" . $STATE_FILE . "'.");550 308 my $dump_file = new IO::File($STATE_FILE, "a"); 551 309 … … 556 314 $dump_file->close(); 557 315 } 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 }571 316 572 317 # XXX: There is an issue where if we try to quit but are in the … … 630 375 # set. 631 376 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'}); 639 380 640 381 for (;;) { … … 642 383 $agentState = $class->runSession(%args); 643 384 $args{'agent_state'} = $agentState; 644 645 385 # XXX: Delete this, eventually. 646 386 $globalAgentState = $agentState; 647 387 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))); 651 392 } 652 393 } 394 653 395 654 396 sub runSession { … … 661 403 662 404 # XXX: Remove some of these, eventually. 663 my $stubVM = undef;664 my $stubFW = undef;665 405 my $stubAgent = undef; 666 406 my $som = undef; 667 407 my $ret = undef; 668 #DELETE ME UNUSEDmy $vmName = undef;669 #DELETE ME UNUSEDmy $URL = undef;670 #DELETE ME UNUSEDmy $vmState = undef;408 my $vmName = undef; 409 my $URL = undef; 410 my $vmState = undef; 671 411 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; 699 413 700 414 # Build our VM's connection table. 701 415 # Note: We assume our VM has a single MAC address 702 416 # and a single IP address. 703 $vmStateTable ->{$vm->name}->{sources}->{$vm->mac_address}->{$vm->ip_address} = {417 $vmStateTable{"127.0.0.1"} = { 704 418 # XXX: We assume we can't pinpoint what source TCP ports the 705 419 # corresponding driver will need. (We may want to get this … … 712 426 $Data::Dumper::Terse = 0; 713 427 $Data::Dumper::Indent = 2; 714 print Dumper( $vmStateTable) . "\n";428 print Dumper(\%vmStateTable) . "\n"; 715 429 716 # Initialize the firewall.717 $stubFW->installDefaultRules();718 719 # Add new chain, per cloned VM.720 $stubFW->addChain($vmStateTable);721 722 430 sleep (2); 723 431 724 432 # Recreate the client stub; handle faults. 725 433 $stubAgent = getClientHandle(namespace => "HoneyClient::Agent", 726 address => $vm->ip_address,434 address => "127.0.0.1", 727 435 fault_handler => \&_handleFaultAndCleanup); 728 436 … … 731 439 # from user input. 732 440 print "Calling updateState()...\n"; 441 print "YOU MUST BE AT LEAST THIS COMPLETE TO RIDE THE UPDATESTATE\n"; 442 print Dumper($args{'agent_state'}); 733 443 $som = $stubAgent->updateState($args{'agent_state'}); 734 444 735 445 # Recreate the client stub; ignore faults. 736 446 $stubAgent = getClientHandle(namespace => "HoneyClient::Agent", 737 address => $vm->ip_address,447 address => "127.0.0.1", 738 448 fault_handler => \&_agentHandleFault); 739 740 # Recreate the firewall stub; ignore faults.741 $stubFW = getClientHandle(namespace => "HoneyClient::Manager::FW",742 fault_handler => \&_handleFault);743 449 744 450 for (my $counter = 1;; $counter++) { … … 748 454 # assume that the Agent's watchdog process will recover. 749 455 eval { 456 750 457 print "Calling getState()...\n"; 751 458 $som = $stubAgent->getState(); … … 761 468 # Make Dumper format more verbose. 762 469 $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 766 491 767 492 # Check to see if Agent::run() thread has stopped … … 771 496 # Check to see if the VM has been compromised. 772 497 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"; 777 499 $vmCompromised = 1; 778 500 779 501 my $fingerprint = $ret->{$args{'driver'}}->{status}->{fingerprint}; 780 $LOG->warn("VM Compromised. Last Resource (" . $fingerprint->{'last_resource'} . ")");781 502 782 503 # Dump the fingerprint to the compromise file, if needed. … … 785 506 if (length($COMPROMISE_FILE) > 0 && 786 507 defined($fingerprint)) { 787 $LOG->info("Saving fingerprint to '" . $COMPROMISE_FILE . "'.");788 508 my $dump_file = new IO::File($COMPROMISE_FILE, "a"); 789 509 … … 796 516 } 797 517 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 830 519 return; # Return out of eval block. 831 } else { 520 } 521 else { 832 522 print "VM Integrity Check: OK!\n"; 833 523 … … 836 526 if (!$ret->{$args{'driver'}}->{status}->{links_remaining}) { 837 527 838 $LOG->info("All URLs exhausted. Shutting down Manager.");839 $vm = undef;840 528 # 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);845 529 print "Done!\n"; 846 530 _cleanup(); … … 851 535 # to allow access to the new targets. 852 536 853 # Delete the old firewall rules, based upon existing854 # targets.855 $stubFW->deleteRules($vmStateTable);856 537 857 538 # 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}; 860 540 861 541 print "VM State Table:\n"; … … 863 543 $Data::Dumper::Terse = 0; 864 544 $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"; 869 546 870 547 print "Calling run()...\n"; … … 884 561 # the daemon, in which case, we indefinately try to reset the 885 562 # firewall accordingly. 886 $stubFW->installDefaultRules();887 $stubFW->addChain($vmStateTable);888 $stubFW->addRules($vmStateTable);889 563 }; 890 564 if (!$@) { … … 897 571 if ($vmCompromised) { 898 572 # Reset the FW state table. 899 $vmStateTable = ( );573 %vmStateTable = ( ); 900 574 return $args{'agent_state'}; 901 575 } 902 if ($ globalAgentErrorCount >= getVar(name => "max_agent_error_count")) {903 $ globalAgentErrorCount = 0;576 if ($G_error_count >= 3) { 577 $G_error_count = 0; 904 578 # Reset the FW state table. 905 $vmStateTable = ( );579 %vmStateTable = ( ); 906 580 return $args{'agent_state'}; 907 581 } 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 908 591 print "Sleeping for 2s...\n"; 909 592 sleep (2); 593 } #end infinite for loop 594 } 595 596 #helper for checking for priority links to interrupt the current run session 597 sub _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 910 612 } 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; 994 617 } 995 618
