Skip to content
Snippets Groups Projects
Commit 79b3ab6e authored by Pavel Břoušek's avatar Pavel Břoušek
Browse files

Merge branch 'workflow' into 'main'

workflow, SP-initiated login via Request Initiation Protocol

See merge request !3
parents f4a04625 af8aae4b
Branches
No related tags found
1 merge request!3workflow, SP-initiated login via Request Initiation Protocol
......@@ -85,11 +85,27 @@ where
* `ENTITY_ID_HERE` is the entity ID of the SP
* `BEARER_TOKEN_HERE` is your authorization token for the conformance IdP
### SP-initiated (workflow)
Peforming SP-initiated login is more difficult than the IdP-initiated login used in previous templates.
You can use the included [nuclei workflow](https://docs.projectdiscovery.io/templates/workflows/overview)
to scan a server for available endpoints and perform SP-initiated login if possible:
```sh
nuclei -w workflow/saml-sp-workflow.yaml -u https://sp.example.com/ -code -sf secret-file.yaml
```
where
* `https://sp.example.com/` is the address of a (potential) SP server (only the domain is relevant)
## Current limitations
* templates are only usable with the conformace IdP
* testing cannot be run in parallel for the same entity ID
* only `HTTP-POST` binding is currently supported
* nuclei has to be invoked individually for each target (for each entity ID)
* only SPs which accept unsolicited logins (IdP-initiated) can be tested
* IdP-initiated templates have to be invoked individually for each target (for each entity ID)
* only SPs which accept unsolicited logins (IdP-initiated)
or with a [Request Initiation](https://docs.oasis-open.org/security/saml/Post2.0/sstc-request-initiation.html) endpoint can be tested
* headless browser test behaves differently than raw HTTP test (nuclei limitation)
......@@ -3,7 +3,7 @@ info:
name: SAML signature validation
author: T&I Incubator, GÉANT
severity: high
tags: saml,raw
tags: saml,signature,raw
variables:
CONFORMANCE_IDP_BASE_URL: https://conformance-idp.maiv1.incubator.geant.org/
CONFORMANCE_IDP_HOSTNAME: '{{replace_regex(CONFORMANCE_IDP_BASE_URL, "^https?://|/.*$", "")}}'
......
id: saml-detect-endpoints
info:
name: SAML endpoints detection
author: T&I Incubator, GÉANT
severity: info
tags: saml,detect,tech
variables:
CONFORMANCE_IDP_ENTITY_ID: "urn:x-simplesamlphp:geant:incubator:conformance-idp"
http:
- method: GET
path:
- "{{RootURL}}{{spinitendpoint}}?entityID={{url_encode(CONFORMANCE_IDP_ENTITY_ID)}}"
redirects: false
attack: batteringram
payloads:
spinitendpoint:
- ""
- "/"
- "/api/login/sso"
- "/api/saml-client/returnFromSAML"
- "/applications/secure-sp/Shibboleth.sso/Login"
- "/auth/shibboleth.sso/ds"
- "/auth/shibexternal/Shibboleth.sso/DS"
- "/auth/shibexternal/Shibboleth.sso/Login"
- "/edugainlogin/Shibboleth.sso/Login"
- "/edugain/Shibboleth.sso/Login"
- "/eduid/Shibboleth.sso/Login"
- "/federation-manager/Shibboleth.sso/Login"
- "/login/shibboleth/callback"
- "/research-and-scholarship/Shibboleth.sso/DS"
- "/research-and-scholarship/Shibboleth.sso/EDS"
- "/research-and-scholarship/Shibboleth.sso/Login"
- "/research-and-scholarship/Shibboleth.sso/Login1"
- "/research-and-scholarship/Shibboleth.sso/SeamlessAccess"
- "/research-and-scholarship/Shibboleth.sso/Wayfinder"
- "/saml/login"
- "/saml/sp"
- "/saml/start"
- "/Shibboleth.sso/discovery"
- "/Shibboleth.sso/Discovery"
- "/shibboleth.sso/DS"
- "/Shibboleth.sso/DS"
- "/Shibboleth.sso/DS/Login"
- "/Shibboleth.sso/DS/seamless-access"
- "/Shibboleth.sso/DS/thiss.io"
- "/Shibboleth.sso/DS-WayfOA"
- "/Shibboleth.sso/DS1"
- "/Shibboleth.sso/DS2"
- "/Shibboleth.sso/DS3"
- "/Shibboleth.sso/EDS"
- "/Shibboleth.sso/edugain"
- "/Shibboleth.sso/FORCE"
- "/-shibboleth.sso/Login"
- "/shibboleth.sso/Login"
- "/Shibboleth.sso/Login"
- "/Shibboleth.sso/Loginn"
- "/Shibboleth.sso/Login1"
- "/Shibboleth.sso/OpenAthens"
- "/Shibboleth.sso/SeamlessAccess"
- "/Shibboleth.sso/SeamlessLogin"
- "/Shibboleth.sso/Shibboleth.sso/Login"
- "/Shibboleth.sso/shibtest"
- "/Shibboleth.sso/UniboAuth"
- "/Shibboleth.sso/WAYF"
- "/Shibboleth.sso/WAYF/Chooser"
- "/test/edugain/Shibboleth.sso/Login"
- "/wayf/"
- "/wayfless/boa"
stop-at-first-match: true
matchers:
- type: dsl
name: hasspinitendpoint
condition: and
dsl:
- "status_code == 302 || status_code == 303 || status_code == 307"
- "contains(location, 'SAMLRequest=')"
extractors:
- type: dsl
name: spinitendpoint
dsl:
- "spinitendpoint"
code:
- engine:
- python3
- python
- py
source: |
import base64
import zlib
import os
import re
from urllib.parse import unquote
saml_request = unquote(re.sub(r'^.*SAMLRequest=(.*?)(&|$).*', r'\1', os.getenv("http_location")))
saml_request = zlib.decompress(base64.b64decode(saml_request), -zlib.MAX_WBITS).decode()
SP_ENTITY_ID = re.sub(r'^.*>(.*?)</\w+:Issuer.*$', r'\1', saml_request)
print(SP_ENTITY_ID)
extractors:
- type: dsl
name: SP_ENTITY_ID
dsl:
- response
# digest: 4a0a0047304502205ecec927cfdf45f5d2711393ed7e8321517f98a969858659a1aa75db26d0b23b022100a390a5522fef78825412f4b60c38abb0f7f41d6f5ac970b24bb5b4c0308887ad:16ea744faf4d9956cf0107f1f3cb7c4c
\ No newline at end of file
id: saml-signature-request-init-raw
info:
name: SP initiated SAML authentication endpoint check
author: T&I Incubator, GÉANT
severity: high
tags: saml,signature,raw
variables:
CONFORMANCE_IDP_BASE_URL: https://conformance-idp.maiv1.incubator.geant.org/
CONFORMANCE_IDP_HOSTNAME: '{{replace_regex(CONFORMANCE_IDP_BASE_URL, "^https?://|/.*$", "")}}'
CONFORMANCE_IDP_ENTITY_ID: "urn:x-simplesamlphp:geant:incubator:conformance-idp"
TEST_CASES:
- noSignature
- invalidSignature
flow: |
set("TEST_CASE", "standardResponse");
http();
for (let testcase of iterate(template["TEST_CASES"])) {
set("TEST_CASE", testcase);
http();
}
http:
- raw:
- |
@Host: https://{{CONFORMANCE_IDP_HOSTNAME}}
POST /module.php/conformance/test/setup?testId={{url_encode(TEST_CASE)}}&spEntityId={{url_encode(SP_ENTITY_ID)}} HTTP/1.1
Host: {{CONFORMANCE_IDP_HOSTNAME}}
- |
GET {{spinitendpoint}}?entityID={{url_encode(CONFORMANCE_IDP_ENTITY_ID)}} HTTP/1.1
Host: {{Hostname}}
# HTTP-POST binding
- |
@Host: {{replace_regex(trim(acs,"[]"), "^https?://|/.*$", "")}}
POST {{trim(acs,"[]")}} HTTP/1.1
Host: {{replace_regex(trim(acs,"[]"), "^https?://|/.*$", "")}}
Content-Type: application/x-www-form-urlencoded
SAMLResponse={{url_encode(trim(samlresponse,"[]"))}}
disable-path-automerge: true
redirects: true
extractors:
- type: xpath
name: acs
internal: true
attribute: action
xpath:
- '/html/body/form'
- type: xpath
name: samlresponse
internal: true
attribute: value
xpath:
- '/html/body/form/input[2]'
# breaks the template :(
#- type: dsl
# dsl:
# - 'TEST_CASE'
matchers-condition: and
matchers:
- type: status
condition: or
status:
- 200
- 302
- 303
- type: word
words:
- Welcome
- Hello
- Logged in
condition: or
part: body
- type: dsl
dsl:
# ignore the happy case
- '!contains(TEST_CASE, "standardResponse")'
condition: and
id: saml-sp-workflow
info:
name: SAML signature checks
author: T&I Incubator
description: Scan SAML SPs for SAML signature validation problems and vulnerabilities
severity: high
workflows:
- template: workflow/saml-detect-endpoints.yaml
subtemplates:
- template: workflow/saml-signature-request-init-raw.yaml
# unfortunatelly it seems that is not possible to combine matchers and shared execution context like this:
#matchers:
#- name: hasspinitendpoint
#subtemplates:
#- template: nuclei-templates/saml-signature-request-init-raw.yaml
#subtemplates:
# - template: nuclei-templates/saml-signature-request-init-invalid-signatures.yaml
#- tags: ssl,tls,dns,tech,detect
- tags: ssl,tls,dns,tech,detect
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment