Définir des données sensibles & spécifiques au code, au moment de la compilation

Partagez vos scripts, et vos applications AutoIt.
Règles du forum
.
Répondre
Avatar du membre
ZDS
Membre émérite
Membre émérite
Messages : 554
Enregistré le : jeu. 10 juin 2010 09:35
Localisation : 22300 Cul-d'chouette Langue-de-vache
Status : Hors ligne

Définir des données sensibles & spécifiques au code, au moment de la compilation

#1

Message par ZDS » mer. 05 déc. 2018 18:04

Bonjour à tous ! (depuis le temps, désolé)

Je viens à vous pour vous présenter un exemple de procédure qui peut être améliorée et j'ai envie de dire qui DOIT être améliorée, c'est pour ça que j'aimerai vos avis, critiques et alternatives possibles !


L'OBJECTIF :

Enregistrer une valeur dans une variable au moment de la compilation, et pas avant ! Ca peut concerner des IDs de connexion, un mot de passe, un token, etc... qu'on ne souhaite pas mettre en dur dans le code, mais passer comme une donnée volatile qui serait figée ensuite dans l'EXE.


LA METHODE DE BASE :

Mettre la valeur sensible dans un fichier INI, et utiliser FileInstall pour incorporer le fichier INI dans l'EXE... Problème, le fichier INI doit être extrait pour que la donnée puisse être récupérée, et donc le mot de passe est lisible par d'autres moyens.
► Afficher le texteMéthode de base
Cette méthode est inacceptable selon moi !


MA METHODE EN UTILISANT AU3WRAPPER:

Le Wrapper utilise une commande Run_Before pour génèrer un AU3 à inclure dans le code d'origine, à partir d'un template ; lors de cette phase il demande la valeur secrète à incorporer. Puis la compilation s'effectue, et efface ensuite le fichier sensible avec une commande Run_After :
  • Fichier "Script.au3", contient le code d'exemple qui utilise la valeur secrète
    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Run_Before=""%autoitdir%\AutoIt3.exe" ".\Compile.au3" "START""
    #AutoIt3Wrapper_Run_After=""%autoitdir%\AutoIt3.exe" ".\Compile.au3" "END""
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #include ".\Data.au3"
    MsgBox(0, "", "Valeur secrète : '"&$__SECRET_VALUE&"'")
  • Fichier "Template.au3", fichier de référence destiné à être dupliqué après modification des champs entre {{ }}
    #include-once
    Global Const $__SECRET_VALUE = "{{secret_value}}"
  • Fichier "Compile.au3" :, script faisant la préparation à la compilation et la finalisation après compilation
    If $cmdLine[0] = 0 Then
            Local $mode = InputBox("", "Mode ? (START, END, NONE)", "", " M")
            proceed($mode)
    Else
            For $i = 1 To $cmdLine[0]
                    proceed($cmdLine[$i])
            Next
    EndIf

    Exit 0

    Func proceed($mode)
            Local $fileIn = @ScriptDir&"\Template.au3", $fileOut = @ScriptDir&"\Data.au3"
            Switch $mode
                    Case "START"
                            Local $value = InputBox("", "Secret value?", "", " M")
                            Local $fluxIn = FileOpen($fileIn)
                            If $fluxIn = -1  Then
                                    MsgBox(0, "", "Error on input file '"&$fileIn&"'")
                                    Exit 1
                            EndIf
                            Local $fluxOut = FileOpen($fileOut, 8+2)
                            If $fluxOut = -1  Then
                                    MsgBox(0, "", "Error on output file '"&$fileOut&"'")
                                    Exit 1
                            EndIf
                            Local $contentIn = FileRead($fluxIn)
                            Local $contentOut = StringReplace($contentIn, "{{secret_value}}", $value)
                            FileWrite($fluxOut, $contentOut)
                            FileClose($fluxIn)
                            FileClose($fluxOut)
                    Case "END"
                            If FileExists($fileOut) Then
                                    Local $fluxOut = FileOpen($fileOut, 8+2)
                                    If $fluxOut <> -1 Then
                                            FileWrite($fluxOut, "")
                                    EndIf
                                    FileClose($fluxOut)
                                    If FileDelete($fileOut) = 0 Then
                                            MsgBox(0, "", "Cannot delete output file '"&$fileOut&"'")
                                            Exit 1
                                    EndIf
                            EndIf
                    Case "NONE"
                            ; Nothing
                    Case Else
                            MsgBox(0, "", "Unknown mode '"&$mode&"'")
                            Exit 1
            EndSwitch
    EndFunc

Ce genre de méthode ne casse pas trois pattes à un connard, mais au moins ça donne une méthode (même si je la trouve crade personnellement). J'attends donc vos avis, vos critiques, et surtout vos alternatives ! :)

A bientôt !
ZDS : Chef de projet du nAiO (logiciel AutoIt gratuit sous licence CC 4.0 BY-NC-SA)
Tout problème a une solution, donc si il y a pas d'solution, c'est qu'il y a pas d'problème !

Avatar du membre
jl56
Niveau 7
Niveau 7
Messages : 365
Enregistré le : mer. 24 oct. 2007 21:42
Localisation : 56000
Status : Hors ligne

Re: Définir des données sensibles & spécifiques au code, au moment de la compilation

#2

Message par jl56 » sam. 08 déc. 2018 12:11

Bonjour à tous,

@ZDS ta procédure tombe a pic je recherchais un moyen de protection pour un code ou je crypte des données sensibles dans un fichier.ini
Mais comme ma clé de cryptage est dans le code lui même , elle est potentiellement lisible en cas de décompilation.

En regardant ton code je constate que c'est également le cas, tu stocks la valeur dans un include qui lors de la compilation est intégré au code global
La valeur sera en dur dans le code et la aussi lisible en cas de décompilation.

J'ai repris ta remarque sur le fichier ini et je te propose ceci:
On stock la valeur dans un fichier ini avant la compilation
Fichier qui est ajouté au code via fileinstal

On test, avant l’extraction du fichier contenant la valeur, si un malin voulais bloquer l'effacement et récupérer en clair la valeur dans le fichier ini

Si le test est ok on extrait le fichier contenant la valeur

une fois lu on efface la valeur et on détruit le fichier.
Avec cette méthode, même en cas de décompilation la valeur n'est pas présente dans le code

je suppose qu'il y a une méthode pour extraire le fichier sans exécuter le code mais ce n'est pas a ma porté donc encore moins a des utilisateurs lambda.

voici mon code d'exemple: ou dans le fichier joint
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=test_code.exe
#AutoIt3Wrapper_UseX64=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

IniWrite(@ScriptDir & "\code_test.ini", "code", "valeur", "test ecriture")
Sleep(100)

If IniRead(@ScriptDir & "\code_test.ini", "code", "valeur", "") = "test ecriture" Then ; on test si on peut ecrire
        FileDelete(@ScriptDir & "\code_test.ini"); ok on efface le fichier
        Sleep(100)
        If FileExists(@ScriptDir & "\code_test.ini") Then ;on test si on peut effacer le fichier
                MsgBox(0, "Erreur", "Vous n'avez pas les droits d'effacement sur ce dossier " & @ScriptDir, 180)
                Exit
        EndIf
Else
        MsgBox(0, "Erreur", "Vous n'avez pas les droits d'écriture sur ce dossier " & @ScriptDir, 180)
        Exit
EndIf

FileInstall("C:\pi\forum\test code\code_avant_compilation\code.ini", @ScriptDir & "\code.ini", 1) ; si tout est ok on extrait le fichier code
Sleep(100)
$code = IniRead(@ScriptDir & "\code.ini", "code", "valeur", ""); lecture du code
IniWrite(@ScriptDir & "\code.ini", "code", "valeur", ""); on ecrase aussitot la valeur dans le fichier code.ini


FileDelete(@ScriptDir & "\code.ini"); on efface aussitot le fichier code.ini

MsgBox(0, "Code", "Valeur =" & $code, 180)

créez un fichier code.ini avec votre valeur voir fichier joint


Placez ce fichier dans le sous dossier "code_avant_compilation\code.ini"

Corrigez les chemins dans le code

JL56


test_code.au3
(1.26 Kio) Téléchargé 32 fois
test_code.au3
(1.26 Kio) Téléchargé 32 fois
code.ini
(27 Octets) Téléchargé 32 fois
code.ini
(27 Octets) Téléchargé 32 fois

Avatar du membre
walkson
Modérateur
Modérateur
Messages : 639
Enregistré le : ven. 12 août 2011 18:49
Localisation : Essonne
Status : Hors ligne

Re: Définir des données sensibles & spécifiques au code, au moment de la compilation

#3

Message par walkson » sam. 08 déc. 2018 18:46

Bonjour,
je recherchais un moyen de protection pour un code ou je crypte des données sensibles dans un fichier.ini
Mais comme ma clé de cryptage est dans le code lui même , elle est potentiellement lisible en cas de décompilation.
La solution est peut être de mettre le hachage du mot de passe dans le code. On rentre le MP dans un input et le programme compare le hachage du MP avec celui du code.

Pour mes besoins personnels, j'ai fait des programmes à double usage. Par exemple, une minuterie où quand j’écris x heures x minutes x secondes lance veracrypt et ouvre des volumes. Tout est écrit en dur même les MP mais qui aurait l'idée de décortiquer une minuterie à part un lecteur de ce forum :mrgreen:
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi

Avatar du membre
ZDS
Membre émérite
Membre émérite
Messages : 554
Enregistré le : jeu. 10 juin 2010 09:35
Localisation : 22300 Cul-d'chouette Langue-de-vache
Status : Hors ligne

Re: Définir des données sensibles & spécifiques au code, au moment de la compilation

#4

Message par ZDS » ven. 25 janv. 2019 11:35

@jl56 : Tu dis que le fichier INI n'est pas lisible dans le cas d'une décompilation, c'est autant faux pour ce fichier externe que pour une variable, car le fichier INI en question fait partie des ressources extractibles (à voir si des softs comme ResHacker ne permettent pas de récupérer le fichier en question, d'ailleurs). De plus, créer le fichier pour l'effacer juste après en espérant que rien n'empêchera la suppression, c'est assez ballsy et pas propre ni sécurisé à mon sens (un UAC maison suffira à mettre en attente les opérations en question pour les valider une à une).
Et surtout, ma demande concerne un système d'ajout au moment de la compilation, et pas avant ^^C'est une feature que je souhaite ajouter au système de signature de mes EXE avec un certificat (système que j'ai déjà). La valeur secrète en question servira de salt pour mes algo d'encodage/décodage.
En fait, ton système serait presque parfait si on pouvait faire un FileInstall en mémoire au lieu de le faire sur disque. Merci pour l'alternative!

@walkson : La comparaison avec le hash est classique et connue de tous, ce n'est pas ce que je cherche à faire
ZDS : Chef de projet du nAiO (logiciel AutoIt gratuit sous licence CC 4.0 BY-NC-SA)
Tout problème a une solution, donc si il y a pas d'solution, c'est qu'il y a pas d'problème !

Avatar du membre
jl56
Niveau 7
Niveau 7
Messages : 365
Enregistré le : mer. 24 oct. 2007 21:42
Localisation : 56000
Status : Hors ligne

Re: Définir des données sensibles & spécifiques au code, au moment de la compilation

#5

Message par jl56 » dim. 27 janv. 2019 20:53

Bonjour à tous,
@ZDS
Je me doute bien qu'il y des solutions pour récupérer le fichier ini. moi je n'ai pas réussi j'ai tenté avec reshacker.
Il en a été plusieurs fois questions dans ce forum , il n'est pas possible de protéger un script point, c'est ainsi il faut l’accepter.

Pour contrer l'UAC je test en début de script si je peux ecrire/effacer, si je ne peux pas le script s’arrête.

A+

JL56

Jeep
Niveau 1
Niveau 1
Messages : 14
Enregistré le : jeu. 24 janv. 2019 16:34
Localisation : Belgique
Status : Hors ligne

Re: Définir des données sensibles & spécifiques au code, au moment de la compilation

#6

Message par Jeep » lun. 28 janv. 2019 14:55

Bonjour,

Voici une petite idée à creuser, pour mettre en place une "protection pas trop coûteuse", mais pas inviolable.

On crée une première application d'enregistrement, cette application capture par exemple la MAC adresse de la carte réseau du PC ou se réalisera l'installation ou la référence du disque dur ou ... .

Ces informations donnerons une bonne identification de la machine où sera installée l'application.

Pour éviter de rendre cette information trop repérable on peut y incorporé des données fictives qui évoluent telles que les composantes de la date et l'heure et on cryptera le résultat avec votre propre clé.

Les informations vous sont transmises par mail, affichage, ... . Vous analyserez ces données et vous en servirez pour l'encryption de vos données critiques. un peu à l'image de informations inscrite dans les données sauvegardées lors de la compilation. En effet, elles lierons physiquement votre application à l'ordinateur.

Lors de l'utilisation de l'application finale installées sur l'ordinateur. On commence par effacer (correctement) le programme d'installation sur cet ordinateur. A l'exécution, on peut reconstruire la clé d'encryption par une lecture de la MAC adresse ou ... . Pour s'assurer que l'on tourne sur le bon ordinateur.

La mise en place de ce type de protection, à plusieurs endroits dans votre application avec différentes caractéristique physiques va alourdir les efforts pour le cracking du programme. Après le niveau 1, il y a le niveau 2, puis ... .

Maintenant, comme chacun le dit, la protection totale n'existe pas avec un langage interprété. Mais je peux vous assurer que c'est également le cas avec des langages compilés. C'est juste un peu plus long. Donc essayons d'allonger le temps.

Jeep.
Un problème complexe peut souvent se découper en problèmes simples. Mais où est la scie ?

Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11355
Enregistré le : ven. 20 juil. 2007 20:00
Localisation : Bordeaux
Status : Hors ligne

Re: Définir des données sensibles & spécifiques au code, au moment de la compilation

#7

Message par Tlem » lun. 28 janv. 2019 15:59

Bonjour à tous.
Comme cela a déjà été expliqué, voici les étapes qu'une personne malveillante mettra en œuvre pour pirater votre programme :
  1. Analyse et décompilation de l'exécutable.
  2. Analyse du code et suppression ou contournement des mesures de protection.
  3. Recompilation du code.
et voilà, la personne malveillante possède une version gratuite qu'elle peux utiliser ou diffuser tranquillement.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".

jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2014
Enregistré le : lun. 30 mars 2009 21:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: Définir des données sensibles & spécifiques au code, au moment de la compilation

#8

Message par jchd » mar. 29 janv. 2019 11:49

Maintenant, comme chacun le dit, la protection totale n'existe pas avec un langage interprété. Mais je peux vous assurer que c'est également le cas avec des langages compilés. C'est juste un peu plus long. Donc essayons d'allonger le temps.
La question n'est pas du tout "d'allonger le temps". C'est une vision réductrice qui incite à faire de mauvais choix et n'est, de plus, pas généralisable.

La seule approche qui ait un sens consiste à rendre incomparables la valeur obtenue par une opération de reverse-engineering (de vol, de pénétration, ...) et le coût de cette opération. Dit autrement, si on veut "protéger" quoi que ce soit (matériel ou immatriel) il suffit de s'assurer que le gain obtenu par contournement des mesures de protection soit "suffisament inférieur" au coût associé à ce contournement.
C'est aussi, en partie, l'escalade entre le coût du boulet contre celui de la cuirasse, et ce depuis la nuit des temps.

Malheureusement, le tableau général est un poil plus subtil et il faut distinguer plusieurs valeurs dans beaucoup de cas concrets :
o) la valeur de ce qui est à protéger, aux yeux de son détenteur légitime. Disons que c'est le trésor T.
o) le coût global de la mise en oeuvre de la protection P.
o) la valeur du trésor aux yeux de la partie adverse. Appelons-ça le gain G.
o) le coût global de l'attaque A.

T et G peuvent ne pas être du même ordre de grandeur, ni être de même nature (cas du terrorisme) et idem pour A et P !
En outre il y a souvent des considérations temporelles (certaines de ces valeurs sont susceptibles d'évoluer au fil du temps), judiciaires (risques encourus par l'attaquant s'il est pris) et des conséquences à terme d'une attaque menée à bien. Ce n'est souvent pas un jeu à somme nulle, au sens traditionnel du terme, la difficulté étant de s'y ramener.

Pour l'attaquant, il faut que le gain espéré soit significativement supérieur au coût de l'attaque : G << A
Pour le défendeur D, il faut que le gain final pour l'attaquant soit nettement inférieur à ce que D risque de perdre : G - A << T + P
Si P >> T alors on doit se poser la question de la pertinence de cette protection et celle de l'évaluation de T.

La seule vraie difficulté est d'estimer correctement ces coûts et valeurs, que ce soit en € à investir, en temps requis, en neurones nécessaires, en gloire acquise, en perte de CA ou d'image, en vanité flattée, en capacité de nuisance, ...
P et A sont la plupart du temps des valeurs assez facilement comptabilisables, tandis que T et G sont de plus en plus fréquemment immatérielles.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.

Répondre