TLDR
This blog walks you through setting up an ADFS lab using Ludus and/or a flexible hybrid cloud environment for testing.
The associated GitHub repo is here.
Introduction
I was recently on an engagement where the customer was using Active Directory Federated Services (ADFS). ADFS is an Identity Provider (idP) by Microsoft that allows third-party applications and internal applications to delegate authentication to Active Directory.
I see ADFS all the time during my engagements, and although I knew about this technology in theory, I wanted to gain more experience with it. How fun would it be to spin up an ADFS lab, learn how it works under the hood, practice attacks, and analyze possible detection’s? The possibilities are endless with a home lab!
I’m a heavy Ludus user, and I use Zach Stein’s SCCM Ludus range all the time, so going with Ludus was a no brainer. Erik Hunstad developed Ludus which simplifies lab deployments, making it a powerful tool for managing virtual environments. If you’re not familiar with it yet, be sure to check out the Ludus documentation here.
Entra Challenge
While I was building the lab, I wanted to see if it would be possible to automate the process for integrating Microsoft 365 apps with ADFS for authentication. To do this on a domain-joined system, I would need to run the AzureAdConnect.msi installer, which replicates objects from an on-prem Active Directory environment to Entra ID and when configured can also write changes from Entra ID back to on-prem AD. Automating this became more difficult than I anticipated.
Instead, I’ve created an Ansible role called “entra_prep”, which prepares a dedicated server to connect your on-prem AD environment to Entra ID. You can find more details in the “Roles” section on how this works. Keep in mind that you’ll need your own Entra tenant to move forward. Once that’s set up, the only other step is running the AzureADConnect installer and following the wizard. Everything else you need for a hybrid cloud lab is ready to go.
What makes this lab super flexible is that it is essentially “choose your own adventure”. You have the freedom to decide exactly how you would like to structure your lab.
- Don’t want to use ADFS, but just want a hybrid cloud lab? This setup works for that!
- Want to experiment with ADFS locally and not use the cloud? Perfect!
- Desire to understand how password hash syncing works under the hood? We have a winner!
- Interested in playing with setting up Office Apps with ADFS and researching potential weaknesses? This works for that as well!
- Want to test how a Golden SAML attack works and pivot from on-prem AD to the cloud? This lab will help you get there!
You get the picture, there’s a lot you can do with this home lab. I do believe this lab strikes a good balance between automation and manual setup that lets you set up how you want the cloud environment to be and still save you some time.
Roles
Ludus uses Ansible roles to manage the software and configurations in the lab environment. The following are roles that I created for this lab.
install_adfs
This role installs the ADFS role on a server, creates an ADFS service account, and requests a certificate that ADFS uses.
import_root_cert
This role requests the root certificate from the certificate authority (CA) and imports it into the local machine security store. This is necessary to remove the following certificate error which is caused because the lab machine does not trust the CA that signed the cert being used by ADFS.
entra_prep
This role adds an alternative user principal name (UPN) to the local domain which is required before connecting an on-prem domain to Entra ID. This role also installs TLS 1.2 which AzureAdConnect.msi requires. Next, this role creates a service account which is used for syncing AD objects from on-prem AD to Entra ID. There are some settings that allow Entra ID to replicate changes to on-prem AD such as group writeback, device writeback, or password writeback. If any of these settings are configured, then some changes in Entra ID like group creation, or password resets will be replicated from Entra ID to on-prem AD. Finally, this role downloads the AzureAdConnect.msi installer to the server that will be used for replication between on-prem AD and Entra ID.
Installation
I won’t be covering the installation of Ludus as this is already heavily documented in the Ludus docs. Installation of the ADFS range is simple, you just need to clone the ludas_adfs repo.
git clone https://github.com/bagelByt3s/ludus_adfs /opt/ludus_adfs
Then you add the Ansible collection to Ludus.
ludus ansible collection add /opt/ludus_adfs
Review the sample range configuration file, updating fields to suit your desired environment:
ADFS-Range.yml
ludus:
- vm_name: "DC01-WinServer2022"
hostname: "DC01"
template: win2022-server-x64-template
vlan: 10
ip_last_octet: 10
ram_gb: 8
cpus: 4
windows:
sysprep: true
domain:
fqdn: ludus.nuketown
role: primary-dc
roles:
- bagelByt3s.ludus_adfs.install_adcs
- vm_name: "ADFS-WinServer2022"
hostname: "ADFS"
template: win2022-server-x64-template
vlan: 10
ip_last_octet: 11
ram_gb: 8
ram_min_gb: 2
cpus: 4
windows:
sysprep: true
domain:
fqdn: ludus.nuketown
role: member
roles:
- bagelByt3s.ludus_adfs.import_root_cert
- bagelByt3s.ludus_adfs.install_adfs
role_vars:
adfs_service_account: 'adfs_svc'
adfs_service_account_password: 'password'
adfs_service_display_name: 'ADFS Service'
adfs_hostname: 'adfs.ludus.nuketown'
adfs_FQDN_CA: 'DC01.ludus.nuketown\ludus-CA'
adfs_CA: "ludus-CA"
adfs_certificate_subject: "CN=adfs.ludus.nuketown, O=Ludus, C=US"
- vm_name: "EntraConnect-WinServer2022"
hostname: "EntraConnect"
template: win2022-server-x64-template
vlan: 10
ip_last_octet: 12
ram_gb: 8
ram_min_gb: 2
cpus: 4
windows:
sysprep: true
domain:
fqdn: ludus.nuketown
role: member
roles:
- bagelByt3s.ludus_adfs.import_root_cert
- bagelByt3s.ludus_adfs.entra_prep
role_vars:
adfs_CA: "ludus-CA"
ludus_entra_join_svc_account: "entra_svc"
ludus_entra_join_svc_account_password: "password"
ludus_entra_join_alt_upn: "" #Example: domain.onmicrosoft.com or leave blank to skip
- vm_name: "Workstation-Win11"
hostname: "Workstation"
template: win11-22h2-x64-enterprise-template
vlan: 10
ip_last_octet: 13
ram_gb: 4
ram_min_gb: 2
cpus: 4
windows:
sysprep: true
domain:
fqdn: ludus.nuketown
role: member
roles:
- bagelByt3s.ludus_adfs.import_root_cert
role_vars:
adfs_CA: "ludus-CA"
ludus range config set -f /opt/ludus_adfs/ADFS-Range.yml
ludus range deploy
Once the deployment completes, you can visit the following URL to confirm that the ADFS deployment was successful (the domain and hostname will be different if you modified the ADFS-Range.yml file).
https://adfs.ludus.nuketown/adfs/ls/IdpInitiatedSignOn.aspx
This provides a working ADFS deployment. All that is left for you to do is to integrate third-party applications for Single Sign-On (SSO) using ADFS.
Additionally, if you have an Entra tenant and would like to migrate the domain to a hybrid deployment, simply login to the EntraConnect-WinServer2022 virtual machine and run the installer found at c:\windows\tasks\AzureAdConnect.msi.
Follow the wizard with your details and you’re on your way!
Closing Thoughts
It was a pleasure to write this blog! If you find this tool helpful in any way, or have suggestions for improvements, please don’t hesitate to reach out!
Special thanks to Erik Hunstad from https://badsectorlabs.com/ , I love Ludus and this would not be possible without it!
Also thank you to Zach Stein, his SCCM Ludus range was a big inspiration for this. Check it out here!
Originally published at https://medium.com on December 19, 2024.
ADFS Entra Lab with Ludus was originally published in Posts By SpecterOps Team Members on Medium, where people are continuing the conversation by highlighting and responding to this story.
Introduction to Malware Binary Triage (IMBT) Course
Looking to level up your skills? Get 10% off using coupon code: MWNEWS10 for any flavor.
Enroll Now and Save 10%: Coupon Code MWNEWS10
Note: Affiliate link – your enrollment helps support this platform at no extra cost to you.