Cibles uniquement OS Linux
Challenge:
gcc -o chall1 challenge_leak.c -lbluetooth
sudo ./chall1 [Addr_BT_Target] [Leak_Offset]
Correction:
gcc -o leak answers_leak.c -lbluetooth
sudo ./leak [Addr_BT_Target] [Leak_Offset]
Lien vers le papier de recherche expliquant la vulnérabilité du code SDP: Armis BlueBorne Technical Paper
Lien vers le code Bluez avec la fonction SDP vulnérable service_search_attr_req
Copie du code Bluez avec la partie vulnérable en surlignée:
Quelques informations sur les fonctions utilisées dans le code C:
Le Session Description Protocol (SDP) est un protocole de communication de description de paramètres d'initialisation d'une session de diffusion en flux (streaming).
Pour découvrir des services, un client SDP envoie une SDP request
et attends le retour d'une réponse appropriée du serveur SDP. Le protocol SDP dispose d'un méchanisme de fragmentation pour les SDP responses
retournées par un serveur SDP. Ce méchanisme de fragmentation appelé SDP Continuation
fonctionne de manière un peu différente d'un méchanisme de fragmentation "normal":
- Le client envoie une
SDP request
- Si la réponse dépasse la
MTU
définie lors de la connections L2CAP (672 par défault), un premier fragment de la réponse est retourné dans lequel est ajouté la structurecontinuation state
. - Pour recevoir les fragments restatns, le client SDP doit re-envoyer la même
SDP request
en y ajoutant cette fois lecontinuation state
qu'il a reçu lors de la précedente réponse. Ce type de requête est appelécontinuation request
. - Le serveur SDP envoie alors le fragment de réponse suivant.
Il est possible d'abuser de ce méchanisme de continuation state
du fait que le client est libre de modifier ses valeurs à chaque continuation request
.
“The format of the continuation information is not standardized among SDP servers. Each continuation state parameter is meaningful only to the SDP server that generated it.” Bluetooth Specification v5.0, Vol 3, Part B, page 1926
SDP Continuation Struct, as defined in BlueZ (src/sdpd-request.c):
typedef struct {
uint32_t timestamp;
union {
uint16_t maxBytesSent;
uint16_t lastIndexSent;
} cStateValue;
} sdp_cont_state_t;
Cette structure permet aisément de récuper le timestamp
de la machine cible, permettant au serveur SDP d'entrer dans certaines partie de code (il va utiliser des données mis en cache lorsqu'il voit un paquet SDP avec le même timestamp
).
Et comme un attaquant peut contrôler facilement la structure du continuation state
envoyé à chaque requêtes, il peut modifier ses valeurs, notamment l'index maxBytesSent
que l'on va utiliser comme un pointeur d'adresse pour fuire des données.
Excerpt from SDP Search Attribute Request handler - service_search_attr_req (src/sdpd-request.c):
...
} else {
/* continuation State exists -> get from cache */
sdp_buf_t *pCache = sdp_get_cached_rsp(cstate);
if (pCache) {
uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent);
pResponse = pCache->data;
memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent);
buf->data_size += sent;
cstate->cStateValue.maxBytesSent += sent;
if (cstate->cStateValue.maxBytesSent == pCache->data_size)
cstate_size = sdp_set_cstate_pdu(buf, NULL);
else
cstate_size = sdp_set_cstate_pdu(buf, cstate);
} ...
Ci-dessus, la partie du code vulnérable dans Bluez SDP Server. On remarque que ce code situé dans la fonction service_search_attr_req
de sdpd-request.c.
ne valide pas correctement le maxByteSent
provenant du cstate
et permet alors d'utiliser le memcpy
pour copier des données au-delà de la taille allouée par pResponse
en utlisant cette valeur de maxByteSent
comme pointeur des données à faire fuire.
La seule chose qu'un attaquant doit réaliser pour réussir ce leak
est d'empêcher la validation des données à envoyer (maxByteSent == data_size
), ce qu'il peut faire facilement car il contrôle la valeur de maxByteSent.
La valeur de pResponse
étant stoquée sur la Heap
, cette fuite d'information peut permettre à l'attaquant d'y trouver d'autres données sensibles comme des clés de chiffrement utilisées dans les protocoles de communication, etc...
Ce challenge consiste uniquement en la modification de 4 lignes de code du script challenge_leak.c
. Il repose surtout sur la compréhension du méchanisme de fragmentation, en l'observation du paquets SDP avec une capture Wireshark et en la compréhension de la vulnérabilité de sdp-request.c
et de son exploitation.
Ce challenge tuto est donc purement éducatif, il n'y aura donc pas de flag
à trouver.
Nous n'allons pas nous interresser à la Part1
du main
(ni tout ce qui le précède) qui consiste à créer la socket de communication Bluetooth, y associer les différentes addresses MAC Bluetooth et innitier la connection.
La Part2
consiste à l'envoie d'un paquet SDP auquel on y ajoute manullement certaines données.
char sdp_1_data[] = "\x35\x03\x19\x01\x00" // L2CAP PATTERN
"\x00\x10" // max attribute byte count
"\x35\x05\x0a\x00\x00\xff\xff" //attribute id list
"\x00"; //continuation state
Le but de l'envoie de l'envoie de ce paquet et de forcer le retour d'une réponse fragmentée dans laquelle nous allons pouvoir récupérer le timestamp
situé dans le continuation state
.
Question 1
Pour celà, il va falloir que vous récupéreriez cette valeur de timestamp
dans la réponse reçu recv_sdp_2
en Part3
.
Pour comprendre le code plus facilement, je l'ai instrumenté de façon à afficher les paquets SDP envoyés et reçus. Ainsi il est assez simple de retrouver ces paquets dans la capture Wireshark sur l'interface de Bluetooth utilisée.
Rappel:
typedef struct {
uint32_t timestamp;
union {
uint16_t maxBytesSent;
uint16_t lastIndexSent;
} cStateValue;
} sdp_cont_state_t;
Question 2
Dans la Part4
, vous devez retrouver comment acceder à la partie du code vulnérable (expliquée ci-dessus) continuation State exists -> get from cache
grâce à la question précédente.
Question 3
Toujours grâce aux explications précédentes de la vulnérabilité, vous devez trouver comment pointer les données à fuire grâce à la structure continuation state
.
Ces données seront ensuite ajoutées au paquet sdp_3
que l'on envoie à la machine victime pour provoquer la fuite de données.
Question 4
Enfin, en Part5
vous devez retrouver l'information que vous aurez réussi à faire fuire dans la seconde réponse SDP recv_sdp_4
.