
Iniezione di template non autenticata in Atlassian Jira
4.4.x
5.x.x
6.x.x
7.0.x
7.1.x
7.2.x
7.3.x
7.4.x
7.5.x
7.6.x before 7.6.14 (the fixed version for 7.6.x)
7.7.x
7.8.x
7.9.x
7.10.x
7.11.x
7.12.x
7.13.x before 7.13.5 (the fixed version for 7.13.x)
8.0.x before 8.0.3 (the fixed version for 8.0.x)
8.1.x before 8.1.2 (the fixed version for 8.1.x)
8.2.x before 8.2.3 (the fixed version for 8.2.x)
set JVM_SUPPORT_RECOMMENDED_ARGS= nel file ./bin/setenv.bat (o analogamente nel file ./bin/setenv.sh su Linux) per poter eseguire il debug remotoset JVM_SUPPORT_RECOMMENDED_ARGS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
Remote JVM Debug con host e port localhost:5005 e Command line arguments for remote JVM-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
Eseguire il file ./bin/config.bat (o il file config.sh su Linux) e impostare "Jira home" sulla propria cartella jira home

Eseguire il file ./bin/start-jira.bat (o ./bin/start-jira.sh su Linux). Verificate che la versione di Java e le porte 8080 e 5005 siano libere, altrimenti non si avvierà!
Scegliamo la modalità private

A questo punto, ricordate di usare un indirizzo email in grado di ricevere email :)

Configurate e testate la connessione

In http://localhost:8080/secure/admin/EditApplicationProperties!default.jspa abilitiamo la funzionalità Contact Administrators Form

Ho solo annotato alcune note per la compilazione, potete consultare compilare Jira dal sorgente
Dopo aver letto Advisory sappiamo che questo bug si trova in ContactAdministrators e SendBulkMail (quest'ultimo lo salto perché richiede autenticazione). Quindi comincio a testare la funzionalità ContactAdministrators e catturo la richiesta.

Vedo che la richiesta va a /secure/ContactAdministrators.jspa, quindi guardo il file ./atlassian-jira/WEB-INF/web.xml per vedere a quale classe verrà inoltrata questa richiesta


Quindi la richiesta verrà gestita da JiraWebworkActionDispatcher, così metto un breakpoint su init e server in questa classe e avvio il debug

Così il programma si ferma nella funzione server, traccio un po' e il programma salta in ContactAdministrators.doExecute()

Poi passa a send, dove il programma elenca gli account admin attivi

Poi il programma passa alla funzione sendTo. Qui vediamo che il programma crea un MailQueueItem e lo aggiunge a mailQueue.

Il programma chiama la funzione EmailBuilder.withSubject. Qui la stringa dell'oggetto dell'email (inviata dall'attaccante) viene convertita da String a TemplateSources e assegnata al parametro subjectTemplate di EmailBuilder.

Nella funzione renderLater il programma crea un EmailRenderer e lo usa per creare un RenderingMailQueueItem

Da qui, tornando alla funzione ContactAdministrators.sendTo. Dopo aver creato un MailQueueItem, il programma aggiunge l'elemento a mailQueue e torna alla funzione doExecute per il redirect. Seguendo questo flusso di debug non possiamo saltare alla parte in cui il programma renderizza l'email, quindi non possiamo arrivare al punto in cui avviene l'iniezione del template. Cosa devo fare per poter seguire l'elaborazione dell'email???
Vedo che in EmailRenderer c'è la funzione renderNow (il programma chiama solo renderLater); suppongo che quando l'email in coda viene chiamata per essere renderizzata, segua lo stesso flusso di renderNow, quindi decido di tracciare a partire dalla funzione renderNow

Da renderNow il programma chiama EmailRenderer.render(). Metto un breakpoint qui e ripeto la richiesta per vedere se il programma arriva davvero fin qui.

Fortunatamente il programma ha seguito la direzione che avevo previsto. Successivamente il programma chiama renderEmailSubject

Poi il programma chiama DefaultVelocityTemplatingEngine.render(this.subjectTemplate)

Arriva a DefaultVelocityTemplatingEngine.applying e DefaultVelocityTemplatingEngine.asPlainText

Continuando, chiama asPlainText(Writer writer)

Arriva a toWriterImpl; poiché writer che passo è un Fragment, il programma salta al ramo else
private void toWriterImpl(Writer writer, boolean attachCartridge) throws IOException {
if (this.source instanceof File) {
File template = (File)this.source;
if (attachCartridge) {
this.context.attachEventCartridge(DefaultVelocityTemplatingEngine.this.createDefaultCartridge());
}