System Security Administration for NT

原创 2007年09月19日 00:58:00
Network Solutions 


System security administration has, for the most part, been largely ignored as network administration has flourished. The result of this is that there are large installations of NT that need to be retrofitted with some form of security administration and management system. There are various third party tools available to assist in this endeavor, but they are somewhat general and not tailored to meet the needs of a particular user or organization. System administrators must therefore learn to mold their infrastructure to the tool, rather than the other way around. Often times, the tools may also be quite expensive, and difficult to learn and maintain. 

1. Introduction 

Security administration for a single NT system can be cumbersome, at best. There is no single interface for configuring and monitoring the security posture of an NT system. For example, the audit policy for a standalone NT system is set via the User Manager, while log specific settings and all monitored activity is recorded in the EventLog. Further, each object (file, directory, share, Registry key) has it's own interface for enabling access control lists (ACLs) and audit settings. Rolling out a common audit standard across an NT enterprise, and then monitoring the EventLogs, can be a daunting task. However, there are many third party commercial tools available to assist the system administrator. Two drawbacks of these tools are their vagueness and cost. Commercially available solutions are very general in nature, not providing the ability to focus in on the specific needs of the administrator. Some check for compliance with "best practices" but the definition of "best practices" is purely arbitrary. Other tools provide a wealth of information. In fact, they provide too much information, inundating the administrator with facts, requiring him to sift through this information and attempt to extract the real issues at hand. None of the tools take other aspects of the administrator's infrastructure into account, such as corporate security policies, the existence of a firewall, ACLs on routers, VLAN implementations on switches, etc. The cost of purchasing and installing the tools, coupled with the "cost" of deciphering the collected data, makes for a very low return on investment (ROI). Updates to the tools to look for new vulnerabilities may even be an added expense. 

System administrators need a more viable solution. The appropriate solution for a security administration system must: 

Be simple, and easy to construct and maintain. 
Be centralized. 
Be scalable. 
Be configurable, to meet the specific needs of a user. 
Provide for verification of security policy compliance (compliance checking and verification). 
Notify the administrator of systems that are not in compliance. 
Where appropriate, modify system settings to bring systems into compliance with policies. 
Reduce overall cost for administering the system (i.e., no expensive per-seat license fees, etc.). 
1.1 Purpose 
The purpose of this paper is to provide a framework, using Perl, for administering system security across an NT enterprise. Due to space limitations, all code examples cannot be presented in this paper. Additional scripts will be available via the author's web site at 

1.2. Background 

The solution will be implemented in Perl, a scripting language that has been used on Unix platforms for administration purposes of years, and has been made available for the Win32 platform. ActiveState provides a fairly complete distribution of Perl for Win32 systems, as well as several avenues of support. There are also several additional modules that provide a quantum leap in functionality and usability, in the NT environment, to the ActiveState distribution. These modules provide a convenient wrapper around the Win32 API functions, making them more accessible, and easier to use and understand. This access to the Win32 API facilitates collection, and if necessary, modification, of security-relevant data for NT machines across the enterprise. 

2. Solution 

The solution for the centralized security administration of NT systems can be separated into three phases: collection, filtering/analysis, and modification. The three phases are kept distinctly separate in order to maintain simplicity, scalability and functionality. Separating the phases also makes it easier to construct a working set of tools, by allowing for testing and verification of one phase before moving on to the next. Additional functionality can be added to one phase without requiring any changes to the other phases. 

The collection phase is used to extract raw configuration data from NT machines across the enterprise: 

Generate MD5 checksums of specific files to ensure file integrity. 
Registry settings (checking for security-specific settings, trojans, viruses, etc.) 
File, directory, share and Registry key ACLs 
Services (running, stopped, and paused), the account each service runs under, and the executable called by the service 
Audit policies and EventLog entries 
User rights and user account information 
File (boot.ini) and directory ("Start Menu" for each user) contents 
This data is saved in a central location, most likely on an administration workstation, in a suitable format. The data may be written to an Access database or an Excel spreadsheet, but the simplest method is to choose a standard delimiter, such as a colon or semi-colon, and write the data to flat text files. The data is simple to parse and review, and easily compressed and encrypted for archival. The examples in this paper will send all data to STDOUT, allowing it to also be redirected to a flat file. 
The data can be easily analyzed using filters written in Perl, making use of its inherent ability to parse data and files. These filters access and process the data based on predefined conditions, making full use of the pattern matching abilities of regular expressions. Filters may be designed to check for: 

Known security issues, such as ACLs (on files, directories, and Registry keys) or specific Registry values. 
More complex issues, such as the ACLs on a file as it's related to the function of the particular system (PDC, BDC, or workstation) and a Registry key entry. 
General trends across the enterprise, such as the level of Service Packs and HotFixes installed. 
Compliance with corporate security policies, to include the audit policy for each system, or the existence of modems on workstations vice RAS servers. 
The processed information can then be presented in whichever format meets the needs of the user, to include: 
Word document 
Excel spreadsheet 
Access database 
EventLog entries 
The system administrator can also use Perl to act upon the information derived from filtering and analysis, making modifications as necessary. Services can be stopped or started, Registry values added or deleted, auditing can enabled, and EventLogs can be collected and filtered, all from a single workstation. 
Due to it's simple, modular nature, this system can be easily updated as new information (new vulnerabilities, updated security policies) is incorporated. 

This system can also be used to establish a baseline, which managers and administrators can use to look for system changes, or develop and implement security policies and standards. 

Once the data is filtered and analyzed, system administrators can begin the modification phase. Using the same Perl modules that were used to collect data from systems, the system administrator can bring the NT systems into compliance with security standards, by updating settings (i.e., Registry entries, file/directory/share/Registry permissions, audit policy, etc.). As this is done from a centralized location, only one account, with a strong password, is required to perform this entire range of security administration. 

Once all settings have been implemented and tested, the collection and filtering phases can again be used to verify compliance with security standards, by executing those phases as part of a regular security scan. Using the baseline information, the system administrator need only to look for anomalies and unusual settings, indicating that a lack of compliance with security policies and standards. 

As an example, assume the system administrator wishes to not only check for the existence of trojan programs on her NT servers and workstations, but she also wants to ensure that these programs (or any other programs, for that matter) can not be installed on the systems. She uses Perl scripts collect relevant data (Registry key entries and permissions, file and directory ACLs, etc.) from across the enterprise, to include offices connected to the master domain by WAN and VPN links. Once she's collected data from all systems, she filters the Registry entries based on published signatures of known trojan programs, and then reviews the entries for suspicious or unauthorized entries. Not finding anything significant, she then sets about modifying Registry and directory ACLs on all systems to prevent the installation of trojan programs in the future. She follows this up with periodic scans of the Registry keys and Security EventLog to ensure compliance, and incorporates new data, as it becomes available. The entire process is simple to maintain, and automated to reduce errors and increase efficiency. 

3. Implementation 

The examples presented in this paper are not meant to be all-inclusive. Rather, they are presented as a framework or set of tools from which system administrators can build solutions that meet their specific needs. Also, space requirements limit the number and functionality of the scripts that can be presented. Additional scripts will be available via the web, at 

The following examples lay the groundwork from which specific solutions and systems can be built. 

3.1 Checksums 

The integrity of critical system files is a serious security concern, as there are publicly available web sites that demonstrate the construction of a rootkit for NT ( Rootkits have been a thorn in the sides of Unix administrators, as they are used to patch the kernel and trojanize commands in order to hide malicious activities. DIGEST.PL (Script 1) demonstrates a method for generating MD5 hashes of critical files. These hashes can be saved to a protected file or database and be used to verify the integrity of critical system files on a regular basis. 

3.2 Registry Settings 

The NT Registry can be as much a treasure trove as it is a technological minefield. There are several Registry values that have a direct or indirect impact on the security posture of the system. 

3.2.1 Individual Registry Values 

REGKEYS.PL (Script 2) shows how Registry values can be collected from remote NT systems. The values can then be verified, and a message printed to STDOUT for each incorrectly set Registry value. This information can be logged to a database or file, or the value simply modified as needed. For example, the system administrator can check NT systems for compliance by checking the Service Pack level on each system. 

3.2.2 Trojan Keys 

TROJANKEYS.PL (Script 3) demonstrates collecting the contents of Registry keys. The values can be scanned for known trojan signatures using the grep() function. Trojan signatures are available from anti-virus sites such as F-Secure ( For example, using grep(), the system administrator can quickly scan incoming data using the following signatures for network backdoor, remote administration trojan programs (signature in parens): 

NetBus (Patch) 
DeepThroat (SystemDLL32) 
NetSphere (NSSX) 
GateCrasher (Command) 
Portal of Doom (ljsgz.exe) 
Girlfriend (Windll.exe) 
HackATack (Expl32.exe) 
Phase Zero (MsgServ|msgsvr32.exe) 
MyPics Variant (agent5|zip01.exe) 
NewApt (tpawen|panth) 
SubSeven (mtmtask.dl) 
By simply changing the Registry key examined, system administrators can verify which HotFixes are installed on each NT system. 
3.3 ACLs 

Access control lists (ACLs) define which users and groups have what level of access to specific resources. PERMS.PL (Script 4) demonstrates a method for collecting the ACLs from files, directories, Registry keys, and shares, and presenting the ACLs in an easy to understand format. Credit goes to Dave Roth for both his Win32::Perms module, as well as the code for the getperms() method. 

3.4 Services 

SERVICES.PL (Script 5) demonstrates a method for collecting information from services available on NT systems, such as the service's status, the service executable, and the account that the service runs under. Other methods in the Win32::Lanman module will allow the system administrator to start or stop services. Dave Roth's Win32::Daemon module provides a nice interface for creating services from Perl scripts. 

3.5 Auditing and Logging 

NT systems have the capability of performing auditing and logging functions. Administrators can use the information available in the EventLog to see if there are problems with applications, look for clean or dirty system shutdowns, or even as a rudimentary intrusion detection system. 

3.5.1 Audit Policies 

The AUDITPOL.PL (Script 6) script shows how the audit policy can be determined. Auditing can be enabled if the current state shows it to be disabled, and the particular events to be audited can be set. 

3.5.2 EventLog Entries 

The DUMPEVENTS.PL (Script 7) script demonstrates a means of collecting EventLog entries from multiple machines within the domain. The script collects the entries and sends them to STDOUT. However, the entries can be deposited in an Excel spreadsheet or Access database, making the entries more manageable. Specific events can be filtered during the collection process, such as Dr. Watson messages, failed logon attempts, etc. If ACLs are set to prevent users from writing to specific directories and Registry keys, attempts to do so (as when the user attempts to install software, or when a trojan attempts to install itself) appear as EventID 650 in the Security EventLog. 

3.6 User Privileges and User Account Information 

The administrator may need to determine the privileges that users have available in order to diagnosis access issues. The Win32::Lanman module provides methods for displaying privileges assigned to particular users or groups, or assigning privileges as necessary. 

USERS.PL (Script 8) demonstrates how an administrator might collect information about user accounts from the local NT system. Other Win32::Lanman methods allow the administrator to enumerate global and local groups, or add users and groups. 

3.7 Directory and File Contents 

STARTUPCHK.PL (Script 9) shows how an administrator can examine the contents of the Start Up directories for all profiles on an NT system. This script will also show the executable files pointed to by shortcuts. 

Administrators can also use Perl to get the contents of particular files, such as boot.ini or lmhosts, in order to aid in troubleshooting problems. 

4. Conclusions 

The system and example scripts presented in this paper are quite simple, yet scalable and easy to maintain. All requirements for a security administration system have been met, to include reducing overall cost. At the same time, system administrators using this model have an understanding of the necessity for maintaining the security of their NT systems. They also have a complete security administration toolkit consisting of resources for NT-specific security information, a powerful scripting language (Perl), and a wide variety of tools and techniques to make their jobs easier and more efficient. 

Using other modules, system administrators can perform a wide variety of other centralized security administration tasks. For example, there are modules available that allow the system administrator to interface with the Performance Monitor on remote NT systems to check running processes. System administrators can also use Win32::OLE to interface locally with IIS 4.0's metabase and make configuration changes, or use LWP::UserAgent to test their IIS 4.0 web servers for susceptibility to the latest exploit (note: Rain Forest Puppy's is uses to provide the functionality of LWP::UserAgent). 

5. Appendix A: Resources 

5.1 Perl on NT 

All scripts associated with this paper were written and tested using ActiveState's ActivePerl build 522 on Windows NT 4.0. At the time of this writing, ActivePerl build 522 was available from 

5.2 Extensions 

The following extensions are available as part of the default distribution of ActiveState's ActivePerl: 

The Digest::MD5 module is not installed as part of the standard distribution, but is available via PPM ("ppm install Digest-MD5"). 
The following extensions are available from Dave Roth's web site, and installable via PPM: 

The Win32::Lanman module, authored by Jens Helberg (,  is available in a zipped archive from Dave Roth's FTP site ( or it can be installed via PPM from 
5.3 Books and Papers 

Schwartz, R. L., Olson, E., and Christiansen, T., "Learning Perl on Win32 Systems", O'Reilly & Associates, 1997 

Roth, D., "Win32 Programming: The Standard Extensions", MacMillian Technical Publishing, 1998 

Roth, D., "A Network Machine Management System", USENIX's 2nd Large Installation System Administration of Windows NT (LISA-NT) Conference, July, 1999 

Jumes, J. G., Cooper, N. F., Chamoun, P., and Feinman, T. M., "Windows NT 4.0 Security, Audit, and Control", Microsoft Press, 1999 

5.4 Web Sites 

The author's web site lists several scripts which could not be listed in this paper due to space requirements ( 

Dave Roth's site is the home of several extremely useful Perl modules, as well as his paper from the Usenix LISA-NT '99 Conference ( 

Joe Casadonte's web site lists many modules available for NT ( 

6. Appendix B: Scripts 

6.1 (Script 1) 

#! c:/perl/bin/perl.exe 
# Generate MD5 checksums on files to verify file 
# integrity 
# Use with system files, web pages, etc. Can also use 
# files on mapped drives, but must use complete path. 

use strict; 
use Digest::MD5; 

my $server = shift || Win32::NodeName; 
my @files = ("io.sys","ntldr","boot.ini","", "winnt//system32//fpnwclnt.dll"); 
my $path; 
$server =~ y/a-z/A-Z/; 
($server eq Win32::NodeName) ? ($path = "c://") : 
($path = "////$server//c/$//"); 
foreach (@files) { 
    my $file = $path.$_; 
    if (-e $file) { 
        my $hash = hash($file); 
        print "$server/t$file =>; $hash/n"; 
    else { 
        print "$file could not be found./n"; 

# sub() to generate the actual hash 
sub hash { 
    my ($file) = @_; 
    open (FILE, $file) or die "Can't open $file: $!/n"; 
    my $digest = Digest::MD5->;new->;addfile(*FILE)->;b64digest; 
    return $digest; 

6.2 (Script 2) 

#! c:/perl/bin/perl.exe 
# Collect Registry key values for analysis 

use strict; 
use Win32::TieRegistry(Delimiter=>;"/"); 

my $server = shift || Win32::NodeName; 
my $remote; 
if ($remote = $Registry->;{"//$server/LMachine"}) { 

else { 
    print "Could not connect to $server Registry./n"; 

sub getRegValues { 
    my %regkeys = (); 
# Keys are kept in a datafile, in format: Value;Path 
# Ex: EnableDCOM;SOFTWARE/Microsoft/Ole 
    my $datafile = "RegKeyValues"; 
    if (-e $datafile) { 
        open(FL,$datafile) || die "Could not open  $datafile: $!/n"; 
        while(<FL>;) { 
# Skip comments and blank lines 
            next if ($_ =~ m/^#/); 
            next if ($_ =~ m/^/s+$/); 
            my($key,$path) = split(/;/,$_); 
            $regkeys{$key} = $path; 
        foreach my $key (keys %regkeys) { 
            $value = $remote->;{$regkeys{$key}}; 
            $data = $value->;{$key}; 
            if (defined $data) { 
                $data = hex($data) if ($data =~ m/^0x/); 
                print "$key = $data/n"; 
            else { 
                print "$key = NotFound/n"; 

6.3 (Script 3) 

#! c:/perl/bin/perl.exe 
# Check Registry keys where trojans 
# like to hide for suspicious entries 

use strict; 
use Win32::TieRegistry(Delimiter=>;"/"); 
my ($remote); 
my $server = shift || Win32::NodeName; 
my %hives = ("LMachine" =>; "HKLM", "CUser" =>; "HKCU"); 
foreach my $hive (keys %hives) { 
    print "Checking $hives{$hive} hive.../n"; 
    ($remote = $Registry->;{"//$server/$hive"}) ? 
    (/&amp;getTrojanKeys($server)) : 
    (print "Could not connect to $hives{$hive} hive./n"); 
    print "/n"; 

sub getTrojanKeys { 
    my($path) = 'SOFTWARE/Microsoft/Windows/CurrentVersion'; 
    my(@keys) = ('Run','RunOnce','RunOnceEx','RunServices'); 
    foreach my $k (@keys) { 
        my $key = $remote->;{"$path/$k"}; 
        if (defined $key) { 
            my @vals = $key->;ValueNames; 
            if($#vals != -1) { 
                foreach my $val (@vals) { 
                    my $data = $key->;{$val}; 
                    $data = "NotFound" unless($data); 
                    print "$k:$val:$data/n"; 

6.4 (Script 4) 

#! c:/perl/bin/perl.exe 
# usage: perl [obj] 
# ex: perl c:/winnt 

use strict; 
use Win32::Perms; 

my $obj = shift || die "You must enter an object: File, Dir, or Reg key./n"; 

# Credit goes to Dave Roth for providing the following code to translate the DACL mask 
# into something readable; ie, Explorer-like listing 
sub getperms { 
    my($obj) = @_; 
    my($Perm) = new Win32::Perms($obj); 
    my (%PERM) = (R =>; 0, W =>; 1, 
                                 X =>; 2, D =>; 3, 
                                 P =>; 4, O =>; 5, 
                                A =>; 6); 

    my(%MAP) = ('FILE_READ_DATA' =>; 'R', 
                           'GENERIC_READ' =>; 'R', 
                           'KEY_READ' =>; 'R', 
                           'KEY_QUERY_VALUE' =>; 'R', 
                           'FILE_WRITE_DATA' =>; 'W', 
                           'KEY_WRITE' =>; 'W', 
                           'GENERIC_WRITE' =>; 'W', 
                           'KEY_SET_VALUE' =>; 'W', 
                           'DELETE' =>; 'D', 
                           'FILE_DELETE_CHILD' =>; 'D', 
                           'FILE_EXECUTE' =>; 'X', 
                           'FILE_TRAVERSE' =>; 'X', 
                           'GENERIC_EXECUTE' =>; 'X', 
                           'CHANGE_PERMISSION' =>; 'P', 
                           'TAKE_OWNERSHIP' =>; 'O', 
                           'FILE_ALL_ACCESS' =>; 'A', 
                           'GENERIC_ALL' =>; 'A', 
                           'STANDARD_RIGHTS_ALL'  =>;'A'); 

    die "Can not obtain permissions for '$Path'/n"  if  (!$Perm); 

    foreach $Acct (@List) { 
        my(@String) = split(//, "-" x scalar(keys(%PERM))); 
        next if($Acct->;{Entry} ne "DACL"); 
        foreach $Mask (@M) { 
            $Perm |= 2**$PERM{$MAP{$Mask}}; 
        foreach $Mask (keys(%PERM)) { 
            $String[$PERM{$Mask}] = $Mask if ($Perm &amp; 2**$PERM{$Mask}) ; 
        $DaclType = $Acct->;{ObjectName}; 
        if( 2 == $Acct->;{ObjectType} ) { 
# We have either a file or directory. Therefore we need to figure out if this 
# DACL represents an object (file) or a container (dir)... 
            ($Acct->;{Flag} &amp; DIR) ? ($DaclType = "Directory") : ($DaclType = "File"); 
        my $permstr = join("",@String); 
        print "$Acct->;{Account}:$DaclType:$permstr/n"; 
    print "Everyone has full permissions./n" if(!$iTotal); 

6.5 (Script 5) 

#! c:/perl/bin/perl.exe 
# Retrieve info on services on $server 

use strict; 
use Win32::Lanman; 
my $server = shift || Win32::NodeName; 

sub Services { 
    my($server) = @_; 
# Array to translate the current state of the service into something readable 
    my(@state) = ("","Stopped","Start_Pending","Stop_Pending", "Running", 
# Array to translate the startup options for the service into something readable 
    my(@startup) = ("","","Automatic","Manual","Disabled"); 
    if (Win32::Lanman::EnumServicesStatus("////$server","",&amp;SERVICE_WIN32, 
                                &amp;SERVICE_STATE_ALL,/@services)) { 
        foreach $service (@services) { 
            if (Win32::Lanman::QueryServiceConfig("////$server","",${$service}{name},/%info)) { 
# Print out in an easy to read format 
                print "${$service}{display}/n"; 
                print "/tName/t${$service}{name}/n"; 
                print "/tState/t".$state[${$service}{state}]."/n"; 
                print "/tAccount/t$info{account}/n"; 
                print "/tFile/t$info{filename}/n"; 
                print "/tStart/t".$startup[$info{start}]."/n"; 
                print "/n"; 
            else { 
                $err = Win32::FormatMessage Win32::Lanman::GetLastError(); 
                $err = Win32::Lanman::GetLastError() if ($err eq ""); 
                print "$server: QueryServiceConfig Error: $err"; 
    else { 
        $err = Win32::FormatMessage Win32::Lanman::GetLastError(); 
        $err = Win32::Lanman::GetLastError() if ($err eq ""); 
        print "$server: Services Error: $err"; 

6.6 (Script 6) 

#! c:/perl/bin/perl.exe 
# Determine the audit policy of an NT system 

use strict(vars); 
use Win32::Lanman; 

my $server = shift || Win32::NodeName; 

sub AuditPol { 
    my($server) = @_; 
    my(%hash) = ("AuditCategoryLogon" =>; "Logon and Logoff", 
            "AuditCategoryObjectAccess" =>; "File and Object Access", 
            "AuditCategoryPrivilegeUse" =>; "Use of User Rights", 
            "AuditCategoryAccountManagement" =>; "User/Group Mgmt", 
            "AuditCategoryPolicyChange" =>; "Security Policy Changes", 
            "AuditCategorySystem" =>; "Restart and Shutdown System", 
            "AuditCategoryDetailedTracking" =>; "Process Tracking"); 

    my(%settings) = (0 =>; "None", 
                                    1 =>; "Success", 
                                    2 =>; "Failure", 
                                    3 =>; "Success and Failure"); 

    if (Win32::Lanman::LsaQueryAuditEventsPolicy("////$server",/%info)) { 
        my $audit = $info{auditingmode}; 
        if (!$audit) { 
            print "$server: Auditing is NOT enabled!/n"; 
        else { 
            print "/n"; 
            printf "%-35s %-20s/n","Audit Events","Settings"; 
            printf "%-35s %-20s/n","------------","--------"; 
            my $options = $info{eventauditingoptions}; 
            foreach my $key (keys %hash) { 
                printf "%-35s %-20s/n", $hash{$key},$settings{$$options[&amp;$key]}; 
    else { 
        my $err = Win32::FormatMessage Win32::Lanman::GetLastError(); 
        print "$server: Audit Error: $err/n"; 

6.7 (Script 7) 

#! c:/perl/bin/perl.exe 

use strict; 
use Win32::Lanman; 
use Win32::Perms; 

my $server = shift || Win32::NodeName; 

# This is an important setting, to prevent your 

sub GetEvents { 
    my($server,$evtlog) = @_; 
    my %types = (1 =>; "(Error)", 
                             4 =>; "(Information)", 
                             8 =>; "(Success Audit)", 
                             16 =>; "(Failure Audit)"); 

    my %category = (0 =>; "(None)", 
                                    1 =>; "(System Event)", 
                                    2 =>; "(Logon/Logoff)", 
                                    3 =>; "(Object Access)", 
                                    4 =>; "(Privilege Use)"); 

    if(Win32::Lanman::ReadEventLog("////$server", $evtlog, 0xffffffff, 0, /@events)) { 
        foreach $event (@events) { 
            print"Computer: ".${$event}{computername}."/n"; 
            print "Category:".${$event}{eventcategory}." ".$category{${$event}{eventcategory}}."/n"; 
            my $id = (${$event}{eventid} &amp; 0xffff); 

# Use the EventID to filter on specific types of events 
            print "Event ID: ".$id."/n"; 
            print "EventType: ".${$event}{eventtype}." ".$types{${$event}{eventtype}}."/n"; 
            print "Source: ".${$event}{source}."/n"; 
            print "SourceName: ".${$event}{sourcename}."/n"; 
            print"Generated: ".localtime(${$event}{timegenerated})."/n"; 
            print "Written: ".localtime(${$event}{timewritten})."/n"; 
            print "Flags: ".${$event}{reservedflags}."/n"; 
            print "User: ".Win32::Perms::ResolveAccount(${$event}{usersid})."/n"; 
            print "Description: "; 
            if (Win32::Lanman::GetEventDescription("////$server", $event)) { 
                $desc = ${$event}{eventdescription}; 
                print $desc."/n"; 
            else { 
                my $strings = ${$event}{strings}; 
                print "/n"; 
                foreach (@$strings) { 
                    print "/t+".$_."/n"; 
# print "Data:".unpack("H".2*length(${$event}{data}), ${$event}{data})."/n" 
# if (${$event}{data} ne ""); 
            print "/n/n"; 
    else { 
        my $err = Win32::FormatMessage Win32::Lanman::GetLastError(); 
        $err = Win32::Lanman::GetLastError() if ($err eq ""); 
        print "$server: ReadEventLog error: $err./n"; 

6.8 (Script 8) 

#! c:/perl/bin/perl.exe 
# Get user info from local system 

use strict; 
use Win32::Lanman; 

my $server = shift || Win32::NodeName; 
print "$server users.../n"; 

sub GetUserInfo { 
    my($server) = @_; 
    if (Win32::Lanman::NetUserEnum("////$server",0,/@users)) { 
        foreach my $user (@users) { 
            $pwage = (split(//./,${$user}{'password_age'}))/(3600*24); 
            print "${$user}{'name'}/n"; 
            print "/tComment =>; ${$user}{'comment'}/n"; 
            print "/tUID =>; ${$user}{'user_id'}/n"; 
            print "/tPasswd Age =>; $pwage/n"; 
#         print "/tLogon Svr =>; ${$user}{'logon_server'}/n"; 
            print "/tLast Logon =>;".mlocaltime(${$user}{'last_logon'})."/n"; 
            print "/tLast Logoff =>;".mlocaltime(${$user}{'last_logoff'})."/n"; 
            print "/tAccount does not expire./n" if (${$user}{'acct_expires'} == -1); 
            print "/tACCOUNT DISABLED./n" if (${$user}{'flags'} &amp; UF_ACCOUNTDISABLE); 
            print "/tUser cannot change password./n" if (${$user}{'flags'} &amp; UF_PASSWD_CANT_CHANGE); 
            print "/tAccount is locked out./n" if (${$user}{'flags'} &amp; UF_LOCKOUT); 
            print "/tPassword does not expire./n" if (${$user}{'flags'} &amp; UF_DONT_EXPIRE_PASSWD); 
            print "/tPassword not required./n" if (${$user}{'flags'} &amp; UF_PASSWD_NOTREQD); 
            print "/n/n"; 
    else { 
        my $err = Win32::FormatMessage Win32::Lanman::GetLastError(); 
        $err = Win32::Lanman::GetLastError() if ($err eq ""); 
        print "NetUserEnum Error: $err/n"; 

sub mlocaltime { 
    ($_[0] == 0) ? (return "Never") : (return localtime($_[0])); 

6.9 (Script 9) 

#! c:/perl/bin/perl.exe 
# Checks contents of StartUp folder 
# for each profile 

use strict; 
use Win32::Shortcut; 

my $server = shift || Win32::NodeName; 
my $me = Win32::NodeName; 

my $startdir; 
($server eq $me) ? ($startdir = "c://") : ($startdir = "////$server//c/$//"); 
my $start = $startdir."winnt//profiles//"; 
my $startup = "//start menu//programs//startup"; 
my ($dir,$err); 
if (-e $start &amp;&amp; -d $start) { 
    foreach $dir (sort readdir(ST)) { 
        next if ($dir eq "." || $dir eq ".."); 
        my $dir2 = $start.$dir; 
        if (-e $dir2 &amp;&amp; -d $dir2) { 
            my $newdir = "$start".$dir."$startup"; 
            if (-e $newdir &amp;&amp; -d $newdir) { 
                my @files = readdir(SUP); 
                if (@files) { 
                    foreach my $file (@files) { 
                        next if ($file eq "." || $file eq ".."); 
                        if ($file =~ m/lnk$/) { 
                            my $shortcut = Win32::Shortcut->;new($newdir."//".$file); 
                            ($shortcut) ? (print "$dir:$file:$shortcut->;{Path}/n") : (print "Error with Shortcut: ".Win32::FormatMessage Win32::GetLastError."/n"); 
                        else { 
                            print "$dir:$file/n"; 
            else { 
                print "$newdir does not exist or is not a directory./n"; 
        else { 
            print "$dir2 does not exist or is not a directory./n"; 

else { 
    print "$start does not exist or is not a directory./n"; 

System Security Administration for NT

文章来源:文章提交:xyzw ( Security Administration for NT Harlan C...
  • iiprogram
  • iiprogram
  • 2007年05月30日 16:13
  • 960

System Security Administration for NT

System Security Administration for NT Harlan Carvey Network Solutions http://www....
  • bz201
  • bz201
  • 2005年10月16日 09:18
  • 3613

Windows2003 Enterprise Edition 服务里没有NT LM Security Support Provider

今天在做两台Windows2003 + SQL2008数据库镜像,由于无法Telnet到其中一台服务器,所以去查找了原因。 发现其中一台的Telnet服务没有开启,尝试开启时,又出现了 “错误 ...
  • gtosky4u
  • gtosky4u
  • 2012年08月01日 14:21
  • 2570

电脑太卡之NT kernel & System

  • Code_Road
  • Code_Road
  • 2016年04月11日 16:03
  • 3384

关于 win7 NT kernel&system 占用大量CPU 问题

打开设备管理器, 网络适配器
  • leecyi
  • leecyi
  • 2014年04月10日 09:44
  • 14498

80端口被NT kernel & System占用

 前段时间停止了Apache,结果在打开的时候发现无法打开,80端口被占用,于是win+r 运行cmd 输入netstat -ano 可以看到80端口被PID4占用,于是打开...
  • u012074791
  • u012074791
  • 2015年07月27日 17:41
  • 3092

Windows:NT Kernel & System占用80端口

最近打算在一台windows系统的机子上apache服务,不过在安装时报了error,最后发现,原来是80端口被占用了导致失败。步骤: 1.运行’netstat -ano’发现80端口被pid=4的...
  • qq_20847637
  • qq_20847637
  • 2016年10月21日 14:54
  • 1090

80端口被NT KERNEL & SYSTEM 占用PID 4解决方法

 80端口被NT KERNEL & SYSTEM 占用PID 4解决方法 2012. 05. 17 原文地址:80端口被NT kernel & System 占用pid ...
  • yxwmzouzou
  • yxwmzouzou
  • 2015年02月16日 22:23
  • 1190

我的计算机问题解决之:NT Kernel & System 进程CPU占用过高(开机便保持在50%)

最近电脑突然出现顿卡顿卡的现象,查看进程管理,发现有一个System的进程一直占用CPU 50%,并且开机便如此。 针对这个问题我在网上查了很多资料,大部分都说系统该清理啦或...
  • yulingha
  • yulingha
  • 2013年03月11日 22:24
  • 35165

计划任务中使用NT AUTHORITY\SYSTEM用户和普通管理员用户有什么区别

原文地址: 系统管理员会碰到这样的问题,为什么在更...
  • shangzhihaohao
  • shangzhihaohao
  • 2011年12月20日 16:55
  • 18141
您举报文章:System Security Administration for NT