Au cours de ma veille quotidienne, je suis tombé sur cet article de Gunter Ollmann qui fait un retour sur les dangers des injections SQL appliquées au monde physique. L’illustration humoristique suivante, qui commence à dater, décrit une des applications possibles des SQLi physiques (bien que ce soit très probablement non fonctionnel) :
Ce constat m’a rappelé de vieux souvenirs quant à l’exploitation de vecteurs d’attaques de type XSS/SQLi au travers de représentation non-textuelle. Je me suis donc replongé dans mes archives pour retrouver ces sources documentaires.
Cibles potentielles d’attaques sur codes-barres et QRcode
Les vecteurs d’attaques non-textuels auxquels je fait référence concernent l’exploitation des codes barres en général et plus particulièrement des récents QRcode. L’idée est de générer des codes barres sous une forme valide en vue d’injecter des données arbitraires dans un système. Parmi les systèmes vulnérables à de potentielles attaques sur codes barres on peut citer :
- Les lecteurs manuels de code barre, généralement utilisé en caisse dans les supermarchés pour enregistrer les produits achetés :
- Les caisses de supermarchés en libre service, très à la mode depuis quelques années et qui assurent un gain de temps en caisse. Beaucoup de supermarchés les ont déployé. A noter que celles-ci embarquent souvent un Windows :
- Les bornes informatives des prix, qui commencent à dater. Ces bornes sont souvent présentes dans les grands supermarchés au milieu des rayons. Elles permettent de scanner un code barre afin d’afficher le prix du produit. On peut aisément traduire ce fonctionnement par une simple requête SQL SELECT dans la base des produits du magasin.
- Bien évidemment, les caisses de paiement en elles-mêmes disposent d’un lecteur de code barre fixe (pour les codes-barres des produits mais aussi des cartes fidélité) ; ainsi que les systèmes portatif de self-scan que les clients utilisent avec eux dans les magasins :
- Finalement, je citerai les lecteurs de code-barre et QRcode très présents sur les téléphones portables. Ces lecteurs qui exploitent les caméras des téléphones sont voués à remplacer progressivement tous instruments dédiés dans les grandes surfaces. Ces lecteurs permettent de scanner tous QRcode que l’on peut croiser en abondance dans les nouvelles campagnes publicitaires. Autant dire que ces applications sont elles aussi vulnérables à de potentielles injections.
Exploitation des codes-barres
Plus récemment, et suite au succès des QRcode, de nombreuses applications, API et systèmes logiciels sont apparus pour exploiter ces codes-barres. Comme énoncé précédemment les smartphones en sont quasi-tous équipés ; mais des solutions existent aussi sur PC fixe en exploitant la webcam des ordinateurs.
Parmi ces solutions de reconnaissance de QRcode/codes-barres sur PC on peut citer (par Webcam ou via upload d’image) :
- Flash Webcam QRcode Reader online
- Web QRcode scanner
- De nombreux plugins JQuery comme ScriptCam
- Etc.
Et bien évidemment, en plus de solution de reconnaissance, il y a celles de génération de code barre dans de nombreux langages :
Type de codes-barres, représentation et caractéristiques
Il existe une multitude de codes-barres. Chacun d’eux à ses spécificités (lecture linéaire en 1 dimension, 2 dimensions…) et prend en compte plus ou moins de caractères.
C’est sur ce dernier point qui concerne le charset exploitable par les codes barres que le type d’injection et sa faisabilité vont se jouer. De plus, la cible envisagée dépend bien évidemment des types de codes-barres supportés.
Il parait logique qu’une injection sera plus complexe voir inefficace si un code-barres n’accepte que des caractères numériques par exemple.
Avant de présenter des vecteurs fonctionnels et de présenter un PoC, voici un état de l’art des types de codes-barres les plus courants et leurs spécifications (source makebarcode.com) :
Barcode | Type | Character Set | Length | Checksum | Applications |
Australia Postal Code | 2D | Numbers Only | 4 | Required | Includes error correction |
Aztec Code | 2D | Full ASCII; FNC1 and ESI control codes | Variable Min 12 Max 3832 |
Required | Includes error correction; minimum is 15×15 square, largest is 151×151 |
Codabar | 1D | Numbers: 0-9; Symbols: – : . $ / + Start/Stop Characters: A, B, C, D, E, *, N, or T |
Variable | None | Older code; often used in libraries and blood banks. See also USD-4, NW-7, 2of7 |
Code 11 | 1D | Numbers Only | Variable | Required | Recommend 2nd check digit |
Code 128 | 1D | All ASCII characters and control codes |
Variable | Required | Widely used; excellent for many applications |
Code 39 | 1D | Uppercase letters A-Z; Numbers 0-9; Space – . $ / + % |
Variable | Optional | In very wide use for many types of applications |
Extended Code 39 | 1D | All ASCII characters and control codes |
Variable | Optional | Uses pairs of characters to encode non-standard symbols; wasteful of space |
Code 93 | 1D | Uppercase letters A-Z; Numbers 0-9; Space – . $ / + % |
Variable | Optional | A more compact cousin of Code 39, not as widely in use |
Composite Code | 2D | All ASCII characters | Variable | Required | Code comprised of a PDF417 code stacked on top of a Code128; used in UCC/EAN standards |
DataMatrix | 2D | All ASCII characters | Variable | Required | Includes error correction, up to 2335 ASCII characters |
EAN-13 | 1D | Numbers Only | 13 + check digit +2 optional +5 optional |
Required | Retail product marking world-wide |
EAN-8 | 1D | Numbers Only | 7 + check digit | Required | Retail product marking world-wide; compressed code for products with limited label space |
EAN Bookland | 1D | Numbers Only | 13 + check digit +2 optional +5 optional |
Required | Special use of the EAN-13 symbol to encode ISBN number on books |
Industrial 2 of 5 | 1D | Numbers Only | Variable | None | Older type of code |
Interleaved 2 of 5 | 1D | Numbers Only | Variable | Optional | Very compact encodes digits in pairs so total length must be even number of digits |
ITF-14
(UPC Ship Container Code) |
1D | Numbers Only | 13 + check digit | Required | Special use of the Interleaved 2 of 5 code to mark shipping cartons containing UPC encoded products (see also SCC-14) |
LOGMARS | 1D | Uppercase letters A-Z; Numbers 0-9; Space – . $ / + % |
Variable | Optional | Same as Code 39; this is the US government specification |
Maxicode | 2D | All ASCII characters | 93 | Required | Includes error correction, developed by the United Parcel Service for encoding destination information |
MSIMSI Plessey | 1D | Numbers Only | Variable | Required | Grocery store shelf tags |
OPC Optical Industry Assoc. | 1D | Numbers Only | 9 + check digit | Required | Special use of Interleaved 2 of 5 for marking retail optical products |
PDF-417 | 2D | All ASCII characters | Variable | Required | Includes error correction, up to about 1850 ASCII or 2725 numeric characters |
Plessey | 1D | Numbers Only | Variable | Required | Grocery store shelf tags |
Postnet | 2D* | Numbers Only | 5 + check digit +4 optional +6 optional |
Required | USA postal code (ZIP code) |
QR Code | 2D | All ASCII Characters | Variable | Required | Includes error correction, up to about 1520 ASCII or 2509 numeric charcters |
SCC-14
(UCC/EAN Ship Cont. Code) |
1D | Numbers Only | 13 + checksum | Required | Special use of Code 128 to mark shipping cartons containing UPC encoded products (see also ITF-14) |
Standard 2 of 5 | 1D | Numbers Only | Variable | None | Also called Industrial 2 of 5. |
UCC/EAN-128 | 1D | All ASCII characters and control codes |
Variable | Required | Special ise of Code 128 which defines data formats for commerce |
UCC/EAN Shipping Container Code (SCC-14) |
1D | Numbers Only | 13 +check digit | Required | Special use of Code 128 to mark shipping cartons containing UPC encoded products (see also ITF-14) |
UPC Shipping Container Code (ITF-14) |
1D | Numbers Only | 13 + check digit | Required | Special use of the Interleaved 2 of 5 code to mark shipping cartons containing UPC encoded products (see also SCC-14) |
UPC-A | 1D | Numbers Only | 11 + check digit +2 optional +5 optional |
Required | Retail product marking in USA and Canada |
UPC-E | 1D | Numbers Only | 7 + check digit | Required | Retail product in USA and Canada; compressed code for products with limited label space |
Vecteurs d’attaques de codes-barres
Parmi les codes-barres les plus répandus, les plus utilisés et les plus vulnérables, on dénote le code 93, le code 39 et 39 étendu, le code 128 A, B et C, et bien évidemment les QRcode. Ces codes disposent tous de charsets exploitables relativement complets (avec gestion de symboles) et peuvent représenter des chaînes de caractères assez importantes. Il suffit d’encoder un vecteur usuel d’attaque (XSS, SQLi…) sous sa forme de codes-barres pour évaluer la résistance d’un lecteur quelconque.
Code 93
- XSS standard alert()
- SQLi standard bypass authentification
Code 39
Version simple avec URLencode
- XSS standard alert()
- SQLi standard bypass authentification
Remarques :
- Le code 39 non-étendu ne permet pas l’utilisation d’un charset de symboles complet. C’est pourquoi les injections au travers de celui-ci peuvent se faire avec un encodage URLencode pour tous les caractères non pris en comptes.
Version étendue
- XSS standard alert()
- SQLi standard bypass authentification
Code 128 version A, B ou C
- XSS standard alert()
- SQLi standard bypass authentification
QRcode
- XSS standard alert()
- SQLi standard bypass authentification
Génération de vecteurs personnalisés
L’ensemble des codes-barres précédents ont été réalisés à l’aide de l’outil en ligne d’irongeek. Il est possible d’y générer des codes-barres personnalisés, embarquant des vecteurs d’attaques destinés à des audits/pentest de votre choix.
Démonstration et PoC
Il ne m’est pas possible de faire une démonstration d’un de ces vecteurs d’attaques via les équipements de lecture de codes-barres présentés plus haut. Toutefois, pour illustrer le contenu de cet article dans un PoC fonctionnel, nous allons nous intéresser à la solution ScriptCam. Cette solution, sous forme d’un plugin JavaScript JQuery permet d’utiliser la webcam des ordinateurs communs à des fins de lecteur de codes-barres et en particulier de QRcode.
Le fonctionnement de ce plugin JQuery est de charger un module Flash qui peut interagir avec la webcam de l’utilisateur, afin de récupérer des images et d’en extraire des informations par la suite.
ScriptCam permet diverses manipulations de webcams, et l’analyse de codes-barres/QRcode n’est qu’une de ses fonctionnalités. Une page de démonstration de cette analyse est disponible sur le site officiel. Il suffit d’autoriser l’application flash à utiliser la webcam, présenter un QRcode à la caméra puis de cliquer sur « Decode image » pour visualiser le texte du QRcode juste à côté (sur l’exemple suivant, c’est l’url du site dans le QRcode) :
Imprimons et testons avec un QRcode exploitant un code JavaScript XSS (celui présenté un peu plus haut) :
Le vecteur d’attaque XSS renfermé dans le QRcode s’injecte bien dans l’application et est interprété comme tel. Il est alors possible d’imaginer toutes sortes de scénarios d’attaques pour tout équipement qui peut lire des codes barres. Dans l’exemple, seule une alertbox est générée. Mais il aurait été possible de concevoir une injection Javascript qui automatiserait toutes les N secondes la prise d’une photo de la webcam, et de l’envoie de celle-ci sur un serveur annexe par exemple ; ou tout simplement la prise de contrôle du navigateur victime par le framework BeEF.
Conclusion et perspectives
Injection SQL, XSS, corruption de données, plantage de système… Les codes barres ont été sous-estimés comme vecteur d’injection, et le nettoyage (sanitization) des données extraites de ces codes bien trop souvent oublié.
Avec l’avènement du QRcode et son utilisation de plus en plus courante au travers des smartphones, les injections et attaques avec ces mécanismes se répandent de plus en plus. Il est nécessaire de prendre en compte ces considérations.
Les codes-barres et QRcode ne sont qu’un moyen d’appliquer des attaques informatiques sur des équipements physiques. Comme énoncé en introduction, d’autres équipements comme les caméras d’autoroute sont susceptibles d’être corrompues par des vecteurs d’attaques similaires. Bien d’autres applications au monde réel peuvent être exploitées ; à vous de les imaginer !
Edits
J’ai contacté le support de ScriptCam le 3 avril 2013 au matin pour les prévenir de cette petite injection XSS dans leur page de démonstration, bien qu’elle n’engendre pas un réel danger. En l’espace de 15 minutes ils ont corrigé la vulnérabilité et m’ont fait un feedback de remerciement. Je retire mon chapeau quant à leur réactivité ! Le PoC précédent n’est donc plus exploitable à titre de démonstration sur ScriptCam.
Pour information, la correction portait sur la réinjection dans la page du contenu décodé du QRcode. Ils utilisaient la méthode html() de JQuery, qui interprète le contenu, plutôt que la méthode text().
Avant correction :
<button class='btn btn-small' id='btn1' onclick="$('#decoded').html($.scriptcam.getBarCode());">Decode image</button>
Après correction :
<button class='btn btn-small' id='btn1' onclick="$('#decoded').text($.scriptcam.getBarCode());">Decode image</button>