Entidade externa
Uma entidade SYSTEM manda o parser buscar um arquivo ou URL e colar o conteúdo no documento.
Uma entidade comum guarda um texto fixo. Uma entidade externa guarda um endereço, com a palavra SYSTEM:
<!DOCTYPE invoice [
<!ENTITY x SYSTEM "notes.txt">
]>
<invoice><customer>&x;</customer></invoice>
Agora &x; não vale um texto que você escreveu: vale o conteúdo do arquivo notes.txt. Quando o parser resolve &x;, ele abre o arquivo e cola o que estiver lá dentro de <customer>. O identificador pode ser um caminho (secrets/app.conf), um file://... ou até uma URL http://....
É aí que o XXE vira leitura de arquivos: você declara uma entidade apontando para um arquivo que interessa, referencia ela num campo que volta na resposta, e o conteúdo do arquivo aparece ali. O servidor nem percebe, porque para ele o valor do campo é só o valor de uma entidade.
A correção é não deixar o parser resolver entidades externas (e, de preferência, recusar o DTD por inteiro).