Voici un extrait d'un message paru sur Bugtraq, à propos de la date de
compilation incluse dans les fichiers PE. Grosso mod, certains comilateurs
mettent dans l'en-tête la date de compilation, et le programme ci-joint la
récupère. Pour info, VC++ remplit la champ "date".
Pour les spécialistes : quels compilos font (ou pas) cela ?
You can easily differentiate between Sobig versions by
reading the PE timestamp field. Below you can find a short Perl script
I wrote to automate the process of retrieving the PE timestamp from an
executable. Not every compiler sets this field with the compile date,
but the one the Sobig author uses does (VC++).
If your pif sample was not compiled on Sun Aug 17 12:54:53 2003 then you
have a different variant.
[cut]
#!/usr/bin/perl
# read-pe-timestamp.pl
# by Joe Stewart <jstewart@lurhq.com>
# usage: ./read-pe-timestamp.pl <PE file>
# tested on Linux; Win32 users may need to add binmode()
use strict;
my $filename = $ARGV[0];
my $now = time;
my $old = 800000000;
die "Usage: $0 <PE file>\n" unless $filename;
open(IN, $filename) or die "Couldn't open $filename : $!\n";
for (0..255) {
my $dword;
read(IN, $dword, 4);
next unless $dword eq "PE\x00\x00";
read(IN, $dword, 4);
read(IN, $dword, 4);
my $t = unpack("N*", reverse($dword));
my $time = localtime($t);
print "$filename was compiled on $time\n";
print "(Probably erroneous)\n" if ($t >= $now || $t <= $old);
close IN;
exit;
}
close IN;
print "Could not find PE header in $filename\.\n";
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Nicob
On Fri, 26 Sep 2003 16:29:21 +0200, Nicob wrote:
Voici un extrait d'un message paru sur Bugtraq, à propos de la date de compilation incluse dans les fichiers PE. Grosso mod, certains comilateurs mettent dans l'en-tête la date de compilation, et le programme ci-joint la récupère. Pour info, VC++ remplit la champ "date".
Pour les spécialistes : quels compilos font (ou pas) cela ?
Sur plusieurs programmes écrits en Delphi/Borland, j'ai ça : "XYZ.exe was compiled on Sat Jun 20 00:22:17 1992 (Probably erroneous)"
Donc une date fixe ...
Nicob
On Fri, 26 Sep 2003 16:29:21 +0200, Nicob wrote:
Voici un extrait d'un message paru sur Bugtraq, à propos de la date de
compilation incluse dans les fichiers PE. Grosso mod, certains
comilateurs mettent dans l'en-tête la date de compilation, et le
programme ci-joint la récupère. Pour info, VC++ remplit la champ
"date".
Pour les spécialistes : quels compilos font (ou pas) cela ?
Sur plusieurs programmes écrits en Delphi/Borland, j'ai ça : "XYZ.exe was
compiled on Sat Jun 20 00:22:17 1992 (Probably erroneous)"
Voici un extrait d'un message paru sur Bugtraq, à propos de la date de compilation incluse dans les fichiers PE. Grosso mod, certains comilateurs mettent dans l'en-tête la date de compilation, et le programme ci-joint la récupère. Pour info, VC++ remplit la champ "date".
Pour les spécialistes : quels compilos font (ou pas) cela ?
Sur plusieurs programmes écrits en Delphi/Borland, j'ai ça : "XYZ.exe was compiled on Sat Jun 20 00:22:17 1992 (Probably erroneous)"
Donc une date fixe ...
Nicob
Arnold McDonald \(AMcD\)
Salut Nicob !
Heu, je suis ultra à la bourre là, je répondrai en détail ce soir. Cela dit, les dates de link, les versions de compilos, etc. dans le PE, cela n'a aucun intérêt, ça se change en 5 secondes. J'ai déjà reçu des vers avec date de link inférieure à l'original ;o) !
Bref !
Bon, j'y go là, a+
-- AMcD
http://arnold.mcdonald.free.fr/
Salut Nicob !
Heu, je suis ultra à la bourre là, je répondrai en détail ce soir. Cela dit,
les dates de link, les versions de compilos, etc. dans le PE, cela n'a aucun
intérêt, ça se change en 5 secondes. J'ai déjà reçu des vers avec date de
link inférieure à l'original ;o) !
Heu, je suis ultra à la bourre là, je répondrai en détail ce soir. Cela dit, les dates de link, les versions de compilos, etc. dans le PE, cela n'a aucun intérêt, ça se change en 5 secondes. J'ai déjà reçu des vers avec date de link inférieure à l'original ;o) !
Bref !
Bon, j'y go là, a+
-- AMcD
http://arnold.mcdonald.free.fr/
Frederic Bonroy
Nicob wrote:
Voici un extrait d'un message paru sur Bugtraq, à propos de la date de compilation incluse dans les fichiers PE. Grosso mod, certains comilateurs mettent dans l'en-tête la date de compilation, et le programme ci-joint la récupère. Pour info, VC++ remplit la champ "date".
Pour les spécialistes : quels compilos font (ou pas) cela ?
Borland C++ 5.5 met l'heure locale, chez moi Fri Sep 26 17:27:08 2003
Sinon, mes échantillons de Sobig:
Sobig.A: 3E1CFD59 : Thu Jan 09 05:40:57 2003 Sobig.B: 3EC50EFB : Fri May 16 18:16:59 2003 Sobig.C: 3ED79344 : Fri May 30 19:22:12 2003 Sobig.D: 3EEF5648 : Tue Jun 17 19:56:24 2003 Sobig.E: 3EF89A91 : Tue Jun 24 20:38:09 2003 Sobig.F: 3F3FB35D : Sun Aug 17 18:54:53 2003 (testé sur deux fichiers)
Pour Sobig.F, on notera la différence d'exactement 6 heures avec l'heure indiquée dans le message Bugtraq. J'ai utilisé Tdump de Borland pour l'affichage, je ne sais pas s'il convertit en heure locale.
Nicob wrote:
Voici un extrait d'un message paru sur Bugtraq, à propos de la date de
compilation incluse dans les fichiers PE. Grosso mod, certains comilateurs
mettent dans l'en-tête la date de compilation, et le programme ci-joint la
récupère. Pour info, VC++ remplit la champ "date".
Pour les spécialistes : quels compilos font (ou pas) cela ?
Borland C++ 5.5 met l'heure locale, chez moi Fri Sep 26 17:27:08 2003
Sinon, mes échantillons de Sobig:
Sobig.A: 3E1CFD59 : Thu Jan 09 05:40:57 2003
Sobig.B: 3EC50EFB : Fri May 16 18:16:59 2003
Sobig.C: 3ED79344 : Fri May 30 19:22:12 2003
Sobig.D: 3EEF5648 : Tue Jun 17 19:56:24 2003
Sobig.E: 3EF89A91 : Tue Jun 24 20:38:09 2003
Sobig.F: 3F3FB35D : Sun Aug 17 18:54:53 2003 (testé sur deux fichiers)
Pour Sobig.F, on notera la différence d'exactement 6 heures avec
l'heure indiquée dans le message Bugtraq. J'ai utilisé Tdump de
Borland pour l'affichage, je ne sais pas s'il convertit en heure
locale.
Voici un extrait d'un message paru sur Bugtraq, à propos de la date de compilation incluse dans les fichiers PE. Grosso mod, certains comilateurs mettent dans l'en-tête la date de compilation, et le programme ci-joint la récupère. Pour info, VC++ remplit la champ "date".
Pour les spécialistes : quels compilos font (ou pas) cela ?
Borland C++ 5.5 met l'heure locale, chez moi Fri Sep 26 17:27:08 2003
Sinon, mes échantillons de Sobig:
Sobig.A: 3E1CFD59 : Thu Jan 09 05:40:57 2003 Sobig.B: 3EC50EFB : Fri May 16 18:16:59 2003 Sobig.C: 3ED79344 : Fri May 30 19:22:12 2003 Sobig.D: 3EEF5648 : Tue Jun 17 19:56:24 2003 Sobig.E: 3EF89A91 : Tue Jun 24 20:38:09 2003 Sobig.F: 3F3FB35D : Sun Aug 17 18:54:53 2003 (testé sur deux fichiers)
Pour Sobig.F, on notera la différence d'exactement 6 heures avec l'heure indiquée dans le message Bugtraq. J'ai utilisé Tdump de Borland pour l'affichage, je ne sais pas s'il convertit en heure locale.
Arnold McDonald \(AMcD\)
Bon, me re !
Alors.
Tout PE commence par une section MS-DOS Header, suit la signature PE, l' IMAGE_FILE_HEADER, l'IMAGE_OPTIONAL_HEADER, etc.
Le champ TimeDateStamp est situé dans le header IMAGE_FILE_HEADER. On a :
MS-DOS Header Signature PE IMAGE_FILE_HEADER Etc.
La signature PE fait 4 octets et contient la chaîne « PE ». L' IMAGE_FILE_HEADER est constitué comme suit :
Offset - Taille - Champ
0 2 Machine 2 2 NumberOfSection 4 4 TimeDateStamp Etc.
TimeDateStamp fait 4 octets et représente le nombre de secondes écoulées depuis le 1er janvier 1970 (heure GMT). Tiens, puisqu'on parlait de dates récemment ici, amusons-nous un peu :o). Par exemple, si on a un TimeDateStamp valant t = 1060600874 :
1 an = 365 x 24 x 60 x 60 = 31536000 secondes
t / 31536000 = 33.63 -> 33
t - 33 x 31536000 = 19912874
1 jour = 24 x 60 x 60 = 86400 secondes
t / 86400 = 230.47 -> 230
t - 230 x 86400 = 40874
1 heure = 60 x 60 = 3600 secondes
t / 3600 = 11.35 -> 11
t - 11 x 3600 = 1274
1 minute = 60 secondes
t / 60 = 21.23 -> 21
1 seconde = heu, une seconde
t - 21 x 60 = 14
On a donc 33 ans, 230 jours, 11 heures, 21 minutes et 14 secondes.
De 1970 à 2003, 8 années bissextiles (72, 76, 80, 84, 88, 92, 96, 2000) : restent 222 jours.
Janvier 2003 - 31 Février 2003 - 28 / 59 Mars 2003 - 31 / 90 Avril 2003 - 30 / 120 Mai 2003 - 31 / 151 Juin 2003 - 30 / 181 Juillet 2003 - 31 / 212 Août 2003 - 10 / 222
Nous voilà donc rendu au 10 Août 2003 à 11h21'14 ? Pas tout à fait ! En fait, la date de référence est prise à partir du 01/01/1970 à 01h00'00, donc, il nous faut rajouter 1 jour et 1 heure :o). Donc, un TimeDateStamp de 1060600874 correspond au 11 Août 2003 à 12h21'14.
Voilà, voilà... Pour ceux qui stressent à l'idée de calculer des dates à la main, précisons qu'il y a la fonction (je parle de compilos Microsoft) ctime() :o).
En C, on peut accéder facilement au champ TimeDateStamp. Note que l'exemple en Perl est plutôt « amateur », rien n'empêche une suite « PE » de se trouver avant le bon endroit. Par exemple, on peut rajouter des données additionnelles dans le DOS header (si, si, c'est trop marrant de faire planter un script Bugtraq :o)).
La bonne technique est de lire le champ e_lfanew dans le DOS header ; il indique l'offset du PE header. Bon, à 100 à l'heure (j'ai pas que ça à faire non plus là !):
if ( INVALID_HANDLE_VALUE != hFile ) { ReadFile(hFile,&idh,sizeof(idh),&dw,NULL);
SetFilePointer(hFile,idh.e_lfanew,0,FILE_BEGIN);
ReadFile(hFile,&Signature,4,&dw,NULL);
ReadFile(hFile,&ifh,sizeof(ifh),&dw,NULL);
CloseHandle(hFile);
t = ifh.TimeDateStamp;
printf("Time: %s",ctime(&t));
return 0; } else return 2;
} else return 1; }
Oui, je sais, on peut faire nettement plus court, mais bon, quid de la pédagogie :o) ?
Les compilos remplissent-ils ce champ ? Ceux de la liste qui suit, oui (j'ai testé) :
Visual C++ 5.0 Visual C++ 6.0 Visual C++ 7.0 (.Net) Visual Basic 6.0
Mais l'intérêt ? Il est évident que se baser là-dessus pour dater un code PE malveillant est vraiment aléatoire ! Il faut une seconde pour modifier cette valeur dans l'en-tête PE de l'exécutable. Et, comme dit plus haut, j'ai déjà vu des variantes de virus avec cette date inférieure à celle du code original ! Et puis bon, si j'étais auteur de virus, c'est bien la première chose que je truquerai !
Bref.
-- AMcD
http://arnold.mcdonald.free.fr/
Bon, me re !
Alors.
Tout PE commence par une section MS-DOS Header, suit la signature PE, l'
IMAGE_FILE_HEADER, l'IMAGE_OPTIONAL_HEADER, etc.
Le champ TimeDateStamp est situé dans le header IMAGE_FILE_HEADER. On a :
MS-DOS Header
Signature PE
IMAGE_FILE_HEADER
Etc.
La signature PE fait 4 octets et contient la chaîne « PE ». L'
IMAGE_FILE_HEADER est constitué comme suit :
Offset - Taille - Champ
0 2 Machine
2 2 NumberOfSection
4 4 TimeDateStamp
Etc.
TimeDateStamp fait 4 octets et représente le nombre de secondes écoulées
depuis le 1er janvier 1970 (heure GMT). Tiens, puisqu'on parlait de dates
récemment ici, amusons-nous un peu :o). Par exemple, si on a un
TimeDateStamp valant t = 1060600874 :
1 an = 365 x 24 x 60 x 60 = 31536000 secondes
t / 31536000 = 33.63 -> 33
t - 33 x 31536000 = 19912874
1 jour = 24 x 60 x 60 = 86400 secondes
t / 86400 = 230.47 -> 230
t - 230 x 86400 = 40874
1 heure = 60 x 60 = 3600 secondes
t / 3600 = 11.35 -> 11
t - 11 x 3600 = 1274
1 minute = 60 secondes
t / 60 = 21.23 -> 21
1 seconde = heu, une seconde
t - 21 x 60 = 14
On a donc 33 ans, 230 jours, 11 heures, 21 minutes et 14 secondes.
De 1970 à 2003, 8 années bissextiles (72, 76, 80, 84, 88, 92, 96, 2000) :
restent 222 jours.
Janvier 2003 - 31
Février 2003 - 28 / 59
Mars 2003 - 31 / 90
Avril 2003 - 30 / 120
Mai 2003 - 31 / 151
Juin 2003 - 30 / 181
Juillet 2003 - 31 / 212
Août 2003 - 10 / 222
Nous voilà donc rendu au 10 Août 2003 à 11h21'14 ? Pas tout à fait ! En
fait, la date de référence est prise à partir du 01/01/1970 à 01h00'00,
donc, il nous faut rajouter 1 jour et 1 heure :o). Donc, un TimeDateStamp de
1060600874 correspond au 11 Août 2003 à 12h21'14.
Voilà, voilà... Pour ceux qui stressent à l'idée de calculer des dates à la
main, précisons qu'il y a la fonction (je parle de compilos Microsoft)
ctime() :o).
En C, on peut accéder facilement au champ TimeDateStamp. Note que l'exemple
en Perl est plutôt « amateur », rien n'empêche une suite « PE » de se
trouver avant le bon endroit. Par exemple, on peut rajouter des données
additionnelles dans le DOS header (si, si, c'est trop marrant de faire
planter un script Bugtraq :o)).
La bonne technique est de lire le champ e_lfanew dans le DOS header ; il
indique l'offset du PE header. Bon, à 100 à l'heure (j'ai pas que ça à faire
non plus là !):
if ( INVALID_HANDLE_VALUE != hFile )
{
ReadFile(hFile,&idh,sizeof(idh),&dw,NULL);
SetFilePointer(hFile,idh.e_lfanew,0,FILE_BEGIN);
ReadFile(hFile,&Signature,4,&dw,NULL);
ReadFile(hFile,&ifh,sizeof(ifh),&dw,NULL);
CloseHandle(hFile);
t = ifh.TimeDateStamp;
printf("Time: %s",ctime(&t));
return 0;
}
else return 2;
}
else return 1;
}
Oui, je sais, on peut faire nettement plus court, mais bon, quid de la
pédagogie :o) ?
Les compilos remplissent-ils ce champ ? Ceux de la liste qui suit, oui (j'ai
testé) :
Visual C++ 5.0
Visual C++ 6.0
Visual C++ 7.0 (.Net)
Visual Basic 6.0
Mais l'intérêt ? Il est évident que se baser là-dessus pour dater un code PE
malveillant est vraiment aléatoire ! Il faut une seconde pour modifier cette
valeur dans l'en-tête PE de l'exécutable. Et, comme dit plus haut, j'ai déjà
vu des variantes de virus avec cette date inférieure à celle du code
original ! Et puis bon, si j'étais auteur de virus, c'est bien la première
chose que je truquerai !
Tout PE commence par une section MS-DOS Header, suit la signature PE, l' IMAGE_FILE_HEADER, l'IMAGE_OPTIONAL_HEADER, etc.
Le champ TimeDateStamp est situé dans le header IMAGE_FILE_HEADER. On a :
MS-DOS Header Signature PE IMAGE_FILE_HEADER Etc.
La signature PE fait 4 octets et contient la chaîne « PE ». L' IMAGE_FILE_HEADER est constitué comme suit :
Offset - Taille - Champ
0 2 Machine 2 2 NumberOfSection 4 4 TimeDateStamp Etc.
TimeDateStamp fait 4 octets et représente le nombre de secondes écoulées depuis le 1er janvier 1970 (heure GMT). Tiens, puisqu'on parlait de dates récemment ici, amusons-nous un peu :o). Par exemple, si on a un TimeDateStamp valant t = 1060600874 :
1 an = 365 x 24 x 60 x 60 = 31536000 secondes
t / 31536000 = 33.63 -> 33
t - 33 x 31536000 = 19912874
1 jour = 24 x 60 x 60 = 86400 secondes
t / 86400 = 230.47 -> 230
t - 230 x 86400 = 40874
1 heure = 60 x 60 = 3600 secondes
t / 3600 = 11.35 -> 11
t - 11 x 3600 = 1274
1 minute = 60 secondes
t / 60 = 21.23 -> 21
1 seconde = heu, une seconde
t - 21 x 60 = 14
On a donc 33 ans, 230 jours, 11 heures, 21 minutes et 14 secondes.
De 1970 à 2003, 8 années bissextiles (72, 76, 80, 84, 88, 92, 96, 2000) : restent 222 jours.
Janvier 2003 - 31 Février 2003 - 28 / 59 Mars 2003 - 31 / 90 Avril 2003 - 30 / 120 Mai 2003 - 31 / 151 Juin 2003 - 30 / 181 Juillet 2003 - 31 / 212 Août 2003 - 10 / 222
Nous voilà donc rendu au 10 Août 2003 à 11h21'14 ? Pas tout à fait ! En fait, la date de référence est prise à partir du 01/01/1970 à 01h00'00, donc, il nous faut rajouter 1 jour et 1 heure :o). Donc, un TimeDateStamp de 1060600874 correspond au 11 Août 2003 à 12h21'14.
Voilà, voilà... Pour ceux qui stressent à l'idée de calculer des dates à la main, précisons qu'il y a la fonction (je parle de compilos Microsoft) ctime() :o).
En C, on peut accéder facilement au champ TimeDateStamp. Note que l'exemple en Perl est plutôt « amateur », rien n'empêche une suite « PE » de se trouver avant le bon endroit. Par exemple, on peut rajouter des données additionnelles dans le DOS header (si, si, c'est trop marrant de faire planter un script Bugtraq :o)).
La bonne technique est de lire le champ e_lfanew dans le DOS header ; il indique l'offset du PE header. Bon, à 100 à l'heure (j'ai pas que ça à faire non plus là !):
if ( INVALID_HANDLE_VALUE != hFile ) { ReadFile(hFile,&idh,sizeof(idh),&dw,NULL);
SetFilePointer(hFile,idh.e_lfanew,0,FILE_BEGIN);
ReadFile(hFile,&Signature,4,&dw,NULL);
ReadFile(hFile,&ifh,sizeof(ifh),&dw,NULL);
CloseHandle(hFile);
t = ifh.TimeDateStamp;
printf("Time: %s",ctime(&t));
return 0; } else return 2;
} else return 1; }
Oui, je sais, on peut faire nettement plus court, mais bon, quid de la pédagogie :o) ?
Les compilos remplissent-ils ce champ ? Ceux de la liste qui suit, oui (j'ai testé) :
Visual C++ 5.0 Visual C++ 6.0 Visual C++ 7.0 (.Net) Visual Basic 6.0
Mais l'intérêt ? Il est évident que se baser là-dessus pour dater un code PE malveillant est vraiment aléatoire ! Il faut une seconde pour modifier cette valeur dans l'en-tête PE de l'exécutable. Et, comme dit plus haut, j'ai déjà vu des variantes de virus avec cette date inférieure à celle du code original ! Et puis bon, si j'étais auteur de virus, c'est bien la première chose que je truquerai !
Bref.
-- AMcD
http://arnold.mcdonald.free.fr/
Frederic Bonroy
"Arnold McDonald (AMcD)" wrote:
Mais l'intérêt ? Il est évident que se baser là-dessus pour dater un code PE malveillant est vraiment aléatoire ! Il faut une seconde pour modifier cette valeur dans l'en-tête PE de l'exécutable.
Et surtout la valeur n'est pas toujours correcte, par exemple dans le cas des exécutables produits par Delphi.
Et puis bon, si j'étais auteur de virus, c'est bien la première chose que je truquerai !
Quel intérêt pratique cela aurait-il? Aucun.
Et puis de toute façon beaucoup d'auteurs de virus en sont incapables.
"Arnold McDonald (AMcD)" wrote:
Mais l'intérêt ? Il est évident que se baser là-dessus pour dater un code PE
malveillant est vraiment aléatoire ! Il faut une seconde pour modifier cette
valeur dans l'en-tête PE de l'exécutable.
Et surtout la valeur n'est pas toujours correcte, par exemple dans
le cas des exécutables produits par Delphi.
Et puis bon, si j'étais auteur de virus, c'est bien la première
chose que je truquerai !
Quel intérêt pratique cela aurait-il? Aucun.
Et puis de toute façon beaucoup d'auteurs de virus en sont incapables.
Mais l'intérêt ? Il est évident que se baser là-dessus pour dater un code PE malveillant est vraiment aléatoire ! Il faut une seconde pour modifier cette valeur dans l'en-tête PE de l'exécutable.
Et surtout la valeur n'est pas toujours correcte, par exemple dans le cas des exécutables produits par Delphi.
Et puis bon, si j'étais auteur de virus, c'est bien la première chose que je truquerai !
Quel intérêt pratique cela aurait-il? Aucun.
Et puis de toute façon beaucoup d'auteurs de virus en sont incapables.
Arnold McDonald \(AMcD\)
Frederic Bonroy wrote:
Et puis bon, si j'étais auteur de virus, c'est bien la première chose que je truquerai !
Quel intérêt pratique cela aurait-il? Aucun.
Ben dissimuler la date de link...
Et puis de toute façon beaucoup d'auteurs de virus en sont incapables.
Là, on va être d'accord ;o).
-- AMcD
http://arnold.mcdonald.free.fr/
Frederic Bonroy wrote:
Et puis bon, si j'étais auteur de virus, c'est bien la première
chose que je truquerai !
Quel intérêt pratique cela aurait-il? Aucun.
Ben dissimuler la date de link...
Et puis de toute façon beaucoup d'auteurs de virus en sont incapables.
Dissimuler la date de création du virus. Ou, plus fûté, faire croire qu'il vient d'ailleurs : si tu es un des premiers infecté avec un fichier datant de deux fuseaux horaires te précédant, tu vas douter que le coupable est dans le tien (de fuseau).
-- AMcD
http://arnold.mcdonald.free.fr/
Frederic Bonroy wrote:
Oui, mais quel intérêt cela aurait-il...?
Dissimuler la date de création du virus. Ou, plus fûté, faire croire qu'il
vient d'ailleurs : si tu es un des premiers infecté avec un fichier datant
de deux fuseaux horaires te précédant, tu vas douter que le coupable est
dans le tien (de fuseau).
Dissimuler la date de création du virus. Ou, plus fûté, faire croire qu'il vient d'ailleurs : si tu es un des premiers infecté avec un fichier datant de deux fuseaux horaires te précédant, tu vas douter que le coupable est dans le tien (de fuseau).