File Coverage

blib/lib/Metabrik/Remote/Windiff.pm
Criterion Covered Total %
statement 9 88 10.2
branch 0 52 0.0
condition 0 6 0.0
subroutine 3 10 30.0
pod 1 7 14.2
total 13 163 7.9


line stmt bran cond sub pod time code
1             #
2             # $Id$
3             #
4             # remote::windiff Brik
5             #
6             package Metabrik::Remote::Windiff;
7 1     1   632 use strict;
  1         2  
  1         28  
8 1     1   5 use warnings;
  1         2  
  1         27  
9              
10 1     1   5 use base qw(Metabrik::Client::Smbclient);
  1         2  
  1         485  
11              
12             sub brik_properties {
13             return {
14 0     0 1   revision => '$Revision$',
15             tags => [ qw(unstable) ],
16             author => 'GomoR ',
17             license => 'http://opensource.org/licenses/BSD-3-Clause',
18             attributes => {
19             datadir => [ qw(datadir) ],
20             domain => [ qw(domain) ],
21             user => [ qw(username) ],
22             password => [ qw(password) ],
23             host => [ qw(host) ],
24             share => [ qw(share) ],
25             remote_path => [ qw(path) ],
26             vm => [ qw(id) ],
27             profile => [ qw(volatility_profile) ],
28             },
29             attributes_default => {
30             profile => 'Win7SP1x64',
31             },
32             commands => {
33             upload => [ qw(file remote_path|OPTIONAL share|OPTIONAL) ],
34             execute => [ qw(command) ],
35             restart => [ qw(vm) ],
36             snapshot => [ qw(vm) ],
37             process_diff => [ qw(source_file.vol destination_file.vol) ],
38             netstat_diff => [ qw(source_file.vol destination_file.vol) ],
39             },
40             require_modules => {
41             'Metabrik::Forensic::Volatility' => [ ],
42             'Metabrik::Remote::Winexe' => [ ],
43             'Metabrik::System::Virtualbox' => [ ],
44             'Metabrik::Network::Address' => [ ],
45             },
46             };
47             }
48              
49             sub upload {
50 0     0 0   my $self = shift;
51 0           my ($file, $remote_path, $share) = @_;
52              
53 0 0         $self->brik_help_run_undef_arg('execute', $file) or return;
54              
55 0           return $self->SUPER::upload($file, $remote_path, $share);
56             }
57              
58             sub execute {
59 0     0 0   my $self = shift;
60 0           my ($command) = @_;
61              
62 0 0         $self->brik_help_run_undef_arg('execute', $command) or return;
63              
64 0 0         my $rw = Metabrik::Remote::Winexe->new_from_brik_init($self) or return;
65 0           $rw->host($self->host);
66 0           $rw->user($self->user);
67 0           $rw->password($self->password);
68              
69 0           return $rw->execute_in_background($command);
70             }
71              
72             sub restart {
73 0     0 0   my $self = shift;
74 0           my ($vm) = @_;
75              
76 0 0         $self->brik_help_run_undef_arg('restart', $vm) or return;
77              
78 0 0         if ($vm !~ m{^[-a-z0-9]+$}) {
79 0           return $self->log->error("restart: vm [$vm] does not look like an ID");
80             }
81              
82 0 0         my $sv = Metabrik::System::Virtualbox->new_from_brik_init($self) or return;
83 0           $sv->type('headless');
84 0 0         $sv->restart($vm) or return;
85              
86 0           return 1;
87             }
88              
89             sub snapshot {
90 0     0 0   my $self = shift;
91 0           my ($vm, $output) = @_;
92              
93 0   0       $output ||= $self->datadir.'/'.$vm.'.snapshot';
94 0 0         $self->brik_help_run_undef_arg('snapshot', $vm) or return;
95              
96 0 0         if ($vm !~ m{^[-a-z0-9]+$}) {
97 0           return $self->log->error("snapshot: vm [$vm] does not look like an ID");
98             }
99              
100 0 0         my $sv = Metabrik::System::Virtualbox->new_from_brik_init($self) or return;
101 0           $sv->type('headless');
102              
103 0           $self->log->info("snapshot: dumping VM core...");
104              
105 0 0         my $elf = $sv->dumpvmcore($vm) or return;
106              
107 0           $self->log->info("snapshot: extracting memdump...");
108              
109 0 0         my $vol = $sv->extract_memdump_from_dumpguestcore($elf, $output) or return;
110              
111 0           $self->log->info("snapshot: done.");
112              
113 0           return $vol;
114             }
115              
116             sub process_diff {
117 0     0 0   my $self = shift;
118 0           my ($snap1, $snap2) = @_;
119              
120 0 0         $self->brik_help_run_undef_arg('process_diff', $snap1) or return;
121 0 0         $self->brik_help_run_undef_arg('process_diff', $snap2) or return;
122              
123 0 0         my $fv = Metabrik::Forensic::Volatility->new_from_brik_init($self) or return;
124 0           $fv->profile($self->profile);
125              
126 0           $self->log->info("process_diff: performing pslist on first snapshot...");
127              
128 0 0         my $pslist1 = $fv->pslist($snap1) or return;
129              
130 0           $self->log->info("process_diff: performing pslist on second snapshot...");
131              
132 0 0         my $pslist2 = $fv->pslist($snap2) or return;
133              
134 0           my %pid = ();
135 0           for my $this (@$pslist1) {
136 0           $pid{$this->{pid}} = $this;
137             }
138              
139 0           $self->log->info("process_diff: searching pslist diff...");
140              
141 0           my @new = ();
142 0           for my $this (@$pslist2) {
143 0 0         if (! exists($pid{$this->{pid}})) {
144 0           push @new, $this;
145             }
146             }
147              
148 0           $self->log->info("process_diff: done.");
149              
150 0           return \@new;
151             }
152              
153             sub netstat_diff {
154 0     0 0   my $self = shift;
155 0           my ($snap1, $snap2) = @_;
156              
157 0 0         $self->brik_help_run_undef_arg('netstat_diff', $snap1) or return;
158 0 0         $self->brik_help_run_undef_arg('netstat_diff', $snap2) or return;
159              
160 0 0         my $fv = Metabrik::Forensic::Volatility->new_from_brik_init($self) or return;
161 0           $fv->profile($self->profile);
162              
163 0           $self->log->info("netstat_diff: performing netscan on first snapshot...");
164              
165 0 0         my $netscan1 = $fv->netscan($snap1) or return;
166              
167 0           $self->log->info("netstat_diff: performing netscan on second snapshot...");
168              
169 0 0         my $netscan2 = $fv->netscan($snap2) or return;
170              
171 0           my %pid = ();
172 0           for my $this (@$netscan1) {
173 0           $pid{$this->{pid}} = $this;
174             }
175              
176 0           $self->log->info("netstat_diff: searching netscan diff...");
177              
178 0 0         my $na = Metabrik::Network::Address->new_from_brik_init($self) or return;
179              
180 0           my @new = ();
181 0           for my $this (@$netscan2) {
182 0 0         if (! exists($pid{$this->{pid}})) {
183 0           my ($address, $port) = split(/:/, $this->{foreign_address});
184 0 0 0       if ($na->is_ip($address) && $address !~ m{^0\.0\.0\.0$}) {
185 0           push @new, $this;
186             }
187             }
188             }
189              
190 0           $self->log->info("netstat_diff: done.");
191              
192 0           return \@new;
193             }
194              
195             1;
196              
197             __END__