2008年7月8日星期二

[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 $userkeys(%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.
       

没有评论: