Changeset 1008
- Timestamp:
- 11/16/07 16:20:26 (10 months ago)
- Files:
-
- honeyclient/trunk/bin/StartAgent.pl (modified) (1 diff)
- honeyclient/trunk/bin/StartManager.pl (modified) (3 diffs)
- honeyclient/trunk/etc/honeyclient.xml (modified) (6 diffs)
- honeyclient/trunk/etc/honeyclient_log.conf (modified) (1 diff)
- honeyclient/trunk/lib/HoneyClient/Agent.pm (modified) (5 diffs)
- honeyclient/trunk/lib/HoneyClient/Agent/Driver/Browser.pm (modified) (3 diffs)
- honeyclient/trunk/lib/HoneyClient/Agent/Integrity.pm (modified) (18 diffs)
- honeyclient/trunk/lib/HoneyClient/Agent/Integrity/Filesystem.pm (modified) (5 diffs)
- honeyclient/trunk/lib/HoneyClient/Agent/Integrity/Registry.pm (modified) (9 diffs)
- honeyclient/trunk/lib/HoneyClient/Manager.pm (modified) (32 diffs)
- honeyclient/trunk/lib/HoneyClient/Manager/FW.pm (modified) (1 diff)
- honeyclient/trunk/lib/HoneyClient/Manager/VM.pm (modified) (40 diffs)
- honeyclient/trunk/lib/HoneyClient/Manager/VM/Clone.pm (modified) (17 diffs)
- honeyclient/trunk/lib/HoneyClient/Util/Config.pm (modified) (4 diffs)
- honeyclient/trunk/t/honeyclient_agent_integrity.t (modified) (2 diffs)
- honeyclient/trunk/t/honeyclient_agent_integrity_filesystem.t (modified) (2 diffs)
- honeyclient/trunk/t/honeyclient_agent_integrity_registry.t (modified) (4 diffs)
- honeyclient/trunk/t/honeyclient_manager.t (modified) (4 diffs)
- honeyclient/trunk/t/honeyclient_manager_fw.t (modified) (1 diff)
- honeyclient/trunk/t/honeyclient_manager_vm.t (modified) (21 diffs)
- honeyclient/trunk/t/honeyclient_manager_vm_clone.t (modified) (7 diffs)
- honeyclient/trunk/t/test_vm/nvram (modified) (previous)
- honeyclient/trunk/t/test_vm/winXPPro.vmx (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
honeyclient/trunk/bin/StartAgent.pl
r409 r1008 60 60 $URL = HoneyClient::Agent->init(); 61 61 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 62 68 # Restore state information. 63 $som = $stub->updateState(encode_base64(nfreeze($agentState))); 69 if (defined($agentState)) { 70 $som = $stub->updateState(encode_base64(nfreeze($agentState))); 71 } 64 72 } 65 73 honeyclient/trunk/bin/StartManager.pl
r942 r1008 7 7 use Carp (); 8 8 9 # Include Dumper Library 9 10 use Data::Dumper; 10 11 … … 18 19 use Getopt::Long; 19 20 21 # Include utility access to global configuration. 22 use HoneyClient::Util::Config qw(getVar); 23 24 # Include Manager Library 20 25 use HoneyClient::Manager; 21 26 27 # Include Logging Library 28 use Log::Log4perl qw(:easy); 29 30 # The global logging object. 31 our $LOG = get_logger(); 32 22 33 # 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. 25 35 26 36 # Change to 'HoneyClient::Agent::Driver::Browser::IE' or 27 37 # 'HoneyClient::Agent::Driver::Browser::FF' 28 my $driver = "HoneyClient::Agent::Driver::Browser::IE";38 my $driver = undef; 29 39 my $config = undef; 30 my $maxrel = 5;40 my $maxrel = undef; 31 41 my $nexturl = ""; 32 42 my $urllist= ""; … … 38 48 'url_list=s' => \$urllist, 39 49 'max_relative_links:i' => \$maxrel); 50 51 # Sanity Check. Make sure $driver is set. 52 unless (defined($driver)) { 53 $driver = getVar(name => "default_driver", 54 namespace => "HoneyClient::Agent"); 55 } 56 57 # Sanity Check. Make sure $max_relative_links is set. 58 unless (defined($maxrel)) { 59 $maxrel = getVar(name => "max_relative_links_to_visit", 60 namespace => "HoneyClient::Agent::Driver::Browser"); 61 } 40 62 41 63 # Go through the list of urls to create the array honeyclient/trunk/etc/honeyclient.xml
r986 r1008 72 72 <name>HoneyClient::Agent::Driver::Browser::FF</name> 73 73 </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> 74 77 <!-- HoneyClient::Agent::Driver Options --> 75 78 <Driver> … … 94 97 1 95 98 </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.exe99 </process_name>100 99 <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 -1100 5 102 101 </max_relative_links_to_visit> 103 102 <positive_words description="If a link contains any number of these words, then its probability of being visited (its score) will increase."> … … 123 122 <word>jobs</word> 124 123 <word>careers</word> 124 <word>term</word> 125 125 </negative_words> 126 126 <IE> … … 155 155 </changes_found_file> 156 156 <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.txt157 /tmp/realtime-changes.txt 158 158 </realtime_changes_file> 159 159 <!-- HoneyClient::Agent::Integrity::Filesystem Options --> … … 329 329 <DB> 330 330 <enable description="Enables database operations. 1 enables, 0 disables." default="0"> 331 1331 0 332 332 </enable> 333 333 <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"> … … 349 349 <Manager> 350 350 <!-- TODO: Update this. --> 351 <manager_state description="Upon termination, the Manager will attempt to savea 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=""> 352 352 Manager.dump 353 353 </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> 354 357 <!-- TODO: Update this. --> 355 358 <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 65 65 #log4perl.logger.HoneyClient.Manager=INFO, Screen, Syslog 66 66 #log4perl.logger.HoneyClient.DB=DEBUG, Screen, Syslog 67 #log4perl.logger.HoneyClient.Manager.VM.Clone=DEBUG, Screen 67 68 # Suppress Parser Debugging Messages 68 69 #log4perl.logger.HoneyClient.Agent.Integrity.Registry.Parser=INFO, Screen honeyclient/trunk/lib/HoneyClient/Agent.pm
r994 r1008 346 346 Carp::croak "Error: " . __PACKAGE__ . " daemon is already running (PID = $DAEMON_PID)!\n"; 347 347 } 348 349 # Reinitialize global constants (for dynamic updates). 350 $PERFORM_INTEGRITY_CHECKS = getVar(name => "perform_integrity_checks"); 348 351 349 352 # Figure out what our list of allowed Drivers are. … … 896 899 my $driverTargetsChanged = 0; 897 900 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 898 907 while (!$driver->isFinished() && !$driverTargetsChanged) { 899 908 # XXX: Debug. Remove this. … … 907 916 # If the operation fails, then an exception will be generated. 908 917 $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 910 942 # Acquire lock on stored driver state. 911 943 $data = _lock(); … … 928 960 $data->{$driverName}->{'next'} = $driver->next(); 929 961 $data->{$driverName}->{'status'} = $driver->status(); 930 $data->{$driverName}->{'status'}->{'is_compromised'} = 0;962 $data->{$driverName}->{'status'}->{'is_compromised'} = $isCompromised; 931 963 $data->{$driverName}->{'status'}->{'is_running'} = 1; 932 964 $data->{$driverName}->{'state'} = $driver; … … 935 967 _unlock($data); 936 968 } 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 958 987 # Release our copy of the integrity object, but do not destroy 959 988 # any internal references. honeyclient/trunk/lib/HoneyClient/Agent/Driver/Browser.pm
r994 r1008 438 438 439 439 =cut 440 441 my %PARAMS = (442 443 # This is a hashtable of fully qualified URLs444 # to visit by the browser. Specifically, the 'key' is445 # the absolute URL and the 'value' is always 1.446 links_to_visit => { },447 448 # This is a hashtable of fully qualified URLs that the449 # browser has already visited. Specifically, the450 # 'key' is the absolute URL and the 'value' is a string451 # representing the date and time of when the link was visited.452 #453 # Note: See _getTimestamp() for the corresponding date/time454 # format.455 links_visited => { },456 457 # This is a hashtable of URLs that the browser has found458 # during its traversal process, but the browser could not459 # access the link.460 #461 # Links could be added to this list if access requires any type of462 # authentication, or if the link points to a non-HTTP or HTTPS463 # resource (i.e., "javascript:doNetDetect()").464 #465 # The 'key' is the absolute URL and the 'value' is a string466 # representing the date and time of when the link was visited.467 #468 # Note: See _getTimestamp() for the corresponding date/time469 # format.470 links_ignored => { },471 472 # This is a hashtable of fully qualified URLs473 # that all share a common *hostname*. This hashtable should be474 # initially empty. As the driver extracts and removes new URLs475 # off the 'links_to_visit' hashtable, driving the browser to each URL,476 # any *relative* links found are added into this hashtable; any477 # *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 prior481 # to the main 'links_to_visit' hashtable. This allows a482 # browser to navigate to all links hosted on the same server, prior483 # 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, then493 # 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 found499 # during its traversal process, but the browser could not500 # access the resource due to the operation timing out.501 #502 # The 'key' is the absolute URL and the 'value' is a string503 # representing the date and time of when the link was visited.504 #505 # Note: See _getTimestamp() for the corresponding date/time506 # format.507 links_timed_out => { },508 509 # If this parameter is a defined scalar, then the browser510 # will also never attempt to revisit any links that caused511 # 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 browser519 # should continue to drive to, before moving onto another520 # website. If negative, then the browser will exhaust all possible521 # relative links, before moving on. (This internal variable should522 # 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 that526 # the browser should visit, before moving onto another website. If527 # negative, then the browser will exhaust all possible relative links528 # found, before moving on. This functionality is best effort; it's529 # possible for the browser to visit new links on previously visited530 # 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 being534 # visited (its score) will increase, if the link contains any of these535 # words.536 positive_words => getVar(name => "positive_words")->{word},537 538 # An array of negative words, where a link's probability of being539 # visited (its score) will decrease, if the link contains any of these540 # words.541 negative_words => getVar(name => "negative_words")->{word},542 543 # If set to 1, then the code will attempt to parse and extract links544 # within active content (e.g., Flash animations). Otherwise, the545 # code will ignore all active content.546 parse_active_content => getVar(name => "enable",547 namespace => "HoneyClient::Agent::Driver::ActiveContent"),548 );549 440 550 441 ####################################################################### … … 907 798 # 908 799 # - For each parameter given, it overwrites any corresponding 909 # parameters specified within the default hashtable, % PARAMS,800 # parameters specified within the default hashtable, %params, 910 801 # with custom entries that were given as parameters. 911 802 # … … 926 817 927 818 # 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 929 928 $self = $class->SUPER::new(); 930 929 @{$self}{keys %params} = values %params; honeyclient/trunk/lib/HoneyClient/Agent/Integrity.pm
r994 r1008 61 61 } 62 62 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 72 This library allows the Agent module to easily baseline and perform subsequent 73 checks of different aspects of the Windows OS for any changes that may occur, 74 while Agent instruments a target application. 75 76 Currently, the Integrity module performs the following checks, using the 77 listed sub-modules. Please refer to the sub-module documentation for 78 further details about how each check is implemented. 79 80 No initialization is currently necessary, as real-time changes are read in from 70 81 a list exported by the Capture C code. However, in the future it may become 71 de israble to perform an initial baseline of the systemin order to automatically72 determine the original value for things which were changed. This is because the82 desirable to perform an initial baseline of the system, in order to automatically 83 determine the original value for things which were changed. This is because the 73 84 mechanisms 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. 85 to record the initial value (e.g., a registry key). 86 87 =over 4 88 89 =item * 90 91 Checks Windows OS Registry. See L<HoneyClient::Agent::Integrity::Registry>. 92 93 =item * 94 95 Checks Windows OS Filesystem. See L<HoneyClient::Agent::Integrity::Filesystem>. 96 97 =back 75 98 76 99 =cut … … 250 273 =back 251 274 275 =head2 changes_found_file 276 277 A string to the absolute path of a file on the VM's filesystem. 278 When an integrity check fails, all changes will be written to this 279 file within the compromized honeyclient VM's filesystem. 280 281 =back 282 252 283 =cut 253 254 my %PARAMS = (255 # When set to 1, the object will forgo any type of initial baselining256 # process, upon initialization. Otherwise, baselining will occur257 # as normal, upon initialization.258 # XXX: Bypass static baselining, for now.259 # XXX: Baselining will not be used with the current version which includes Capture260 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 this271 _changes_found_file => getVar(name => 'changes_found_file'),272 273 # XXX: comment this274 _realtime_changes_file => getVar(name => 'realtime_changes_file'),275 276 );277 284 278 285 ####################################################################### … … 289 296 # the Registry object creates new files that must exist to be added to the 290 297 # 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(); 292 299 $self->{'_filesystem'} = HoneyClient::Agent::Integrity::Filesystem->new(); 293 300 } … … 334 341 diag("Performing baseline check of the system; this may take some time..."); 335 342 336 # XXX: Uncomment this next check, eventually. (It's commented out right now, in order to save some time).337 343 # Perform baseline. 338 344 $integrity = HoneyClient::Agent::Integrity->new(); 339 345 isa_ok($integrity, 'HoneyClient::Agent::Integrity', "new()") or diag("The new() call failed."); 346 $integrity->destroy(); 340 347 341 348 =end testing … … 349 356 # 350 357 # - For each parameter given, it overwrites any corresponding 351 # parameters specified within the default hashtable, % PARAMS,358 # parameters specified within the default hashtable, %params, 352 359 # with custom entries that were given as parameters. 353 360 # … … 369 376 # Initialize default parameters. 370 377 $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 372 403 @{$self}{keys %params} = values %params; 373 404 … … 404 435 hashtable has the following format: 405 436 406 $changes = {437 $changes = { 407 438 #A reference to an anonymous array of process objects 408 439 processes => [ { … … 456 487 file_system => [ { 457 488 #The full path and name of the file which was effected 458 'name' => 'C:\WINDOWS\SYSTEM32...',489 'name' => 'C:\WINDOWS\SYSTEM32...', 459 490 460 491 'event_type' => { Deleted | Read | Write }, #TODO: add created & renamed/moved 461 492 462 493 'time' => ISO 8601 Timestamp, 463 494 464 495 #OPTIONAL, this will not exist for deleted files 465 'content' => {466 'size' => 1234, # size of new content467 'type' => 'application/octect-stream', # type of new content468 'md5' => 'b1946ac92492d2347c6235b4d2611184', # md5 of new content469 'sha1' => 'f572d396fae9206628714fb2ce00f72e94f2258f', # sha1 of new content470 },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 }, 471 502 },] 472 503 },] 473 }504 } 474 505 475 506 I<Notes>: 476 507 477 508 =back 478 479 #=begin testing480 #481 # TODO:482 #483 #=end testing484 509 485 510 =cut … … 506 531 }); 507 532 508 # my $changes = {533 # my $changes = { 509 534 # 'registry' => $self->{'_registry'}->check(), 510 535 # 'filesystem' => $self->{'_filesystem'}->check(), 511 536 # }; 512 537 #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}; 514 539 my %changes; 515 540 my @capdump; … … 670 695 }; 671 696 my $tmp_name = $toks[$F_NAME]; 672 eval{697 eval{ 673 698 if(-f $tmp_name){ 674 699 my $md5_ctx = Digest::MD5->new(); … … 680 705 my $size = 0; 681 706 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 size696 $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; 703 728 $file_obj->{'contents'}->{'size'} = $size; 704 729 $file_obj->{'contents'}->{'md5'} = $md5; … … 738 763 # filesystem. 739 764 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} . "'."); 742 767 } else { 743 768 $Data::Dumper::Terse = 1; … … 749 774 } 750 775 751 return \%changes;776 return \%changes; 752 777 } 753 778 779 # TODO: Comment this. 754 780 # This function looks for if there is already a process object with the given pid and name 755 781 # and if it exists, returns its index in the processes array … … 777 803 } 778 804 779 780 781 # TODO: Comment this. 805 =pod 806 807 =head2 $object->closeFiles() 808 809 =over 4 810 811 Closes any temporary files that may have been created by any 812 of the Integrity::* sub-modules. By performing this operation, 813 the Integrity B<$object> can become serializable. 814 815 =back 816 817 =cut 818 782 819 sub closeFiles { 783 820 my $self = shift; … … 796 833 } 797 834 798 # TODO: Comment this. 835 =pod 836 837 =head2 $object->destroy() 838 839 =over 4 840 841 Destroys any temporary files that have been created by any 842 of the Integrity::* sub-modules. By performing this operation, 843 the Integrity B<$object> can be released from memory without 844 leaving any residual temporary files on the filesystem. 845 846 =back 847 848 =cut 849 799 850 sub destroy { 800 851 my $self = shift; … … 819 870 =head1 BUGS & ASSUMPTIONS 820 871 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. 872 When performing an integrity check, this library assumes that it will never 873 see the same process name and process ID (PID) pair twice, because the malware 874 will not have had enough time to create processes that cause the OS to reissue 875 the same PIDs again. 876 877 For a complete list of when these checks may fail, see the following sections: 878 879 =over 4 880 881 =item * 882 883 L<HoneyClient::Agent::Integrity::Registry/"BUGS & ASSUMPTIONS"> 884 885 =item * 886 887 L<HoneyClient::Agent::Integrity::Filesystem/"BUGS & ASSUMPTIONS"> 888 889 =back 890 891 =head1 TODO 892 893 The following sub-modules are still a work-in-progress: 894 895 =over 4 896 897 =item * 898 899 Real-time filesystem detection. 900 901 =item * 902 903 Real-time registry detection. 904 905 =item * 906 907 Static and/or real-time rogue process detection. 908 909 =item * 910 911 Static and/or real-time memory alteration detection. 912 913 =back 824 914 825 915 =head1 SEE ALSO … … 833 923 =head1 ACKNOWLEDGEMENTS 834 924 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. 925 Christian Seifert E<lt>cseifert@mcs.vuw.ac.nzE<gt> and Ramon Steenson 926 E<lt>rsteenson@gmail.comE<gt> from the Victoria University of Wellington, 927 for their work on the Capture Client-Side Honeypot, which is used to 928 obtain kernel-level system events from Windows in the event of a compromise. 929 930 L<http://www.client-honeynet.org/capture.html> 837 931 838 932 =head1 AUTHORS … … 845 939 846 940 Brad Stephenson, E<lt>stephenson@mitre.orgE<gt> 847 848 Thanh Truong, E<lt>ttruong@mitre.orgE<gt>849 941 850 942 =head1 COPYRIGHT & LICENSE honeyclient/trunk/lib/HoneyClient/Agent/Integrity/Filesystem.pm
r994 r1008 175 175 =begin testing 176 176 177 # Make sure ExtUtils::MakeMaker loads. 178 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."); } 179 require_ok('ExtUtils::MakeMaker'); 180 can_ok('ExtUtils::MakeMaker', 'prompt'); 181 use ExtUtils::MakeMaker qw(prompt); 182 177 183 # Make sure Log::Log4perl loads 178 184 BEGIN { use_ok('Log::Log4perl', qw(:nowarn)) … … 358 364 359 365 =cut 360 361 my %PARAMS = (362 # When set to 1, the object will forgo any type of initial baselining363 # process, upon initialization. Otherwise, baselining will occur
