Cmd,ps: Signaturzeitpunkt einer datei auslesen, unmöglich
hallo,
ich hab ein kleines problem:
ich möchte von einer datei "C:\Windows\explorer.exe"
gewisse zertifikatinformationen herausbekommen.
eigentlich nur eine, und zwar den
"Signaturzeitpunkt/Signature Date/Date signed"-wert.
es ist schwerer als ich gedacht habe.
bei powerschell hab ich & ein kollege mich schon mit 'Get-Certificate' & 'Get-ItemProperty' rumgeprügelt
bei cmd bin ich bei 'certutil' hängengeblieben.
bei 'certutil' gibs zwar haufen schalter, aber da scheind keiner so recht zu passen.
aber mit dem 'dump' befehl konnte ich immerhin meine information finden.
theoretisch könnte ich den string filtern,
zu dumm das das filterwort meiner wahl auf deutsch ist "Signaturzeitpunkt",
was auf einem potenziellen sprach fremden system nicht funktioniert.
in powershell konnte ich leider keinen vergleichbaren 'dump'-befehl nicht finden,
das hätte die interoperabilität gesichert.
es wäre natürlich wunderbar, wenn man den wert irgendwie direkt auslesen könnte...
ich hab ein kleines problem:
ich möchte von einer datei "C:\Windows\explorer.exe"
gewisse zertifikatinformationen herausbekommen.
eigentlich nur eine, und zwar den
"Signaturzeitpunkt/Signature Date/Date signed"-wert.
es ist schwerer als ich gedacht habe.
bei powerschell hab ich & ein kollege mich schon mit 'Get-Certificate' & 'Get-ItemProperty' rumgeprügelt
bei cmd bin ich bei 'certutil' hängengeblieben.
bei 'certutil' gibs zwar haufen schalter, aber da scheind keiner so recht zu passen.
aber mit dem 'dump' befehl konnte ich immerhin meine information finden.
theoretisch könnte ich den string filtern,
zu dumm das das filterwort meiner wahl auf deutsch ist "Signaturzeitpunkt",
was auf einem potenziellen sprach fremden system nicht funktioniert.
in powershell konnte ich leider keinen vergleichbaren 'dump'-befehl nicht finden,
das hätte die interoperabilität gesichert.
es wäre natürlich wunderbar, wenn man den wert irgendwie direkt auslesen könnte...
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 3358340273
Url: https://administrator.de/contentid/3358340273
Ausgedruckt am: 17.11.2024 um 23:11 Uhr
33 Kommentare
Neuester Kommentar
Hi.
Hat tatsächlich auch eine Weile gebraucht, es per Google zu finden, aber hier wird genau dein Problem beschrieben und gelöst:
www.sysadmins.lv/blog-en/retrieve-timestamp-attribute-from-digital-signature.aspx
bzw.
www.sysadmins.lv/blog-en/reading-multiple-signatures-from-signed-file-with-powershell.aspx
Hoffe das hilft.
Viele Grüße
Trelane
Hat tatsächlich auch eine Weile gebraucht, es per Google zu finden, aber hier wird genau dein Problem beschrieben und gelöst:
www.sysadmins.lv/blog-en/retrieve-timestamp-attribute-from-digital-signature.aspx
bzw.
www.sysadmins.lv/blog-en/reading-multiple-signatures-from-signed-file-with-powershell.aspx
Hoffe das hilft.
Viele Grüße
Trelane
Servus.
Mit einer lokal liegenden "sigcheck" dann bspw. so in einer CMD
Grüße Uwe
p.s. die oben verlinkten PS Funktionen versagen übrigens kläglich bei Signaturen vom Typ "Catalog" im Gegensatz zu sigcheck!
p.s.2 Einzeiler kann man immer bauen indem man den Code in Base64 kodiert und via Invoke-Expression ausführt, ob das aber immer sinnvoll ist ... Dann baue ich mir doch lieber gleich eine eigene exe mit c# oder verlagere die Funktion in eine eigene Bibliothek/dll wenn es mal etwas aufwändiger ist.
Zitat von @zeddler0:
ich kann nicht sicher sein, dass auf alle sprachversionen die zeit identisch dargestellt wird.
leider unbrauchbar ich wirr auch ungern die einstellungen fremder systeme verstellen,
nur um den wert richtig zu formatieren.
Dazu hat die PS doch die passenden DateTime Parse-Methoden mit CultureInfo ich kann nicht sicher sein, dass auf alle sprachversionen die zeit identisch dargestellt wird.
leider unbrauchbar ich wirr auch ungern die einstellungen fremder systeme verstellen,
nur um den wert richtig zu formatieren.
Mit einer lokal liegenden "sigcheck" dann bspw. so in einer CMD
@echo off
set "file=C:\Windows\explorer.exe"
powershell -EP Bypass -C "[datetime]::Parse(([regex]::match((sigcheck.exe '%file%' -accepteula | out-string),'(?i)(?<=Signing date:\s+).*').Value.trim() -replace '([^\s]+) ([^\s]+)','$2 $1'),[cultureinfo]::CurrentCulture).toString('dd.MM.yyyy HH:mm:ss')"
p.s. die oben verlinkten PS Funktionen versagen übrigens kläglich bei Signaturen vom Typ "Catalog" im Gegensatz zu sigcheck!
p.s.2 Einzeiler kann man immer bauen indem man den Code in Base64 kodiert und via Invoke-Expression ausführt, ob das aber immer sinnvoll ist ... Dann baue ich mir doch lieber gleich eine eigene exe mit c# oder verlagere die Funktion in eine eigene Bibliothek/dll wenn es mal etwas aufwändiger ist.
Zitat von @zeddler0:
powershell kann ziehmlich gut die zeitformatierungen erkennen.
ich weiß aber nicht ob es alle erkennen kann.
in den usa wird gern mal der tag&monat vertauscht.
"2022/18/06"
und das bekommt der nicht erkannt...
powershell kann ziehmlich gut die zeitformatierungen erkennen.
ich weiß aber nicht ob es alle erkennen kann.
in den usa wird gern mal der tag&monat vertauscht.
"2022/18/06"
und das bekommt der nicht erkannt...
Doch aber man muss das System-Pattern nur auslesen ...
[cultureinfo]::CurrentUICulture.DateTimeFormat.ShortDatePattern
[cultureinfo]::CurrentUICulture.DateTimeFormat.ShortTimePattern
Um beim obigen Beispiel zu bleiben dann
@echo off
set "file=C:\Windows\explorer.exe"
powershell -EP Bypass -C "[datetime]::ParseExact([regex]::match((sigcheck.exe '%file%' -accepteula | out-string),'(?i)(?<=Signing date:\s+).*').Value.trim(),([cultureinfo]::CurrentUICulture.DateTimeFormat.ShortTimePattern,[cultureinfo]::CurrentUICulture.DateTimeFormat.ShortDatePattern) -join ' ',[cultureinfo]::CurrentUICulture).toString('dd.MM.yyyy HH:mm:ss')"
Hmpf, Sonntag ... du scheinst allgemein Probleme mit "Länge" zu haben ...
$c = [cultureinfo]::CurrentUICulture
[datetime]::ParseExact("12:51 2022-06-18",($c.DateTimeFormat.ShortTimePattern,$c.DateTimeFormat.ShortDatePattern) -join ' ',$c).toString('<yyyy_MM_dd> [hh=mm=ss]')
Für das Beispiel muss dein Culture-DateTimeFormat also wie der Beispiel String konfiguriert sein (der ja für die Ausgabe von sigcheck steht).
Sicher, einfach überall das $c durch [cultureinfo]::CurrentUICulture ersetzen, versteht sich doch eigentlich von selbst, du wolltest es doch "kurz" und so hätte es einige Wiederholungen durch die Verwendung der Variablen gespart. Entscheide dich mal ... 🖖
Grüße Uwe
Nein einfach nur ersetzen [cultureinfo]::CurrentUICulture ist ein Object, und von diesem wird per folgendem Punkt die Property DateTimeFormat.ShortTimePattern etc. abgerufen
Ergo ist bspw.
gleich das
Ergo ist bspw.
$c = [cultureinfo]::CurrentUICulture
$c.DateTimeFormat.ShortTimePattern
[cultureinfo]::CurrentUICulture.DateTimeFormat.ShortTimePattern
Ich habe doch oben schon gesagt das dafür das Format in den Regionsoptionen umgestellt werden muss wenn man es mit einem plain string eines anderen Formats testet!! Das klappt sonst nur wenn der String direkt von sigcheck kommt weil diese das hinterlegte Format aus den Regionsoptionen benutzt!!!!
Von Copy und Paste lernst du nichts mein Freund du musst die Posts schon komplett lesen und verstehen was da passiert!
Also als erstes mal Doku lesen
https://docs.microsoft.com/de-de/dotnet/api/system.datetime.parseexact?v ...
Und als Wochenend-Lektüre
Powershell Leitfaden für Anfänger
Von Copy und Paste lernst du nichts mein Freund du musst die Posts schon komplett lesen und verstehen was da passiert!
Also als erstes mal Doku lesen
https://docs.microsoft.com/de-de/dotnet/api/system.datetime.parseexact?v ...
Und als Wochenend-Lektüre
Powershell Leitfaden für Anfänger
Zitat von @zeddler0:
dann kann ich es so nicht immer verwenden,
da diese werte nicht immer von einer anwendung kommen.
Du kannst auch mit TryParseExact verschiedene Format-Varianten einer Liste durchprüfen bis eine davon matcht und das Datum als DateTime zurückgeben, das wäre auch kein Problem.dann kann ich es so nicht immer verwenden,
da diese werte nicht immer von einer anwendung kommen.
Beispiel
<#
Check if string can be parsed from multiple valid datetime formats
#>
function Check-ValidDate {
[OutputType([datetime])]
param(
[parameter(mandatory=$true,ValueFromPipeline=$true)][string[]]$datestring,
[parameter(mandatory=$true)][string[]]$dateformats
)
$dt = [datetime]0
$dateformats | %{
if([datetime]::TryParseExact($datestring,$_,[cultureinfo]'','None',[ref]$dt)){
return $dt
break
}
}
}
Check-ValidDate -datestring '10/21/2010' -dateformats 'yyyy/MM/dd','yyyy-MM-dd','dd.MM.yyyy','MM/dd/yyyy'
Wie sollte also ein Programm 2022/04/03 zu 100% interpretieren? Die 04 könnten der Monat oder auch der Tag sein, du must also zwingend eine Definition oder Referenz haben ...
Das Beispiel von Colinardo ist wirklich toll. Schreib doch einfach mal den ganzen Code in
sigcheck.bat (pass die zweite Zeile an deinen Pfad zur sigcheck.exe an)
=>
sigcheck.bat (pass die zweite Zeile an deinen Pfad zur sigcheck.exe an)
@echo off
set "file=C:\Windows\explorer.exe"
set "sigcheckpath=C:\Path\to\sigcheck.exe"
set "timeformat=dd.MM.yyyy HH:mm:ss"
powershell -EP Bypass -C "$c = [cultureinfo]::CurrentUICulture;[datetime]::ParseExact([regex]::match((%sigcheckpath% '%file%' -accepteula | out-string),'(?i)(?<=Signing date:\s+).*').Value.trim(),($c.DateTimeFormat.ShortTimePattern,$c.DateTimeFormat.ShortDatePattern) -join ' ',$c).toString('%timeformat%')"
pause
18.06.2022 12:51:00
Drücken Sie eine beliebige Taste . . .
Zitat von @zeddler0:
bei mir kann cultureinfo nicht gehen,
da ich mein datumsformat von (de) dd.MM.yyyy eigenmächtig zu yyyy-MM-dd geändert habe.
Doch denn das Skript liest diesen Pattern aus.bei mir kann cultureinfo nicht gehen,
da ich mein datumsformat von (de) dd.MM.yyyy eigenmächtig zu yyyy-MM-dd geändert habe.
damit ist es ein weiterer theoretischer fehlerpunkt.
Nö denn das Skript liest den selbst angepassten Pattern ja aus automatisch !ist es möglich das pattern auszulesen und anzuzeigen?
Macht das Skript bereits hiermit 😉[cultureinfo]::CurrentUICulture.DateTimeFormat.ShortTimePattern
[cultureinfo]::CurrentUICulture.DateTimeFormat.ShortDatePattern
Bitte dann auch den Thread hier zu einem Ende bringen und schließen nicht vergessen.
Merci.
So long.
Grüße Uwe
Hallo zeddler0,
es ist (so wie ich den Code/Microsoft verstehe) schnuppe, wie Du das Datumformat eingestellt hast.
Falls Du aber als Ausgabe lieber - hast, ändere doch das Skript (Zeile 4):
Ich habe, wie Colinardo, auch mal das Datumformat umgestellt. Läuft.
es ist (so wie ich den Code/Microsoft verstehe) schnuppe, wie Du das Datumformat eingestellt hast.
Falls Du aber als Ausgabe lieber - hast, ändere doch das Skript (Zeile 4):
@echo off
set "file=C:\Windows\explorer.exe"
set "sigcheckpath=C:\Path\to\sigcheck.exe"
set "timeformat=dd-MM-yyyy HH:mm:ss"
powershell -EP Bypass -C "$c = [cultureinfo]::CurrentUICulture;[datetime]::ParseExact([regex]::match((%sigcheckpath% '%file%' -accepteula | out-string),'(?i)(?<=Signing date:\s+).*').Value.trim(),($c.DateTimeFormat.ShortTimePattern,$c.DateTimeFormat.ShortDatePattern) -join ' ',$c).toString('%timeformat%')"
pause
Auch das stimmt hier überall überein.
ich würd gern die registry-kommandos in deinen code-string inegrieren
Dann mach doch, hindert dich keiner dran.[datetime]::ParseExact([regex]::match((sigcheck64 'C:\Windows\explorer.exe' -accepteula | out-string),'(?i)(?<=Signing date:\s+).*').Value.trim(),((gpv 'HKCU:\Control Panel\International' -Name sShortTime),(gpv 'HKCU:\Control Panel\International' -Name sShortDate)) -join ' ',$c).toString('dd_MM_yyyy HH-mm-ss')
Doch, das geht problemlos, es muss dann aber ein Punkt (.) oder ein und (&) vorangestellt werden damit es als ausführbarer Befehl erkannt wird.
Nennt sich dot-sourcing
Der Unterschied zwischen beiden ist das beim Dot-Sourcing aktuelle Variablen mit in das Environment des Befehls übernommen werden, wohingegen beim "&" das nicht passiert.
Einfach mal hier durcharbeiten da steht das alles wunderbar erklärt und man muss sich nicht unnötig wundern warum und wieso :
Powershell Leitfaden für Anfänger
.'C:\pfad\sigcheck.exe'
& 'C:\pfad\sigcheck.exe'
Einfach mal hier durcharbeiten da steht das alles wunderbar erklärt und man muss sich nicht unnötig wundern warum und wieso :
Powershell Leitfaden für Anfänger
Hallo zeddler0,
colinardo hat das wichtigste schon zusammengefasst. Da ich auch noch nicht sehr viel mit Powershell zu tun hatte, habe ich mir das auch zusammen suchen müssen. Da habe ich dank Dir und colinardo eine ganze Menge gelernt.
Ich habe seine zusammengefassten Befehle mal ein wenig aufgedröselt:
colinardo hat das wichtigste schon zusammengefasst. Da ich auch noch nicht sehr viel mit Powershell zu tun hatte, habe ich mir das auch zusammen suchen müssen. Da habe ich dank Dir und colinardo eine ganze Menge gelernt.
Ich habe seine zusammengefassten Befehle mal ein wenig aufgedröselt:
$sigcheckpath='\\live.sysinternals.com\tools\sigcheck64.exe'
$file='C:\Windows\explorer.exe'
$timeformat='yyyy_MM_dd hh=mm=ss'
$sigcheckresult = & $sigcheckpath $file -accepteula | out-string
$sigcheckresult
$regexresult=[regex]::match($sigcheckresult,'(?i)(?<=Signing date:\s+).*').Value.trim()
$regexresult
$result=[datetime]::ParseExact($regexresult,($c.DateTimeFormat.ShortTimePattern,$c.DateTimeFormat.ShortDatePattern) -join ' ',$c).toString($timeformat)
$result