企业内部AD脆弱密码审计

by 云舒
2008-07-09
http://www.ph4nt0m.org

这个是前段时间做的个小脚本,没什么用,审计内部AD脆弱密码的。做这样一些简单的工作,脚本语言确实挺合适的。需要一个普通的AD账号,导出账户名,过滤掉禁用的,然后开始扫描。密码字典按照自己公司的实际情况写就好了,支持%USERNAME%123这样的格式。

脚本里面的各种参数我写死了,因为自己用,不必要敲参数。如果想要用用看,自己改就是了,perl这种东西简单的学一下的话,一个上午就够了。下午不行,这种天气下午只适合睡觉,或者吃点冰绿豆汤之类的东西,反正是不适合看代码。

#!/usr/bin/perluse warnings;
use strict;
use Win32::OLE;
use Data::Dumper;
use Authen::Simple::ActiveDirectory;

use constant ADS_UF_ACCOUNTDISABLE => 2;
use constant ADS_SCOPE_SUBTREE => 2;

my $server = 'bj.microsoft.com';
my $domain = 'bj.microsoft.com';
my %users;
my @pwds;

select( STDOUT );
$| = 1;

print "Loading account from ad";

&LoadUser( );

print "done!n";
print scalar(keys(%users))." users loaded!n";

print "Loading password from dic";
&LoadPwd( );
print "done!n";

open( REPORT, ">report.txt" ) || die "create report error: $!n";
select( REPORT );
$| = 1;
select( STDOUT );

foreach my $user( keys(%users) )
{
    foreach my $pwd( @pwds )
    {
        $pwd =~ s/%USERNAME%/$user/;

        my $ret = &TestPwd( $user, $pwd );
        if( $ret == 1 )
        {
            print "cracked! username=$user,password=$pwd,mail=".$users{$user}."n";
            print REPORT "cracked! username=$user,password=$pwd,mail=".$users{$user}."n";

            last;
        }
        #print "testing [$user/$pwd] n";
    }
}
close( REPORT );

sub LoadUser
{
    my $objConnection = Win32::OLE->new( "ADODB.Connection" );
    my $objCommand = Win32::OLE->new( "ADODB.Command" );

    # open ad
    $objConnection -> open( "Provider=ADsDSOObject;" );

    $objCommand -> {"ActiveConnection"} = $objConnection;

    # search what and how
    my $cmd = "select userAccountControl,distinguishedName,mail from 'GC://dc=bj,dc=microsoft,dc=com' where objectCategory='user'";
    $objCommand -> {"CommandText"} = $cmd;

    # import all users
    $objCommand -> Properties -> {"Page Size"} = 1000;
    # search all subtree
    $objCommand -> Properties -> {"searchscope"} = ADS_SCOPE_SUBTREE;

    my $objRecordSet = Win32::OLE->new( "ADODB.Recordset" );
    $objRecordSet = $objCommand->Execute( ) || die "query data from active directory error,exitn";

    while( not $objRecordSet -> eof )
    {
        my $intUAC = $objRecordSet -> Fields("userAccountControl") -> value;

        # remove diable account
        if( not ( $intUAC & ADS_UF_ACCOUNTDISABLE ) )
        {
            my $longName = $objRecordSet -> Fields("distinguishedName") -> value;
            my $mail = $objRecordSet -> Fields("mail") -> value;

            if( (!defined($mail)) or $mail eq "" )
            {
                $mail = "null";
            }
            if( $longName =~ /^CN=([w.-_]+),/ )
            {
                #print ."n";
                my $userName = $1;

                chomp( $mail );
                chomp( $userName );

                $users{$userName} = $mail;
            }
        }
        $objRecordSet -> MoveNext();
    }
}

sub LoadPwd
{
    open( FH, "<pass.txt" ) || die "Open password dict error,exit!n";

    @pwds = <FH>;
    chomp( @pwds );
}

sub TestPwd
{
    my $username = shift;
    my $password = shift;

    my $ad = Authen::Simple::ActiveDirectory -> new( host => $server, principal => $domain ) || die "Connected error: $!";

    if ( $ad->authenticate( $username, $password ) )
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

相关日志

发表评论