end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

perlでldap検索

ldapを使ってsingle sign on環境を構築したいという相談を受けたのですが、便利なldapも使い方によっては、セキュリティ上、危険というお話。

今回のldapではユーザ情報が次のように登録されており、氏名やmail,部署等の他にpasswdがSHAアルゴリズムにより登録されていることが分かります。

objectClass = top
objectClass = person
objectClass = organizationalPerson
objectClass = inetOrgPerson
objectClass = mailRecipient
objectClass = sexyPerson
objectClass = sexyPersonIndividual
uid = hogehoge021
userPassword = {SHA}Ow+HOGEHOGEI7+6vWJtHXaI=  ←★ココ
cn = 仮姓 仮名
cn;lang-ja-phonetic = カリセイ カリナ
sn = 仮姓
<略>
telephoneNumber = 03-xxxx-xxxx
facsimileTelephoneNumber = 03-xxxx-xxxx
o = (株)テスト会社
employeeNumber = 999580
mail = hogehoge@sexy.jp
sexyIdCardValidity = 1
sexyIdCardDepartment = 01FH0009
sexyIdCardDepartment = 01FH0009-20
sexyAuthDepartment = 01FH
sexyAuthDepartment = 01FH-20
sexyAuthDepartment = 01FH0008
<略>
sexyAuthDepartment = -20
sexyPwdLastSet = 1222228308
sexyAllowProxy = 1

ldapにあるSHAパスワードをローカルにコピーし、総当りでパスワードを解読する方法もありますが、企業の場合、社員番号や電話番号をパスワードに利用しているユーザは必ずいます。

試しに、次のようなscriptである部署の中で、社員番号をpasswdにしている人数を調べてみましょう。

#!perl	#ActivePerl for win

use strict;
use warnings;
use Net::LDAP;
use Digest::SHA1 qw/sha1_base64/;

my $LDAP_HOST = "ldap.sexy.co.jp";
my $BASE_DN =   "ou=people,o=sexy-group";
my $FILTER =    "(sexyAuthDepartment=01HA)";

main();

sub main {

    my $ldap = Net::LDAP->new($LDAP_HOST) or
        die "can't connect ldap $LDAP_HOST : $@";

    $ldap->bind;

    my $res = $ldap->search(base =>$BASE_DN, filter =>$FILTER);
    $res->code and die $res->error;

    my $count_all = 0;
    my $count_passwd = 0;
    for my $entry ( $res->all_entries ) {   # Net::LDAP::Entry

        $count_all++;
        # $entry->attributes
        # 主要なldap属性一覧は↓こちらにも記載
        # http://d.hatena.ne.jp/end0tknr/20131119/1384787962
        my $emp =       $entry->get_value("employeeNumber");
        next unless $emp;

        my $passwd_emp = sha1_base64( $emp );
        $passwd_emp =~ s/(\/|\\|\+)/\\$1/go;

        my $passwd =    $entry->get_value("userPassword");

        $count_passwd++ if ( $passwd =~ /$passwd_emp/ );
    }
    $ldap->unbind;

    print "USER COUNT:$count_all\tWEAK PASSWD:$count_passwd\n";
    return 1;
}

社員番号をパスワードに使っている人数は 394人中 3名で、少ないと思う方もいるかもしれませんが、悪い人にとっては3名のパスワードがあれば十分です。

USER COUNT:394  WEAK PASSWD:3

パスワードはランダム&長めの文字列で、定期的に変更することをお勧めします。