Changeset 521
- Timestamp:
- 06/17/07 17:21:39 (1 year ago)
- Files:
-
- honeyclient/trunk/bin/StartManager.pl (modified) (1 diff)
- honeyclient/trunk/bin/TestRegistry.pl (modified) (2 diffs)
- honeyclient/trunk/bin/install_honeyclient_db.pl (copied) (copied from honeyclient/branches/exp/mbriggs-db/bin/install_honeyclient_db.pl)
- honeyclient/trunk/bin/run.sh (modified) (1 diff)
- honeyclient/trunk/etc/honeyclient.xml (modified) (8 diffs)
- honeyclient/trunk/lib/HoneyClient/Agent.pm (modified) (5 diffs)
- honeyclient/trunk/lib/HoneyClient/Agent/Driver.pm (modified) (2 diffs)
- honeyclient/trunk/lib/HoneyClient/Agent/Integrity/Filesystem.pm (modified) (39 diffs)
- honeyclient/trunk/lib/HoneyClient/Agent/Integrity/Registry.pm (modified) (22 diffs)
- honeyclient/trunk/lib/HoneyClient/DB (copied) (copied from honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/DB)
- honeyclient/trunk/lib/HoneyClient/DB.pm (copied) (copied from honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/DB.pm)
- honeyclient/trunk/lib/HoneyClient/Manager.pm (modified) (15 diffs)
- honeyclient/trunk/lib/HoneyClient/Manager/DB.pm (copied) (copied from honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager/DB.pm)
- honeyclient/trunk/lib/HoneyClient/Manager/VM (copied) (copied from honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager/VM)
- honeyclient/trunk/lib/bin (copied) (copied from honeyclient/branches/exp/mbriggs-db/lib/bin)
- honeyclient/trunk/lib/etc (copied) (copied from honeyclient/branches/exp/mbriggs-db/lib/etc)
- honeyclient/trunk/t/db_test.pl (copied) (copied from honeyclient/branches/exp/mbriggs-db/t/db_test.pl)
- honeyclient/trunk/t/honeyclient_agent.t (modified) (1 diff)
- honeyclient/trunk/t/honeyclient_agent_driver.t (modified) (1 diff)
- honeyclient/trunk/t/honeyclient_agent_integrity_filesystem.t (modified) (8 diffs)
- honeyclient/trunk/t/honeyclient_agent_integrity_registry.t (modified) (8 diffs)
- honeyclient/trunk/t/honeyclient_manager_db.t (copied) (copied from honeyclient/branches/exp/mbriggs-db/t/honeyclient_manager_db.t)
- honeyclient/trunk/t/honeyclient_manager_vm_clone.t (added)
- honeyclient/trunk/t/honeyclient_util_config.t (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
honeyclient/trunk/bin/StartManager.pl
r409 r521 25 25 26 26 my $driver = "IE"; 27 my $config = "/vm/master-vms/Agent.Master- 19/winXPPro.cfg";28 my $maxrel = 5;27 my $config = "/vm/master-vms/Agent.Master-20/winXPPro.cfg"; 28 my $maxrel = 10; 29 29 my $nexturl = ""; 30 30 my $urllist= ""; honeyclient/trunk/bin/TestRegistry.pl
r131 r521 51 51 } else { 52 52 foreach my $change (@{$changes}) { 53 print $change->{'key '} . " (" . $change->{'status'} . ")\n";53 print $change->{'key_name'} . " (" . $change->{'status'} . ")\n"; 54 54 } 55 55 } … … 62 62 print "Detailed registry changes were written to: " . $file . "\n"; 63 63 } 64 honeyclient/trunk/bin/run.sh
r350 r521 2 2 3 3 echo "Starting up Agent - (Hit CTRL-C multiple times to exit.)" 4 5 # Remove all old /tmp/* entries. 6 rm /tmp/* 4 7 5 8 IP=$(/cygdrive/c/Program\ Files/VMware/VMware\ Tools/VMip.exe -get) honeyclient/trunk/etc/honeyclient.xml
r432 r521 72 72 <!-- TODO: Update this. --> 73 73 <timeout description="How long the Driver waits during a drive operation, before timing out (in seconds)." default="60"> 74 3074 20 75 75 </timeout> 76 76 <Browser> … … 124 124 </Driver> 125 125 <perform_integrity_checks description="An integer, representing whether the Agent should perform any integrity checks. 1 enables, 0 disables." default="1"> 126 1 126 1 127 127 </perform_integrity_checks> 128 128 <!-- HoneyClient::Agent::Integrity Options --> … … 205 205 <regex>^HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Security\\AntiPhishing.*$</regex> 206 206 <regex>^HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\TypedURLs$</regex> 207 <regex>^HKEY_CURRENT_USER\\Software\\Microsoft\\MediaPlayer.*$</regex> 208 <regex>^HKEY_CURRENT_USER\\Software\\Microsoft\\Multimedia.*$</regex> 207 209 <regex>^HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites\\Links.*$</regex> 208 210 <regex>^HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Start Menu2\\Programs.*$</regex> … … 244 246 <regex>^HKEY_USERS\\.+\\UNICODE Program Groups.*$</regex> 245 247 <regex>^HKEY_USERS\\S.+\\SessionInformation$</regex> 248 <regex>^HKEY_USERS\\S.+\\Software\\Microsoft\\ActiveMovie\\devenum.*$</regex> 246 249 <regex>^HKEY_USERS\\S.+\\Software\\Microsoft\\Internet Explorer\\IntelliForms$</regex> 247 250 <regex>^HKEY_USERS\\S.+\\Software\\Microsoft\\Internet Explorer\\International$</regex> … … 250 253 <regex>^HKEY_USERS\\S.+\\Software\\Microsoft\\Internet Explorer\\Security\\AntiPhishing.*$</regex> 251 254 <regex>^HKEY_USERS\\S.+\\Software\\Microsoft\\Internet Explorer\\TypedURLs$</regex> 252 <regex>^HKEY_USERS\\S.+\\Software\\Microsoft\\MediaPlayer\\Preferences.*$</regex> 255 <regex>^HKEY_USERS\\S.+\\Software\\Microsoft\\MediaPlayer.*$</regex> 256 <regex>^HKEY_USERS\\S.+\\Software\\Microsoft\\Multimedia.*$</regex> 253 257 <regex>^HKEY_USERS\\S.+\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites\\Links.*$</regex> 254 258 <regex>^HKEY_USERS\\S.+\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Start Menu2\\Programs.*$</regex> … … 291 295 </Integrity> 292 296 </Agent> 297 <!-- HoneyClient::DB Options --> 298 <DB> 299 <enable description="Enables database operations. 1 enables, 0 disables." default="0"> 300 1 301 </enable> 302 <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"> 303 172.16.164.1 304 </host> 305 <dbname description="The name of the HoneyClient database." default="HoneyClient"> 306 HoneyClient 307 </dbname> 308 <user description="The username to use, when connecting to the HoneyClient database."> 309 honeyclient_user 310 </user> 311 <pass description="The password to use, when connecting to the HoneyClient database."> 312 honeyclient_password 313 </pass> 314 <port description="The default TCP port number used to communicate with the database." default="3306"> 315 3306 316 </port> 317 </DB> 293 318 <Manager> 294 319 <!-- TODO: Update this. --> … … 396 421 <!-- TODO: Update this. --> 397 422 <fwprocess description="Name of external SOAP listener."> 398 startFWListener.pl 423 startFWListener.pl 399 424 </fwprocess> 400 425 <!-- TODO: Update this. --> … … 403 428 </config_file> 404 429 </FW> 405 <!-- HoneyClient::Manager::DB Options -->406 <DB>407 <!-- TODO: Update this. -->408 <address description="eth0 interface static IP">409 192.168.0.128410 </address>411 <!-- TODO: Update this. -->412 <port description="Default FW port number" default="8083">413 8089414 </port>415 </DB>416 430 <!-- HoneyClient::Manager::VM Options --> 417 431 <VM> honeyclient/trunk/lib/HoneyClient/Agent.pm
r411 r521 792 792 # Initially set all driver objects to undef. 793 793 my $driver = undef; 794 795 # Last resource used by driver. 796 my $lastResource = undef; 794 797 795 798 # Acquire lock on stored driver state. … … 846 849 foreach my $resource (keys %{$driver->next()->{resources}}) { 847 850 $LOG->info("Driving To Resource: " . $resource); 851 $lastResource = $resource; 848 852 } 849 853 … … 882 886 # TODO: Perform Integrity Check 883 887 my $isCompromised = 0; 888 my $changes = undef; 884 889 if (defined($integrity)) { 885 890 # For now, we update a scalar called 'is_compromised' within 886 891 # the $data->{$driverName}->{'status'} sub-hashtable. 887 892 $LOG->info("Performing Integrity Checks."); 888 my$changes = $integrity->check();893 $changes = $integrity->check(); 889 894 if (scalar(@{$changes->{registry}}) || 890 895 scalar(@{$changes->{filesystem}})) { 891 896 $LOG->warn("Integrity Check: FAILED"); 892 897 $isCompromised = 1; 898 $changes->{'last_resource'} = $lastResource; 893 899 } else { 894 900 $LOG->info("Integrity Check: PASSED"); … … 900 906 901 907 # Update driver state one last time, before exiting. 902 903 908 # Acquire lock on stored driver state. 904 909 $data = _lock(); … … 911 916 $data->{$driverName}->{'status'} = $driver->status(); 912 917 $data->{$driverName}->{'status'}->{'is_compromised'} = $isCompromised; 918 $data->{$driverName}->{'status'}->{'fingerprint'} = $changes; 913 919 $data->{$driverName}->{'status'}->{'is_running'} = 0; 914 920 $data->{$driverName}->{'state'} = $driver; honeyclient/trunk/lib/HoneyClient/Agent/Driver.pm
r411 r521 288 288 # 289 289 # use HoneyClient::Agent::Driver; 290 # my $driver = Driver->new(someVar => 'someValue');290 # my $driver = HoneyClient::Agent::Driver->new(someVar => 'someValue'); 291 291 # 292 292 # What this function allows us to do, is programmatically, get or set … … 375 375 my $driver = HoneyClient::Agent::Driver->new(test => 1); 376 376 is($driver->{test}, 1, "new(test => 1)") or diag("The new() call failed."); 377 isa_ok($driver, 'HoneyClient::Agent::Driver', "new(test => 1)") or diag("The new() call failed."); 377 378 378 379 =end testing honeyclient/trunk/lib/HoneyClient/Agent/Integrity/Filesystem.pm
r427 r521 66 66 # # Indicates if the filesystem entry was deleted, 67 67 # # added, or changed. 68 # 'status' => 'deleted' | 'added' | 'changed', 68 # 'status' => $STATUS_DELETED | $STATUS_ADDED | $STATUS_MODIFIED, 69 # 'name' => 'C:\WINDOWS\SYSTEM32...', 70 # 'mtime' => 'YYYY-MM-DD HH:MM:SS', # new mtime for added/modified files; 71 # # old mtime for deleted files 69 72 # 70 # # If the entry has been added/changed, then this 71 # # hashtable contains the file/directory's new information. 72 # 'new' => { 73 # 'name' => 'C:\WINDOWS\SYSTEM32...', 74 # 'size' => 1263, # in bytes 75 # 'mtime' => 1178135092, # modification time, seconds since epoch 76 # }, 77 # 78 # # If the entry has been deleted/changed, then this 79 # # hashtable contains the file/directory's old information. 80 # 'old' => { 81 # 'name' => 'C:\WINDOWS\SYSTEM32...', 82 # 'size' => 802, # in bytes 83 # 'mtime' => 1178135028, # modification time, seconds since epoch 73 # # content will only exist for added/modified files 74 # 'content' => { 75 # 'size' => 1263, # size of new content 76 # 'type' => 'application/octect-stream', # type of new content 77 # 'md5' => 'b1946ac92492d2347c6235b4d2611184', # md5 of new content 78 # 'sha1' => 'f572d396fae9206628714fb2ce00f72e94f2258f', # sha1 of new content 84 79 # }, 85 80 # }, ] … … 124 119 # Include Logging Library 125 120 use Log::Log4perl qw(:easy); 121 122 # Use DateTime Library 123 use DateTime; 124 125 # Use MD5 Library 126 use Digest::MD5; 127 128 # Use SHA Library 129 use Digest::SHA; 130 131 # Use File::Type Library 132 use File::Type; 133 134 # Use IO::File Library 135 use IO::File; 126 136 127 137 ####################################################################### … … 242 252 use HoneyClient::Agent::Integrity::Filesystem; 243 253 254 # Make sure DateTime loads. 255 BEGIN { use_ok('DateTime') or diag("Can't load DateTime package. Check to make sure the package library is correctly listed within the path."); } 256 require_ok('DateTime'); 257 use DateTime; 258 259 # Make sure Digest::MD5 loads. 260 BEGIN { use_ok('Digest::MD5') or diag("Can't load Digest::MD5 package. Check to make sure the package library is correctly listed within the path."); } 261 require_ok('Digest::MD5'); 262 use Digest::MD5; 263 264 # Make sure Digest::SHA loads. 265 BEGIN { use_ok('Digest::SHA') or diag("Can't load Digest::SHA package. Check to make sure the package library is correctly listed within the path."); } 266 require_ok('Digest::SHA'); 267 use Digest::SHA; 268 269 # Make sure File::Type loads. 270 BEGIN { use_ok('File::Type') or diag("Can't load File::Type package. Check to make sure the package library is correctly listed within the path."); } 271 require_ok('File::Type'); 272 use File::Type; 273 274 # Make sure IO::File loads. 275 BEGIN { use_ok('IO::File') or diag("Can't load IO::File package. Check to make sure the package library is correctly listed within the path."); } 276 require_ok('IO::File'); 277 use IO::File; 278 244 279 =end testing 245 280 … … 249 284 # Global Configuration Variables # 250 285 ####################################################################### 286 287 # TODO: Need to link these constants with DB code. 288 # Filesystem Status Identifiers 289 our $STATUS_DELETED = 0; 290 our $STATUS_ADDED = 1; 291 our $STATUS_MODIFIED = 2; 292 293 # TODO: Need to link these constants with DB code. 294 # Set hash value to this constant, if unable to compute. 295 our $HASH_UNKNOWN = 'UNKNOWN'; 296 # Set type value to this constant, if unable to compute. 297 our $TYPE_UNKNOWN = 'UNKNOWN'; 251 298 252 299 # The global logging object. … … 432 479 # Input: Algorithm::Diff object 433 480 # Output: Array reference of hashtables 481 # Notes: This function returns hashtables in the following 482 # format: 483 # 484 # $changes = [ { 485 # # Indicates if the filesystem entry was deleted, 486 # # added, or changed. 487 # 'status' => $STATUS_DELETED | $STATUS_ADDED | $STATUS_MODIFIED, 488 # 489 # # If the entry has been added/changed, then this 490 # # hashtable contains the file/directory's new information. 491 # 'new' => { 492 # 'name' => 'C:\WINDOWS\SYSTEM32...', 493 # 'size' => 1263, # in bytes 494 # 'mtime' => 1178135092, # modification time, seconds since epoch 495 # }, 496 # 497 # # If the entry has been deleted/changed, then this 498 # # hashtable contains the file/directory's old information. 499 # 'old' => { 500 # 'name' => 'C:\WINDOWS\SYSTEM32...', 501 # 'size' => 802, # in bytes 502 # 'mtime' => 1178135028, # modification time, seconds since epoch 503 # }, 504 # }, ] 434 505 sub _diff { 435 506 … … 458 529 459 530 push (@{$ret}, { 460 'status' => 'deleted',531 'status' => $STATUS_DELETED, 461 532 'old' => $_, 462 533 }); … … 471 542 472 543 push (@{$ret}, { 473 'status' => 'added',544 'status' => $STATUS_ADDED, 474 545 'new' => $_, 475 546 }); … … 501 572 502 573 push (@{$ret}, { 503 'status' => 'changed',574 'status' => $STATUS_MODIFIED, 504 575 'old' => $old_entry, 505 576 'new' => $new_entry, … … 515 586 516 587 push (@{$ret}, { 517 'status' => 'deleted',588 'status' => $STATUS_DELETED, 518 589 'old' => $old_entry, 519 590 }); 520 591 push (@{$ret}, { 521 'status' => 'added',592 'status' => $STATUS_ADDED, 522 593 'new' => $new_entry, 523 594 }); … … 543 614 544 615 push (@{$ret}, { 545 'status' => 'changed',616 'status' => $STATUS_MODIFIED, 546 617 'old' => $old_entry, 547 618 'new' => $new_entry, … … 557 628 558 629 push (@{$ret}, { 559 'status' => 'deleted',630 'status' => $STATUS_DELETED, 560 631 'old' => $old_entry, 561 632 }); … … 568 639 $LOG->debug("File Added - " . Dumper($new_entry)); 569 640 push (@{$ret}, { 570 'status' => 'added',641 'status' => $STATUS_ADDED, 571 642 'new' => $new_entry, 572 643 }); … … 584 655 $LOG->debug("File Added - " . Dumper($new_entry)); 585 656 push (@{$ret}, { 586 'status' => 'added',657 'status' => $STATUS_ADDED, 587 658 'new' => $new_entry, 588 659 }); … … 604 675 " - New - " . Dumper($new_entry)); 605 676 push (@{$ret}, { 606 'status' => 'changed',677 'status' => $STATUS_MODIFIED, 607 678 'old' => $old_entry, 608 679 'new' => $new_entry, … … 617 688 $LOG->debug("File Added - " . Dumper($new_entry)); 618 689 push (@{$ret}, { 619 'status' => 'added',690 'status' => $STATUS_ADDED, 620 691 'new' => $new_entry, 621 692 }); … … 628 699 $LOG->debug("File Deleted - " . Dumper($old_entry)); 629 700 push (@{$ret}, { 630 'status' => 'deleted',701 'status' => $STATUS_DELETED, 631 702 'old' => $old_entry, 632 703 }); … … 644 715 $LOG->debug("File Deleted - " . Dumper($old_entry)); 645 716 push (@{$ret}, { 646 'status' => 'deleted',717 'status' => $STATUS_DELETED, 647 718 'old' => $old_entry, 648 719 }); … … 659 730 # 660 731 # Input: Array reference of hashtables 661 # Output: Array reference of hashtables (filtered) 732 # Output: Array reference of hashtables (filtered) 733 # Notes: This function expects and returns hashtables in the following 734 # format: 735 # 736 # $changes = [ { 737 # # Indicates if the filesystem entry was deleted, 738 # # added, or changed. 739 # 'status' => $STATUS_DELETED | $STATUS_ADDED | $STATUS_MODIFIED, 740 # 741 # # If the entry has been added/changed, then this 742 # # hashtable contains the file/directory's new information. 743 # 'new' => { 744 # 'name' => 'C:\WINDOWS\SYSTEM32...', 745 # 'size' => 1263, # in bytes 746 # 'mtime' => 1178135092, # modification time, seconds since epoch 747 # }, 748 # 749 # # If the entry has been deleted/changed, then this 750 # # hashtable contains the file/directory's old information. 751 # 'old' => { 752 # 'name' => 'C:\WINDOWS\SYSTEM32...', 753 # 'size' => 802, # in bytes 754 # 'mtime' => 1178135028, # modification time, seconds since epoch 755 # }, 756 # }, ] 662 757 sub _filter { 663 758 my ($self, $changes) = @_; … … 668 763 # Extract the file name from each entry. 669 764 my $name = undef; 670 if (($_->{status} eq 'added') or ($_->{status} eq 'changed')) {765 if (($_->{status} == $STATUS_ADDED) or ($_->{status} == $STATUS_MODIFIED)) { 671 766 $name = $_->{'new'}->{name}; 672 767 } else { … … 705 800 706 801 # Sanity check. 707 if ((($prev_entry->{status} eq 'changed') ||708 ($curr_entry->{status} eq 'changed')) ||709 (($prev_entry->{status} eq 'added') &&710 ($curr_entry->{status} eq 'added')) ||711 (($prev_entry->{status} eq 'deleted') &&712 ($curr_entry->{status} eq 'deleted'))) {802 if ((($prev_entry->{status} == $STATUS_MODIFIED) || 803 ($curr_entry->{status} == $STATUS_MODIFIED)) || 804 (($prev_entry->{status} == $STATUS_ADDED) && 805 ($curr_entry->{status} == $STATUS_ADDED)) || 806 (($prev_entry->{status} == $STATUS_DELETED) && 807 ($curr_entry->{status} == $STATUS_DELETED))) { 713 808 $LOG->error("Duplicate filesystem change entries were found. " . 714 809 "Previous Entry - " . Dumper($prev_entry) . " - ". … … 720 815 # If the previous entry was added and the current 721 816 # was deleted. 722 if (($prev_entry->{status} eq 'added') &&723 ($curr_entry->{status} eq 'deleted')) {724 $prev_entry->{status} = 'changed';817 if (($prev_entry->{status} == $STATUS_ADDED) && 818 ($curr_entry->{status} == $STATUS_DELETED)) { 819 $prev_entry->{status} = $STATUS_MODIFIED; 725 820 $prev_entry->{old} = $curr_entry->{old}; 726 821 … … 728 823 # current was added. 729 824 } else { 730 $prev_entry->{status} = 'changed';825 $prev_entry->{status} = $STATUS_MODIFIED; 731 826 $prev_entry->{'new'} = $curr_entry->{'new'}; 732 827 } … … 741 836 } 742 837 return $ret; 838 } 839 840 # A helper function, designed to manipulate the array of changes into 841 # a format that is expected by the check() function -- collecting 842 # more forensic data about each change along the way. 843 # 844 # Input: Array reference of hashtables 845 # Output: Array reference of hashtables (manipulated) 846 # Notes: This function expects hashtables in the following 847 # format: 848 # 849 # $inputChanges = [ { 850 # # Indicates if the filesystem entry was deleted, 851 # # added, or changed. 852 # 'status' => $STATUS_DELETED | $STATUS_ADDED | $STATUS_MODIFIED, 853 # 854 # # If the entry has been added/changed, then this 855 # # hashtable contains the file/directory's new information. 856 # 'new' => { 857 # 'name' => 'C:\WINDOWS\SYSTEM32...', 858 # 'size' => 1263, # in bytes 859 # 'mtime' => 1178135092, # modification time, seconds since epoch 860 # }, 861 # 862 # # If the entry has been deleted/changed, then this 863 # # hashtable contains the file/directory's old information. 864 # 'old' => { 865 # 'name' => 'C:\WINDOWS\SYSTEM32...', 866 # 'size' => 802, # in bytes 867 # 'mtime' => 1178135028, # modification time, seconds since epoch 868 # }, 869 # }, ] 870 # 871 # And outputs hashtables in the following format: 872 # 873 # $outputChanges = [ { 874 # # Indicates if the filesystem entry was deleted, 875 # # added, or changed. 876 # 'status' => $STATUS_DELETED | $STATUS_ADDED | $STATUS_MODIFIED, 877 # 'name' => 'C:\WINDOWS\SYSTEM32...', 878 # 'mtime' => 'YYYY-MM-DD HH:MM:SS', # new mtime for added/modified files; 879 # # old mtime for deleted files 880 # 881 # # content will only exist for added/modified files 882 # 'content' => { 883 # 'size' => 1263, # size of new content 884 # 'type' => 'application/octet-stream', # type of new content 885 # 'md5' => 'b1946ac92492d2347c6235b4d2611184', # md5 of new content 886 # 'sha1' => 'f572d396fae9206628714fb2ce00f72e94f2258f', # sha1 of new content 887 # }, 888 # }, ] 889 # 890 sub _prepare { 891 my ($self, $changes) = @_; 892 my $ret = []; 893 894 $LOG->debug("Preparing changes."); 895 896 my $md5_ctx = Digest::MD5->new(); 897 my $sha1_ctx = Digest::SHA->new("1"); 898 my $type_ctx = File::Type->new(); 899 900 foreach my $entry (@{$changes}) { 901 # Construct a new entry in the new format. 902 my $newEntry = { 903 'status' => $entry->{'status'}, 904 }; 905 906 # Figure out which type of entry it is. 907 if ($entry->{'status'} == $STATUS_DELETED) { 908 # Convert Filename 909 $newEntry->{'name'} = _convertFilename($entry->{'old'}->{'name'}); 910 $newEntry->{'mtime'} = _convertTime($entry->{'old'}->{'mtime'}); 911 912 $LOG->debug("Filename: " . $newEntry->{'name'}); 913 } else { 914 $newEntry->{'name'} = $entry->{'new'}->{'name'}; 915 $newEntry->{'mtime'} = _convertTime($entry->{'new'}->{'mtime'}); 916 917 $LOG->debug("Filename: " . $newEntry->{'name'}); 918 919 # Create a new file handle. 920 my $fh = IO::File->new($newEntry->{'name'}, "r"); 921 my $md5 = $HASH_UNKNOWN; 922 my $sha1 = $HASH_UNKNOWN; 923 my $type = $TYPE_UNKNOWN; 924 925 # Check to make sure the new/changed file exists. 926 if (defined($fh)) { 927 # If the entry is a directory. 928 if (-d $fh) { 929 $type = "directory"; 930 undef $fh; 931 932 # XXX: We currently skip all entries that 933 # only correspond to directories. 934 # This is a known limitation. 935 next; 936 937 # If the entry is a file. 938 } else { 939 # Compute MD5 Checksum. 940 $md5_ctx->addfile($fh); 941 $md5 = $md5_ctx->hexdigest(); 942 943 # Rewind file handle. 944 seek($fh, 0, 0); 945 946 # Compute SHA1 Checksum. 947 $sha1_ctx->addfile($fh); 948 $sha1 = $sha1_ctx->hexdigest(); 949 950 # Close the file handle. 951 undef $fh; 952 953 # Compute File Type. 954 $type = $type_ctx->mime_type($newEntry->{'name'}); 955 } 956 } 957 958 # Populate the content, accordingly. 959 $newEntry->{'content'} = { 960 'size' => $entry->{'new'}->{'size'}, 961 'type' => $type, 962 'md5' => $md5, 963 'sha1' => $sha1, 964 }; 965 966 # Convert Filename 967 $newEntry->{'name'} = _convertFilename($newEntry->{'name'}); 968 } 969 970 # Finally, push it onto our return array. 971 push (@{$ret}, $newEntry); 972 } 973 return $ret; 974 } 975 976 # Helper function, designed to convert seconds since epoch to 977 # an ISO 8601 date time format. 978 # 979 # Input: epoch 980 # Output: iso8601 date/time 981 sub _convertTime { 982 my $dt = DateTime->from_epoch(epoch => shift); 983 return $dt->ymd('-') . " " . $dt->hms(':'); 984 } 985 986 # Helper function, designed to convert Cygwin filename paths to 987 # a Windows format, where the output is always lowercase. 988 # 989 # Input: cygwin filename path 990 # Output: absolute windows filename path 991 sub _convertFilename { 992 return lc(fullwin32path(shift)); 743 993 } 744 994 … … 838 1088 } 839 1089 840 ################################################################################841 842 1090 =pod 843 1091 844 =head2 $object->check( )1092 =head2 $object->check(no_prepare => $no_prepare) 845 1093 846 1094 =over 4 … … 848 1096 Checks the filesystem for various changes, based upon 849 1097 the filesystem baseline, when the new() method was invoked. 1098 1099 I<Inputs>: 1100 B<$no_prepare> is an optional parameter, specifying the output 1101 format of the changes found. 850 1102 851 1103 I<Output>: … … 853 1105 hashtable has the following format: 854 1106 1107 If $no_prepare == 1, then the format will be: 1108 855 1109 $changes = [ { 856 1110 # Indicates if the filesystem entry was deleted, 857 1111 # added, or changed. 858 'status' => 'deleted' | 'added' | 'changed',1112 'status' => $STATUS_DELETED | $STATUS_ADDED | $STATUS_MODIFIED, 859 1113 860 1114 # If the entry has been added/changed, then this … … 875 1129 }, ] 876 1130 1131 Otherwise, the format will be: 1132 1133 $changes = [ { 1134 # Indicates if the filesystem entry was deleted, 1135 # added, or changed. 1136 'status' => $STATUS_DELETED | $STATUS_ADDED | $STATUS_MODIFIED, 1137 'name' => 'C:\WINDOWS\SYSTEM32...', 1138 'mtime' => 'YYYY-MM-DD HH:MM:SS', # new mtime for added/modified files; 1139 # old mtime for deleted files 1140 1141 # content will only exist for added/modified files 1142 'content' => { 1143 'size' => 1263, # size of new content 1144 'type' => 'application/octet-stream', # type of new content 1145 'md5' => 'b1946ac92492d2347c6235b4d2611184', # md5 of new content 1146 'sha1' => 'f572d396fae9206628714fb2ce00f72e94f2258f', # sha1 of new content 1147 }, 1148 }, ] 1149 877 1150 I<Notes>: 1151 If $no_prepare != 1 or $no_prepare == undef, then the outputted changes will B<NEVER> refer to 1152 any directories. All the changes will correspond to individual files. 878 1153 879 1154 =back … … 931 1206 close ADD_FILE; 932 1207 1208 my $md5_ctx = Digest::MD5->new(); 1209 my $sha1_ctx = Digest::SHA->new("1"); 1210 my $type_ctx = File::Type->new(); 1211 1212 my $add_fh = IO::File->new($add_file, "r"); 1213 $md5_ctx->addfile($add_fh); 1214 my $add_file_md5 = $md5_ctx->hexdigest(); 1215 seek($add_fh, 0, 0); 1216 $sha1_ctx->addfile($add_fh); 1217 my $add_file_sha1 = $sha1_ctx->hexdigest(); 1218 undef $add_fh; 1219 my $add_file_type = $type_ctx->mime_type($add_file); 1220 933 1221 @file_attr = stat($add_file); 934 1222 my $add_file_size = $file_attr[7]; … … 940 1228 close CHANGE_FILE; 941 1229 1230 my $change_fh = IO::File->new($change_file, "r"); 1231 $md5_ctx->addfile($change_fh); 1232 my $change_file_md5 = $md5_ctx->hexdigest(); 1233 seek($change_fh, 0, 0); 1234 $sha1_ctx->addfile($change_fh); 1235 my $change_file_sha1 = $sha1_ctx->hexdigest(); 1236 undef $change_fh; 1237 my $change_file_type = $type_ctx->mime_type($change_file); 1238 942 1239 @file_attr = stat($change_file); 943 1240 my $change_file_size2 = $file_attr[7]; … … 945 1242 946 1243 ### Perform check. 947 my $foundChanges = $filesystem->check( );1244 my $foundChanges = $filesystem->check(no_prepare => 1); 948 1245 949 1246 # Uncomment these lines, if you want to see more … … 956 1253 my $expectedChanges = [ 957 1254 { 958 'status' => 'changed',1255 'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_MODIFIED, 959 1256 'new' => { 960 1257 'name' => $change_file, … … 969 1266 }, 970 1267 { 971 'status' => 'added',1268 'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_ADDED, 972 1269 'new' => { 973 1270 'name' => $add_file, … … 977 1274 }, 978 1275 { 979 'status' => 'deleted',1276 'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_DELETED, 980 1277 'old' => { 981 1278 'name' => $delete_file, … … 986 1283 ]; 987 1284 988 is_deeply($foundChanges, $expectedChanges, "check(monitored_directories => [ $monitor_dir ], ignored_entries => [ $monitor_dir ])") or diag("The check() call failed."); 1285 is_deeply($foundChanges, $expectedChanges, "check(no_prepare => 1)") or diag("The check() call failed."); 1286 1287 ### Perform check. 1288 $foundChanges = $filesystem->check(); 1289 1290 # Uncomment these lines, if you want to see more 1291 # detailed information about the changes found. 1292 #$Data::Dumper::Terse = 0; 1293 #$Data::Dumper::Indent = 1; 1294 #diag(Dumper($foundChanges)); 1295 1296 ### Verify changes. 1297 $expectedChanges = [ 1298 { 1299 'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_MODIFIED, 1300 'name' => HoneyClient::Agent::Integrity::Filesystem::_convertFilename($change_file), 1301 'mtime' => HoneyClient::Agent::Integrity::Filesystem::_convertTime($change_file_mtime2), 1302 'content' => { 1303 'size' => $change_file_size2, 1304 'type' => $change_file_type, 1305 'sha1' => $change_file_sha1, 1306 'md5' => $change_file_md5, 1307 }, 1308 }, 1309 { 1310 'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_ADDED, 1311 'name' => HoneyClient::Agent::Integrity::Filesystem::_convertFilename($add_file), 1312 'mtime' => HoneyClient::Agent::Integrity::Filesystem::_convertTime($add_file_mtime), 1313 'content' => { 1314 'size' => $add_file_size, 1315 'type' => $add_file_type, 1316 'sha1' => $add_file_sha1, 1317 'md5' => $add_file_md5, 1318 }, 1319 }, 1320 { 1321 'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_DELETED, 1322 'name' => HoneyClient::Agent::Integrity::Filesystem::_convertFilename($delete_file), 1323 'mtime' => HoneyClient::Agent::Integrity::Filesystem::_convertTime($delete_file_mtime), 1324 }, 1325 ]; 1326 1327 is_deeply($foundChanges, $expectedChanges, "check()") or diag("The check() call failed."); 989 1328 990 1329 ### Clean up test data. … … 1015 1354 }); 1016 1355 1356 # Sanity checks; check if any args were specified. 1357 my $argsExist = scalar(%args); 1358 1017 1359 # Analyze the filesystem. 1018 1360 $LOG->info("Analyzing filesystem."); … … 1024 1366 $file_analysis, 1025 1367 { keyGen => \&_toString })); 1026 # Return filteredresults.1368 # Filter results. 1027 1369 $changes = $self->_filter($changes); 1028 1370 if (scalar(@{$changes})) { … … 1031 1373 $LOG->info("No filesystem changes found."); 1032 1374 } 1375 1376 # Prepare results, if not directed otherwise. 1377 if (!$argsExist || 1378 !exists($args{'no_prepare'}) || 1379 !defined($args{'no_prepare'}) || 1380 !$args{'no_prepare'}) { 1381 $changes = $self->_prepare($changes); 1382 } 1383 1384 # Return formatted results. 1033 1385 return $changes; 1034 1386 } … … 1059 1411 1060 1412 =back 1413 1414 This library also only monitors B<FILE> changes. Thus, if malware 1415 manipulates B<EMPTY DIRECTORIES> on the system, then this library will 1416 B<NOT&
