-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnixinfo.pl
executable file
·329 lines (259 loc) · 7.63 KB
/
nixinfo.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
#!/usr/bin/env perl
=head1 NAME
nixinfo - Gather System Information for UNIX and UNIX-like systems.
=head1 SYNPOSIS
nixinfo is a cross-platform UNIX system information collection tool.
=head1 DESCRIPTION
nixinfo is designed to be compatible with many different UNIX systems, with
the only requirement being a functional Perl 5.x installation.
The following host information is currently collected:
=over 3
=item * Hostname
=item * Domain
=item * OS Name
=item * OS Version
=item * uname
=item * Archiecture
=item * Endianness
=item * Andrew File System status
=item * Contents of hosts file
=item * Contents of /etc/passwd, and if available, /etc/shadow
=item * Name, Owner, Group, Perms, Size, and MAC times for every file
=item * All available details for every running process
=item * List of loaded kernel modules
=item * List of available network interfaces
=item * Routing table
=item * Current connections, listening services
=back
=head1 TODO
The following information will be collected in the future
=over 4
=item * A hash of any regular files on disk
=item * Identify special files (pipes, symlinks, etc)
=back
=head1 SEE ALSO
TBD
=head1 COPYRIGHT
Copyright (c) 2013 Andrew Benson, et al
All rights reserved.
Redistribution and use in source and binary forms are permitted
provided that the above copyright notice and this paragraph are
duplicated in all such forms and that any documentation,
advertising materials, and other materials related to such
distribution and use acknowledge that the software was developed
by Andrew Benson and its other contributors. Neither the name of
Andrew Benson nor any other contributors may be used to endorse
or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
=cut
# SETUP
# There is no inherent boolean type, so instead we define true and false
# to their accepted values.
use constant false => 0;
use constant true => 1;
# CONFIG
# By default, print to standard out.
$usestdout = true;
# INCLUDES
# Only use capabilities provided by Perl in the default distribution.
use Time::localtime;
use File::Basename;
use Sys::Hostname;
use Config;
# GLOBALS
$version = "0.0.31";
# BUILTIN GLOBALS
# Ensure all input and output is handled on a line-by-line basis. Also,
# ensure all output includes a newline at the end. This can be overridden,
# but it expected that this will be the value, so if you do change it,
# change it back, please.
$\ = "\n";
$/ = "\n";
# SUBROUTINES
# Read all of the output for a command and print it to the expected filehandle.
# Do not use this to generate lengthy output, it may break.
sub printCommand
{
$fh = shift;
$cmd = shift;
$content = slurpCommand($cmd);
print $fh $content
}
# Clean up some output for tabular data. Removes extraneous spaces.
sub tabulateCommand
{
$fh = shift;
$cmd = shift;
$content = slurpCommand($cmd);
$content =~ s/^ +//g;
$content =~ s/ +$//g;
$content =~ s/ +/;/g;
print $fh $content;
}
# Execute a command and returns a string containing all of the output.
sub slurpCommand
{
$cmd = shift;
open(HC, "$cmd|") or die "Can't run $cmd.";
$/="";
$slurp = <HC>;
close(HC);
$/="\n";
return $slurp;
}
# FUNCTIONS
# Use the built-in Config system to determine generic host data.
sub getHostInfo
{
$file = shift;
print $file "Domain: ", $Config{mydomain};
print $file "Hostname: ", hostname . $Config{mydomain};
print $file "OS: ", $Config{osname};
print $file "Version: ", $Config{osvers};
print $file "uname: ", $Config{myuname};
print $file "Arch: ", $Config{archname};
print $file "Byteorder: ", $Config{byteorder};
print $file "Afs?: ", $Config{afs};
}
# Use the built-in Config system to determine the command to print
# the hosts file.
sub getHosts
{
print $file "Contents of hosts file: ";
printCommand($file, $Config{hostcat});
}
# Use the built-in Config system to determine the command to print
# the password file.
# If the shadow file exists, print it as well.
sub getPasswordFile
{
print $file "Contents of passwd file: ";
printCommand($file, $Config{passcat});
if(-f "/etc/shadow") {
print $file "Contents of shadow file: ";
printCommand($file, "cat /etc/shadow");
} else {
print $file "Shadow unknown or non-existent on this system.";
}
}
# Enumerate through the filesystem and gather some information about
# any encountered (regular) files.
sub getFiles
{
$file = shift;
@dirs = ( "/" );
$\ = "\n";
while($dir = shift(@dirs)) {
opendir(DH, $dir);
while($name = readdir(DH)) {
unless($name =~ /^\.\.?/ || $file =~ /^\/proc/) {
if($dir eq "/") {
$path = $dir . $name;
} else {
$path = $dir . "/" . $name;
}
if(-l $path) {
print $file "Link: $path";
print $file " Target: " . readlink($path);
} elsif (-d $path) {
push(@dirs, $path);
} elsif (-f $path) {
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks) = stat($path);
print $file "File: $path";
print $file " Owner: $uid";
print $file " Group: $gid";
printf $file " Permissions: %04o\n", $mode & 07777;
print $file " Size: $size";
print $file " MAC: $mtime, $atime, $ctime";
}
}
}
closedir(DH);
}
}
# Use the ps command to list the running processes.
sub getProcesses
{
$output = shift;
print $output "Process list: ";
printCommand($output, "ps -A -o 'user ruser group rgroup uid ruid gid rgid pid ppid pgid sid pri opri pcpu pmem vsz rss osz nice class time etime stime f s c lwp nlwp psr tty addr wchan fname comm args'");
}
# Use the appropriate system specific command to list loaded kernel modules.
sub getKernelModules
{
$output = shift;
print $output "Kernel Modules: ";
if($Config{osname} eq "solaris") {
printCommand($output, "modinfo");
} elsif ($Config{osname} eq "linux") {
printCommand($output, "lsmod");
} else {
print $output "Not implemented for this platform: $Config{osname}";
}
}
# Use the ifconfig command to list available interfaces.
sub getInterfaces
{
$output = shift;
print $output "Interfaces: ";
printCommand($output, "ifconfig -a");
}
# Use the system specific command to print the routing tables.
sub getRoutes
{
$output = shift;
print $output "Routes: ";
if($Config{osname} eq "linux") {
printCommand($output, "route -n");
} elsif ($Config{osname} eq "solaris") {
printCommand($output, "netstat -nr");
} else {
print $output "Not implemented for this platform: $Config{osname}";
}
}
# Use the system specific command to list open connections and
# listening services.
sub getConnections
{
$output = shift;
print $output "Connections: ";
if($Config{osname} eq "linux") {
printCommand($output, "netstat -pluant");
} elsif ($Config{osname} eq "solaris") {
printCommand($output, "netstat -an -f inet");
} else {
print $output "Not implemented for this platform: $Config{osname}";
}
}
# MAIN
# On startup, print the tool name and current version.
print basename($0), ": ", $version;
if($< != 0) {
print "You must be running as root to execute this command.";
exit();
}
if($usestdout) {
$file = *STDOUT;
} else {
$tm = localtime;
$filename = sprintf("results-%s%s%s-%s%s.log",
$tm->year+1900, $tm->mon+1, $tm->mday, $tm->hour, $tm->min);
print "Saving results to ", $filename, ".";
open($file, ">$filename") or die "Can't open file.";
}
getHostInfo($file);
getHosts($file);
getPasswordFile($file);
getProcesses($file);
getKernelModules($file);
getInterfaces($file);
getRoutes($file);
getConnections($file);
getFiles($file);
unless($usestdout) {
close($file);
}