Hallo verehrte Programmierpros!
Mal eine Frage.. wenn ich ein Programm kompiliere, kann ich es ja mit einem Passwort sichern aber WIE SICHER genau ist das? Wenn ich z.B. in einem Installer ein Admin-PW hinterlege, ist das dann irgendwie trotz PW wieder aus dem Programm zu bekommen oder ist es, wenn es einmal kompiliert ist, "safe"?
Daten "sicher durch kompilieren"?
-
akira2012 -
3. April 2020 um 08:33 -
Erledigt
-
-
Ich hoffe ich lehne mich nicht zu weit aus dem Fenster, da dies nicht mein Gebiet ist aber ich meine mich erinnern zu können:
- Hart einkodierte PAsswörter könnten ausgelesen werden (Datamining)
- Passwörter verschlüsselt speichern und auf den Schlüssel prüfen (eingegebenes Passwort nach Eingabe in z.B. SHA256 verschlüsseln und mit dem SHA256 Schlüssel des PAssworts vergleichen)
-
Hmm. Aber wenn das Harteinkodierte PW ausgelesen werden kann, kann dann nicht auch der Schlüssel für die Entschlüsselung des verschlüsselten Passwortes ausgelesen werden? (toller Satz oder ^.^*)
-
Es gibt keinen Schlüssel zur Entschlüsselung ganz einfach
Beispiel (wie ich es in Delphi mal gemacht habe):
Code
Alles anzeigen//übergebene Parameter prüfen if fileexists('\\Server\key.txt') then //Hier liegt der Key (das Verschlüsselte Passwort als SHA256-Key) auf einem Server, kann aber auch hard eincodiert werden begin assignfile(pwtf, '\\Server\key.txt'); //SHA256 Vergleichsstring laden reset(pwtf); readln(pwtf, pwd); closefile(pwtf); for i := 1 to ParamCount do begin Parameter := Parameter + ' ' + ParamStr(i); if (ParamStr(i)[1] = '/') then begin if ((ParamStr(i)[2] = 'p') or (ParamStr(i)[2] = 'P')) and (ThashSHA2.GetHMAC(Paramstr(i + 1), ThashSHA2.GetHashString(Paramstr(i + 1)), SHA256) = pwd) then //Hier wird das per Parameter übergebene Passwort in SHA256 umgewandelt und mit dem Vergleichsstring abgeglichen begin Do Actions end; end; end; end; //---------------Beispiel um das Passwort in den SHA-String zu wandeln--------------- //Passwort generieren newPW := 'ABCDEFG'; Clipboard.AsText := ThashSHA2.GetHMAC(newPW, ThashSHA2.GetHashString(newPW), SHA256);
-
Alles was im Programm selbst untergebracht ist, kann ausgelesen werden. Seien es einzelne Werte oder auch ganze Programmabläufe.
Das ist auch unabhängig davon ob Interpretersprache wie AutoIt oder ob kompiliert. Lediglich der Aufwand um an die Infos zu kommen unterscheidet sich.
Es ist also auch in C eine ganz ganz blöde Idee eigentlich geheime Passwörter im Quellcode unterzubringen.Wenn unbedingt irgendwelche Zugangsdaten drin stehen müssen, bekommt man die im Grunde nur vernünftig sicher hin, wenn man sie mit Infos von externer Seite außerhalb des Quellcodes verknüpft.
Z. B.: Man hat Anmeldedaten im Quelltext die das Programm benötigt. Diese werden mit einem Passwort verschlüsselt und dieses wird dem Anwender mitgeteilt.
Ohne dieses Passwort kann er die Anmeldedaten nicht auslesen, da diese ja verschlüsselt sind. Nur mit Passwort kann er damit was anfangen.
AutoIt
Alles anzeigen#include <Crypt.au3> ; der Key welcher im Programm untergebracht aber nicht ausgelesen werden können soll $sKey_HardCoded = "123456" ; ein Passwort welches den Key im Programm entschlüsselt $sUserKey = InputBox("Passwort", "Bitte Passwort eingeben") ; der verschlüsselte Key - dieser muss dann im Quelltext des eigentlichen Programms verwendet werden $sKeyHardCoded_crypted = _Crypt_EncryptData($sKey_HardCoded, $sUserKey, $CALG_AES_256) MsgBox(0, "Key verschlüsselt - kann nun im Programm untergebracht werden", $sKeyHardCoded_crypted)
Die hiermit ermittelten Werte können nun im eigentlichen Programm untergebracht werden und werden dort erst zur Laufzeit mit externen Infos (hier ein Userpassword) entschlüsselt:
AutoIt; der verschlüsselte Key im Quelltext: $sKeyHardCoded_crypted = "0x9E1C91210B3581FB3A692416DE76AE64" ; das zur Laufzeit vom User einzugebende Passwort um den Key zu entschlüsseln $sUserKey = InputBox("Passwort", "Bitte Passwort eingeben") ; der entschlüsselte Key $sKey_HardCoded = BinaryToString(_Crypt_DecryptData($sKeyHardCoded_crypted, $sUserKey, $CALG_AES_256)) MsgBox(0, "Inhalt von $sKey_HardCoded nach Entschlüsselung", $sKey_HardCoded)
Wenn es dann darum geht auch dieses externe Passwort (kann z.B. auch ein Hardware-Dongle sein) nicht dem Nutzer zu verraten, dann wird es ganz eklig.
Dann braucht man eher aufwendige Lösungen mit nem zentralen Server usw.
-
Danke erstmal für alle Antworten!
AspirinJunkie - ein beliebiges Passwort dem Nutzer zu nennen wäre schon möglich, denke ich. Zum Hintergrund: Ich suche nach einer Lösung ein Programm (VPN-Client) nachträglich auf Laptops zu installieren, die im Homeoffice sind. Das Problem, wenn ich einen Fernzugriff auf diese Rechner mit Teamviewer oder Teams mache, kann ich die Admin-Daten nicht eingeben, weil ich wegen der UAC keine Eingabemöglichkeit habe. Da war die Idee ein "automatisches" Installationspaket zu senden, dass auch die Admin-Daten übergibt. Aber geht das überhaupt? Kann ein AutoIt-Programm zuerst die Installation starten und dann Daten in die UAC eingeben?
-
Ein ausführen als anderer Benutzer funktioniert wohl nicht? Das heißt, du bist z.B. per TeamViewer auf dem Client und startest dann dein Setup, indem du mit Shift + Rechtsklick auf die Datei das Menü "Als anderer Benutzer ausführen" aufrufst. Das UAC Aufforderung kann man dan doch auch bestätigen.
Gruß gmmg
-
Da wir auch schon ein ähnliches Problem hatten und dem Benutzer das lokale Administrator Passwort nicht einfach so mitteilen konnten:
Du könntest per Teamviewer im Usercontext zugreifen.
Danach lädst du ein kleines Autoitscript hoch, welches hardcodierte Daten des lokalen Administrators enthält und via runas dort einen temporären Adminuser anlegt, dessen Daten du dann bedenkenlos dem User mitteilen kannst. Dein Script löscht sich nach getaner Arbeit am besten selbst, so dass keine Spuren davon auf dem Rechner zurückbleiben.
Den temporären Adminuser kannst du nach der VPN Installation über selbige Methode auch wieder löschen.
Es ist unwahrscheinlich, dass der User unter deiner Beaufsichtigung Unsinn mit dem temporären Adminaccount anstellt.
Alternativ kannst du natürlich auch versuchen die komplette Installation via runas Aufruf zu automatisieren. Aufwand ist aber deulich höher als einem User ein temporäres Admin Passwort mitzuteilen und ihn durch die Installation zu leiten.
Weitere Alternative... statt mit einem temporären Admin Account zu arbeiten kannst du auch den Benutzeraccount temporär zu den Administratoren hinzufügen.
Und zu guter letzt... wir nutzen Teamviewer zwar eher selten, aber ich erinner mich daran schonmal die Windowsanmeldemaske in einer Teamviewersitzung gesehen zu haben. Theoretisch sollte es dir so auch möglich sein dich mit deinem lokalen Administrator anzumelden und die Installation darüber durchzuführen. Zumindestens bei uns erscheint auf dem Superadministrator Account keine UAC Abfrage.
-
Oder du machst das mit einem Remotezugriff (mit psexec):
- Programm was du installieren willst (ohne Benutzereingaben!) zum Ziel-PC kopieren:
AutoIt$Source = @ScriptDir & '\Deine_Install_Datei.exe' ;z.B. Kannst auch ganze Ordner kopieren etc., Anpassen! $Destination = '\\' & $IPdesZielPC & '\c$\Zielverzeichnis\' ;Anpassen Filecopy($Source, $Destination) ;Oder Bei Ordner: DirCopy()
- PSexec ausführen
AutoIt$IPdesZielPC = 'x.x.x.x' ;Anpassen $Adminbenutzer = 'Adminbenutzer' ;Anpassen $AdminPasswort = '' ;Anpassen Runwait('psexec.exe -accepteula -n 30 -s \\' & $IPdesZielPC & ' -u ' & $Adminbenutzer & ' -p "' & $AdminPasswort & '" -c \\' & $IPdesZielPC & '\c$\Zielverzeichnis\Deine_Install_Datei.exe', @ScriptDir, @SW_HIDE) ;Verzeichnis und Datei anpassen Die kopierten Dateien/Ordner wieder löschen!!
Das ganze muss dann besonders (separat) gestartet werden (Ich mache das aktuell über Lazarus, in Autoit gibt es sicherlich auch eine entsprechende Lösung):
Code
Alles anzeigen//Prozess als bestimmten Benutzer starten (Hilfsaufruf) procedure TTools.startas(exe: Widestring; param: string); var User : WideString; PW : WideString; err : DWORD; begin User := ''; PW := ''; err := CreateProcessAsLogon(User, PW, exe, WideString(param), ''); if err <> 0 then begin ShowMessage(SysErrorMessage(err)); end; end; //Aufruf: startasSU(Pfad incl Dateiname welche ausgeführt werden soll (Lokal, obiges Programm), Pfad des obigen Programms); //Prozess als bestimmten Benutzer starten function TTools.CreateProcessAsLogon(const User, PW, Application, param, CmdLine: WideString): DWORD; var s : WideString; si : TStartupInfoW; pif : TProcessInformation; begin ZeroMemory(@si, sizeof(si)); si.cb := sizeof(si); si.dwFlags := STARTF_USESHOWWINDOW; si.wShowWindow := 1; if CmdLine = '' then begin s := Application; end else begin s := Application + ' "' + CmdLine + '"'; end; SetLastError(0); SI.cb := SizeOf(TStartupInfo); if CreateProcessWithLogonW(PWideChar(User), nil, PWideChar(PW), 0, nil, PWideChar(s), CREATE_DEFAULT_ERROR_MODE, nil, PWideChar(param), @si, @pif) then begin sleep(500); if PIf.dwProcessId > 0 then begin AppPID := PIf.dwProcessId; CloseHandle(PIf.hProcess); CloseHandle(PIf.hThread); end; end; Result := GetLastError; end;
Evtl. hilft dir das weiter, denn das kann komplett im Hintergrund laufen ohne das der Benutzer das überhaupt mit bekommt.
Nachteil: Auch hier wäre das Passwort hard codiert enthalten, jedoch nur temporär (auf Zielsystem, da nach Durchführung diese wieder gelöscht werden) bzw. dauerhaft (auf dem Quellsystem). Sollte aber weniger Schlimm sein als dem Benutzer irgendwelche Passwörter oder (temporären) Rechte zu geben.
-
"psexec" mag normalerweise vielleicht möglich sein, wenn sich Quell und Ziel PC im selben Netzwerk befinden und andere Vorraussetzungen (Gruppenrichtlinien, Firewall, Virenschutz) dafür erfüllt sind. Hier ist das aufgrund von Home Office und mangelnder VPN Verbindung aber nicht gegeben.