Sensible String-Daten im Programmcode

Anfängerfragen zum Programmieren mit PureBasic.
ABeltz
Beiträge: 33
Registriert: 21.10.2023 14:27
Computerausstattung: Betriebssystem: Kubuntu 23.10
KDE-Plasma-Version: 5.27.8
KDE-Frameworks-Version: 5.110.0
Qt-Version: 5.15.10
Kernel-Version: 6.5.0-13-generic (64-bit)
Grafik-Plattform: X11
Prozessoren: 32 × AMD Ryzen 9 3950X 16-Core Processor
Speicher: 62,7 GiB Arbeitsspeicher
Grafikprozessor: NVIDIA GeForce RTX 2080 Ti/PCIe/SSE2
Hersteller: Micro-Star International Co., Ltd
Produktname: MS-7C02
Systemversion: 1.0
Wohnort: Deutschland
Kontaktdaten:

Sensible String-Daten im Programmcode

Beitrag von ABeltz »

Hallo Zusammen,

es ist für mich zumindest nicht überlebenswichtig, aber es Interessiert (vielleicht nicht nur) mich:

String Konstanten werden 1 : 1 im Executable abgelegt. Und wenn man weiß wonach man sucht, kann man das Executable mit einem Hex-Editor danach durchsuchen. Soweit richtig?

Wenn ich nun einen sensiblen String fest verdrahten möchte, wie mache ich das so, dass dieser String NICHT ohne weiteres im HexEditor sichtbar ist?

Danke für Eure Vorschläge.
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: Sensible String-Daten im Programmcode

Beitrag von DarkDragon »

Du kannst sie Verschlüsseln, aber selbst dann sind sie noch Strings und der Key liegt irgendwo daneben. Wirklich sicher geht nicht, solange dein Programm selbst den Inhalt des Strings benötigt. Wenn das Programm den Inhalt nicht benötigt und du nur deine Signatur einbauen willst kannst du natürlich einen String verschlüsseln und den Key nicht daneben legen.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
berie
Beiträge: 75
Registriert: 17.01.2018 08:52
Computerausstattung: Windows 11 64 bit, i7, 16GB RAM
Wohnort: Wesertal in Nordhessen

Re: Sensible String-Daten im Programmcode

Beitrag von berie »

Hallo,
ich habe vor Jahren mal ein Programm geschrieben, dessen Daten Passwortgeschützt waren.
Den Passwortstring habe ich in einer Datei "versteckt". Das war zwar eine Variable, sollte sich aber mir etwas Arbeit auch für Stringkonstanten umsetzen lassen:

Code: Alles auswählen

Procedure PasswortFestlegen()
  Protected.s pw0,pw1
  Protected x
  
  pw0=StringFingerprint(InputRequester("Neues Passwort festlegen","Neues Passwort eingeben - Leereingabe für kein Passwort",""),#PB_Cipher_SHA1)
  If pw0<>#LeeresPasswort
    pw1=StringFingerprint(InputRequester("Passwort wiederholen","Passwort wiederholen:",""),#PB_Cipher_SHA1)
    If pw0<>pw1
      MessageRequester("Die Passwörter stimmen nicht überein.","Das Programm wird beendet.",#PB_MessageRequester_Ok|#PB_MessageRequester_Warning)
      ProcedureReturn #False
    EndIf
  EndIf
  
  If CreateFile(0,PwDatei) ;Passwort speichern
    For x=0 To 49          ;Passwort in der Datei "verstecken"
      WriteByte(0,Random(255))
    Next
    For x=1 To Len(pw0) Step 2
      WriteByte(0,Val("$"+Mid(pw0,x,2)))
    Next
    For x=0 To 55 ;Passwort in der Datei "verstecken"
      WriteByte(0,Random(255))
    Next   
    CloseFile(0)
  EndIf
  ProcedureReturn #True
EndProcedure
#LeeresPasswort ist ein leerer String SHA1-verschlüsselt.
pw0 ist dein String als Variable, also keine Konstante.
PwDatei ist die Datei, in der ich das Passwort "verstecke":
Ich schreibe 50 zufällige Daten, dann das Passwort und dann 56 zufäliige Daten-ist lange nicht perfekt, macht es potentiellen Hacker aber etwas schwerer , hofffe ich.
formerly known as bizzl
berie
Beiträge: 75
Registriert: 17.01.2018 08:52
Computerausstattung: Windows 11 64 bit, i7, 16GB RAM
Wohnort: Wesertal in Nordhessen

Re: Sensible String-Daten im Programmcode

Beitrag von berie »

So kann man den String verschlüsset speichern und anschließend die Definition/Deklaration des Strings aus dem Programmcode löschen.
ungefähr so:
GeheimerString.s="Ich bin geheim"
usw.
s.o. StringFingerprint...

Das Programm einmal laufenlassen, erzeugt "PwDatei", dann "GeheimerString"... löschen.
In Zukunft den String (bei Programmstart) aus "PwDatei" einlesen.
Okay, reichlich workaround, aber deine Stringskontante (nun Variable) ist verschlüsselt.
formerly known as bizzl
ABeltz
Beiträge: 33
Registriert: 21.10.2023 14:27
Computerausstattung: Betriebssystem: Kubuntu 23.10
KDE-Plasma-Version: 5.27.8
KDE-Frameworks-Version: 5.110.0
Qt-Version: 5.15.10
Kernel-Version: 6.5.0-13-generic (64-bit)
Grafik-Plattform: X11
Prozessoren: 32 × AMD Ryzen 9 3950X 16-Core Processor
Speicher: 62,7 GiB Arbeitsspeicher
Grafikprozessor: NVIDIA GeForce RTX 2080 Ti/PCIe/SSE2
Hersteller: Micro-Star International Co., Ltd
Produktname: MS-7C02
Systemversion: 1.0
Wohnort: Deutschland
Kontaktdaten:

Re: Sensible String-Daten im Programmcode

Beitrag von ABeltz »

berie hat geschrieben: 31.12.2023 01:36
For x=1 To Len(pw0) Step 2
WriteByte(0,Val("$"+Mid(pw0,x,2)))
Next
Hallo Berie,
Vielen Dank für den Code. Das kommt dem, so wie ich es mir vorgestellt habe, ganz nahe und werde ich auch so umsetzen. Kleine Rückfrage: wie dekodiere ich das Passwort wieder? Ich kann leider nicht ganz nachvollziehen, was du in der WriteByte-Zeile machst.

Beispiel: pw0 = "ich bin geheim"
x = 1: Mid(pw0,1,2) = "ic"
Val("$ic") = ??

Danke für die Nachhilfe ;-)
Benutzeravatar
mk-soft
Beiträge: 3844
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Sensible String-Daten im Programmcode

Beitrag von mk-soft »

Du kannst ruhig dein Programm Password im Programm hinterlegen.

Code: Alles auswählen

UseSHA3Fingerprint()

Global pass.s

; Build program password for datasetion
; pass = StringFingerprint("password", #PB_Cipher_SHA3)
; Debug pass

; Test

pass = InputRequester("Programm Password", "Eingabe", "", #PB_InputRequester_Password)

If StringFingerprint(pass, #PB_Cipher_SHA3) <> PeekS(?pass)
  Debug "Invalid Password!"
  End
EndIf

Debug "Start Program"

DataSection
  pass:
  Data.s "c0067d4af4e87f00dbac63b6156828237059172d1bbeac67427345d6a9fda484"
  Data.i 0
EndDataSection
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3844
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Sensible String-Daten im Programmcode

Beitrag von mk-soft »

Oder erstellen ein Include Datei mit Verschlüsselten Strings

Hier das Werkzeug dafür ...

Update v1.03

Code: Alles auswählen

;-TOP by mk-soft, v1.03, 31.12.2023, 01.01.2024

; Create AES DataSection Strings

Macro AddElementValue(_list_, _value_)
  AddElement(_list_) : _list_ = _value_
EndMacro

Structure ArrayOfByte
  b.b[0]
EndStructure

Procedure CreateAESDataSection(Filename.s)
  Protected label.s, text.s, len, size, *buffer.ArrayOfByte, i, temp.s
  Protected NewList rows.s()
  
  Restore Strings
  
  AddElementValue(rows(), ";-TOP AES DataSection Strings")
  AddElementValue(rows(), "")
  AddElementValue(rows(), "Procedure.s GetAESDataString(*Label)")
  AddElementValue(rows(), "  Protected len, size, temp.s")
  AddElementValue(rows(), "  len = PeekL(*Label)")
  AddElementValue(rows(), "  If len < 8")
  AddElementValue(rows(), "    size = 16")
  AddElementValue(rows(), "  Else")
  AddElementValue(rows(), "    size = len * 2")
  AddElementValue(rows(), "  EndIf")
  AddElementValue(rows(), "  *Label + 4")
  AddElementValue(rows(), "  temp = Space(size / 2)")
  AddElementValue(rows(), "  If AESDecoder(*Label, @temp, size, ?StringKey, 128, ?StringInitializationVector)")
  AddElementValue(rows(), "    temp = Left(temp, len)")
  AddElementValue(rows(), "  EndIf")
  AddElementValue(rows(), "  ProcedureReturn temp")
  AddElementValue(rows(), "EndProcedure")
  AddElementValue(rows(), "")
  AddElementValue(rows(), "DataSection")
  AddElementValue(rows(), "  StringKey:")
  *buffer = ?StringKey
  For i = 0 To 15
    If i = 0
      temp = "  Data.b $" + RSet(Hex(*buffer\b[i], #PB_Byte), 2, "0")
    Else
      temp + ",$" + RSet(Hex(*buffer\b[i], #PB_Byte), 2, "0")
    EndIf
  Next
  AddElementValue(rows(), temp)
  AddElementValue(rows(), "  StringInitializationVector:")
  *buffer = ?StringInitializationVector
  For i = 0 To 15
    If i = 0
      temp = "  Data.b $" + RSet(Hex(*buffer\b[i], #PB_Byte), 2, "0")
    Else
      temp + ",$" + RSet(Hex(*buffer\b[i], #PB_Byte), 2, "0")
    EndIf
  Next
  AddElementValue(rows(), temp)
  AddElementValue(rows(), "")
  
  ; Max String Len 32768
  *buffer = AllocateMemory($10000)
  
  Repeat
    Read.s label
    If label = #ETX$
      Break
    EndIf
    Read.s text
    len = Len(text)
    If len < 8
      text + Space(8 - len)
    EndIf
    AddElementValue(rows(), "  " + label)
    size = StringByteLength(text)
    AddElementValue(rows(), "  Data.l " + Str(len))
    If AESEncoder(@text, *buffer, size, ?StringKey, 128, ?StringInitializationVector)
      For i = 0 To size - 1
        If i = 0
          temp = "  Data.b $" + RSet(Hex(*buffer\b[i], #PB_Byte), 2, "0")
        Else
          temp + ",$" + RSet(Hex(*buffer\b[i], #PB_Byte), 2, "0")
        EndIf
      Next
      AddElementValue(rows(), temp)
    EndIf
    
  ForEver
  AddElementValue(rows(), "EndDataSection")
  AddElementValue(rows(), "")
  
  If Filename
    If CreateFile(0, Filename)
      ForEach rows()
        WriteStringN(0, rows())
      Next
      CloseFile(0)
    EndIf
  Else
    ForEach rows()
      Debug rows()
    Next
  EndIf
  
  FreeMemory(*buffer)
  
EndProcedure

CreateAESDataSection("")

;- Data
; Strings:
; - Label name
; - Text contents
; ...
; ETX

DataSection
  StringKey:
  Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $07
  StringInitializationVector:
  Data.b $3d, $af, $ba, $42, $9d, $9e, $b4, $30, $b4, $22, $da, $80, $2c, $9f, $ac, $42
  
  Strings:
  Data.s "text1:"
  Data.s "Hello World!"
  Data.s "text2:"
  Data.s "*** I like PureBasic ***"
  Data.s #ETX$
  
EndDataSection
Zuletzt geändert von mk-soft am 01.01.2024 15:40, insgesamt 2-mal geändert.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Sensible String-Daten im Programmcode

Beitrag von NicTheQuick »

Ein Passwort im Programm zu speichern ist immer falsch. Auch wenn es verschlüsselt ist und der Schlüssel irgendwo anders liegt.

Ich würde deshalb gerne erst mal die grundsätzliche Frage stellen: Gegen wen willst du es absichern und wozu wird das Passwort benötigt?
Benutzeravatar
mk-soft
Beiträge: 3844
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Sensible String-Daten im Programmcode

Beitrag von mk-soft »

Eigentlich ist es egal wo man das Passwort ablegt. Wer es möchte und den Aufwand betreibt kann es mit Disassembler die Abfrage umgehen.

Eigentlich habe ich erst die Frage falsch beantwortet. Somit habe ich die Methode die String als AES in Datenbaustein zu hinterlegen hinzugefügt.
Somit sind diese mit einen Hex Editor nicht mehr zu sehen. Auch diese kann man mit sehr viel Aufwand mit Disassembler hacken.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Sensible String-Daten im Programmcode

Beitrag von NicTheQuick »

Ich hab jetzt auch an Passwörter gedacht, die vielleicht bei externen APIs zur Authentifizierung genutzt werden.
Wir hatten ja auch schon öfter den Fall, dass Leute Daten mit einem FTP-Server austauschen wollten, aber nicht wussten wie sie das Passwort speichern sollten.

Wenn man nur ein Passwort prüfen will, empfehlen sich natürlich Hash-Werte anstatt das Passwort selbst zu speichern. Aber wer Zugriff auf einen Hex-Editor hat kann auch einfach den Hash durch einen anderen ersetzen. Das wäre vermutlich noch einfacher als den Disassembler anzuwerfen.
Antworten