Changeset 150
- Timestamp:
- 01/10/07 13:37:40 (2 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager/DB.pm
r60 r150 9 9 ############################################################################## 10 10 # Package: HoneyClient::Manager::DB 11 # $LastChangedRevision: 183 0$11 # $LastChangedRevision: 1834 $ 12 12 # File: DB.pm 13 13 # Description: A module server that provides an interface to the Honeyclient DB 14 14 # Author: mbriggs 15 15 # 16 # CVS: $Id: DB.pm 183 0 2006-11-30 20:43:34Z mbriggs $16 # CVS: $Id: DB.pm 1834 2007-01-10 18:10:58Z mbriggs $ 17 17 # 18 18 # Copyright (C) 2006 The MITRE Corporation. All rights reserved. … … 100 100 vmid => 1, 101 101 datedetected => 0, 102 subsecs => 0,103 102 CVENum => 0, 104 103 notes => 0, … … 109 108 Files => { 110 109 fields => { 111 md5 => 1, 112 sha1 => 1, 110 content => { 111 md5 => 1, 112 sha1 => 1, 113 size => 1, 114 type => 1, 115 notes => 0, 116 }, 113 117 path => 1, 114 118 name => 1, 115 size => 1,116 type => 1,117 119 datecreated => 0, 118 subsecs => 0,119 notes => 0,120 120 }, 121 121 selectFunc => \&_SelectFiles, … … 124 124 RegKeys => { 125 125 fields => { 126 key => 1, 127 name => 1, 128 value => 1, 126 key_name => 1, 127 status => 1, 128 entries => { 129 name => 1, 130 new_val => 1, 131 old_val => 1, 132 }, 129 133 datecreated => 0, 130 subsecs => 0,131 134 notes => 0, 132 '`key`' => 0 # TODO: HACK - Find a better way handle this!133 135 }, 134 136 selectFunc => undef, … … 139 141 name => 1, 140 142 datecreated => 0, 141 subsecs => 0,142 143 notes => 0, 143 144 }, … … 147 148 ); 148 149 150 our %required_fields; 151 149 152 our $threshold=.2; 150 153 … … 161 164 my ($contentid,$rc); 162 165 eval { 163 my %fileContent = map { $_ => $self->{dbh}->quote($h_file->{$_}) } ('md5','sha1','type','size');164 my $abstract = new Relations::Abstract($self->{dbh});165 166 166 167 if (!$self->_VerifyHash($h_file,$tables{Files}{fields},1)) {return;} 168 my %fileContent = map { $_ => $self->{dbh}->quote($h_file->{content}->{$_}) } ('md5','sha1','type','size'); 169 170 my $abstract = new Relations::Abstract($self->{dbh}); 167 171 # Check for existence of file content in Database 168 172 my $query = new Relations::Query( … … 227 231 sub _InsertRegKey { 228 232 my ($self,$h_regkey,$serial) = @_; 229 my $ rc;233 my $id; 230 234 eval { 231 235 if (!$self->_VerifyHash($h_regkey,$tables{RegKeys}{fields},1)){return;} 232 236 my $abstract = new Relations::Abstract($self->{dbh}); 233 237 234 my %regkey = map { $_ => $self->{dbh}->quote($h_regkey->{$_}) } ('name','value','datecreated'); 235 $regkey{'`key`'} = $self->{dbh}->quote($h_regkey->{key}); 238 my %regkey = map { $_ => $self->{dbh}->quote($h_regkey->{$_}) } ('key_name','status','datecreated','notes'); 236 239 $regkey{serial} = $serial; 237 240 238 $ rc= $abstract->insert_id(241 $id = $abstract->insert_id( 239 242 -id => 'id', 240 243 -table => 'RegKeys', 241 244 -set => \%regkey 242 245 ); 246 foreach my $entry (@{$h_regkey->{entries}}) { 247 my %entry = map { $_ => $self->{dbh}->quote($entry->{$_}) } (keys %$entry); 248 $abstract->insert_id( 249 -id => 'id', 250 -table => 'RegKeyEntries', 251 -set => \%entry 252 ) or Carp::croak __PACKAGE__."->_InsertRegKey Failed: Insert returned a NULL ID"; 253 } 243 254 }; 244 255 if ($@) { 245 256 Carp::croak "__PACKAGE__->_InsertRegKey Failed:\n\t$@"; 246 257 } 247 return $ rc;258 return $id; 248 259 249 260 } … … 284 295 285 296 foreach $key (keys %$hash) { 286 if(exists $fields{$key}) { 297 if (ref $key && ref $fields{$key}) { 298 $self->_VerifyHash($hash{$key},$h_fields{$key},$required); 299 } 300 elsif (exists $fields{$key}) { 287 301 delete $fields{$key}; 288 302 } … … 356 370 sub deploy { 357 371 my $self = shift; 372 my $dbname; 373 #Check if DB exists already: 374 my $sth = $self->{dbh}->prepare("SHOW DATABASES"); 375 $sth->execute(); 376 while ($dbname = $sth->fetchrow_array()) { 377 if ($dbname eq 'HoneyClient') { 378 print "It thinks DB exists!\n";#TODO: Delete Debug statement 379 return 1; 380 } 381 } 382 358 383 my $abstract = new Relations::Abstract($self->{dbh}); 359 384 $abstract->run_query("CREATE DATABASE HoneyClient"); … … 402 427 id INT UNSIGNED AUTO_INCREMENT, 403 428 serial INT UNSIGNED NOT NULL, 404 `key` VARCHAR(255) NOT NULL, 405 name VARCHAR(255) NOT NULL, 406 value VARCHAR(255), 429 key_name VARCHAR(255) NOT NULL, 430 status INT UNSIGNED NOT NULL, 407 431 datecreated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 408 432 notes TEXT, 433 PRIMARY KEY (id) 434 ) ENGINE=InnoDB 435 "); # or die "Failed Creating RegKeys Table"; not necessary because of RaiseError?? 436 $abstract->run_query(" 437 CREATE TABLE RegKeyEntries 438 ( 439 id INT UNSIGNED AUTO_INCREMENT, 440 regkeyid INT UNSIGNED NOT NULL, 441 name VARCHAR(255) NOT NULL, 442 new_val VARCHAR(255) NOT NULL, 443 old_val VARCHAR(255) NOT NULL, 409 444 PRIMARY KEY (id) 410 445 ) ENGINE=InnoDB … … 421 456 ) ENGINE=InnoDB 422 457 "); # or die "Failed Creating Procs Table"; not necessary because of RaiseError?? 458 $abstract->run_query(" 459 CREATE FUNCTION objcount (s INT) RETURNS INT DETERMINISTIC 460 BEGIN 461 DECLARE f,r,p,sum INT; 462 SET sum = 0; 463 SELECT numfiles,numregkeys,numprocs INTO f,r,p FROM Fingerprints WHERE serial=s; 464 SET sum = f + r + p; 465 RETURN sum; 466 END; 467 "); # or die "Failed Creating Procs Table"; not necessary because of RaiseError?? 423 468 return 1; 424 469 } … … 442 487 443 488 { 444 md5 => '388b8fbc36a8558587afc90fb23a3b99', 445 sha1 => 'ed55ad0a7078651857bd8fc0eedd8b07f94594cc', 446 path => 'c:\Windows', 489 path => 'c:\Windows', 447 490 name => 'notepad.exe', 448 size => '69120', 449 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 491 content => { 492 md5 => '388b8fbc36a8558587afc90fb23a3b99', 493 sha1 => 'ed55ad0a7078651857bd8fc0eedd8b07f94594cc', 494 size => '69120', 495 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 496 } 450 497 } 451 498 … … 457 504 458 505 { 459 key => 'HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/run//notepad', 460 value => 'notepad.exe' 506 key_name => 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\run', 507 status => 1, # 0 -> Deleted, 1 -> Added, 2 -> Modified 508 entries => [ 509 { 510 name => 'notepad', 511 old_val => '', 512 new_val => 'notepad.exe' 513 } 514 ] 461 515 } 462 516 … … 546 600 547 601 push @Files, { 548 md5 => '82da9a561687f841a61e752e401471d2',549 sha1 => '7552ad083713e6d6b79539b64d598d4dcadfba35',550 602 path => 'c:\windows\system32', 551 603 name => 'calc.exe', 552 size => 114688, 553 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 554 }; 555 push @Files, { 556 md5 => 'bab513fc028515389eb6b2ad16e35ad2', 557 sha1 => 'c5597928b22d2c49a41510d6ab11d8f19bfab0af', 558 path => 'c:\windows\system32', 604 content => { 605 md5 => '82da9a561687f841a61e752e401471d2', 606 sha1 => '7552ad083713e6d6b79539b64d598d4dcadfba35', 607 size => 114688, 608 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 609 } 610 }; 611 push @Files, { 612 path => 'c:\windows\system32', 559 613 name => 'msgina.dll', 560 size => 994304, 561 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 614 content => { 615 md5 => 'bab513fc028515389eb6b2ad16e35ad2', 616 sha1 => 'c5597928b22d2c49a41510d6ab11d8f19bfab0af', 617 size => 994304, 618 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 619 } 562 620 }; 563 621 push @Files, { 564 md5 => '37564f065866fa7215453e72f1264f4b',565 sha1 => '7144ee8b57f3fcae6870f452b140365f75b5265c',566 622 path => 'c:\windows\system32', 567 623 name => 'drwatson.exe', 568 size => 28112, 569 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 624 content => { 625 md5 => '37564f065866fa7215453e72f1264f4b', 626 sha1 => '7144ee8b57f3fcae6870f452b140365f75b5265c', 627 size => 28112, 628 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 629 } 570 630 }; 571 631 push @RegKeys, { 572 key => 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run', 573 name => 'QuickTime Task', 574 value => '"C:\Program Files\QuickTime\qttask.exe" -atboottime' 632 key_name => 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run', 633 status => 1, 634 entries => [ 635 { 636 name => 'QuickTime Task', 637 new_val => '"C:\Program Files\QuickTime\qttask.exe" -atboottime' 638 } 639 ] 575 640 }; 576 641 push @Procs, { … … 670 735 671 736 push @Files, { 672 md5 => '82da9a561687f841a61e752e401471d2',673 sha1 => '7552ad083713e6d6b79539b64d598d4dcadfba35',674 737 path => 'c:\windows\system32', 675 738 name => 'calc.exe', 676 size => 114688, 677 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 678 }; 679 push @Files, { 680 md5 => 'bab513fc028515389eb6b2ad16e35ad2', 681 sha1 => 'c5597928b22d2c49a41510d6ab11d8f19bfab0af', 682 path => 'c:\windows\system32', 739 content => { 740 md5 => '82da9a561687f841a61e752e401471d2', 741 sha1 => '7552ad083713e6d6b79539b64d598d4dcadfba35', 742 size => 114688, 743 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 744 } 745 }; 746 push @Files, { 747 path => 'c:\windows\system32', 683 748 name => 'msgina.dll', 684 size => 994304, 685 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 749 content => { 750 md5 => 'bab513fc028515389eb6b2ad16e35ad2', 751 sha1 => 'c5597928b22d2c49a41510d6ab11d8f19bfab0af', 752 size => 994304, 753 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 754 } 686 755 }; 687 756 push @Files, { 688 md5 => '37564f065866fa7215453e72f1264f4b',689 sha1 => '7144ee8b57f3fcae6870f452b140365f75b5265c',690 757 path => 'c:\windows\system32', 691 758 name => 'drwatson.exe', 692 size => 28112, 693 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 759 content => { 760 md5 => '37564f065866fa7215453e72f1264f4b', 761 sha1 => '7144ee8b57f3fcae6870f452b140365f75b5265c', 762 size => 28112, 763 type => 'MS-DOS executable (EXE), OS/2 or MS Windows' 764 } 694 765 }; 695 766 push @RegKeys, { 696 key => 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run', 697 name => 'QuickTime Task', 698 value => '"C:\Program Files\QuickTime\qttask.exe" -atboottime' 767 key_name => 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run', 768 status => 1, 769 entries => [ 770 { 771 name => 'QuickTime Task', 772 new_val => '"C:\Program Files\QuickTime\qttask.exe" -atboottime' 773 } 774 ] 699 775 }; 700 776 push @Procs, { … … 736 812 my ($i,$rows,$r,$serial); 737 813 for ($i = 0; $i < $numfiles; $i++) { 814 815 } 738 816 $rows = $self->Select({ 739 817 table => 'Files', … … 744 822 $fileMatches{$serial}{$i} = $r; 745 823 } 746 }747 824 for ($i = 0; $i < $numregkeys; $i++) { 748 825 $rows = $self->Select({ … … 779 856 $scores{$key} += keys %{$procMatches{$key}}; 780 857 } 781 $h_scores->{Scores} = \%scores;782 $h_scores->{Files} = \%fileMatches;783 $h_scores->{RegKeys} = \%regMatches;784 $h_scores->{Procs} = \%procMatches;785 786 858 foreach $key (keys %scores) { 787 859 if ($scores{$key}/$objCount < $threshold) { … … 791 863 delete $scores{$key}; 792 864 } 793 elsif ($scores{$key}/$objCount == 1) {push @matches,$key;} 794 } 865 elsif ($scores{$key}/$objCount == 1) { 866 my $matchObjCount = $self->{dbh}->selectrow_array("SELECT objcount($key)"); 867 if($matchObjCount = $objCount) {push @matches,$key;} 868 } 869 } 870 $h_scores->{Scores} = \%scores; 871 $h_scores->{Files} = \%fileMatches; 872 $h_scores->{RegKeys} = \%regMatches; 873 $h_scores->{Procs} = \%procMatches; 795 874 return @matches; 796 875 } … … 848 927 } 849 928 850 # _SelectFiles($h_query) - Private Helper function to Select 929 # _SelectFiles($h_query) - Private Helper function to Select files 851 930 # Creates a SQL Select statement from the Query Hash passed to it. 852 931 # Returns - An array reference to an array of file records … … 855 934 my ($self,$q) = @_; 856 935 $q->{'select'} = [ 'Files.id','Files.contentid','Files.serial','Files.name', 857 'Files.path','Files.datecreated','File Content.md5','FileContent.sha1',858 'FileContent.size','FileContent.type' ,'FileContent.notes'936 'Files.path','Files.datecreated','Files.notes','FileContent.md5','FileContent.sha1', 937 'FileContent.size','FileContent.type' 859 938 ]; 860 939 #map {$q->{where}->{$_} = $self->{dbh}->quote($q->{where}->{$_})} (keys %{$q->{where}}); … … 866 945 $query->add("-$property" => $q->{$property}) if( $q->{$property} ); 867 946 } 868 return $self->{dbh}->selectall_arrayref($query->get(),{ Slice => {} }); 947 my $sth = $self->{dbh}->prepare($query->get()); 948 $sth->execute(); 949 950 my $file = {}; my @files; 951 map {$file->{$_}=undef} ('id','contentid','serial','name','path','datecreated','notes'); 952 map {$file->{content}->{$_}=undef} ('.md5','sha1','size','type'); 953 $sth->bind_columns(\$file->{id},\$file->{contentid},\$file->{serial},\$file->{name}, 954 \$file->{path},\$file->{datecreated},\$file->{notes},\$file->{content}->{md5},\$file->{content}->{sha1}, 955 \$file->{content}->{size},\$file->{content}->{type} 956 ); 957 while ($sth->fetch) { 958 push @files, $file; 959 } 960 return \@files; 961 } 962 963 # _SelectRegKeys($h_query) - Private Helper function to Select regkeys 964 # Creates a SQL Select statement from the Query Hash passed to it. 965 # Returns - An array reference to an array of regkey records 966 967 sub _SelectRegKeys { 968 #TODO: _SelectRegKeys function 869 969 } 870 970
