As many organizations are moving aggressively towards cloud based platforms, we as Red Teamers are coming more into contact with Federation services. Federations essentially extend authentication mechanisms from one system to another. These systems may be part of the same organization or completely separate. One of the most common implementations of this is Microsoft’s Active Directory Federation Servers (ADFS). For a good overview of securing ADFS, check out adsecurity’s article here. As these services are becoming more popular,
For the purposes of this article,
password spraying refers to the attack method that takes a large number of usernames, and iterates over them with a single password. We may perform multiple iterations using different passwords, but the number of passwords attempted is generally low when compared to the number of users attempted. This allows us to avoid password lockouts, and is often more effective at uncovering weak passwords than targeting specific users.
Coming up with a good password list is essential to the success of this attack. You can use tools like CeWL to generate target specific lists using words from web-sites, or come up with your own methodology. In the past, I have had a lot of success using MonthYear, welcome1, and organization1.
Finding an ADFS instance provides us with a direct login to services generally reserved for members of the organization. Many times, we are presented with an option of which services to sign directly into. This may expose additional attack surface and 3rd party service providers that may be in scope for our engagements.
By default, the login page is located at
/adfs/ls/IdpInitiatedSignOn.aspx. We can use common attributes of the URL to effectively find exposed login interfaces using Google and the following search terms.
inurl:"/adfs/ls/" intitle:"Sign In"
Setting up BurpSuite Proxy
The default port is
127.0.0.1:8080, but I already have something bound there. I simply added a new Proxy Listener with the bind address of 127.0.0.1 port 9999. You can now point your favorite browser to whichever port you decided to listen on. While testing web applications, I usually prefer a dedicated instance of Firefox
Firefox can be configured by navigating to
about:preferences and find the section labeled
Testing the Login
Now that we have Burp and our browser setup, navigate to the newly found ADFS login page.
Attempt to login using any credentials (that may be valid), and click Sign In. In the Target tab in Burp, locate the POST request to
Right click the request, and choose
Send to Intruder. In the Intruder tab, select the second inner tab and click the
Clear button. This will reset the attack positions within the payload. Change the password to whatever password you would like to run against all usernames. Now, highlight just the username portion of the form, and click the Add button on the right hand side.
Now, in the payload tab we’ll add a list of e-mails to check against.
You can tweak more advanced options like how many threads to use and more in the
Options tab. Once you have it setup the way you would like, simply click
As you can see, we had one response that was type 302 (Not Found). This is the response that we get during a successful login to ADFS. In addition, the cookie
MSIAuth is set. We can use these two identifying marks to find successful logins.
Password Spraying with Curl
If you don’t have Burp Suite Pro (It’s worth it!), you can still use Burp Intruder to conduct this attack. Certain features may not work and may be throttled as well. In addition to this technique, you can still capture the POST request from earlier and use curl. Find the POST request again, and right click that line and select
Copy as curl command
Now, we can save a list of usernames to a file named emails (one per line) and run a simple for loop. When you paste the link to your terminal, it should look something like this.
curl -i -s -k -X $'POST' -H $'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0' -H $'Referer: https://address.com/adfs/ls/IdpInitiatedSignOn.aspx' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Upgrade-Insecure-Requests: 1' -b $'MSISSamlRequest=QmFzZVVy...==' --data-binary $'UserName=bbob%40dev.bitrot.sh&Password=Winter2017&AuthMethod=FormsAuthentication' $'https://devfs.bitrot.sh/adfs/ls/IdpInitiatedSignOn.aspx'
We can modify that slightly and throw it into a for loop like so. It will print out any successful usernames that it finds.
for USER in $(cat users); do curl -i -s -k -X $'POST' -H $'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0' -H $'Referer: https://address.com/adfs/ls/IdpInitiatedSignOn.aspx' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Upgrade-Insecure-Requests: 1' -b $'MSISSamlRequest=QmFzZVVy...==' --data-binary "UserName=$USER%40dev.bitrot.sh&Password=Winter2017&AuthMethod=FormsAuthentication" $'https://devfs.bitrot.sh/adfs/ls/IdpInitiatedSignOn.aspx' | grep 'MSISAuth=' && echo $USER; done