Git Product home page Git Product logo

adfspoof's Introduction

ADFSpoof

A python tool to forge AD FS security tokens.

Created by Doug Bienstock (@doughsec) while at Mandiant FireEye.

Detailed Description

ADFSpoof has two main functions:

  1. Given the EncryptedPFX blob from the AD FS configuration database and DKM decryption key from Active Directory, produce a usable key/cert pair for token signing.
  2. Given a signing key, produce a signed security token that can be used to access a federated application.

This tool is meant to be used in conjunction with ADFSDump. ADFSDump runs on an AD FS server and outputs important information that you will need to use ADFSpoof.

If you are confused by the above, you might want to read up on AD FS first. For more information on AD FS spoofing I will post a link to my TROOPERS 19 talk and slides when they are released.

Installation

ADFSpoof is written in Python 3.

ADFSpoof requires the installation of a custom fork of the Python Cryptography package, available here. Microsoft did not exactly follow the RFC for Key Deriviation 😉, so a fork of the package was needed. The modified key derivation function has been ported to work with the newer versions of cryptography lib.

All requirements are captured in the repo's requirements.txt.

pip install -r requirements.txt

Usage

usage: ADFSpoof.py [-h] (-b BLOB BLOB | -c CERT) [-p PASSWORD] [-v VERBOSE]
                   [--assertionid ASSERTIONID] [--responseid RESPONSEID]
                   [-s SERVER] [-a ALGORITHM] [-d DIGEST] [-o OUTPUT]
                   {o365,dropbox,saml2,dump} ...

optional arguments:
  -h, --help            show this help message and exit
  -b BLOB BLOB, --blob BLOB BLOB
                        Encrypted PFX blob and decryption key
  -c CERT, --cert CERT  AD FS Signing Certificate
  -p PASSWORD, --password PASSWORD
                        AD FS Signing Certificate Password
  -v VERBOSE, --verbose VERBOSE
                        Verbose Output
  --assertionid ASSERTIONID
                        AssertionID string. Defaults to a random string
  --responseid RESPONSEID
                        The Response ID. Defaults to random string
  -s SERVER, --server SERVER
                        Identifier for the federation service. Usually the
                        fqdn of the server. e.g. sts.example.com DO NOT
                        include HTTPS://
  -a ALGORITHM, --algorithm ALGORITHM
                        SAML signing algorithm to use
  -d DIGEST, --digest DIGEST
                        SAML digest algorithm to use
  -o OUTPUT, --output OUTPUT
                        Write generated token to the supplied filepath

modules:
  loaded modules

  {o365,dropbox,saml2,dump}
                        additional help

Cryptographic Material

All ADFSpoof functionality requires cryptographic material for the AD FS signing key. This can be supplied in one of two ways:

  • -b BLOB BLOB: Supply the EncryptedPFX binary blob (base64 decode what is pulled out of the configuration database) and the DKM key from Active directory. Order matters!
  • -c CERT: Provide a PKCS12-formatted file for the signing key and certificate. If it is password protected supply a password with -p. The overall file password and private key password must be the same.

Global Options

  • -s SERVER: The AD FS service identifier. Required when using any module that generates a security token. This goes into the security token to let the federated application know who generated it.
  • -o FILEPATH: Outputs the generated token to disk instead of printing it.
  • --assertionid and --responseid: If you wish to supply custom attribute values for SAML AssertionID and ResponseID. Defaults to random strings.
  • -d DIGEST: Set the MAC digest algorithm. Defaults to SHA256.
  • -a ALGORITHM: Set the signature algorithm. Defaults to RSA-SHA256.

Command Modules

ADFSpoof is built modularly with easy expansion in mind. Currently, it comes preloaded with four command modules that support different functionality.

Each module encapsulates the SAML attributes and values necessary to generate a valid security token for a specific token type or federated application. Note that for the applications specific modules, the template represents the generic installation. Customization may be required for organizations that have messed with the defaults.

o365

Generates a forged security token to access Microsoft Office 365. This is a SAML 1.1 token.

  • --upn UPN: The universal principal name of the user to generate a token for. Get this from AD.
  • --objectguid: The Object GUID of the user to generate a token for. Get this from AD. Include the curly braces.

Dropbox

Generats a forged security token to access Dropbox. This is a SAML 2.0 token.

  • --email EMAIL: The email address of the user to generate a token for.
  • --accountname ACCOUNT: The SamAccountName of the user to generate a token for.

SAML2

A command that encapsulates generating a generic SAML 2.0 security token. Use this module to generate security tokens for arbitrary federated applications that are using SAML 2.0. By reading the data returned by ADFSDump you should be able to generate a valid token for just about any federated application using this module.

  • --endpoint ENDPOINT: The recipient of the seucrity token. This should be a full URL.
  • --nameidformat URN: The value for the 'Format' attribute of the NameIdentifier tag. This should be a URN.
  • --nameid NAMEID: The NameIdentifier attribute value.
  • --rpidentifier IDENTIFIER: The Identifier of the relying party that is receiving the token.
  • --assertions ASSERTIONS: The assertions that the relying party is expecting. Use the claim rules output by ADFSDump to ascertain this. Should be a single-line (do not include newlines) XML string.
  • --config FILEPATH: A filepath to a JSON file containing the above arguments. Optional - use this if you don't want to supply everything over the command line.

Dump

Helper command that will take the supplied EncryptedPFX blob and DKM key from -b, decrypt the blob, and output the PFX file to disk. Use this to save the PFX for later.

--path PATH: The filepath to save the generated PFX.

Examples

Decrypt the EncryptedPFX and write to disk

python ADFSpoof.py -b EncryptedPfx.bin DKMkey.bin dump

Generate a security token for Office365

python ADFSpoof.py -b EncryptedPfx.bin DkmKey.bin -s sts.doughcorp.com o365 --upn [email protected] --objectguid {1C1D4BA4-B513-XXX-XXX-3308B907D759}

Generate a SAML 2.0 token for some app

python ADFSpoof.py -b EncryptedPfx.bin DkmKey.bin -s sts.doughcorp.com saml2 --endpoint https://my.app.com/access/saml --nameidformat urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress --nameid [email protected] --rpidentifier myapp --assertions <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"><AttributeValue>[email protected]</AttributeValue></Attribute>

Reading Issuance Authorization Rules

More coming soon! As a tl;dr for SAML 2.0 each issuance rule (with the exception of the nameid rule) is going to be translated into a SAML assertion. SAML assertions are tags. The Attribute tag must have an attribute called "Name" that value of which is the claim type. The claim value goes inside the tags.

There is a little more nuance which I hope to discuss in a wiki page soon, but that is the basic idea. Relying Parties may have "StrongAuth" rules and MFA requirements, but usually we don't care about those.

adfspoof's People

Contributors

dmb2168 avatar szymex73 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adfspoof's Issues

O365 Template

Is this still valid? Got everything done, except having issue with the O365 template/output. If this is still valid, I'll put the head down and "keep trying".

Awesome work--great research and more people need to talk about ADFS, SAML 2.0, misplaced trust, etc..

Keep getting a:
AADSTS90013 error

Screen Shot 2021-03-12 at 2 26 28 PM

Note: I dumped the ADFS properly (thanks). Decoded where i needed to, converted to Hex where needed. ADFSpoof with o365 gives me a great output.

It's just using Burp now with the provided output of ADFSpoof which is causing the issue.

Calculated MAC did not match anticipated MAC

Hello,
Thanks for this interesting job! I was not there during the presentation and this may explain my question ;-)

With ADFSDump, I extracted the Encrypted Signing Key (Encrypted_pfx) from the database in this format: AAAAAQAAAAA....
And the DKM Private Key in this format 9F-D2-85-5F-D6-EF-D9-15-22-21-EC-5E-45-9E-5C-DF-25-BB-0B-B4-....

I understand that i need to convert both in bin format. The first one from base 64. But I dont kwow for the second one (The DKM Key)...?

I think this is my problem because when i tried to lauch python3 ADFSpoof.py -b pfx.bin key.txt dump i encounter the Calculated MAC did not match anticipated MAC error.

I will really appreciate your help.

Rémi

Impossible to make it work

Look like the use of an unstable and unmaintain fork of cryptography shows its limit.
It's impossible to build the fork with OpenSSL3.0 which is now the default version installed.
It's a pity

AADSTS50107: The requested federation realm object <URL> does not exist

Running ADFSpoof generates the token as expected but when replacing the 'wresult' parameter in an authentication flow (through burp) I keep getting the "AADSTS50107: The requested federation realm object does not exist" error.

The generated token look nearly identical to the one that is created by ADFS - I saw another issue that stated that now you have to go through the entire login process as the login.srf request should contain all the headers to the server as opposed to just sending a request with the token (like on the video from RT19) so I wonder if anything else was change that causes the error I am experiencing?

Informative:

  • key is converted to binary format
  • signing token is decoded with base64 and saved to a file (it looks like the expected binary format as well)

Version should be 1 .

When running python ADFSpoof.py -b Token_sign_blob.bin DKMkey.bin dump
I am getting "Version should be 1" message and script dies.
I modified EncryptedPfx.py to output what the actual version is. The version is: "538976257"
Probably the problem lies in the way I saved EncryptedPfx and DKMkey from ADFSDump
What I did:

  1. EncryptedPfx
    a) I took everything between: [-] Encrypted Token Signing Key Begin and [-] Encrypted Token Signing Key End, which looks like this:
    AAAAAQAAAAAEEGXuqoRBIwFInUU[....]q6YTotIB2BA8v+zfmKuMDPw==
    b) I based64 decoded and saved the output to Token_sign_blob.bin

  2. DKM key
    a) I took Private Key: B7-12-96-C1-50-89-CA-54-B7-D2-ED-E5-F0-8E-24-AA-4F-27-2F-1B-2C-9E-2E-8A-43-47-42-FD-55-B0-72-CB
    b) I removed dashes.
    c) I base64 decoded it and saved the output to DKMkey.bin

Is there any other type of conversation that needs to be done?

Getting error while installing "pip install -r requirements.txt"

Running setup.py install for restructuredtext-lint ... done
Running setup.py develop for cryptography
ERROR: Command errored out with exit status 1:
command: 'c:\users\hemant\appdata\local\programs\python\python39\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\Hemant\Downloads\cryptography-master\cryptography-master\setup.py'"'"'; file='"'"'C:\Users\Hemant\Downloads\cryptography-master\cryptography-master\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' develop --no-deps
cwd: C:\Users\Hemant\Downloads\cryptography-master\cryptography-master
Complete output (20 lines):
running develop
running egg_info
writing src\cryptography.egg-info\PKG-INFO
writing dependency_links to src\cryptography.egg-info\dependency_links.txt
writing requirements to src\cryptography.egg-info\requires.txt
writing top-level names to src\cryptography.egg-info\top_level.txt
reading manifest file 'src\cryptography.egg-info\SOURCES.txt'
reading manifest template 'MANIFEST.in'
no previously-included directories found matching 'docs_build'
warning: no previously-included files matching '*' found under directory 'vectors'
writing manifest file 'src\cryptography.egg-info\SOURCES.txt'
running build_ext
generating cffi module 'build\temp.win-amd64-3.9\Release\_padding.c'
creating build
creating build\temp.win-amd64-3.9
creating build\temp.win-amd64-3.9\Release
generating cffi module 'build\temp.win-amd64-3.9\Release\_constant_time.c'
generating cffi module 'build\temp.win-amd64-3.9\Release\_openssl.c'
building '_openssl' extension
error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
----------------------------------------
ERROR: Command errored out with exit status 1: 'c:\users\hemant\appdata\local\programs\python\python39\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\Hemant\Downloads\cryptography-master\cryptography-master\setup.py'"'"'; file='"'"'C:\Users\Hemant\Downloads\cryptography-master\cryptography-master\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' develop --no-deps Check the logs for full command output.

Two private key outputted

Hi, It's a nice work.
When i ran it on adfs server it outputted two private key like this:

[-] Private Key: F1-5A-5F-C0-26-29-80-07-E1-FC-C4-70-2C-12-BB-C5-28-04-42-A4-35-62-90-07-B1-D0-CA-7D-26-ED-F6-95

[-] Private Key: DD-AD-55-55-B6-50-21-BA-7E-B2-97-33-B5-42-58-4C-D3-3D-A6-AD-AC-30-0C-30-CD-83-5D-0E-62-BC-CC-ED

Why did this happen? Witch key is correct?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.