[Tips]企业内部AD脆弱密码审计
by 云舒
2008-07-09
http://www.ph4nt0m.org
这个是前段时间做的个小脚本,没什么用,审计内部AD脆弱密码的。做这样一些简单的工作,脚本语言确实挺合适的。需要一个普通的AD账号,导出账户名,过滤掉禁用的,然后开始扫描。密码字典按照自己公司的实际情况写就好了,支持%USERNAME%123这样的格式。
脚本里面的各种参数我写死了,因为自己用,不必要敲参数。如果想要用用看,自己改就是了,perl这种东西简单的学一下的话,一个上午就够了。下午不行,这种天气下午只适合睡觉,或者吃点冰绿豆汤之类的东西,反正是不适合看代码。
1.
#!/usr/bin/perl
2.
3.
use warnings;
4.
use strict;
5.
use Win32::OLE;
6.
use Data::Dumper;
7.
use Authen::Simple::ActiveDirectory;
8.
9.
use constant ADS_UF_ACCOUNTDISABLE => 2;
10.
use constant ADS_SCOPE_SUBTREE => 2;
11.
12.
my $server = 'bj.microsoft.com';
13.
my $domain = 'bj.microsoft.com';
14.
my %users;
15.
my @pwds;
16.
17.
select( STDOUT );
18.
$| = 1;
19.
20.
print "Loading account from ad";
21.
22.
&LoadUser( );
23.
24.
print "done!n";
25.
print scalar(keys(%users))." users loaded!n";
26.
27.
print "Loading password from dic";
28.
&LoadPwd( );
29.
print "done!n";
30.
31.
open( REPORT, ">report.txt" ) || die "create report error: $!n";
32.
select( REPORT );
33.
$| = 1;
34.
select( STDOUT );
35.
36.
foreach my $user( keys(%users) )
37.
{
38.
foreach my $pwd( @pwds )
39.
{
40.
$pwd =~ s/%USERNAME%/$user/;
41.
42.
my $ret = &TestPwd( $user, $pwd );
43.
if( $ret == 1 )
44.
{
45.
print "cracked! username=$user,password=$pwd,mail=".$users{$user}."n";
46.
print REPORT "cracked! username=$user,password=$pwd,mail=".$users{$user}."n";
47.
48.
last;
49.
}
50.
#print "testing [$user/$pwd] n";
51.
}
52.
}
53.
close( REPORT );
54.
55.
sub LoadUser
56.
{
57.
my $objConnection = Win32::OLE->new( "ADODB.Connection" );
58.
my $objCommand = Win32::OLE->new( "ADODB.Command" );
59.
60.
# open ad
61.
$objConnection -> open( "Provider=ADsDSOObject;" );
62.
63.
$objCommand -> {"ActiveConnection"} = $objConnection;
64.
65.
# search what and how
66.
my $cmd = "select userAccountControl,distinguishedName,mail from 'GC://dc=bj,dc=microsoft,dc=com' where objectCategory='user'";
67.
$objCommand -> {"CommandText"} = $cmd;
68.
69.
# import all users
70.
$objCommand -> Properties -> {"Page Size"} = 1000;
71.
# search all subtree
72.
$objCommand -> Properties -> {"searchscope"} = ADS_SCOPE_SUBTREE;
73.
74.
my $objRecordSet = Win32::OLE->new( "ADODB.Recordset" );
75.
$objRecordSet = $objCommand->Execute( ) || die "query data from active directory error,exitn";
76.
77.
while( not $objRecordSet -> eof )
78.
{
79.
my $intUAC = $objRecordSet -> Fields("userAccountControl") -> value;
80.
81.
# remove diable account
82.
if( not ( $intUAC & ADS_UF_ACCOUNTDISABLE ) )
83.
{
84.
my $longName = $objRecordSet -> Fields("distinguishedName") -> value;
85.
my $mail = $objRecordSet -> Fields("mail") -> value;
86.
87.
if( (!defined($mail)) or $mail eq "" )
88.
{
89.
$mail = "null";
90.
}
91.
if( $longName =~ /^CN=([w.-_]+),/ )
92.
{
93.
#print ."n";
94.
my $userName = $1;
95.
96.
chomp( $mail );
97.
chomp( $userName );
98.
99.
$users{$userName} = $mail;
100.
}
101.
}
102.
$objRecordSet -> MoveNext();
103.
}
104.
}
105.
106.
sub LoadPwd
107.
{
108.
open( FH, "<pass.txt" ) || die "Open password dict error,exit!n";
109.
110.
@pwds = <FH>;
111.
chomp( @pwds );
112.
}
113.
114.
sub TestPwd
115.
{
116.
my $username = shift;
117.
my $password = shift;
118.
119.
my $ad = Authen::Simple::ActiveDirectory -> new( host => $server, principal => $domain ) || die "Connected error: $!";
120.
121.
if ( $ad->authenticate( $username, $password ) )
122.
{
123.
return 1;
124.
}
125.
else
126.
{
127.
return 0;
128.
}
129.
}
130.
#!/usr/bin/perl
2.
3.
use warnings;
4.
use strict;
5.
use Win32::OLE;
6.
use Data::Dumper;
7.
use Authen::Simple::ActiveDirectory;
8.
9.
use constant ADS_UF_ACCOUNTDISABLE => 2;
10.
use constant ADS_SCOPE_SUBTREE => 2;
11.
12.
my $server = 'bj.microsoft.com';
13.
my $domain = 'bj.microsoft.com';
14.
my %users;
15.
my @pwds;
16.
17.
select( STDOUT );
18.
$| = 1;
19.
20.
print "Loading account from ad";
21.
22.
&LoadUser( );
23.
24.
print "done!n";
25.
print scalar(keys(%users))." users loaded!n";
26.
27.
print "Loading password from dic";
28.
&LoadPwd( );
29.
print "done!n";
30.
31.
open( REPORT, ">report.txt" ) || die "create report error: $!n";
32.
select( REPORT );
33.
$| = 1;
34.
select( STDOUT );
35.
36.
foreach my $user( keys(%users) )
37.
{
38.
foreach my $pwd( @pwds )
39.
{
40.
$pwd =~ s/%USERNAME%/$user/;
41.
42.
my $ret = &TestPwd( $user, $pwd );
43.
if( $ret == 1 )
44.
{
45.
print "cracked! username=$user,password=$pwd,mail=".$users{$user}."n";
46.
print REPORT "cracked! username=$user,password=$pwd,mail=".$users{$user}."n";
47.
48.
last;
49.
}
50.
#print "testing [$user/$pwd] n";
51.
}
52.
}
53.
close( REPORT );
54.
55.
sub LoadUser
56.
{
57.
my $objConnection = Win32::OLE->new( "ADODB.Connection" );
58.
my $objCommand = Win32::OLE->new( "ADODB.Command" );
59.
60.
# open ad
61.
$objConnection -> open( "Provider=ADsDSOObject;" );
62.
63.
$objCommand -> {"ActiveConnection"} = $objConnection;
64.
65.
# search what and how
66.
my $cmd = "select userAccountControl,distinguishedName,mail from 'GC://dc=bj,dc=microsoft,dc=com' where objectCategory='user'";
67.
$objCommand -> {"CommandText"} = $cmd;
68.
69.
# import all users
70.
$objCommand -> Properties -> {"Page Size"} = 1000;
71.
# search all subtree
72.
$objCommand -> Properties -> {"searchscope"} = ADS_SCOPE_SUBTREE;
73.
74.
my $objRecordSet = Win32::OLE->new( "ADODB.Recordset" );
75.
$objRecordSet = $objCommand->Execute( ) || die "query data from active directory error,exitn";
76.
77.
while( not $objRecordSet -> eof )
78.
{
79.
my $intUAC = $objRecordSet -> Fields("userAccountControl") -> value;
80.
81.
# remove diable account
82.
if( not ( $intUAC & ADS_UF_ACCOUNTDISABLE ) )
83.
{
84.
my $longName = $objRecordSet -> Fields("distinguishedName") -> value;
85.
my $mail = $objRecordSet -> Fields("mail") -> value;
86.
87.
if( (!defined($mail)) or $mail eq "" )
88.
{
89.
$mail = "null";
90.
}
91.
if( $longName =~ /^CN=([w.-_]+),/ )
92.
{
93.
#print ."n";
94.
my $userName = $1;
95.
96.
chomp( $mail );
97.
chomp( $userName );
98.
99.
$users{$userName} = $mail;
100.
}
101.
}
102.
$objRecordSet -> MoveNext();
103.
}
104.
}
105.
106.
sub LoadPwd
107.
{
108.
open( FH, "<pass.txt" ) || die "Open password dict error,exit!n";
109.
110.
@pwds = <FH>;
111.
chomp( @pwds );
112.
}
113.
114.
sub TestPwd
115.
{
116.
my $username = shift;
117.
my $password = shift;
118.
119.
my $ad = Authen::Simple::ActiveDirectory -> new( host => $server, principal => $domain ) || die "Connected error: $!";
120.
121.
if ( $ad->authenticate( $username, $password ) )
122.
{
123.
return 1;
124.
}
125.
else
126.
{
127.
return 0;
128.
}
129.
}
130.
没有评论:
发表评论