Étape 7: Quels messages à envoyer ?
ctrl_transfer (bmRequestType, bmRequest, wValue, wIndex, nBytes)
Cette commande peut faire origine et d’accueil en fonction de ce que bmRequestType dit (entrée ou sortie). Pourtant, il y a beaucoup d’options ici. Pour envoyer la commande de droite, vous avez besoin de savoir le RequestType et la droite demande et ther droit valeur ainsi que l’Index et le nombre d’octets à lire ou à écrire.
Si nous étions totalement nous-mêmes, nous commencerions en essayant de lire les données de l’appareil. Cela signifie que nous devons d’abord définir le RequestType
Direction Type destinataire
D7 D6 D5 D4 D3 D2 D1 D0
Pour bmRequestType la valeur passée est très structurée, donc ce n’est pas aussi difficile à deviner. (Voir lvr.com pour plus d’informations)
Bits 2, 3 et 4 sont réserves donc définir sur 0.
La direction passe par bit #7, 0 est un « Ecrire » sorti de l’appareil, 1 est une « lecture » de l’appareil
Le type de message est deux bits, 0 = normal, 1 = classe, 2 = Vendor, 3 = réservé. Pour de nombreux périphériques qui sont non standards, vous voudrez probablement 2 pour le type de fournisseur. Si c’est un type de dispositif, comme une caméra ou un micro, plus standard, essayez 0 ou 1. 3 n’est pas utilisée
Les deux derniers bits sont usd pour déterminer le destinataire du message 0 = périphérique, 1 = Interface, 2 = point de terminaison, 3 = autre. Aller avec 0 pour commencer, vous pouvez essayer 2 s’il existe des autres points de terminaison
La chose la plus sûre à faire est lire les données (pas moyen de remplacer quoi que ce soit ou de configurer) vous pouvez le faire en envoyant des paquets avec 0b11000000 (données de fournisseur de lecture du périphérique) = 0xC0.
Si je devais écrire un fuzzer, je commencerais par la définition d’Index 0 et itération sur toutes les valeurs d’octets (255 valeurs différentes) de bmRequest et les premières centaines wValues peu. Son joli coffre juste lire des données aléatoires à un périphérique USB. Commencez par lire un octet pour voir si quelque chose se présente, puis augmentez la valeur
importation usb.core
importation usb.util
import sys
# trouver notre dispositif
dev = usb.core.find (idVendor = 0x045e, idProduct = 0x02B0)
# a été trouvé ?
Si aucune n’est dev :
générer ValueError ("périphérique non trouvé")
# définir la configuration active. Sans argument, la première
# configuration sera celle active
dev.set_configuration()
# Let's fuzz autour !
# Permet de démarrer en lisant 1 octet de l’appareil à l’aide de requêtes différentes
# bRequest est un octet, donc il y a 255 valeurs différentes
pour bRequest dans range(255) :
Essayez :
RET = dev.ctrl_transfer (0xC0, bRequest, 0, 0, 1)
Print « bRequest », bRequest
imprimer le ret
sauf :
# Impossible d’obtenir des données pour cette demande
Pass
Ressemble à la demande de valeurs 0, 5, 16, 50, 54, 64, 80 et 112 que retournent toutes une sorte de données. Le reste n’a rien à lire
Ensuite, nous allons essayer de lire plus de données en changeant le dernier argument à 100 octets
OK beaucoup de données, mais ce que cela signifie ? C’est où quelques devinettes basées sur l’appareil lui-même me serait utile. Je suis paresseux terriblement bien et si une option pour éviter beaucoup de conjectures, je vais le prendre !