Recherche sur le blog

lundi 16 mars 2015

[Utilitaires] µBlock, une alternative à Adblock Plus

Il y a quelques jours, on m'a fait découvrir une extension qui tout comme Adblock Plus permet de bloquer des publicités et d'autres contenus ayant tendance pouvant rendre la navigation assez désagréable. Il s'agit de µBlock. L'extension est disponible sur les navigateurs Safari, Firefox et Google Chrome. Sa particularité est qu'elle a un très faible impact sur les ressources CPU et mémoire utilisées. Autre point important : il semblerait qu'elle bloque beaucoup plus d'éléments par rapport à Adblock Plus. Évidemment cela est sans doute partiellement lié au fait que pas mal de gros acteurs du web comme Amazon ou Google aient envoyé une certaine somme en vue de se retrouver dans la liste blanche de cette dernière (réf. Financial Times).


Le graphique ci-dessus n'est qu'un exemple parmi tant d'autres pour démontrer sa légèreté ; celui-ci provient de la page officielle de l'extension, hébergée sur GitHub. L'article suivant, "µBlock vs. ABP: efficiency compared", étudie l'impact sur la consommation des ressources et ce dans différentes situations, pour de nouveau prouver son efficacité. De mon côté, j'ai effectivement remarqué une consommation de mémoire bien inférieure lorsque j'utilise Firefox et ce avec 10 onglets.

Pourquoi ne pas la tester chez vous ?
     
(Merci à Reka pour la découverte)

[Sécurité] Un malware cryptant les fichiers de jeux

Une nouvelle variante du ransomware CryptoLocker a vu le jour et semblerait viser les joueurs. Celle-ci porte le nom de TeslaCrypt et crypte les fichiers de plus d'une vingtaine de jeux solo et multijoueur (+ DLC, mods, etc) tels que Half-Life 2, Assassin's Creed, Bioshock 2, ainsi que de nombreux titres EA Sport ou encore World of Warcraft. Même les kits de développement de Unity3D et Unreal Engine sont affectés ! Comme d'habitude le procédé est le suivant : une fenêtre s'affiche et vous demande de payer une certaine somme pour débloquer les fichiers, le tout à envoyer en Bitcoin. Le paiement est effectué depuis une page web qui se trouve dans le domaine TOR.


Le logiciel malveillant s'installe automatiquement après avoir visité une page web piégée, qui redirige l'utilisateur vers un outil chargé d'installer les fichiers par l'intermédiaire d'un clip Flash bien planqué. Il se peut donc que l'antivirus ne le détecte pas. Le site Bromium Labs explique en détail comment cela fonctionne et donne davantage de détails quant à la technique utilisée dans ce cas...

Sources

Guru3D

lundi 9 mars 2015

[WD19] Safescan TA-855 et les événements

Nous avons vu il y a quelques jours comment accéder aux données stockées sur une pointeuse Safescan TA-855 (modèle avec écran noir et blanc, lecteur d'empreinte digitale, identification par badge RF, etc). Si vous ne l'avez pas encore fait n'hésitez pas à lire la première partie qui explique comment se connecter à l'appareil et lire le journal des événements global. Nous allons aujourd'hui voir comment programmer simplement la gestion des événements, lors de la connexion par exemple.

Événement lors de la connexion

Lorsqu'on se connecte à la pointeuse, l'événement OnConnected est toujours émis. Il est donc possible d'intercepter celui-ci de manière automatique dans Windev. Mais comment doit-on faire cela ? C'est plutôt simple : on utilise la fonction AutomationEvénement() pour brancher une procédure du code sur un événement de notre objet automation précédemment créé (voir l'article précédent). On peut l'appeler lors du chargement du projet ou même de notre fenêtre principale. 


Les paramètres à indiquer dans l'ordre sont : la procédure qui devra être exécuter lors de la réception de l'événement, l'objet automation en question, et le nom exact de l'événement (attention car la casse est importante). Dans l'exemple ci-dessus, on a demandé à ce que la procédure "lproc_onConnected()" nous signale lorsque le PC est bien connecté à la pointeuse - OnConnected. Dans cette fameuse procédure on affiche simplement un message sous forme de "Toast" grâce à ToastAffiche().

Evénement lors de la déconnexion

Il existe également l'événement OnDisConnected d'après la documentation. Cependant, même lorsqu'on branche la procédure à celui-ci, et qu'on se déconnecte de la machine, l'événement ne semble pas être intercepté. Pourtant il est indiqué que celui-ci est émis lorsque le PC est correctement déconnecté de l'appareil.

Événement lors du pointage

Nous avons également souhaité récupérer les données de la pointeuse de manière automatique lorsqu'un utilisateur pointe (que ce soit avec le lecteur d'empreintes ou bien avec sa carte RF). Ces événements sont ajoutés dans un tableau d'une fenêtre fille MDI. Ils sont temporaires : pour savoir comment les récupérer dans la mémoire de la pointeuse, n'hésitez pas à regarder l'article précédent.

Les événements comme OnAttTransaction doivent être "enregistrés" pour être interceptés, d'après la documentation. On utilise toujours AutomationEvénement() pour brancher des procédures à ces derniers. Voici les étapes à réaliser :
  • Appel de la fonction WLangage AutomationEvénement().
  • Lors de la connexion on va enregistrer les événements avec la fonction RegEvent() de notre objet automation. En paramètre il faut indiquer le n° de la machine mais également le ou les événement(s) que l'on souhaite traiter (EventMask). La documentation donne tous les codes des événements que l'on peut utiliser. Pour en traiter plusieurs, il faut les combiner en effectuant une opération XOR. Si on souhaite tous les utiliser on peut indiquer la valeur 65535.
  • La procédure qui va traiter cet événement reçoit 10 paramètres. En les typant en entier, vous obtiendrez une exception "le type vide ne peut pas être converti en entier". C'est pourquoi nous n'avons pas indiqué de type. 
    • L'ID utilisateur qui pointe.
    • Pointage invalide (1) / valide (0).
    • Statut ; par exemple, 0 = entrée, 1 = sortie.
    • Mode de vérification (0 = password, 1 = FP, 2 = Carte) .
    • Année.
    • Mois.
    • Jour.
    • Heure.
    • Minute.
    • Seconde.
  • La procédure utilisée est locale à la fenêtre d'accueil mais nous ajoutons les données dans le champ Table d'une fenêtre MDI (possédant un alias) seulement si elle est ouverte. Pour cela les indirections sont très utiles.

Voici un exemple concret :

1) Appel de AutomationEvénement() dans le code d'initialisation de la fenêtre d'accueil par exemple. Le premier paramètre correspond au nom de la procédure à brancher, le second à notre objet automation et enfin le troisième au nom exact de l'événement tel qu'on peut le voir via OLE/COM Object Viewer. Il est important de respecter la casse.

2) Après l'appel de Connect_Net() de l'objet automation, et uniquement si la connexion a réussi, on appelle RegEvent().


3) On a branché la procédure lproc_onAttTransaction() sur l'événement correspondant. Voici le contenu de la procédure. On remarque donc bien les 10 paramètres en entrée, sans type comme c'était prévu. On remplit le champ Table en insérant chaque fois une ligne au début, puis à l'aide des indirections on remplit chacune des colonnes. 


Voici ce que cela donne comme résultat à l'exécution :


Bon développement à tous !

mardi 3 mars 2015

[WD19] Safescan TA-855, Connexion et Lecture

Safescan est une société hollandaise spécialisée dans les appareils de détection de faux billets mais également dans les pointeuses (avec ou sans lecteur d'empreinte digitale). Un logiciel sous licence est fourni avec chaque pointeuse mais ne propose pas de gérer une base de données sur un serveur en temps réel. En effet le logiciel Time Attandance génère une base de données Firebird SQL, au format fichier. Celle-ci est sauvegardée lorsqu'on ferme le programme, et n'est jamais alimenté puisqu'il n'y a pas de service qui s'en occupe. L'idée ici est donc d'aller lire directement les données sur la pointeuse, en téléchargeant le journal des événements. 

La société ne fournit aucun SDK pour effectuer cette opération, mais après de nombreuses recherches sur internet, il s'avère que la technologie utilisée est la même que celle utilisée par ZKTeco. La machine ici présente utilise par défaut le port UDP 4370 pour communiquer, et dispose d'un serveur web sur lequel on peut effectuer quelques opérations de base. Les machines fournies par ZKTeco fonctionnent de la même manière. C'est l'article sur Infobytesec - "Perverting Embedded Devices" - qui a permis de faire le lien entre les deux marques (rem : n'hésitez pas à le lire car il est plutôt intéressant).
     
Une API pour Windows

Il existe donc bien une API pour Windows qui permet d'interagir avec les appareils disposant d'un écran en noir et blanc mais également ceux équipés d'un écran TFT couleur ou d'une caméra (iFace). Les bibliothèques sont disponibles en 32 et 64 bits. Rendez-vous sur la page http://www.zkteco.co.za/downloads.html puis déroulez la section "Communication Protocol SDK". Nous avons pris la version 6.2.5.7 en 32 bits pour notre développer notre application.

Pour installer et enregistrer le SDK, décompressez l'archive puis allez dans le dossier du même nom lancez le script "Auto Install" (qui correspond bien entendu à la version de votre système d'exploitation). Il copie toutes les DLL dans le bon dossier de Windows puis les enregistre à l'aide de la commande "regsvr32".

Utilisation dans Windev

Lorsqu'on dispose de bibliothèques de ce type, elles peuvent être distribuées sous forme d'assemblage .NET, mais peuvent aussi reprendre des fonctions qui auraient été écrites en C ou C++. Dans ce cas il faut soit appeler les fonctions avec AppelDLL32, ou utiliser un objet de type Automation. La deuxième solution est celle qui fonctionne : merci à Ada Atchinard qui a posté l'info sur le forum des développeurs de PC SOFT.

Connexion via IP et affichage du n° de série

La première opération consiste à se connecter à la machine et à récupérer l'identifiant ainsi que le numéro de série. La bibliothèque "zkemkeeper.dll" permet d'utiliser un objet de type ActiveX / Automation dans Windev. L'utilitaire OLE/COM Object Viewer (disponible dans le SDK Windows) permet d'avoir l'information sur tous les paramètres passés à chaque fonction. La documentation au format PDF vous permet également d'obtenir tout ce qu'il vous faut.
  • Il faut créer un objet Automation de type "zkemkeeper.ZKEM".
  • Pour la connexion on appelle "Connect_Net()".
  • En guise de 1er paramètre, l'adresse IP (chaine).
  • Le second paramètre est le port (chaine/entier).
  • La réponse est un booléen.
  • Récupérer le n° d'appareil (propriété MachineNumber).
  • Récupérer le n° de série (fonction GetSerialNumber).
Voici un exemple de code qui permet de réaliser une connexion à la pointeuse puis de sauvegarder dans des variables locales le n° d'appareil ainsi que le S/N. Attention, la connexion peut prendre un certain temps.


Si la connexion aboutit, le booléen "bStatus" va avoir pour valeur "True". C'est uniquement dans ce cas qu'on récupère les informations désirées. Si la connexion échoue on remet simplement les variables à zéro (leur définition n'a pas été reprise dans l'image ci-dessus pour ne laisser que le code considéré comme important).

Lecture du journal global

Une fois que l'on est connecté on peut lire les informations du journal afin de récupérer les entrées/sortie et les pauses, pour chaque jour et chaque utilisateur. Le procédé est le suivant : on doit d'abord "lire" l'entièreté du contenu de ce journal. Le tout est alors stocké en mémoire. On doit alors appeler une fonction qui va lire chaque enregistrement.
  • On doit appeler la fonction ReadGeneralLogData().
  • L'unique paramètre est le numéro de machine (récupéré plus haut).
  • On appelle une première fois GetGeneralLogData().
  • Le 1er paramètre est le numéro de machine (format entier 4 octets).
  • Les paramètres suivants sont des entiers système permettant de stocker chaque information. Il y en a 10. Dans l'ordre : n° de l'appareil qui a enregistré le pointage, l'ID utilisateur, de nouveau le n° de la pointeuse, le mode de vérification (ex : par carte), le type (entrée, sortie, pause), l'année, le mois, le jour, l'heure et les minutes. Voir "Conversions de type C"
  • La fonction renvoie un booléen sinon une valeur négative en cas d'erreur. Nous ne traiterons pas les erreurs dans l'exemple ci-dessous.
  • Elle peut être appelée tant que la valeur est vraie ; cela lira à chaque fois l'enregistrement suivant en mémoire. Une fois qu'il n'y en a plus, la fonction devrait retourner 0.
L'exemple ci-dessous va donc récupérer dans un champ Table les informations du journal de la pointeuse. Nous sommes donc en direct sur la pointeuse, les informations sont lues directement dans sa mémoire interne.


Nous traitons chaque enregistrement en prenant bien soin de vérifier la valeur de chaque entier retourné, surtout en ce qui concerne le type (pour distinguer l'entrée de la sortie) ou bien le mode de vérification (par empreinte digitale, mot de passe ou carte RFID). Voici ce qu'on obtient alors comme résultat dans une fenêtre.


Nous avons également prévu un bouton "Déconnexion" dans la fenêtre. Cela permet juste d'appeler la fonction Disconnect() de notre objet Automation. Elle ne reçoit aucun paramètre en entrée et ne retourne aucune valeur.

Et ensuite ?

Nous pouvons donc constater qu'il y a bel et bien un moyen d'interagir avec la pointeuse en direct tout en se passant du logiciel fourni par Safescan. Par exemple, nous avons vu qu'il existe une fonction pour nettoyer le journal des événements global. Il existe également tout un tas de fonctions pour récupérer les informations comme l'adresse MAC ou l'état de l'appareil, ou pour gérer différents événements. Au fil de nos essais nous verrons donc ce qu'il est possible de réaliser.