Skip to content

Commit

Permalink
feat: add edge information panel components for ADCSESC10b (#377)
Browse files Browse the repository at this point in the history
  • Loading branch information
elikmiller authored Feb 2, 2024
1 parent d4c74bb commit ab2ba1f
Show file tree
Hide file tree
Showing 7 changed files with 516 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2024 Specter Ops, Inc.
//
// Licensed under the Apache License, Version 2.0
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

import General from './General';
import WindowsAbuse from './WindowsAbuse';
import LinuxAbuse from './LinuxAbuse';
import Opsec from './Opsec';
import References from './References';

const ADCSESC10b = {
general: General,
windowsAbuse: WindowsAbuse,
linuxAbuse: LinuxAbuse,
opsec: Opsec,
references: References,
};

export default ADCSESC10b;
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2024 Specter Ops, Inc.
//
// Licensed under the Apache License, Version 2.0
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

import { FC } from 'react';
import { useHelpTextStyles, groupSpecialFormat } from '../utils';
import { EdgeInfoProps } from '../index';
import { Typography } from '@mui/material';

const General: FC<EdgeInfoProps> = ({ sourceName, sourceType, targetName }) => {
const classes = useHelpTextStyles();
return (
<Typography variant='body2' className={classes.containsCodeEl}>
{groupSpecialFormat(sourceType, sourceName)} has the privileges to perform the ADCS ESC10 Scenario B attack
against the target domain.
<br />
<br />
The principal has control over a victim computer with permission to enroll on one or more certificate
templates, configured to enable certificate authentication, and require the <code>dNSHostName</code> of the
enrollee included in the Subject Alternative Name (SAN). The victim computer also has enrollment permission
for an enterprise CA with the necessary templates published. This enterprise CA is trusted for NT
authentication in the forest, and chains up to a root CA for the forest. There is an affected Domain
Controller (DC) configured to allow UPN certificate mapping. This setup lets the principal impersonate any
AD forest computer without their credentials.
<br />
<br />
The attacker principal can abuse their control over the victim computer to modify the victim computer's{' '}
<code>dNSHostName</code> attribute to match the <code>dNSHostName</code> of a targeted computer. The
attacker principal will then abuse their control over the victim computer to obtain the credentials of the
victim computer, or a session as the victim computer, and enroll a certificate as the victim in one of the
affected certificate templates. The <code>dNSHostName</code> of the victim will be included in the issued
certificate under SAN DNS name. The UPN certificate mapping configuration on the affected DCs make it
possible to authenticate over Schannel as the targeted computer. The DC will split the SAN DNS name into a
computer name and a domain name, confirm that the domain name is correct, and use the computer name appended
a $ to identify a computer with matching <code>sAMAccountName</code> which the attacker will be
authenticated as.
</Typography>
);
};

export default General;
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// Copyright 2024 Specter Ops, Inc.
//
// Licensed under the Apache License, Version 2.0
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

import { FC } from 'react';
import { Box, Link, Typography } from '@mui/material';
import { useHelpTextStyles } from '../utils';

const LinuxAbuse: FC = () => {
const classes = useHelpTextStyles();
const step1 = (
<>
<Typography variant='body2' className={classes.containsCodeEl}>
<b>Step 1: </b>Set <code>dNSHostName</code> of victim computer to targeted computer's{' '}
<code>dNSHostName</code>.
<br />
<br />
Set the <code>dNSHostName</code> of the victim computer using Certipy:
</Typography>
<Typography component='pre'>
{
'certipy account update -username [email protected] -password PWD -user VICTIM$ -dns TARGET.CORP.LOCAL'
}
</Typography>
</>
);

const step2 = (
<>
<Typography variant='body2' className={classes.containsCodeEl}>
<b>Step 2: </b>Check if <code>mail</code> attribute of victim must be set and set it if required.
<br />
<br />
If the certificate template is of schema version 2 or above and its attribute{' '}
<code>msPKI-CertificateNameFlag</code> contains the flag <code>SUBJECT_REQUIRE_EMAIL</code> and/or{' '}
<code>SUBJECT_ALT_REQUIRE_EMAIL</code> then the victim principal must have their <code>mail</code>{' '}
attribute set for the certificate enrollment. The CertTemplate BloodHound node will have{' '}
<em>"Subject Require Email"</em> or <em>"Subject Alternative Name Require Email"</em> set to true if any
of the flags are present.
<br />
<br />
If the certificate template is of schema version 1 or does not have any of the email flags, then
continue to Step 3.
<br />
<br />
If any of the two flags are present, you will need the victim's mail attribute to be set. The value of
the attribute will be included in the issues certificate but it is not used to identify the target
principal why it can be set to any arbitrary string.
<br />
<br />
Check if the victim has the mail attribute set using ldapsearch:
</Typography>
<Typography component='pre'>{`ldapsearch -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME -b "VICTIM-DN" mail`}</Typography>
<Typography variant='body2'>
If the victim has the mail attribute set, continue to Step 3.
<br />
<br />
If the victim does not has the mail attribute set, set it to a dummy mail using ldapmodify:
</Typography>
<Typography component='pre'>
{`echo -e "dn: VICTIM-DN\nchangetype: modify\nreplace: mail\nmail: [email protected]" | ldapmodify -x -D "ATTACKER-DN" -w 'PWD' -h DOMAIN-DNS-NAME`}
</Typography>
</>
);

const step3 = (
<Box
sx={{
borderRadius: '4px',
backgroundColor: '#eee',
}}>
<Typography variant='body2' sx={{ marginBottom: '-8px' }}>
<b>Step 3: </b>Obtain a session as victim.
<br />
<br />= There are several options for this step. You can obtain a session as SYSTEM on the host, which
allows you to interact with AD as the computer account, by abusing control over the computer AD object
(see{' '}
<Link
target='blank'
rel='noopener'
href='https://support.bloodhoundenterprise.io/hc/en-us/articles/17312347318043-GenericAll'>
GenericAll edge documentation
</Link>
).
</Typography>
</Box>
);

const step4 = (
<>
<Typography variant='body2'>
<b>Step 4: </b>Enroll certificate as victim.
<br />
<br />
Use Certipy as the victim computer to request enrollment in the affected template, specifying the
affected EnterpriseCA:
</Typography>
<Typography component='pre'>
{'certipy req -u [email protected] -p PWD -ca CA-NAME -target CA-SERVER -template TEMPLATE'}
</Typography>
<Typography variant='body2'>
The issued certificate will be saved to disk with the name of the targeted computer.
</Typography>
</>
);

const step5 = (
<>
<Typography variant='body2'>
<b>Step 5 (Optional): </b>Set <code>dNSHostName</code> of victim to the previous value.
<br />
<br />
To avoid DNS issues in the environment, set the <code>dNSHostName</code> of the victim computer back to
it's previous value using Certipy:
</Typography>
<Typography component='pre'>
{
'certipy account update -username [email protected] -password PWD -user VICTIM -dns VICTIM.CORP.LOCAL'
}
</Typography>
</>
);

const step6 = (
<>
<Typography variant='body2'>
<b>Step 6: </b>Perform Schannel authentication as targeted principal against affected DC using
certificate.
<br />
<br />
Open an LDAP shell as the victim using Certipy by specifying the certificate created in Step 5 and the
IP of an affected DC:
</Typography>
<Typography component='pre'>{'certipy auth -pfx TARGET.pfx -dc-ip IP -ldap-shell'}</Typography>
</>
);

return (
<>
<Typography variant='body2'>An attacker may perform this attack in the following steps:</Typography>
{step1}
{step2}
{step3}
{step4}
{step5}
{step6}
</>
);
};

export default LinuxAbuse;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2024 Specter Ops, Inc.
//
// Licensed under the Apache License, Version 2.0
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

import { FC } from 'react';
import { Typography } from '@mui/material';

const Opsec: FC = () => {
return (
<Typography variant='body2'>
When the affected certificate authority issues the certificate to the attacker, it will retain a local copy
of that certificate in its issued certificates store. Defenders may analyze those issued certificates to
identify illegitimately issued certificates and identify the computer that requested the certificate, as
well as the target identity the attacker is attempting to impersonate.
</Typography>
);
};

export default Opsec;
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2024 Specter Ops, Inc.
//
// Licensed under the Apache License, Version 2.0
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

import React, { FC } from 'react';
import { Link, Box } from '@mui/material';

const References: FC = () => {
const references = [
{
label: 'Certipy 4.0',
link: 'https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7',
},
{
label: 'Certipy',
link: 'https://github.com/ly4k/Certipy',
},
{
label: 'Set-DomainObject',
link: 'https://powersploit.readthedocs.io/en/latest/Recon/Set-DomainObject',
},
{
label: 'LDAPSearch',
link: 'https://linux.die.net/man/1/ldapsearch',
},
{
label: 'LDAPModify',
link: 'https://linux.die.net/man/1/ldapmodify',
},
];
return (
<Box sx={{ overflowX: 'auto' }}>
{references.map((reference) => {
return (
<React.Fragment key={reference.link}>
<Link target='_blank' rel='noopener' href={reference.link}>
{reference.label}
</Link>
<br />
</React.Fragment>
);
})}
</Box>
);
};

export default References;
Loading

0 comments on commit ab2ba1f

Please sign in to comment.