Seite 1 von 2

Sensible String-Daten im Programmcode

Verfasst: 30.12.2023 19:45
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.

Re: Sensible String-Daten im Programmcode

Verfasst: 30.12.2023 20:32
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.

Re: Sensible String-Daten im Programmcode

Verfasst: 31.12.2023 01:36
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.

Re: Sensible String-Daten im Programmcode

Verfasst: 31.12.2023 01:46
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.

Re: Sensible String-Daten im Programmcode

Verfasst: 31.12.2023 14:52
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 ;-)

Re: Sensible String-Daten im Programmcode

Verfasst: 31.12.2023 15:53
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

Re: Sensible String-Daten im Programmcode

Verfasst: 31.12.2023 17:45
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

Re: Sensible String-Daten im Programmcode

Verfasst: 01.01.2024 13:26
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?

Re: Sensible String-Daten im Programmcode

Verfasst: 01.01.2024 15:25
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.

Re: Sensible String-Daten im Programmcode

Verfasst: 01.01.2024 16:00
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.