извлечение хеша из CAT файлов

Тема в разделе "WASM.CRYPTO", создана пользователем acpi, 26 авг 2008.

  1. acpi

    acpi New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2008
    Сообщения:
    15
    интересуюсь возможностью извлечь sha1 хеши из \windows\system32\catroot\{xxxx}\*.CAT файлов. Это возможно сделать прямым разбором CAT-файла, без использования CryptoAPI или внешних программ (sigcheck, chktrust, sigverif итд) ?

    информация которую удалось найти:

    http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt

    http://blog.didierstevens.com/2008/01/11/the-case-of-the-missing-digital-signatures-tab/

    http://msdn.microsoft.com/en-us/library/ms537359(VS.85).aspx
     
  2. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    Это обычный ASN1-файл в формате DER.
    C:\OpenSSL\bin\openssl.exe asn1parse -inform DER -in admt.cat -dump >s
    Код (Text):
    1.     0:d=0  hl=4 l=23514 cons: SEQUENCE          
    2.     4:d=1  hl=2 l=   9 prim: OBJECT            :pkcs7-signedData
    3.    15:d=1  hl=4 l=23499 cons: cont [ 0 ]        
    4.    19:d=2  hl=4 l=23495 cons: SEQUENCE          
    5.    23:d=3  hl=2 l=   1 prim: INTEGER           :01
    6.    26:d=3  hl=2 l=  11 cons: SET              
    7.    28:d=4  hl=2 l=   9 cons: SEQUENCE          
    8.    30:d=5  hl=2 l=   5 prim: OBJECT            :sha1
    9.    37:d=5  hl=2 l=   0 prim: NULL              
    10.    39:d=3  hl=4 l=14076 cons: SEQUENCE          
    11.    43:d=4  hl=2 l=   9 prim: OBJECT            :1.3.6.1.4.1.311.10.1
    12.    54:d=4  hl=4 l=14061 cons: cont [ 0 ]        
    13.    58:d=5  hl=4 l=14057 cons: SEQUENCE          
    14.    62:d=6  hl=2 l=  12 cons: SEQUENCE          
    15.    64:d=7  hl=2 l=  10 prim: OBJECT            :1.3.6.1.4.1.311.12.1.1
    16.    76:d=6  hl=2 l=  16 prim: OCTET STRING      
    17.       0000 - 42 32 d2 f1 ac 84 d5 4f-96 29 10 7a 79 5f d8 41   B2.....O.).zy_.A
    18.    94:d=6  hl=2 l=  13 prim: UTCTIME           :070217141518Z
    19.   109:d=6  hl=2 l=  14 cons: SEQUENCE          
    20.   111:d=7  hl=2 l=  10 prim: OBJECT            :1.3.6.1.4.1.311.12.1.2
    21.   123:d=7  hl=2 l=   0 prim: NULL              
    22.   125:d=6  hl=4 l=13934 cons: SEQUENCE          
    23.   129:d=7  hl=4 l= 294 cons: SEQUENCE          
    24.   133:d=8  hl=2 l=  82 prim: OCTET STRING      
    25.       0000 - 30 00 36 00 37 00 44 00-45 00 41 00 44 00 43 00   0.6.7.D.E.A.D.C.
    26.       0010 - 35 00 35 00 34 00 42 00-34 00 30 00 37 00 34 00   5.5.4.B.4.0.7.4.
    27.       0020 - 42 00 30 00 41 00 36 00-44 00 43 00 42 00 35 00   B.0.A.6.D.C.B.5.
    28.       0030 - 44 00 39 00 46 00 45 00-31 00 39 00 37 00 30 00   D.9.F.E.1.9.7.0.
    29.       0040 - 38 00 41 00 41 00 41 00-30 00 38 00 36 00 35      8.A.A.A.0.8.6.5
    30.       0052 - <SPACES/NULS>
    31.   217:d=8  hl=3 l= 207 cons: SET              
    32.  
    33. <skipped>
    34.  
    35. 22971:d=5  hl=4 l= 543 cons: cont [ 1 ]        
    36. 22975:d=6  hl=4 l= 539 cons: SEQUENCE          
    37. 22979:d=7  hl=2 l=   9 prim: OBJECT            :countersignature
    38. 22990:d=7  hl=4 l= 524 cons: SET              
    39. 22994:d=8  hl=4 l= 520 cons: SEQUENCE          
    40. 22998:d=9  hl=2 l=   1 prim: INTEGER           :01
    41. 23001:d=9  hl=3 l= 135 cons: SEQUENCE          
    42. 23004:d=10 hl=2 l= 121 cons: SEQUENCE          
    43. 23006:d=11 hl=2 l=  11 cons: SET              
    44. 23008:d=12 hl=2 l=   9 cons: SEQUENCE          
    45. 23010:d=13 hl=2 l=   3 prim: OBJECT            :countryName
    46. 23015:d=13 hl=2 l=   2 prim: PRINTABLESTRING   :US
    47. 23019:d=11 hl=2 l=  19 cons: SET              
    48. 23021:d=12 hl=2 l=  17 cons: SEQUENCE          
    49. 23023:d=13 hl=2 l=   3 prim: OBJECT            :stateOrProvinceName
    50. 23028:d=13 hl=2 l=  10 prim: PRINTABLESTRING   :Washington
    51. 23040:d=11 hl=2 l=  16 cons: SET              
    52. 23042:d=12 hl=2 l=  14 cons: SEQUENCE          
    53. 23044:d=13 hl=2 l=   3 prim: OBJECT            :localityName
    54. 23049:d=13 hl=2 l=   7 prim: PRINTABLESTRING   :Redmond
    55. 23058:d=11 hl=2 l=  30 cons: SET              
    56. 23060:d=12 hl=2 l=  28 cons: SEQUENCE          
    57. 23062:d=13 hl=2 l=   3 prim: OBJECT            :organizationName
    58. 23067:d=13 hl=2 l=  21 prim: PRINTABLESTRING   :Microsoft Corporation
    59. 23090:d=11 hl=2 l=  35 cons: SET              
    60. 23092:d=12 hl=2 l=  33 cons: SEQUENCE          
    61. 23094:d=13 hl=2 l=   3 prim: OBJECT            :commonName
    62. 23099:d=13 hl=2 l=  26 prim: PRINTABLESTRING   :Microsoft Timestamping PCA
    63. 23127:d=10 hl=2 l=  10 prim: INTEGER           :614752BA000000000004
    64. 23139:d=9  hl=2 l=   7 cons: SEQUENCE          
    65. 23141:d=10 hl=2 l=   5 prim: OBJECT            :sha1
    66. 23148:d=9  hl=2 l=  93 cons: cont [ 0 ]        
    67. 23150:d=10 hl=2 l=  24 cons: SEQUENCE          
    68. 23152:d=11 hl=2 l=   9 prim: OBJECT            :contentType
    69. 23163:d=11 hl=2 l=  11 cons: SET              
    70. 23165:d=12 hl=2 l=   9 prim: OBJECT            :pkcs7-data
    71. 23176:d=10 hl=2 l=  28 cons: SEQUENCE          
    72. 23178:d=11 hl=2 l=   9 prim: OBJECT            :signingTime
    73. 23189:d=11 hl=2 l=  15 cons: SET              
    74. 23191:d=12 hl=2 l=  13 prim: UTCTIME           :070218085632Z
    75. 23206:d=10 hl=2 l=  35 cons: SEQUENCE          
    76. 23208:d=11 hl=2 l=   9 prim: OBJECT            :messageDigest
    77. 23219:d=11 hl=2 l=  22 cons: SET              
    78. 23221:d=12 hl=2 l=  20 prim: OCTET STRING      
    79.       0000 - dd 6f d8 80 ca 0d d2 d2-27 ef ed 9d fa d3 f7 8a   .o......'.......
    80.       0010 - bd 12 74 3c                                       ..t<
    81. 23243:d=9  hl=2 l=  13 cons: SEQUENCE          
    82. 23245:d=10 hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption
    83. 23256:d=10 hl=2 l=   0 prim: NULL              
    84. 23258:d=9  hl=4 l= 256 prim: OCTET STRING      
    85.       0000 - 5e 27 6e 30 ea fe 16 fc-63 94 eb 08 9b b8 e8 16   ^'n0....c.......
    86.       0010 - f7 37 3d c1 e3 dc 69 76-52 2f 56 94 7d f4 82 44   .7=...ivR/V.}..D
    87.       0020 - 3d 19 a6 5b 7e 07 69 81-7c 25 ac 68 72 01 4f 38   =..[~.i.|%.hr.O8
    88.       0030 - 05 08 1c 67 a8 45 07 dd-57 97 d7 8b 79 66 f0 27   ...g.E..W...yf.'
    89.       0040 - e0 7e 76 14 6a 7b 60 99-d1 ad f6 c5 79 d0 61 85   .~v.j{`.....y.a.
    90.       0050 - 44 2a eb a6 3e 75 6b 03-e8 70 4a 1c cb a7 78 8d   D*..>uk..pJ...x.
    91.       0060 - 73 05 f6 f7 f3 a1 b0 47-8e 2f 89 b3 f1 9f 9a 26   s......G./.....&
    92.       0070 - 11 6f 0b f2 9a a4 be 23-2e 7c ac 30 b8 7b b5 f4   .o.....#.|.0.{..
    93.       0080 - 22 3c c8 c0 cc d5 17 87-2f f2 ce 13 ba 94 ae ee   "<....../.......
    94.       0090 - 2d 64 64 aa b7 8e 70 8f-9d c5 8a de ca 06 a8 6f   -dd...p........o
    95.       00a0 - bc 22 c9 74 23 4a 03 14-f6 5a 70 6e 4d b1 1a fb   .".t#J...ZpnM...
    96.       00b0 - 48 2d d2 0c 7c 72 9e 25-41 b7 d6 ae f5 59 b2 8c   H-..|r.%A....Y..
    97.       00c0 - 2d 00 fd dc 39 a9 09 26-df e4 92 51 4b 16 74 af   -...9..&...QK.t.
    98.       00d0 - 19 c3 93 08 c3 a3 89 7b-22 aa d9 87 dc 36 9b f1   .......{"....6..
    99.       00e0 - 85 01 62 55 7f 7f 79 e2-24 24 d1 49 c3 d0 8a 2f   ..bU..y.$$.I.../
    100.       00f0 - 2c a9 a2 d8 cc 0b 91 45-48 53 fb 5b 23 81 c0 f1   ,......EHS.[#...
     
  3. acpi

    acpi New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2008
    Сообщения:
    15
    Спасибо reverser, дампит прекрасно!

    только хеши из этого CAT не совпадают ни с одним подсчитанным "в лоб", например с sigcheck.exe -h

    :-(

    например хеш acpi.sys должнен находится в NT5.CAT, но такого хеша там нет
     
  4. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    Похоже хэш, вычисляемый sigcheck, не подходит для .cat файлов. Утилитка отсюда даёт подходящий хэш.
    Из Google Groups:
    "A C14n pre-processing is done of the files before being hashed,
    this removes the variable (per machine) bits of the data
    so that the signatures can validate accross machines; remember some
    bits in the pe header get modified periodically we wouldnt want the
    signature to get invalidated.

    Ones that are static do not have c14n done against them
    which is why some match. "

    В доке по PE упоминается только пропускание полей Checksum и Certificate Table, но похоже этого недостаточно.
     
  5. acpi

    acpi New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2008
    Сообщения:
    15
    Ok, спасибо reverser

    Проблема в том, что необходимо сверить хеши без помощи CryptoAPI, а без знания алгоритма вычисления (какие поля отбрасывать) это невозможно.

    В каком направлении мне двигаться? Пробовать вырезать поля из хидера и считать хеш до тех пор пока не совпадет? Поля Checksum, OEM Identifier/OEM Information, Machine, Time/Date Stamp, Characteristics, что-нибудь из optional header?

    - что он хочет этим сказать, что переносе на другую машину меняется бинарник? Это для меня новая информация. Особенно слово "periodically" - интересно.
     
  6. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    Посмотрел внутренности wintrust.dll. С виду вроде всё по спецификации - хэшится весь файл за исключением Checksum и записи Certificate Table в Directory.
    Код (Text):
    1. int __stdcall MapIt(HANDLE hFile, struct _LOADED_IMAGE *loadedImage)
    2. {
    3.   HANDLE _mapping; // eax@1
    4.   void *v3; // ebx@1
    5.   struct _LOADED_IMAGE *_loadedImage; // esi@2
    6.   int result; // eax@4
    7.   DWORD _filesize; // eax@2
    8.   char v7; // zf@2
    9.  
    10.   _mapping = CreateFileMappingA(hFile, 0, 2u, 0, 0, 0);
    11.   v3 = _mapping;
    12.   if ( _mapping )
    13.   {
    14.     _loadedImage = loadedImage;
    15.     loadedImage->MappedAddress = (PUCHAR)MapViewOfFile(_mapping, 4u, 0, 0, 0);
    16.     CloseHandle(v3);
    17.     _filesize = GetFileSize(hFile, 0);
    18.     v7 = _loadedImage->MappedAddress == 0;
    19.     _loadedImage->SizeOfImage = _filesize;
    20.     if ( !v7 )
    21.     {
    22.       if ( CalculateImagePtrs(_loadedImage) )
    23.       {
    24.         _loadedImage->hFile = (HANDLE)-1;
    25.         return 1;
    26.       }
    27.       UnmapViewOfFile(_loadedImage->MappedAddress);
    28.     }
    29.     result = 0;
    30.   }
    31.   else
    32.   {
    33.     result = 0;
    34.   }
    35.   return result;
    36. }
    37.  
    38. bool __stdcall imagehack_AuImageGetDigestStream(HANDLE hFile, int a2, int hashproc, int hashparam)
    39. {
    40.   WORD v4; // ax@2
    41.   PIMAGE_NT_HEADERS v5; // esi@4
    42.   DWORD *_pSignatureDirectoryRecord; // edi@6
    43.   DWORD v7; // ecx@7
    44.   int sig_len; // ebx@7
    45.   DWORD sig_offset; // esi@7
    46.   ULONG iSection; // ecx@13
    47.   int section_end; // eax@15
    48.   struct _IMAGE_SECTION_HEADER *_curSection; // eax@15
    49.   DWORD section_start; // edx@15
    50.   EXCLUDE_LIST this; // [sp+3Ch] [bp-50h]@1
    51.   struct _LOADED_IMAGE loaded_image; // [sp+Ch] [bp-80h]@1
    52.   DWORD dwErrCode; // [sp+70h] [bp-1Ch]@2
    53.   CPPEH_RECORD ms_exc; // [sp+74h] [bp-18h]@2
    54.   DWORD v19; // [sp+6Ch] [bp-20h]@2
    55.   PIMAGE_NT_HEADERS v20; // [sp+60h] [bp-2Ch]@5
    56.   DWORD *v21; // [sp+68h] [bp-24h]@7
    57.   DWORD _sig_offset; // [sp+58h] [bp-34h]@7
    58.   int _sig_len; // [sp+54h] [bp-38h]@7
    59.   ULONG v24; // [sp+64h] [bp-28h]@14
    60.   DWORD v25; // [sp+50h] [bp-3Ch]@15
    61.   int v26; // [sp+4Ch] [bp-40h]@15
    62.   PIMAGE_NT_HEADERS v27; // [sp+5Ch] [bp-30h]@26
    63.  
    64.   EXCLUDE_LIST__EXCLUDE_LIST(&this);
    65.   if ( MapIt(hFile, &loaded_image) )
    66.   {
    67.     dwErrCode = ERROR_INVALID_PARAMETER;
    68.     ms_exc.disabled = 0;
    69.     v19 = 0;
    70.     v4 = loaded_image.FileHeader->OptionalHeader.Magic;
    71.     if ( v4 != IMAGE_NT_OPTIONAL_HDR32_MAGIC && v4 != IMAGE_NT_OPTIONAL_HDR64_MAGIC
    72.       || !EXCLUDE_LIST__Init(&this, &loaded_image, hashproc, hashparam) )
    73.       goto error_exit;
    74.     v5 = loaded_image.FileHeader;
    75.     if ( loaded_image.FileHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC )
    76.     {
    77.       v20 = loaded_image.FileHeader;
    78.       if ( !EXCLUDE_LIST__Add(&this, (char *)loaded_image.FileHeader + 88, 4) )
    79.         goto error_exit;
    80.       _pSignatureDirectoryRecord = &v5->OptionalHeader.DataDirectory[4].VirtualAddress;
    81.     }
    82.     else
    83.     {
    84.       v27 = loaded_image.FileHeader;
    85.       if ( !EXCLUDE_LIST__Add(&this, (char *)loaded_image.FileHeader + 88, 4) )
    86.         goto error_exit;
    87.       _pSignatureDirectoryRecord = &v5->OptionalHeader.DataDirectory[6].VirtualAddress;
    88.     }
    89.     v21 = _pSignatureDirectoryRecord;
    90.     v7 = v5->OptionalHeader.SizeOfHeaders;
    91.     v19 = v5->OptionalHeader.SizeOfHeaders;
    92.     sig_offset = *_pSignatureDirectoryRecord;
    93.     _sig_offset = *_pSignatureDirectoryRecord;
    94.     sig_len = *(_pSignatureDirectoryRecord + 1);
    95.     _sig_len = *(_pSignatureDirectoryRecord + 1);
    96.     if ( sig_offset && sig_len )
    97.     {
    98.       if ( sig_offset > loaded_image.SizeOfImage
    99.         || sig_len + sig_offset != loaded_image.SizeOfImage
    100.         || sig_len + sig_offset < sig_offset
    101.         || sig_offset < v7 )
    102.         goto error_exit;
    103.       iSection = 0;
    104.       while ( 1 )
    105.       {
    106.         v24 = iSection;
    107.         if ( iSection >= loaded_image.NumberOfSections )
    108.           break;
    109.         _curSection = &loaded_image.Sections[iSection];
    110.         section_start = _curSection->PointerToRawData;
    111.         v25 = _curSection->PointerToRawData;
    112.         section_end = section_start + _curSection->SizeOfRawData;
    113.         v26 = section_end;
    114.         if ( section_start && sig_offset < section_end )
    115.           goto error_exit;
    116.         ++iSection;
    117.       }
    118.     }
    119.     if ( EXCLUDE_LIST__Add(&this, _pSignatureDirectoryRecord, 8) )
    120.     {
    121.       if ( EXCLUDE_LIST__Add(&this, &loaded_image.MappedAddress[sig_offset], sig_len) )
    122.       {
    123.         EXCLUDE_LIST__Emit(&this, loaded_image.MappedAddress, loaded_image.SizeOfImage);
    124.         dwErrCode = 0;
    125.       }
    126.     }
    127. error_exit:
    128.     ms_exc.disabled = -1;
    129.     UnmapViewOfFile(loaded_image.MappedAddress);
    130.     SetLastError(dwErrCode);
    131.     EXCLUDE_LIST___EXCLUDE_LIST(&this);
    132.     return dwErrCode == 0;
    133.   }
    134.   SetLastError(ERROR_INVALID_PARAMETER);
    135.   EXCLUDE_LIST___EXCLUDE_LIST(&this);
    136.   return 0;
    137. }
    Возможно, как-то по-особенному происходит хэширование.
     
  7. acpi

    acpi New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2008
    Сообщения:
    15
    http://www.jensign.com/hash/cathash.c
     
  8. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    Получил. Постарайся уж как-нибудь сам разобраться.
     
  9. ant

    ant Member

    Публикаций:
    0
    Регистрация:
    19 мар 2008
    Сообщения:
    118
    Доброго времени. Для меня тоже тема актуальна. Не будучи кодером (лужу, паяю, компутеры починяю), взялся писать програмку. В числе прочего хочется проверять по каталогу безопасности файлы. Чтобы работало в WinPE-образной среде, без CryptoAPI. В будущем, возможно вообще не в win32 (мало ли). Если кто-то знает о готовой реализации, поделитесь, пожалуйста, инфой.
    А пока я пытаюсь победить PE-хидер. В WinHex правлю тот же acpi.sys, забиваю сигнатуру нулями - signtool verify утверждает, что все ОК. Следовательно, "верной дорогой идем, товарищи". А вот Certificate Table как находить - не соображу. Хоть прогу пиши, которая меняет байт за байтом и парсит вывод signtool verify. Я бы так и сделал, да потом сообразил, что адрес для разных файлов разным будет :).
    До кучи - пытался найти закономерность в файлах *.CAT. Нашел, что через 9 байт после каждого блока <<<Obsolete>>> находится хэш. Может, есть более детальная инфа? Например, относительные офсеты на следующий блок. Абсолютных, вроде бы нет(написал таки прогу, которая считывает дворды и проверяет, не есть ли это число, равное текущей позиции плюс/минус 1000 байт, всяко больше длины "блока"). Ничего не нарыл.
    Вот на такие извраты приходится идти.
     
  10. ant

    ant Member

    Публикаций:
    0
    Регистрация:
    19 мар 2008
    Сообщения:
    118
    Вот отсюда http://209.85.229.132/search?q=cache:IvCnX_k6HekJ:download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx+sha1+%22Certificate+Table%22+Checksum+exclude&hl=ru&ct=clnk&cd=1&gl=ru

    Hashing the PE Header, omitting the file's checksum and the Certificate Table entry in Optional Header Data Directories

    PEBrowse кажет, что у файла acpi.sys нет секции data в "Optional Header". Где порылась собака, и где порыться мне?