winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

README.md (9874B)


      1 # @ronomon/pure
      2 
      3 Pure is a **static analysis file format checker** that checks ZIP files for dangerous compression ratios, spec deviations, malicious archive signatures, mismatching local and central directory headers, ambiguous UTF-8 filenames, directory and symlink traversals, invalid MS-DOS dates, overlapping headers, overflow, underflow, sparseness, accidental buffer bleeds etc.
      4 
      5 Pure's goal is to **narrow the semantic gap available to attackers** attempting to exploit vulnerable software, and to **reduce the probability of zero-days**, for example David Fifield's [A better zip bomb](https://www.usenix.org/system/files/woot19-paper_fifield_0.pdf), which was [detected by an early version of Pure as a zero-day](https://news.ycombinator.com/item?id=20352439).
      6 
      7 ## Acknowledgements
      8 
      9 Pure was commissioned and sponsored by the **Product Release And Security Team** at **Microsoft**.
     10 
     11 A special thanks to **Maxim Vainstein** and his team at Microsoft for their vision and encouragement.
     12 
     13 Looking to the future, we want to add support for more archive containers (GZ, TAR, RAR etc.) and other file formats (MS-CFBF or OOXML Office files, RTF, PDF, image formats etc.). Please contact [Joran Dirk Greef](mailto:joran@ronomon.com) if you want to support new file formats in Pure.
     14 
     15 ## Files
     16 
     17 * **pure.h**: C interface to library source code.
     18 
     19 * **pure**: CLI script for development testing. Usage: `./pure <file>`.
     20 
     21 * **test.js**: Node.js test runner to run Pure against all test files in `./tests`.
     22 
     23 * **binding.c**: Node.js binding used by CLI and test runner.
     24 
     25 * **make-errors.js**: Script to recreate C error enums, error codes and error strings dynamically.
     26 
     27 * **make-signatures.js**: Script to recreate C signature strings dynamically.
     28 
     29 * **make-tests.js**: Script to recreate test files dynamically.
     30 
     31 ## Installation
     32 
     33 ```shell
     34 npm install @ronomon/pure
     35 ```
     36 
     37 ## Usage
     38 
     39 At the command line, you can run Pure on any zip file:
     40 
     41 ```shell
     42 $ ./pure <file.zip>
     43 ```
     44 
     45 For example:
     46 
     47 ```shell
     48 $ ./pure samples/zbsm.zip
     49 PURE_E_ZIP_BOMB_FIFIELD: zip bomb: local file header overlap (see research by David Fifield)
     50 ```
     51 
     52 As an embedded C library, **pure.h** provides:
     53 
     54 ```c
     55 int pure_zip(
     56   const uint8_t* buffer, // Zip file buffer
     57   const uint64_t size,   // Size of zip file buffer in bytes
     58   const uint64_t flags   // Bit flags (optional)
     59 )
     60 
     61 int pure_zip_bomb(const int error)
     62 
     63 const char* pure_error_code(const int error)
     64 
     65 const char* pure_error_string(const int error)
     66 ```
     67 
     68 * **pure_zip()** returns a non-zero error return code, or a zero return code if the zip file is clean and has no file format anomalies. A buffer instead of a path is passed to pure_zip() for portability, for reduced surface area for bugs, and to avoid forcing unnecessary IO if file contents are already in memory.
     69 
     70 * **pure_zip_bomb()** returns 1 if the error return code indicates a zip bomb, otherwise 0.
     71 
     72 * **pure_error_code()** returns the constant name of the error return code.
     73 
     74 * **pure_error_string()** returns the error message string corresponding the error return code.
     75 
     76 ## File Format Anomalies
     77 
     78 Pure detects **more than 150 zip file format anomalies**.
     79 
     80 Pure provides defenses against directory and symlink traversal exploits, dangerous unix mode permissions, parser ambiguity, and many other defenses against known (and unknown) exploits, including zip bombs and buffer overflows.
     81 
     82 For example, Pure detects **all variants of known (and unknown) zip bombs**:
     83 
     84 1. Overlapping local file headers (cf. [David Fifield](https://www.usenix.org/system/files/woot19-paper_fifield_0.pdf)).
     85 2. Quines (cf. [Russ Cox](https://research.swtch.com/zip)).
     86 3. Dangerous compression ratios for individual files and across an archive.
     87 4. "Lying" zip metadata vs actual compressed data.
     88 5. Excessive archive recursion.
     89 6. Excessive number of files.
     90 
     91 As a static analysis file format checker, Pure reduces the surface area for zero-day exploits by orders of magnitude. **If a file can get past Pure, it's "pure"... or at least 99% pure**.
     92 
     93 Here is the exhaustive list of what Pure can already detect:
     94 
     95 * PURE_E_SIZE_MAX
     96 * PURE_E_MALLOC
     97 * PURE_E_STRING_NOT_FOUND
     98 * PURE_E_UINT64_OVERFLOW
     99 * PURE_E_ZIP_BOMB_ARCHIVES
    100 * PURE_E_ZIP_BOMB_DEPTH
    101 * PURE_E_ZIP_BOMB_FIFIELD
    102 * PURE_E_ZIP_BOMB_FILES
    103 * PURE_E_ZIP_BOMB_RATIO
    104 * PURE_E_ZIP_BOMB_INFLATE_COMPRESSED_OVERFLOW
    105 * PURE_E_ZIP_BOMB_INFLATE_UNCOMPRESSED_OVERFLOW
    106 * PURE_E_ZIP_TOO_SMALL
    107 * PURE_E_ZIP_SIZE_4GB
    108 * PURE_E_ZIP_RAR
    109 * PURE_E_ZIP_TAR
    110 * PURE_E_ZIP_XAR
    111 * PURE_E_ZIP_SIGNATURE
    112 * PURE_E_ZIP_EOCDR_NOT_FOUND
    113 * PURE_E_ZIP_EOCDR_OVERFLOW
    114 * PURE_E_ZIP_EOCDR_COMMENT_OVERFLOW
    115 * PURE_E_ZIP_EOCDR_SIGNATURE
    116 * PURE_E_ZIP_EOCDR_RECORDS
    117 * PURE_E_ZIP_EOCDR_SIZE_OVERFLOW
    118 * PURE_E_ZIP_EOCDR_SIZE_UNDERFLOW
    119 * PURE_E_ZIP_MULTIPLE_DISKS
    120 * PURE_E_ZIP_APPENDED_DATA_ZEROED
    121 * PURE_E_ZIP_APPENDED_DATA_BUFFER_BLEED
    122 * PURE_E_ZIP_PREPENDED_DATA
    123 * PURE_E_ZIP_PREPENDED_DATA_ZEROED
    124 * PURE_E_ZIP_PREPENDED_DATA_BUFFER_BLEED
    125 * PURE_E_ZIP_CDH_OVERFLOW
    126 * PURE_E_ZIP_CDH_SIGNATURE
    127 * PURE_E_ZIP_CDH_RELATIVE_OFFSET_OVERFLOW
    128 * PURE_E_ZIP_CDH_RELATIVE_OFFSET_OVERLAP
    129 * PURE_E_ZIP_CDH_FILE_NAME_OVERFLOW
    130 * PURE_E_ZIP_CDH_EXTRA_FIELD_OVERFLOW
    131 * PURE_E_ZIP_CDH_FILE_COMMENT_OVERFLOW
    132 * PURE_E_ZIP_LFH_OVERFLOW
    133 * PURE_E_ZIP_LFH_SIGNATURE
    134 * PURE_E_ZIP_LFH_FILE_NAME_OVERFLOW
    135 * PURE_E_ZIP_LFH_EXTRA_FIELD_OVERFLOW
    136 * PURE_E_ZIP_LFH_UNDERFLOW_ZEROED
    137 * PURE_E_ZIP_LFH_UNDERFLOW_BUFFER_BLEED
    138 * PURE_E_ZIP_LFH_DATA_OVERFLOW
    139 * PURE_E_ZIP_DDR_OVERFLOW
    140 * PURE_E_ZIP_LF_OVERFLOW
    141 * PURE_E_ZIP_LF_UNDERFLOW_ZEROED
    142 * PURE_E_ZIP_LF_UNDERFLOW_BUFFER_BLEED
    143 * PURE_E_ZIP_CD_OVERFLOW
    144 * PURE_E_ZIP_CD_UNDERFLOW_ZEROED
    145 * PURE_E_ZIP_CD_UNDERFLOW_BUFFER_BLEED
    146 * PURE_E_ZIP_CD_EOCDR_OVERFLOW
    147 * PURE_E_ZIP_CD_EOCDR_UNDERFLOW_ZEROED
    148 * PURE_E_ZIP_CD_EOCDR_UNDERFLOW_BUFFER_BLEED
    149 * PURE_E_ZIP_DIFF_LFH_GENERAL_PURPOSE_BIT_FLAG
    150 * PURE_E_ZIP_DIFF_LFH_COMPRESSION_METHOD
    151 * PURE_E_ZIP_DIFF_LFH_LAST_MOD_FILE_TIME
    152 * PURE_E_ZIP_DIFF_LFH_LAST_MOD_FILE_DATE
    153 * PURE_E_ZIP_DIFF_LFH_CRC32
    154 * PURE_E_ZIP_DIFF_LFH_COMPRESSED_SIZE
    155 * PURE_E_ZIP_DIFF_LFH_UNCOMPRESSED_SIZE
    156 * PURE_E_ZIP_DIFF_LFH_FILE_NAME_LENGTH
    157 * PURE_E_ZIP_DIFF_LFH_FILE_NAME
    158 * PURE_E_ZIP_DIFF_LFH_DDR_CRC32
    159 * PURE_E_ZIP_DIFF_LFH_DDR_COMPRESSED_SIZE
    160 * PURE_E_ZIP_DIFF_LFH_DDR_UNCOMPRESSED_SIZE
    161 * PURE_E_ZIP_DIFF_DDR_CRC32
    162 * PURE_E_ZIP_DIFF_DDR_COMPRESSED_SIZE
    163 * PURE_E_ZIP_DIFF_DDR_UNCOMPRESSED_SIZE
    164 * PURE_E_ZIP_FLAG_OVERFLOW
    165 * PURE_E_ZIP_FLAG_TRADITIONAL_ENCRYPTION
    166 * PURE_E_ZIP_FLAG_ENHANCED_DEFLATE
    167 * PURE_E_ZIP_FLAG_COMPRESSED_PATCHED_DATA
    168 * PURE_E_ZIP_FLAG_STRONG_ENCRYPTION
    169 * PURE_E_ZIP_FLAG_UNUSED_BIT_7
    170 * PURE_E_ZIP_FLAG_UNUSED_BIT_8
    171 * PURE_E_ZIP_FLAG_UNUSED_BIT_9
    172 * PURE_E_ZIP_FLAG_UNUSED_BIT_10
    173 * PURE_E_ZIP_FLAG_ENHANCED_COMPRESSION
    174 * PURE_E_ZIP_FLAG_MASKED_LOCAL_HEADERS
    175 * PURE_E_ZIP_FLAG_RESERVED_BIT_14
    176 * PURE_E_ZIP_FLAG_RESERVED_BIT_15
    177 * PURE_E_ZIP_COMPRESSION_METHOD_DANGEROUS
    178 * PURE_E_ZIP_COMPRESSION_METHOD_ENCRYPTED
    179 * PURE_E_ZIP_COMPRESSION_METHOD_UNSUPPORTED
    180 * PURE_E_ZIP_STORED_COMPRESSION_SIZE_MISMATCH
    181 * PURE_E_ZIP_DANGEROUS_NEGATIVE_COMPRESSION_RATIO
    182 * PURE_E_ZIP_TIME_OVERFLOW
    183 * PURE_E_ZIP_TIME_HOUR_OVERFLOW
    184 * PURE_E_ZIP_TIME_MINUTE_OVERFLOW
    185 * PURE_E_ZIP_TIME_SECOND_OVERFLOW
    186 * PURE_E_ZIP_DATE_OVERFLOW
    187 * PURE_E_ZIP_DATE_YEAR_OVERFLOW
    188 * PURE_E_ZIP_DATE_MONTH_OVERFLOW
    189 * PURE_E_ZIP_DATE_DAY_OVERFLOW
    190 * PURE_E_ZIP_FILE_NAME_LENGTH
    191 * PURE_E_ZIP_FILE_NAME_CONTROL_CHARACTERS
    192 * PURE_E_ZIP_FILE_NAME_TRAVERSAL_DRIVE_PATH
    193 * PURE_E_ZIP_FILE_NAME_TRAVERSAL_RELATIVE_PATH
    194 * PURE_E_ZIP_FILE_NAME_TRAVERSAL_DOUBLE_DOTS
    195 * PURE_E_ZIP_FILE_NAME_COMPONENT_OVERFLOW
    196 * PURE_E_ZIP_FILE_NAME_BACKSLASH
    197 * PURE_E_ZIP_EXTRA_FIELD_MAX
    198 * PURE_E_ZIP_EXTRA_FIELD_MIN
    199 * PURE_E_ZIP_EXTRA_FIELD_ATTRIBUTE_OVERFLOW
    200 * PURE_E_ZIP_EXTRA_FIELD_OVERFLOW
    201 * PURE_E_ZIP_EXTRA_FIELD_UNDERFLOW_ZEROED
    202 * PURE_E_ZIP_EXTRA_FIELD_UNDERFLOW_BUFFER_BLEED
    203 * PURE_E_ZIP_EXTRA_FIELD_UNICODE_PATH_OVERFLOW
    204 * PURE_E_ZIP_EXTRA_FIELD_UNICODE_PATH_VERSION
    205 * PURE_E_ZIP_EXTRA_FIELD_UNICODE_PATH_DIFF
    206 * PURE_E_ZIP_UNIX_MODE_OVERFLOW
    207 * PURE_E_ZIP_UNIX_MODE_BLOCK_DEVICE
    208 * PURE_E_ZIP_UNIX_MODE_CHARACTER_DEVICE
    209 * PURE_E_ZIP_UNIX_MODE_FIFO
    210 * PURE_E_ZIP_UNIX_MODE_SOCKET
    211 * PURE_E_ZIP_UNIX_MODE_PERMISSIONS_STICKY
    212 * PURE_E_ZIP_UNIX_MODE_PERMISSIONS_SETGID
    213 * PURE_E_ZIP_UNIX_MODE_PERMISSIONS_SETUID
    214 * PURE_E_ZIP_DIRECTORY_COMPRESSED
    215 * PURE_E_ZIP_DIRECTORY_UNCOMPRESSED
    216 * PURE_E_ZIP_SYMLINK_COMPRESSED
    217 * PURE_E_ZIP_SYMLINK_LENGTH
    218 * PURE_E_ZIP_SYMLINK_CONTROL_CHARACTERS
    219 * PURE_E_ZIP_SYMLINK_TRAVERSAL_DRIVE_PATH
    220 * PURE_E_ZIP_SYMLINK_TRAVERSAL_RELATIVE_PATH
    221 * PURE_E_ZIP_SYMLINK_TRAVERSAL_DOUBLE_DOTS
    222 * PURE_E_ZIP_SYMLINK_COMPONENT_OVERFLOW
    223 * PURE_E_ZIP_STRING_MAX
    224 * PURE_E_ZIP_STRING_NULL_BYTE
    225 * PURE_E_ZIP_INFLATE
    226 * PURE_E_ZIP_INFLATE_DICTIONARY
    227 * PURE_E_ZIP_INFLATE_STREAM
    228 * PURE_E_ZIP_INFLATE_DATA
    229 * PURE_E_ZIP_INFLATE_MEMORY
    230 * PURE_E_ZIP_INFLATE_COMPRESSED_UNDERFLOW
    231 * PURE_E_ZIP_INFLATE_UNCOMPRESSED_UNDERFLOW
    232 * PURE_E_ZIP_AD_NIHILO
    233 * PURE_E_ZIP_EX_NIHILO
    234 * PURE_E_ZIP_CRC32
    235 * PURE_E_ZIP_EOCDL_64_OVERFLOW
    236 * PURE_E_ZIP_EOCDL_64_SIGNATURE
    237 * PURE_E_ZIP_EOCDL_64_NEGATIVE_OFFSET
    238 * PURE_E_ZIP_EOCDL_64_DISK
    239 * PURE_E_ZIP_EOCDL_64_DISKS
    240 * PURE_E_ZIP_EOCDR_64_OVERFLOW
    241 * PURE_E_ZIP_EOCDR_64_SIGNATURE
    242 * PURE_E_ZIP_EOCDR_EOCDL_64_OVERFLOW
    243 * PURE_E_ZIP_EOCDR_EOCDL_64_UNDERFLOW_ZEROED
    244 * PURE_E_ZIP_EOCDR_EOCDL_64_UNDERFLOW_BUFFER_BLEED
    245 * PURE_E_ZIP_DIFF_EOCDR_DISK
    246 * PURE_E_ZIP_DIFF_EOCDR_CD_DISK
    247 * PURE_E_ZIP_DIFF_EOCDR_CD_DISK_RECORDS
    248 * PURE_E_ZIP_DIFF_EOCDR_CD_RECORDS
    249 * PURE_E_ZIP_DIFF_EOCDR_CD_SIZE
    250 * PURE_E_ZIP_DIFF_EOCDR_CD_OFFSET
    251 * PURE_E_ZIP_EIEF_64_COMPRESSED_SIZE
    252 * PURE_E_ZIP_EIEF_64_DISK
    253 * PURE_E_ZIP_EIEF_64_RELATIVE_OFFSET
    254 * PURE_E_ZIP_EIEF_64_UNCOMPRESSED_SIZE
    255 * PURE_E_ZIP_EIEF_64_UNDERFLOW_ZEROED
    256 * PURE_E_ZIP_EIEF_64_UNDERFLOW_BUFFER_BLEED
    257 * PURE_E_ZIP_EIEF_64_LFH
    258 * PURE_E_ZIP_DIRECTORY_HAS_NO_LFH
    259 
    260 ## ...and this is only for zip files, we want to add static analysis for more file formats, please consider asking your company to [sponsor open-source work on Pure](mailto:joran@ronomon.com).