Changeset 119

Show
Ignore:
Timestamp:
12/17/06 02:35:40 (2 years ago)
Author:
kindlund
Message:

Completed basic capabilities of the Registry object; still have to add exclusion support.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • honeyclient/branches/bug/42/etc/honeyclient.xml

    r112 r119  
    163163            </test_dir> 
    164164            <Registry> 
     165                <!-- HoneyClient::Agent::Integrity::Registry::Test Options --> 
     166                <Test> 
     167                    <!-- 
     168                        Note: you should *never* need to change *any* values 
     169                        within this section of the configuration.  All contents 
     170                        are *only* used for unit testing. 
     171                    --> 
     172                    <before_registry_file description="The relative path to a (before) sample registry dump, that's used during unit testing." default="t/test_registry/before.reg"> 
     173                        t/test_registry/before.reg 
     174                    </before_registry_file> 
     175                    <after_registry_file description="The relative path to an (after) sample registry dump, that's used during unit testing." default="t/test_registry/after.reg"> 
     176                        t/test_registry/after.reg 
     177                    </after_registry_file> 
     178                </Test> 
    165179                <Parser> 
    166180                    <!-- HoneyClient::Agent::Integrity::Registry::Parser::Test Options --> 
  • honeyclient/branches/bug/42/etc/honeyclient_log.conf

    r112 r119  
    5959####################################################################### 
    6060 
    61 log4perl.rootLogger=DEBUG, Screen 
     61log4perl.rootLogger=INFO, Screen 
    6262# Suppress Parser Debugging Messages 
    63 log4perl.logger.HoneyClient.Agent.Integrity.Registry.Parser=INFO, Screen 
     63#log4perl.logger.HoneyClient.Agent.Integrity.Registry.Parser=INFO, Screen 
    6464log4perl.appender.Screen=Log::Log4perl::Appender::Screen 
    6565# If you want colorized logging to the screen, enable this line, instead. 
  • honeyclient/branches/bug/42/lib/HoneyClient/Agent/Integrity/Registry.pm

    r118 r119  
    246246can_ok('File::Temp', 'tmpnam'); 
    247247can_ok('File::Temp', 'unlink0'); 
     248can_ok('File::Temp', 'tempfile'); 
    248249use File::Temp qw(tmpnam unlink0); 
    249250 
     
    267268use HoneyClient::Agent::Integrity::Registry::Parser; 
    268269 
     270# Make sure HoneyClient::Agent::Integrity::Registry loads 
     271BEGIN { use_ok('HoneyClient::Agent::Integrity::Registry') 
     272        or diag("Can't load HoneyClient::Agent::Integrity::Registry package. Check to make sure the package library is correctly listed within the path."); } 
     273require_ok('HoneyClient::Agent::Integrity::Registry'); 
     274use HoneyClient::Agent::Integrity::Registry; 
     275 
     276# Make sure File::Basename loads. 
     277BEGIN { use_ok('File::Basename', qw(dirname basename fileparse)) or diag("Can't load File::Basename package.  Check to make sure the package library is correctly listed within the path."); } 
     278require_ok('File::Basename'); 
     279can_ok('File::Basename', 'dirname'); 
     280can_ok('File::Basename', 'basename'); 
     281can_ok('File::Basename', 'fileparse'); 
     282use File::Basename qw(dirname basename fileparse); 
     283 
    269284=end testing 
    270285 
     
    312327=back 
    313328 
     329=head2 bypass_baseline  
     330 
     331=over 4 
     332 
     333When set to 1, the object will forgo any type of initial baselining 
     334process, upon initialization.  Otherwise, baselining will occur 
     335as normal, upon initialization. 
     336 
     337=back 
     338 
    314339=cut 
    315340 
    316 # XXX: Update this, eventually. 
    317341my %PARAMS = ( 
    318342 
     
    320344    # analyze. 
    321345    hives_to_check => [  
    322 #                        'HKEY_LOCAL_MACHINE', 
    323 #                        'HKEY_CLASSES_ROOT', 
     346                        'HKEY_LOCAL_MACHINE', 
     347                        'HKEY_CLASSES_ROOT', 
    324348                        'HKEY_CURRENT_USER', 
    325 #                        'HKEY_USERS', 
    326 #                        'HKEY_CURRENT_CONFIG', 
     349                        'HKEY_USERS', 
     350                        'HKEY_CURRENT_CONFIG', 
    327351                      ], 
    328352 
     
    332356    # to all content in these matches will also be ignored. 
    333357    key_dirnames_to_ignore => [ ], 
     358 
     359 
     360    # When set to 1, the object will forgo any type of initial baselining 
     361    # process, upon initialization.  Otherwise, baselining will occur 
     362    # as normal, upon initialization. 
     363    bypass_baseline => 0, 
    334364 
    335365    # Baseline File Collection 
     
    379409    my $self = shift; 
    380410 
    381     # TODO: Should eventually delete, based upon $self->_filenames 
    382411    # Delete any temporary files created. 
    383 #    foreach my $hive (@{$self->{hives_to_check}}) { 
    384 #        my $fh = $self->{_baseline_parsers}->{$hive}; 
    385 #        $LOG->debug("Deleting baseline of hive '" . $hive . "' in '" . 
    386 #                    $self->{_filenames}->{$fh} . "'."); 
    387 #        undef($fh); 
    388 #    } 
    389 
    390  
    391 # Trap terminating signals, to perform graceful cleanup. 
    392 END { 
     412    my $parser = undef; 
     413    my $fname = undef; 
     414    foreach my $hive (@{$self->{hives_to_check}}) { 
     415        $parser = $self->{_baseline_parsers}->{$hive}; 
     416        if (defined($parser)) { 
     417            $fname = $self->{_filenames}->{$parser}; 
     418            $LOG->debug("Deleting baseline of hive '" . $hive . "' in '" . 
     419                        $fname . "'."); 
     420            if (!unlink0($parser->getFileHandle(), $fname)) { 
     421                $LOG->fatal("Error: Unable to unlink '" . $hive . "' hive data in '" . $fname ."'."); 
     422                Carp::croak("Error: Unable to unlink '" . $hive . "' hive data in '" . $fname ."'."); 
     423            } 
     424            delete($self->{_filenames}->{$parser}); 
     425            delete($self->{_baseline_parsers}->{$hive}); 
     426        } 
     427        $parser = $self->{_checkpoint_parsers}->{$hive}; 
     428        if (defined($parser)) { 
     429            $fname = $self->{_filenames}->{$parser}; 
     430            $LOG->debug("Deleting checkpoint of hive '" . $hive . "' in '" . 
     431                        $fname . "'."); 
     432            if (!unlink0($parser->getFileHandle(), $fname)) { 
     433                $LOG->fatal("Error: Unable to unlink '" . $hive . "' hive data in '" . $fname ."'."); 
     434                Carp::croak("Error: Unable to unlink '" . $hive . "' hive data in '" . $fname ."'."); 
     435            } 
     436            delete($self->{_filenames}->{$parser}); 
     437            delete($self->{_checkpoint_parsers}->{$hive}); 
     438        } 
     439    } 
    393440} 
    394441 
     
    428475        $parser = HoneyClient::Agent::Integrity::Registry::Parser->init(input_file   => $fname, 
    429476                                                                        index_groups => 1); 
    430  
    431         # Preemptively unlink the file, to prevent any other process from mucking with it. 
    432         # XXX: Check if this can still be used. 
    433 #        if (!unlink0($parser->getFileHandle(), $fname)) { 
    434 #            $LOG->fatal("Error: Unable to unlink '" . $hive . "' hive data in '" . $fname ."'."); 
    435 #            Carp::croak("Error: Unable to unlink '" . $hive . "' hive data in '" . $fname ."'."); 
    436 #        } 
    437477 
    438478        $parser_collection->{$hive} = $parser; 
     
    669709} 
    670710 
    671 # TODO: Comment this. 
     711# Helper function, designed to compare the contents of two registry dumps, 
     712# where each dump is represented by a Parser object. 
     713
     714# Inputs: before_parser => bparser, after_parser => aparser 
     715# Outputs: an arrayref of registry changes 
    672716sub _compare { 
    673717 
     
    691735    # State variable: 
    692736    # - Positive value: Keep comparing groups, linearly. 
    693     # - Negative value: Stop comparing groups, seek to next diff. 
     737    # - Zero or Negative value: Stop comparing groups, seek to 
     738    #                           next diff. 
    694739    # 
    695740    # Note: When a comparison is different, then this variable's 
     
    704749    my ($before_linenums, $after_linenums, $diff_types) = $self->_diff($before_parser, $after_parser); 
    705750 
     751    # Helper variable, used to indirectly locate the corresponding 
     752    # diff type of the current group block. 
     753    my $found_index = undef; 
     754 
    706755    # Helper variables, to extract the latest line number from the diff 
    707756    # operation, along with the latest diff type. 
     
    739788            $diff_type      = shift(@{$diff_types}); 
    740789 
    741  print("Before: ", Dumper($before_linenum) . "\n"); 
    742  print("After: ", Dumper($after_linenum) . "\n"); 
    743  
    744790            # Return early, if no changes were found. 
    745791            if (!defined($before_linenum) && !defined($after_linenum)) { 
    746                 # TODO: delete this, eventually. 
    747                 #$Data::Dumper::Terse = 1; 
    748                 #$Data::Dumper::Indent = 1; 
    749                 #print "Complete list: " . Dumper($changes) . "\n"; 
    750  
    751792                return $changes; 
    752793            } 
     
    755796            $before_total_linenums += $before_parser->getCurrentLineCount(); 
    756797            $after_total_linenums += $after_parser->getCurrentLineCount(); 
    757 print("Before Total Linenums: ", Dumper($before_total_linenums) . "\n"); 
    758 print("After Total Linenums: ", Dumper($after_total_linenums) . "\n"); 
    759798 
    760799            # Seek to nearest common group, that we haven't already parsed. 
    761             # TODO: Check to make sure that linking them is okay. 
    762800            if (($before_linenum > $before_total_linenums) && 
    763801                ($after_linenum > $after_total_linenums)) { 
     
    797835            $after_total_linenums += $after_parser->getCurrentLineCount(); 
    798836 
    799 $self->{'_group_index_linenums'} = $before_linenums; 
    800 my $found_index = binary_search(0, scalar(@{$before_linenums}) - 1, $before_total_linenums, \&_search, $self); 
    801  
    802 # Find the group before corresponding the matched line number. 
    803 if ($found_index > 0) { 
    804     $found_index--; 
    805 
    806  
    807 print("FOUND INDEX: " . Dumper($found_index) . "\n"); 
    808 print("FOUND B_LINENO: " . Dumper(@{$before_linenums}[$found_index]) . "\n"); 
    809 print("FOUND TYPE: " . Dumper(@{$diff_types}[$found_index]) . "\n"); 
    810 $diff_type = @{$diff_types}[$found_index]; 
    811  
    812 print("Before Current Linenums: ", Dumper($before_total_linenums) . "\n"); 
    813 print("After Current Linenums: ", Dumper($after_total_linenums) . "\n"); 
    814  
    815 print "Before Group: " . Dumper($before_group) . "\n"; 
    816 print "After Group: " . Dumper($after_group) . "\n"; 
     837            # Specify the array of line numbers to search in. 
     838            $self->{'_group_index_linenums'} = $before_linenums; 
     839 
     840            # Find the group after the corresponding matched line number. 
     841            $found_index = binary_search(0, scalar(@{$before_linenums}) - 1, $before_total_linenums, \&_search, $self); 
     842 
     843            # Find the group before the corresponding matched line number. 
     844            if ($found_index > 0) { 
     845                $found_index--; 
     846            } 
     847  
     848            # Fetch the corresponding $diff_type 
     849            $diff_type = @{$diff_types}[$found_index]; 
    817850 
    818851            # Reset the current change hashref. 
     
    10281061            } 
    10291062        } 
    1030  
    10311063    } 
    10321064} 
     
    10421074The following functions have been implemented by any Registry object. 
    10431075 
    1044 =head2 HoneyClient::Agent::Driver::Browser->new($param => $value, ...) 
     1076=head2 HoneyClient::Agent::Integrity::Registry->new($param => $value, ...) 
    10451077 
    10461078=over 4 
     
    10621094=begin testing 
    10631095 
     1096diag("These tests will create temporary files in /tmp.  Be sure to cleanup this directory, if any of these tests fail."); 
     1097 
    10641098# Create a generic Registry object, with test state data. 
    1065 my $registry = HoneyClient::Agent::Integrity::Registry->new(test => 1); 
    1066 is($registry->{test}, 1, "new(test => 1)") or diag("The new() call failed."); 
     1099my $registry = HoneyClient::Agent::Integrity::Registry->new(test => 1, bypass_baseline => 1); 
     1100is($registry->{test}, 1, "new(test => 1, bypass_baseline => 1)") or diag("The new() call failed."); 
     1101isa_ok($registry, 'HoneyClient::Agent::Integrity::Registry', "new(test => 1, bypass_baseline => 1)") or diag("The new() call failed."); 
     1102 
     1103diag("Performing baseline check of 'HKEY_CURRENT_USER' hive; this may take some time..."); 
     1104 
     1105# Perform Registry baseline on HKEY_CURRENT_USER. 
     1106$registry = HoneyClient::Agent::Integrity::Registry->new(hives_to_check => [ 'HKEY_CURRENT_USER' ]); 
     1107isa_ok($registry, 'HoneyClient::Agent::Integrity::Registry', "new(hives_to_check => [ 'HKEY_CURRENT_USER' ])") or diag("The new() call failed."); 
    10671108 
    10681109=end testing 
     
    11121153    bless $self, $class; 
    11131154 
    1114     # Perform registry baselining. 
    1115     $self->_snapshot($self->{_baseline_parsers}); 
     1155    # Perform registry baselining, if not bypassed. 
     1156    if (!$self->{'bypass_baseline'}) { 
     1157        $LOG->info("Baselining target registry hives."); 
     1158        $self->_snapshot($self->{_baseline_parsers}); 
     1159    } 
    11161160 
    11171161    # Finally, return the blessed object. 
     
    11211165=pod 
    11221166 
    1123 =head2 $object->check(
     1167=head2 $object->check(before_file => $before_filename, after_file => $after_filename
    11241168 
    11251169=over 4 
     
    11291173 
    11301174I<Inputs>: 
    1131 # XXX: Add here. 
     1175 B<$before_filename> is an optional parameter, specifying the registry dump to use 
     1176as the baseline, rather than using any baseline that was performed during the 
     1177$object->new() operation. 
     1178 B<$after_filename> is an optional parameter, specifying the registry dump to use 
     1179as the checkpoint, rather than creating new a registry checkpoint to compare against. 
    11321180 
    11331181I<Output>: 
     
    11561204  }, ] 
    11571205 
     1206I<Notes>: If B<$before_filename> is specified, then B<$after_filename> must be  
     1207specified as well. 
     1208 
    11581209=back 
    11591210 
    11601211=begin testing 
    11611212 
    1162 # XXX: Test this. 
    1163 1; 
     1213my ($foundChanges, $expectedChanges); 
     1214my $before_registry_file = $ENV{PWD} . "/" . getVar(name      => "before_registry_file", 
     1215                                                    namespace => "HoneyClient::Agent::Integrity::Registry::Test"); 
     1216my $after_registry_file = $ENV{PWD} . "/" . getVar(name      => "after_registry_file", 
     1217                                                   namespace => "HoneyClient::Agent::Integrity::Registry::Test"); 
     1218 
     1219 
     1220# Create a generic Registry object, with test state data. 
     1221my $registry = HoneyClient::Agent::Integrity::Registry->new(bypass_baseline => 1); 
     1222 
     1223# Verify Changes 
     1224$foundChanges = $registry->check(before_file => $before_registry_file, 
     1225                                 after_file  => $after_registry_file); 
     1226$expectedChanges = [ 
     1227  { 
     1228    'entries' => [ 
     1229      { 
     1230        'new_value' => undef, 
     1231        'name' => 'Test_Bin_1', 
     1232        'old_value' => 'hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,bc,02,00,00,00,\\ 
     1233  00,00,00,00,00,00,00,54,00,61,00,68,00,6f,00,6d,00,61,00,00,00,f0,77,3f,00,\\ 
     1234  3f,00,3f,00,3f,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,78,00,1c,10,fc,\\ 
     1235  7f,22,14,fc,7f,b0,fe,12,00,00,00,00,00,00,00,00,00,98,23,eb,77', 
     1236      }, 
     1237      { 
     1238        'new_value' => 'hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,bc,02,00,00,00,\\ 
     1239  00,00,00,00,00,00,00,54,00,61,00,68,00,6f,00,6d,00,61,00,00,00,f0,77,3f,00,\\ 
     1240  3f,00,3f,00,3f,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,78,00,1c,10,fc,\\ 
     1241  7f,22,14,fc,7f,b0,fe,12,00,00,00,00,00,00,00,00,00,98,23,eb,77', 
     1242        'name' => 'Test_Bon_1', 
     1243        'old_value' => undef, 
     1244      } 
     1245    ], 
     1246    'status' => 'changed', 
     1247    'key' => 'HKEY_CURRENT_USER\\Testing Group 3', 
     1248  }, 
     1249  { 
     1250    'entries' => [], 
     1251    'status' => 'deleted', 
     1252    'key' => 'HKEY_CURRENT_USER\\Testing Group 4', 
     1253  }, 
     1254  { 
     1255    'entries' => [ 
     1256      { 
     1257        'new_value' => 'new value', 
     1258        'name' => '@', 
     1259        'old_value' => '', 
     1260      } 
     1261    ], 
     1262    'status' => 'changed', 
     1263    'key' => 'HKEY_CURRENT_USER\\Testing Group 5', 
     1264  }, 
     1265  { 
     1266    'entries' => [ 
     1267      { 
     1268        'new_value' => 'hex:f5,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,90,01,00,00,00,\\ 
     1269  00,00,00,00,00,00,00,4d,00,69,00,63,00,72,00,6f,00,73,00,6f,00,66,00,74,00,\\ 
     1270  20,00,53,00,61,00,6e,00,73,00,20,00,53,00,65,00,72,00,69,00,66,00,00,00,f0,\\ 
     1271  77,00,20,14,00,00,00,00,10,80,05,14,00,f0,1f,14,00,00,00,14,00', 
     1272        'name' => 'Test_Bin_3', 
     1273        'old_value' => undef, 
     1274      } 
     1275    ], 
     1276    'status' => 'added', 
     1277    'key' => 'HKEY_CURRENT_USER\\Testing Group 6', 
     1278  }, 
     1279  { 
     1280    'entries' => [ 
     1281      { 
     1282        'new_value' => 'C:\\\\WINDOWSsystem32\\\\', 
     1283        'name' => 'InstallerLocation', 
     1284        'old_value' => 'C:\\\\WINDOWS\\\\system32\\\\', 
     1285      } 
     1286    ], 
     1287    'status' => 'changed', 
     1288    'key' => 'HKEY_CURRENT_USER\\Testing Group 6\\With\\Really\\Deep\\Nested\\Directory\\Structure', 
     1289  }, 
     1290  { 
     1291    'entries' => [ 
     1292      { 
     1293        'new_value' => '', 
     1294        'name' => 'C:\\\\WINDOWS\\\\Installer\\\\{6855XXXX-BDF9-48E4-B80A-80DFB96FE36C}\\\\', 
     1295        'old_value' => undef, 
     1296      }, 
     1297      { 
     1298        'new_value' => undef, 
     1299        'name' => 'C:\\\\WINDOWS\\\\Installer\\\\{6855CCDD-BDF9-48E4-B80A-80DFB96FE36C}\\\\', 
     1300        'old_value' => '', 
     1301      } 
     1302    ], 
     1303    'status' => 'changed', 
     1304    'key' => 'HKEY_CURRENT_USER\\Testing Group 7', 
     1305  }, 
     1306  { 
     1307    'entries' => [ 
     1308      { 
     1309        'new_value' => undef, 
     1310        'name' => '000', 
     1311        'old_value' => 'String Value', 
     1312      } 
     1313    ], 
     1314    'status' => 'deleted', 
     1315    'key' => 'HKEY_CURRENT_USER\\Testing Group 8\\{00021492-0000-0000-C000-000000000046}', 
     1316  }, 
     1317  { 
     1318    'entries' => [ 
     1319      { 
     1320        'new_value' => 'String Value', 
     1321        'name' => '000', 
     1322        'old_value' => undef, 
     1323      } 
     1324    ], 
     1325    'status' => 'added', 
     1326    'key' => 'HKEY_CURRENT_USER\\Testing Group 8\\{01021492-0000-0000-C000-000000000046}', 
     1327  }, 
     1328  { 
     1329    'entries' => [ 
     1330      { 
     1331        'new_value' => 'newvalue', 
     1332        'name' => 'newkey', 
     1333        'old_value' => undef, 
     1334      } 
     1335    ], 
     1336    'status' => 'added', 
     1337    'key' => 'HKEY_CURRENT_USER\\Tsting Group 9', 
     1338  } 
     1339]; 
     1340 
     1341is_deeply($foundChanges, $expectedChanges, "check(before_file => '" . $before_registry_file . "', after_file => '" . $after_registry_file . "')") or diag("The check() call failed."); 
    11641342 
    11651343=end testing 
     
    12031381    } 
    12041382 
    1205     # Array reference, containing hashtables, where each 
     1383    # Array references, containing hashtables, where each 
    12061384    # hashtable represents a change between the registry hives. 
    1207     my $changes = [];  
     1385    my $changes = []; 
     1386    my $local_changes = []; 
    12081387 
    12091388    # Check to see if a before and after file were specified. 
     
    12251404            $after_parser  = $self->{_checkpoint_parsers}->{$hive}; 
    12261405 
    1227             # TODO: Need to concatinate existing change array. 
    1228             $changes = $self->_compare(before_parser => $before_parser, 
    1229                                        after_parser  => $after_parser); 
     1406            # Obtain local changes per hive. 
     1407            $local_changes = $self->_compare(before_parser => $before_parser, 
     1408                                             after_parser  => $after_parser); 
     1409            # Concatinate these changes, to obtain a complete picture. 
     1410            $changes = [ @{$changes}, @{$local_changes}, ]; 
    12301411 
    12311412            $LOG->info("Finished checking '" . $hive . "' hive."); 
     
    12371418}         
    12381419 
     1420=pod 
     1421 
     1422=head2 $object->getFilesCreated() 
     1423 
     1424=over 4 
     1425 
     1426Returns a list of temporary filenames that have been created by the 
     1427Registry B<$object>. 
     1428 
     1429I<Output>: Returns a list of filenames. 
     1430 
     1431=back 
     1432 
     1433=begin testing 
     1434 
     1435# Perform Registry baseline on HKEY_CURRENT_CONFIG. 
     1436diag("Performing baseline check of 'HKEY_CURRENT_CONFIG' hive; this may take some time..."); 
     1437my $registry = HoneyClient::Agent::Integrity::Registry->new(hives_to_check => [ 'HKEY_CURRENT_CONFIG' ]); 
     1438my @files_created = $registry->getFilesCreated(); 
     1439use Data::Dumper; 
     1440my $tmpfile = tmpnam(); 
     1441unlink($tmpfile);  
     1442my $tmpdir = dirname($tmpfile); 
     1443foreach my $file (@files_created) { 
     1444    like($file, qr/$tmpdir/, "getFilesCreated()") or diag("The getFilesCreated() call failed."); 
     1445} 
     1446 
     1447=end testing 
     1448 
     1449=cut 
     1450 
     1451sub getFilesCreated { 
     1452    # Extract arguments. 
     1453    my ($self, %args) = @_; 
     1454 
     1455    # Log resolved arguments. 
     1456    # Make Dumper format more terse. 
     1457    $Data::Dumper::Terse = 1; 
     1458    $Data::Dumper::Indent = 0; 
     1459    $LOG->debug(Dumper(\%args)); 
     1460 
     1461    return values(%{$self->{_filenames}}); 
     1462} 
     1463 
    123914641; 
    12401465 
     
    12471472=head1 BUGS & ASSUMPTIONS 
    12481473 
    1249 XXX: Fill this in. 
     1474By default, this module performs a baseline integrity check on the 
     1475Windows OS registry during the $object->new() call.  The $object->check() 
     1476call will return any B<visible> changes found in the registry, between 
     1477these two calls. 
     1478 
     1479Any changes that occur to the Windows registry that are performed and 
     1480then undone between these integrity checks B<WILL NOT BE DISCOVERED> by 
     1481the $object->check() operation. 
     1482 
     1483This module relies on the REGEDIT.EXE utility program that is standard 
     1484on all Windows OS installations.  Because REGEDIT.EXE does not expose 
     1485null-encoded registry directory keys, this module will B<NOT> be able 
     1486to identify any adds, deletions, and/or changes to these types of 
     1487directory keys. 
     1488 
     1489For more information about the limitations of this module, please see: 
     1490 
     1491L<http://www.honeyclient.org/trac/wiki/ParsingRegistry> 
    12501492 
    12511493=head1 SEE ALSO 
  • honeyclient/branches/bug/42/lib/HoneyClient/Agent/Integrity/Registry/Parser.pm

    r118 r119  
    14541454    if($self->YYData->{'search_is_linenum'}) { 
    14551455        my $found_linenum = @{$self->YYData->{'group_index_linenums'}}[$found_index]; 
    1456         # TODO: Change this to debug, eventually. 
    1457         $LOG->info("Seeking parser to nearest earlier group line number (" . $found_linenum . ")."); 
     1456        $LOG->debug("Seeking parser to nearest earlier group line number (" . $found_linenum . ")."); 
    14581457        return $found_linenum; 
    14591458    } else { 
  • honeyclient/branches/bug/42/lib/HoneyClient/Agent/Integrity/Registry/Parser.yp

    r118 r119  
    12991299    if($self->YYData->{'search_is_linenum'}) { 
    13001300        my $found_linenum = @{$self->YYData->{'group_index_linenums'}}[$found_index]; 
    1301         # TODO: Change this to debug, eventually. 
    1302         $LOG->info("Seeking parser to nearest earlier group line number (" . $found_linenum . ")."); 
     1301        $LOG->debug("Seeking parser to nearest earlier group line number (" . $found_linenum . ")."); 
    13031302        return $found_linenum; 
    13041303    } else { 
  • honeyclient/branches/bug/42/t/honeyclient_agent_integrity_registry.t

    r99 r119  
    8080can_ok('File::Temp', 'tmpnam'); 
    8181can_ok('File::Temp', 'unlink0'); 
     82can_ok('File::Temp', 'tempfile'); 
    8283use File::Temp qw(tmpnam unlink0); 
    8384 
     
    8889use Filesys::CygwinPaths qw(:all); 
    8990 
     91# Make sure Search::Binary loads 
     92BEGIN { use_ok('Search::Binary') 
     93        or diag("Can't load Search::Binary package. Check to make sure the package library is correctly listed within the path."); } 
     94require_ok('Search::Binary'); 
     95can_ok('Search::Binary', 'binary_search'); 
     96use Search::Binary; 
     97 
    9098# Make sure HoneyClient::Agent::Integrity::Registry::Parser loads 
    9199BEGIN { use_ok('HoneyClient::Agent::Integrity::Registry::Parser') 
     
    93101require_ok('HoneyClient::Agent::Integrity::Registry::Parser'); 
    94102use HoneyClient::Agent::Integrity::Registry::Parser; 
    95 
    96  
    97  
    98  
    99 # =begin testing 
    100 
     103 
     104# Make sure HoneyClient::Agent::Integrity::Registry loads 
     105BEGIN { use_ok('HoneyClient::Agent::Integrity::Registry') 
     106        or diag("Can't load HoneyClient::Agent::Integrity::Registry package. Check to make sure the package library is correctly listed within the path."); } 
     107require_ok('HoneyClient::Agent::Integrity::Registry'); 
     108use HoneyClient::Agent::Integrity::Registry; 
     109 
     110# Make sure File::Basename loads. 
     111BEGIN { use_ok('File::Basename', qw(dirname basename fileparse)) or diag("Can't load File::Basename package.  Check to make sure the package library is correctly listed within the path."); } 
     112require_ok('File::Basename'); 
     113can_ok('File::Basename', 'dirname'); 
     114can_ok('File::Basename', 'basename'); 
     115can_ok('File::Basename', 'fileparse'); 
     116use File::Basename qw(dirname basename fileparse); 
     117
     118 
     119 
     120 
     121# =begin testing 
     122
     123diag("These tests will create temporary files in /tmp.  Be sure to cleanup this directory, if any of these tests fail."); 
     124 
    101125# Create a generic Registry object, with test state data. 
    102 my $registry = HoneyClient::Agent::Integrity::Registry->new(test => 1); 
    103 is($registry->{test}, 1, "new(test => 1)") or diag("The new() call failed."); 
    104 
    105  
    106  
    107  
    108 # =begin testing 
    109 
    110 # XXX: Test this. 
     126my $registry = HoneyClient::Agent::Integrity::Registry->new(test => 1, bypass_baseline => 1); 
     127is($registry->{test}, 1, "new(test => 1, bypass_baseline => 1)") or diag("The new() call failed."); 
     128isa_ok($registry, 'HoneyClient::Agent::Integrity::Registry', "new(test => 1, bypass_baseline => 1)") or diag("The new() call failed."); 
     129 
     130diag("Performing baseline check of 'HKEY_CURRENT_USER' hive; this may take some time..."); 
     131 
     132# Perform Registry baseline on HKEY_CURRENT_USER. 
     133$registry = HoneyClient::Agent::Integrity::Registry->new(hives_to_check => [ 'HKEY_CURRENT_USER' ]); 
     134isa_ok($registry, 'HoneyClient::Agent::Integrity::Registry', "new(hives_to_check => [ 'HKEY_CURRENT_USER' ])") or diag("The new() call failed."); 
     135
     136 
     137 
     138 
     139# =begin testing 
     140
     141my ($foundChanges, $expectedChanges); 
     142my $before_registry_file = $ENV{PWD} . "/" . getVar(name      => "before_registry_file", 
     143                                                    namespace => "HoneyClient::Agent::Integrity::Registry::Test"); 
     144my $after_registry_file = $ENV{PWD} . "/" . getVar(name      => "after_registry_file", 
     145                                                   namespace => "HoneyClient::Agent::Integrity::Registry::Test"); 
     146 
     147 
     148# Create a generic Registry object, with test state data. 
     149my $registry = HoneyClient::Agent::Integrity::Registry->new(bypass_baseline => 1); 
     150 
     151# Verify Changes 
     152$foundChanges = $registry->check(before_file => $before_registry_file, 
     153                                 after_file  => $after_registry_file); 
     154$expectedChanges = [ 
     155  { 
     156    'entries' => [ 
     157      { 
     158        'new_value' => undef, 
     159        'name' => 'Test_Bin_1', 
     160        'old_value' => 'hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,bc,02,00,00,00,\\ 
     161  00,00,00,00,00,00,00,54,00,61,00,68,00,6f,00,6d,00,61,00,00,00,f0,77,3f,00,\\ 
     162  3f,00,3f,00,3f,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,78,00,1c,10,fc,\\ 
     163  7f,22,14,fc,7f,b0,fe,12,00,00,00,00,00,00,00,00,00,98,23,eb,77', 
     164      }, 
     165      { 
     166        'new_value' => 'hex:f4,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,bc,02,00,00,00,\\ 
     167  00,00,00,00,00,00,00,54,00,61,00,68,00,6f,00,6d,00,61,00,00,00,f0,77,3f,00,\\ 
     168  3f,00,3f,00,3f,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,78,00,1c,10,fc,\\ 
     169  7f,22,14,fc,7f,b0,fe,12,00,00,00,00,00,00,00,00,00,98,23,eb,77', 
     170        'name' => 'Test_Bon_1', 
     171        'old_value' => undef, 
     172      } 
     173    ], 
     174    'status' => 'changed', 
     175    'key' => 'HKEY_CURRENT_USER\\Testing Group 3', 
     176  }, 
     177  { 
     178    'entries' => [], 
     179    'status' => 'deleted', 
     180    'key' => 'HKEY_CURRENT_USER\\Testing Group 4', 
     181  }, 
     182  { 
     183    'entries' => [ 
     184      { 
     185        'new_value' => 'new value', 
     186        'name' => '@', 
     187        'old_value' => '', 
     188      } 
     189    ], 
     190    'status' => 'changed', 
     191    'key' => 'HKEY_CURRENT_USER\\Testing Group 5', 
     192  }, 
     193  { 
     194    'entries' => [ 
     195      { 
     196        'new_value' => 'hex:f5,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,90,01,00,00,00,\\ 
     197  00,00,00,00,00,00,00,4d,00,69,00,63,00,72,00,6f,00,73,00,6f,00,66,00,74,00,\\ 
     198  20,00,53,00,61,00,6e,00,73,00,20,00,53,00,65,00,72,00,69,00,66,00,00,00,f0,\\ 
     199  77,00,20,14,00,00,00,00,10,80,05,14,00,f0,1f,14,00,00,00,14,00', 
     200        'name' => 'Test_Bin_3', 
     201        'old_value' => undef, 
     202      } 
     203    ], 
     204    'status' => 'added', 
     205    'key' => 'HKEY_CURRENT_USER\\Testing Group 6', 
     206  }, 
     207  { 
     208    'entries' => [ 
     209      { 
     210        'new_value' => 'C:\\\\WINDOWSsystem32\\\\', 
     211        'name' => 'InstallerLocation', 
     212        'old_value' => 'C:\\\\WINDOWS\\\\system32\\\\', 
     213      } 
     214    ], 
     215    'status' => 'changed', 
     216    'key' => 'HKEY_CURRENT_USER\\Testing Group 6\\With\\Really\\Deep\\Nested\\Directory\\Structure', 
     217  }, 
     218  { 
     219    'entries' => [ 
     220      { 
     221        'new_value' => '', 
     222        'name' => 'C:\\\\WINDOWS\\\\Installer\\\\{6855XXXX-BDF9-48E4-B80A-80DFB96FE36C}\\\\', 
     223        'old_value' => undef, 
     224      }, 
     225      { 
     226        'new_value' => undef, 
     227        'name' => 'C:\\\\WINDOWS\\\\Installer\\\\{6855CCDD-BDF9-48E4-B80A-80DFB96FE36C}\\\\', 
     228        'old_value' => '', 
     229      } 
     230    ], 
     231    'status' => 'changed', 
     232    'key' => 'HKEY_CURRENT_USER\\Testing Group 7', 
     233  }, 
     234  { 
     235    'entries' => [ 
     236      { 
     237        'new_value' => undef, 
     238        'name' => '000', 
     239        'old_value' => 'String Value', 
     240      } 
     241    ], 
     242    'status' => 'deleted', 
     243    'key' => 'HKEY_CURRENT_USER\\Testing Group 8\\{00021492-0000-0000-C000-000000000046}', 
     244  }, 
     245  { 
     246    'entries' => [ 
     247      { 
     248        'new_value' => 'String Value', 
     249        'name' => '000', 
     250        'old_value' => undef, 
     251      } 
     252    ], 
     253    'status' => 'added', 
     254    'key' => 'HKEY_CURRENT_USER\\Testing Group 8\\{01021492-0000-0000-C000-000000000046}', 
     255  }, 
     256  { 
     257    'entries' => [ 
     258      { 
     259        'new_value' => 'newvalue', 
     260        'name' => 'newkey', 
     261        'old_value' => undef, 
     262      } 
     263    ], 
     264    'status' => 'added', 
     265    'key' => 'HKEY_CURRENT_USER\\Tsting Group 9', 
     266  } 
     267]; 
     268 
     269is_deeply($foundChanges, $expectedChanges, "check(before_file => '" . $before_registry_file . "', after_file => '" . $after_registry_file . "')") or diag("The check() call failed."); 
     270
     271 
     272 
     273 
     274# =begin testing 
     275
     276# Perform Registry baseline on HKEY_CURRENT_CONFIG. 
     277diag("Performing baseline check of 'HKEY_CURRENT_CONFIG' hive; this may take some time..."); 
     278my $registry = HoneyClient::Agent::Integrity::Registry->new(hives_to_check => [ 'HKEY_CURRENT_CONFIG' ]); 
     279my @files_created = $registry->getFilesCreated(); 
     280use Data::Dumper; 
     281my $tmpfile = tmpnam(); 
     282unlink($tmpfile);  
     283my $tmpdir = dirname($tmpfile); 
     284foreach my $file (@files_created) { 
     285    like($file, qr/$tmpdir/, "getFilesCreated()") or diag("The getFilesCreated() call failed."); 
     286
     287
     288 
     289 
     290 
     291 
    1112921; 
    112 } 
    113  
    114  
    115  
    116  
    117 1;