├── modules ├── __init__.py ├── plugin_cryptoscan.py ├── ScanMatch.py ├── ScanConfig.py ├── ScanReport.py └── CryptoScan.py ├── .gitignore ├── __init__.py ├── scans ├── des_p32i.json ├── des_sbox1.json ├── des_sbox2.json ├── des_sbox3.json ├── des_sbox4.json ├── des_sbox5.json ├── des_sbox6.json ├── des_sbox7.json ├── des_sbox8.json ├── aes_td0.json ├── aes_td1.json ├── aes_td2.json ├── aes_td3.json ├── aes_te0.json ├── aes_te1.json ├── aes_te2.json ├── aes_te3.json ├── aes_td4.json ├── des_pc2.json ├── mt19937-1.json ├── mt19937-2.json ├── mt19937-3.json ├── mt19937-4.json ├── aes_te4.json ├── des_pc1_left.json ├── des_pc1_right.json ├── tea_delta.json ├── aes_inv_sbox.json ├── rc5_rc6.json ├── mt19937-matrix.json ├── sm4_ck.json ├── sm4_fk.json ├── ec_curve25519.json ├── aria_sbox2.json ├── kasumi_mod.json ├── aria_sbox4.json ├── blowfish_p_array.json ├── aes_sbox.json ├── ec_p192.json ├── ec_p224.json ├── ec_p256.json ├── ec_p384.json ├── ec_p521.json ├── md5_initstate.json ├── sha1_h.json ├── kasumi_sbox_s7.json ├── kasumi_sbox_s9.json ├── salsa20_tau.json ├── salsa20_sigma.json ├── zlib_lengthextrabits.json ├── newdes_sbox.json ├── sm4_sbox.json ├── sm3_init.json ├── blake_224_init.json ├── blake_256_init.json ├── dfc_sbox.json ├── zlib_distanceextrabits.json ├── blowfish_sbox.json ├── md5_t.json ├── zlib_lengthstarts.json ├── sha224_h.json ├── sha256_h.json ├── zlib_distancestarts.json ├── sha256_k.json ├── IKE_prime.json ├── blake_384_init.json ├── blake_512_init.json ├── crc32_lzma_table_0.json ├── crc32_lzma_table_2.json ├── crc32_lzma_table_3.json ├── crc32_lzma_table_5.json ├── crc32_lzma_table_6.json ├── crc32_lzma_table_7.json ├── crc32_lzma_table_4.json ├── crc32_ms_table_1.json ├── crc32_ms_table_2.json ├── crc32_ms_table_3.json ├── crc32_ms_table_4.json ├── crc32_ms_table_5.json ├── crc32_ms_table_6.json ├── crc32_m_tab_be.json ├── crc32_m_tab_le.json ├── crc32_lzma_table_1.json ├── sha512_k.json └── crc32_ms_table_0.json ├── LICENSE ├── __main__.py ├── plugin.json └── README.md /modules/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *.pyc 3 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | cryptoscan 3 | Plugin to scan binaries for common crypto implementations and magic variables. 4 | """ 5 | from binaryninja import PluginCommand 6 | from .modules import plugin_cryptoscan 7 | 8 | PluginCommand.register("Scan for crypto", "Scan the binary file for known crypto constructs", plugin_cryptoscan.run_plugin) 9 | -------------------------------------------------------------------------------- /scans/des_p32i.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_p32i", 4 | "description" : "Detects DES_p32i", 5 | "family" : "DES", 6 | "size" : 1, 7 | "type" : "static", 8 | "flags" : [ "0x0f", "0x06", "0x13", "0x14" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_p32i" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/des_sbox1.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_sbox1", 4 | "description" : "Detects DES_sbox1", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x0e", "0x04", "0x0d", "0x01" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_sbox1" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/des_sbox2.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_sbox2", 4 | "description" : "Detects DES_sbox2", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x0f", "0x01", "0x08", "0x0e" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_sbox2" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/des_sbox3.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_sbox3", 4 | "description" : "Detects DES_sbox3", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x0a", "0x00", "0x09", "0x0e" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_sbox3" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/des_sbox4.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_sbox4", 4 | "description" : "Detects DES_sbox4", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size": 1, 8 | "flags" : [ "0x07", "0x0d", "0x0e", "0x03" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_sbox4" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/des_sbox5.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_sbox5", 4 | "description" : "Detects DES_sbox5", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x02", "0x0c", "0x04", "0x01" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_sbox5" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/des_sbox6.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_sbox6", 4 | "description" : "Detects DES_sbox6", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x0c", "0x01", "0x0a", "0x0f" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_sbox6" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/des_sbox7.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_sbox7", 4 | "description" : "Detects DES_sbox7", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x04", "0x0b", "0x02", "0x0e" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_sbox7" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/des_sbox8.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_sbox8", 4 | "description" : "Detects DES_sbox8", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x0d", "0x02", "0x08", "0x04" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_sbox8" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/aes_td0.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_Td0", 4 | "family" : "AES", 5 | "description" : "Detects Rijndael_Td0", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xf4", "0x51", "0x50", "0xa7" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "Rijndael_Td0" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/aes_td1.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_Td1", 4 | "family" : "AES", 5 | "description" : "Detects Rijndael_Td1", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x51", "0x50", "0xa7", "0xf4" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "Rijndael_Td1" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/aes_td2.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_Td2", 4 | "family" : "AES", 5 | "description" : "Detects Rijndael_Td2", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x50", "0xa7", "0xf4", "0x51" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "Rijndael_Td2" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/aes_td3.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_Td3", 4 | "family" : "AES", 5 | "description" : "Detects Rijndael_Td3", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xa7", "0xf4", "0x51", "0x50" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "Rijndael_Td3" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/aes_te0.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_Te0", 4 | "family" : "AES", 5 | "description" : "Detects Rijndael_Te0", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xa5", "0x63", "0x63", "0xc6" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "Rijndael_Te0" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/aes_te1.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_Te1", 4 | "family" : "AES", 5 | "description" : "Detects Rijndael_Te1", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x63", "0x63", "0xc6", "0xa5" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "Rijndael_Te1" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/aes_te2.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_Te2", 4 | "family" : "AES", 5 | "description" : "Detects Rijndael_Te2", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x63", "0xc6", "0xa5", "0x63" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "Rijndael_Te2" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/aes_te3.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_Te3", 4 | "family" : "AES", 5 | "description" : "Detects Rijndael_Te3", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xc6", "0xa5", "0x63", "0x63" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "Rijndael_Te3" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/aes_td4.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_Td4", 4 | "family" : "AES", 5 | "description" : "Detects Rijndael_Td4", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x52", "0x52", "0x52", "0x52", "0x09", "0x09", "0x09", "0x09" ], 9 | "on_match" : { 10 | "type" : "symbol", 11 | "name" : "Rijndael_Td4" 12 | } 13 | } -------------------------------------------------------------------------------- /scans/des_pc2.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_pc2", 4 | "description" : "Detects DES_pc1 (permuted choice 2)", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x0d", "0x10", "0x0a", "0x17" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_pc2" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/mt19937-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "MT19937-1", 4 | "description" : "Detects Mersenne Twister 19937", 5 | "family" : "PRNG", 6 | "size" : 1, 7 | "type" : "static", 8 | "flags" : [ "0xdf", "0xb0", "0x08", "0x99"], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "MT19937-1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scans/mt19937-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "MT19937-2", 4 | "description" : "Detects Mersenne Twister 19937", 5 | "family" : "PRNG", 6 | "size" : 1, 7 | "type" : "static", 8 | "flags" : [ "0xaa", "0xd6", "0x2b", "0x01"], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "MT19937-2" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scans/mt19937-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "MT19937-3", 4 | "description" : "Detects Mersenne Twister 19937", 5 | "family" : "PRNG", 6 | "size" : 1, 7 | "type" : "static", 8 | "flags" : [ "0x65", "0x8b", "0x58", "0x5b"], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "MT19937-3" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scans/mt19937-4.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "MT19937-4", 4 | "description" : "Detects Mersenne Twister 19937", 5 | "family" : "PRNG", 6 | "size" : 1, 7 | "type" : "static", 8 | "flags" : [ "0x80", "0x56", "0x2c", "0x9d"], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "MT19937-4" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scans/aes_te4.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_Te4", 4 | "family" : "AES", 5 | "description" : "Detects Rijndael_Te4", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x63", "0x63", "0x63", "0x63", "0x7c", "0x7c", "0x7c", "0x7c" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "Rijndael_Te4" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/des_pc1_left.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_pc1_left", 4 | "description" : "Detects DES_pc1_left (permuted choice 1 left)", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x38", "0x30", "0x28", "0x20" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_pc1_left" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/des_pc1_right.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DES_pc1_right", 4 | "description" : "Detects DES_pc1_right (permuted choice 1 right)", 5 | "family" : "DES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x3e", "0x36", "0x2e", "0x26" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "DES_pc1_right" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/tea_delta.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 100, 3 | "name" : "TEA_delta", 4 | "family" : "TEA", 5 | "description" : "Detects the golden-ratio based delta constant used in TEA", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x9e", "0x37", "0x79", "0xb9" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "TEA_delta" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/aes_inv_sbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_inv_sbox", 4 | "family" : "AES", 5 | "description" : "Detects the presence of a hardcoded inverse AES sbox", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x52", "0x09", "0x6a", "0xd5" ], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "Rijndael_inv_sbox" 13 | } 14 | } -------------------------------------------------------------------------------- /scans/rc5_rc6.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "RC5_RC6", 4 | "description" : "Detects Rivest RC5_RC6", 5 | "family" : "Rivest", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xb7", "0xe1", "0x51", "0x63", 9 | "0x9e", "0x37", "0x79", "0xb9"], 10 | "on_match" : { 11 | "threshold" : 50, 12 | "type" : "symbol", 13 | "name" : "RC5_RC6" 14 | } 15 | } -------------------------------------------------------------------------------- /scans/mt19937-matrix.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "MT19937-Matrix", 4 | "description" : "Used in Mersenne Twister 19937 and Borosh-Niederreiter, see Knuth Seminumerical Algorithms", 5 | "family" : "PRNG", 6 | "size" : 1, 7 | "type" : "static", 8 | "flags" : [ "0x65", "0x89", "0x07", "0x6c"], 9 | "on_match" : { 10 | "threshold" : 50, 11 | "type" : "symbol", 12 | "name" : "MT-Borosh-Niederreiter" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scans/sm4_ck.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "SM4_ck", 4 | "description" : "Detects SM4_ck", 5 | "family" : "SM4", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x00", "0x07", "0x0e", "0x15", 9 | "0x1c", "0x23", "0x2a", "0x31", 10 | "0x38", "0x3f", "0x46", "0x4d", 11 | "0x54", "0x5b", "0x62", "0x69" ], 12 | "on_match" : { 13 | "threshold" : 50, 14 | "type" : "symbol", 15 | "name" : "SM4_ck" 16 | } 17 | } -------------------------------------------------------------------------------- /scans/sm4_fk.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "SM4_fk", 4 | "description" : "Detects SM4_fk", 5 | "family" : "SM4", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0xa3", "0xb1", "0xba", "0xc6", 9 | "0x56", "0xaa", "0x33", "0x50", 10 | "0x67", "0x7d", "0x91", "0x97", 11 | "0xb2", "0x70", "0x22", "0xdc" ], 12 | "on_match" : { 13 | "threshold" : 50, 14 | "type" : "symbol", 15 | "name" : "SM4_fk" 16 | } 17 | } -------------------------------------------------------------------------------- /scans/ec_curve25519.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "EC_curve25519", 4 | "description" : "Detects curve25519", 5 | "family" : "EC", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xed", "0xd3", "0xf5", "0x5c", 9 | "0x1a", "0x63", "0x12", "0x58", 10 | "0xd6", "0x9c", "0xf7", "0xa2", 11 | "0xde", "0xf9", "0xde", "0x14" ], 12 | "on_match" : { 13 | "threshold" : 50, 14 | "type" : "symbol", 15 | "name" : "EC_curve25519" 16 | } 17 | } -------------------------------------------------------------------------------- /scans/aria_sbox2.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Aria_sbox2", 4 | "family" : "ARIA", 5 | "description" : "Detects the presence of ARIA's secondary sbox", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0xe2", "0x4e", "0x54", "0xfc", 9 | "0x94", "0xc2", "0x4a", "0xcc", 10 | "0x62", "0x0d", "0x6a", "0x46", 11 | "0x3c", "0x4d", "0x8b", "0xd1" ], 12 | "on_match" : { 13 | "type" : "symbol", 14 | "name" : "Aria_sbox2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scans/kasumi_mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 60, 3 | "name" : "Kasumi_mod", 4 | "family" : "KASUMI", 5 | "description" : "Detects the key expansion constant used in Kasumi", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x01", "0x23", "0x45", "0x67", 9 | "0x89", "0xab", "0xcd", "0xef", 10 | "0xfe", "0xdc", "0xba", "0x98", 11 | "0x76", "0x54", "0x32", "0x10" ], 12 | "on_match" : { 13 | "type" : "symbol", 14 | "name" : "Kasumi_mod" 15 | } 16 | } -------------------------------------------------------------------------------- /scans/aria_sbox4.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Aria_sbox4", 4 | "family" : "ARIA", 5 | "description" : "Detects the presence of ARIA's secondary inverse sbox", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x30", "0x68", "0x99", "0x1b", 9 | "0x87", "0xb9", "0x21", "0x78", 10 | "0x50", "0x39", "0xdb", "0xe1", 11 | "0x72", "0x09", "0x62", "0x3c" ], 12 | "on_match" : { 13 | "type" : "symbol", 14 | "name" : "Aria_sbox4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scans/blowfish_p_array.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Blowfish_P_array", 4 | "family" : "Blowfish", 5 | "description" : "Detects Blowfish_P_array", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x24", "0x3f", "0x6a", "0x88", 9 | "0x85", "0xa3", "0x08", "0xd3", 10 | "0x13", "0x19", "0x8a", "0x2e", 11 | "0x03", "0x70", "0x73", "0x44" ], 12 | "on_match" : { 13 | "threshold" : 50, 14 | "type" : "symbol", 15 | "name" : "Blowfish_P_array" 16 | } 17 | } -------------------------------------------------------------------------------- /scans/aes_sbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Rijndael_sbox", 4 | "family" : "AES", 5 | "description" : "Detects the presence of a hardcoded AES sbox", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x63", "0x7c", "0x77", "0x7b", 9 | "0xf2", "0x6b", "0x6f", "0xc5", 10 | "0x30", "0x01", "0x67", "0x2b", 11 | "0xfe", "0xd7", "0xab", "0x76" ], 12 | "on_match" : { 13 | "threshold" : 50, 14 | "type" : "symbol", 15 | "name" : "Rijndael_sbox" 16 | } 17 | } -------------------------------------------------------------------------------- /scans/ec_p192.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "EC_p192", 4 | "description" : "Detects the P-192 curve", 5 | "family" : "EC", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x30", "0x45", "0xae", "0x6f", 9 | "0xc8", "0x42", "0x2f", "0x64", 10 | "0xed", "0x57", "0x95", "0x28", 11 | "0xd3", "0x81", "0x20", "0xea", 12 | "0xe1", "0x21", "0x96", "0xd5" ], 13 | "on_match" : { 14 | "threshold" : 50, 15 | "type" : "symbol", 16 | "name" : "EC_p224" 17 | } 18 | } -------------------------------------------------------------------------------- /scans/ec_p224.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "EC_p224", 4 | "description" : "Detects the P-224 curve", 5 | "family" : "EC", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xbd", "0x71", "0x34", "0x47", 9 | "0x99", "0xd5", "0xc7", "0xfc", 10 | "0xdc", "0x45", "0xb5", "0x9f", 11 | "0xa3", "0xb9", "0xab", "0x8f", 12 | "0x6a", "0x94", "0x8b", "0xc5" ], 13 | "on_match" : { 14 | "threshold" : 50, 15 | "type" : "symbol", 16 | "name" : "EC_p224" 17 | } 18 | } -------------------------------------------------------------------------------- /scans/ec_p256.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "EC_p256", 4 | "description" : "Detects the P-256 curve", 5 | "family" : "EC", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xc4", "0x9d", "0x36", "0x08", 9 | "0x86", "0xe7", "0x04", "0x93", 10 | "0x6a", "0x66", "0x78", "0xe1", 11 | "0x13", "0x9d", "0x26", "0xb7", 12 | "0x81", "0x9f", "0x7e", "0x90" ], 13 | "on_match" : { 14 | "threshold" : 50, 15 | "type" : "symbol", 16 | "name" : "EC_p256" 17 | } 18 | } -------------------------------------------------------------------------------- /scans/ec_p384.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "EC_p384", 4 | "description" : "Detects the P-384 curve", 5 | "family" : "EC", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xa3", "0x35", "0x92", "0x6a", 9 | "0xa3", "0x19", "0xa2", "0x7a", 10 | "0x1d", "0x00", "0x89", "0x6a", 11 | "0x67", "0x73", "0xa4", "0x82", 12 | "0x7a", "0xcd", "0xac", "0x73" ], 13 | "on_match" : { 14 | "threshold" : 50, 15 | "type" : "symbol", 16 | "name" : "EC_p384" 17 | } 18 | } -------------------------------------------------------------------------------- /scans/ec_p521.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "EC_p521", 4 | "description" : "Detects the P-521 curve", 5 | "family" : "EC", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xd0", "0x9e", "0x88", "0x00", 9 | "0x29", "0x1c", "0xb8", "0x53", 10 | "0x96", "0xcc", "0x67", "0x17", 11 | "0x39", "0x32", "0x84", "0xaa", 12 | "0xa0", "0xda", "0x64", "0xba" ], 13 | "on_match" : { 14 | "threshold" : 50, 15 | "type" : "symbol", 16 | "name" : "EC_p521" 17 | } 18 | } -------------------------------------------------------------------------------- /scans/md5_initstate.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "MD5_initstate", 4 | "description" : "MD5_initstate MD5_initstate", 5 | "family" : "MD5", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x67", "0x45", "0x23", "0x01", 9 | "0xef", "0xcd", "0xab", "0x89", 10 | "0x98", "0xba", "0xdc", "0xfe", 11 | "0x10", "0x32", "0x54", "0x76"], 12 | "on_match" : { 13 | "threshold" : 50, 14 | "type" : "symbol", 15 | "name" : "MD5_initstate" 16 | } 17 | } -------------------------------------------------------------------------------- /scans/sha1_h.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "SHA1_h", 4 | "description" : "Detects SHA1_h", 5 | "family" : "SHA1", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x67", "0x45", "0x23", "0x01", 9 | "0xef", "0xcd", "0xab", "0x89", 10 | "0x98", "0xba", "0xdc", "0xfe", 11 | "0x10", "0x32", "0x54", "0x76", 12 | "0xc3", "0xd2", "0xe1", "0xf0"], 13 | "on_match" : { 14 | "threshold" : 50, 15 | "type" : "symbol", 16 | "name" : "SHA1_h" 17 | } 18 | } -------------------------------------------------------------------------------- /scans/kasumi_sbox_s7.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Kasumi_sbox_s7", 4 | "family" : "KASUMI", 5 | "description" : "Detects Kasumi_sbox_s7", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x36", "0x32", "0x3e", "0x38", 9 | "0x16", "0x22", "0x5e", "0x60", 10 | "0x26", "0x06", "0x3f", "0x5d", 11 | "0x02", "0x12", "0x7b", "0x21", 12 | "0x37", "0x71", "0x27", "0x72", 13 | "0x15", "0x43", "0x41", "0x0c" ], 14 | "on_match" : { 15 | "type" : "symbol", 16 | "name" : "Kasumi_sbox_s7" 17 | } 18 | } -------------------------------------------------------------------------------- /scans/kasumi_sbox_s9.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Kasumi_sbox_s9", 4 | "family" : "KASUMI", 5 | "description" : "Detects Kasumi_sbox_s9", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xa7", "0xef", "0xa1", "0x7b", 9 | "0x87", "0x4e", "0x09", "0x52", 10 | "0x26", "0xe2", "0x30", "0x66", 11 | "0xc4", "0x81", "0x5a", "0x8d", 12 | "0xb7", "0xfd", "0x93", "0x4b", 13 | "0x9f", "0x54", "0x33", "0x6a" ], 14 | "on_match" : { 15 | "type" : "symbol", 16 | "name" : "Kasumi_sbox_s9" 17 | } 18 | } -------------------------------------------------------------------------------- /scans/salsa20_tau.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Salsa20_tau", 4 | "description" : "Detects the tau constant, used in the 128-bit version of Salsa20, i.e. the string 'expand 16-byte k'", 5 | "family" : "Salsa20", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ 9 | "0x65", "0x78", "0x70", "0x61", 10 | "0x6E", "0x64", "0x20", "0x31", 11 | "0x36", "0x2D", "0x62", "0x79", 12 | "0x74", "0x65", "0x20", "0x6B" 13 | ], 14 | "on_match" : { 15 | "threshold" : 50, 16 | "type" : "symbol", 17 | "name" : "Salsa20_tau" 18 | } 19 | } -------------------------------------------------------------------------------- /scans/salsa20_sigma.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Salsa20_sigma", 4 | "description" : "Detects the sigma constant, used in the 256-bit version of Salsa20, i.e. the string 'expand 32-byte k'", 5 | "family" : "Salsa20", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ 9 | "0x65", "0x78", "0x70", "0x61", 10 | "0x6E", "0x64", "0x20", "0x33", 11 | "0x32", "0x2D", "0x62", "0x79", 12 | "0x74", "0x65", "0x20", "0x6B" 13 | ], 14 | "on_match" : { 15 | "threshold" : 50, 16 | "type" : "symbol", 17 | "name" : "Salsa20_sigma" 18 | } 19 | } -------------------------------------------------------------------------------- /scans/zlib_lengthextrabits.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "zinflate_lengthExtraBits", 4 | "description" : "Detects zinflate_lengthExtraBits", 5 | "family" : "zlib", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x01", "0x01", "0x01", "0x01", 9 | "0x02", "0x02", "0x02", "0x02", 10 | "0x03", "0x03", "0x03", "0x03", 11 | "0x04", "0x04", "0x04", "0x04", 12 | "0x05", "0x05", "0x05", "0x05"], 13 | "on_match" : { 14 | "threshold" : 50, 15 | "type" : "symbol", 16 | "name" : "zinflate_lengthExtraBits" 17 | } 18 | } -------------------------------------------------------------------------------- /scans/newdes_sbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "NewDES_sbox", 4 | "description" : "Detects NewDES_sbox", 5 | "family" : "NewDES", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x20", "0x89", "0xef", "0xbc", 9 | "0x66", "0x7d", "0xdd", "0x48", 10 | "0xd4", "0x44", "0x51", "0x25", 11 | "0x56", "0xed", "0x93", "0x95", 12 | "0x46", "0xe5", "0x11", "0x7c", 13 | "0x73", "0xcf", "0x21", "0x14", 14 | "0x7a", "0x8f", "0x19", "0xd7" ], 15 | "on_match" : { 16 | "threshold" : 50, 17 | "type" : "symbol", 18 | "name" : "NewDES_sbox" 19 | } 20 | } -------------------------------------------------------------------------------- /scans/sm4_sbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "SM4_sbox", 4 | "description" : "Detects SM4_sbox", 5 | "family" : "SM4", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0xd6", "0x90", "0xe9", "0xfe", 9 | "0xcc", "0xe1", "0x3d", "0xb7", 10 | "0x16", "0xb6", "0x14", "0xc2", 11 | "0x28", "0xfb", "0x2c", "0x05", 12 | "0x2b", "0x67", "0x9a", "0x76", 13 | "0x2a", "0xbe", "0x04", "0xc3", 14 | "0xaa", "0x44", "0x13", "0x26", 15 | "0x49", "0x86", "0x06", "0x99" ], 16 | "on_match" : { 17 | "type" : "symbol", 18 | "name" : "SM4_sbox" 19 | } 20 | } -------------------------------------------------------------------------------- /scans/sm3_init.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "SM3_init", 4 | "description" : "Detects SM3 Hash init", 5 | "family" : "SM3", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x73", "0x80", "0x16", "0x6f", 9 | "0x49", "0x14", "0xb2", "0xb9", 10 | "0x17", "0x24", "0x42", "0xd7", 11 | "0xda", "0x8a", "0x06", "0x00", 12 | "0xa9", "0x6f", "0x30", "0xbc", 13 | "0x16", "0x31", "0x38", "0xaa", 14 | "0xe3", "0x8d", "0xee", "0x4d", 15 | "0xb0", "0xfb", "0x0e", "0x4e"], 16 | "on_match" : { 17 | "type" : "symbol", 18 | "name" : "SM3_init" 19 | } 20 | } -------------------------------------------------------------------------------- /scans/blake_224_init.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Blake_224_init", 4 | "description" : "Detects Blake_224_init", 5 | "family" : "BLAKE", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0xc1", "0x05", "0x9e", "0xd8", 9 | "0x36", "0x7c", "0xd5", "0x07", 10 | "0x30", "0x70", "0xdd", "0x17", 11 | "0xf7", "0x0e", "0x59", "0x39", 12 | "0xff", "0xc0", "0x0b", "0x31", 13 | "0x68", "0x58", "0x15", "0x11", 14 | "0x64", "0xf9", "0x8f", "0xa7", 15 | "0xbe", "0xfa", "0x4f", "0xa4"], 16 | "on_match" : { 17 | "type" : "symbol", 18 | "name" : "Blake_224_init" 19 | } 20 | } -------------------------------------------------------------------------------- /scans/blake_256_init.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Blake_256_init", 4 | "description" : "Detects Blake_256_init", 5 | "family" : "BLAKE", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x6a", "0x09", "0xe6", "0x67", 9 | "0xbb", "0x67", "0xae", "0x85", 10 | "0x3c", "0x6e", "0xf3", "0x72", 11 | "0xa5", "0x4f", "0xf5", "0x3a", 12 | "0x51", "0x0e", "0x52", "0x7f", 13 | "0x9b", "0x05", "0x68", "0x8c", 14 | "0x1f", "0x83", "0xd9", "0xab", 15 | "0x5b", "0xe0", "0xcd", "0x19"], 16 | "on_match" : { 17 | "type" : "symbol", 18 | "name" : "Blake_256_init" 19 | } 20 | } -------------------------------------------------------------------------------- /scans/dfc_sbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "DFC_sbox", 4 | "description" : "Detects DFC_sbox", 5 | "family" : "DFC", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0xb7", "0xe1", "0x51", "0x62", 9 | "0x8a", "0xed", "0x2a", "0x6a", 10 | "0xbf", "0x71", "0x58", "0x80", 11 | "0x9c", "0xf4", "0xf3", "0xc7", 12 | "0x62", "0xe7", "0x16", "0x0f", 13 | "0x38", "0xb4", "0xda", "0x56", 14 | "0xa7", "0x84", "0xd9", "0x04", 15 | "0x51", "0x90", "0xcf", "0xef" ], 16 | "on_match" : { 17 | "threshold" : 50, 18 | "type" : "symbol", 19 | "name" : "DFC_sbox" 20 | } 21 | } -------------------------------------------------------------------------------- /scans/zlib_distanceextrabits.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "zinflate_distanceExtraBits", 4 | "description" : "Detects zinflate_distanceExtraBits", 5 | "family" : "zlib", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x01", "0x01", "0x02", "0x02", 9 | "0x03", "0x03", "0x04", "0x04", 10 | "0x05", "0x05", "0x06", "0x06", 11 | "0x07", "0x07", "0x08", "0x08", 12 | "0x09", "0x09", "0x0a", "0x0a", 13 | "0x0b", "0x0b", "0x0c", "0x0c"], 14 | "on_match" : { 15 | "threshold" : 50, 16 | "type" : "symbol", 17 | "name" : "zinflate_distanceExtraBits" 18 | } 19 | } -------------------------------------------------------------------------------- /scans/blowfish_sbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Blowfish_sbox", 4 | "family" : "Blowfish", 5 | "description" : "Detects Blowfish_sbox", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xd1", "0x31", "0x0b", "0xa6", 9 | "0x98", "0xdf", "0xb5", "0xac", 10 | "0x2f", "0xfd", "0x72", "0xdb", 11 | "0xd0", "0x1a", "0xdf", "0xb7", 12 | "0xb8", "0xe1", "0xaf", "0xed", 13 | "0x6a", "0x26", "0x7e", "0x96", 14 | "0xba", "0x7c", "0x90", "0x45", 15 | "0xf1", "0x2c", "0x7f", "0x99" ], 16 | "on_match" : { 17 | "threshold" : 50, 18 | "type" : "symbol", 19 | "name" : "Blowfish_sbox" 20 | } 21 | } -------------------------------------------------------------------------------- /scans/md5_t.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "MD5_t", 4 | "description" : "Detects MD5_t", 5 | "family" : "MD5", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xd7", "0x6a", "0xa4", "0x78", 9 | "0xe8", "0xc7", "0xb7", "0x56", 10 | "0x24", "0x20", "0x70", "0xdb", 11 | "0xc1", "0xbd", "0xce", "0xee", 12 | "0xf5", "0x7c", "0x0f", "0xaf", 13 | "0x47", "0x87", "0xc6", "0x2a", 14 | "0xa8", "0x30", "0x46", "0x13", 15 | "0xfd", "0x46", "0x95", "0x01"], 16 | "on_match" : { 17 | "threshold" : 50, 18 | "type" : "symbol", 19 | "name" : "MD5_t" 20 | } 21 | } -------------------------------------------------------------------------------- /scans/zlib_lengthstarts.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "zinflate_lengthStarts", 4 | "description" : "Detects zinflate_lengthStarts", 5 | "family" : "zlib", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x03", "0x04", "0x05", "0x06", 9 | "0x07", "0x08", "0x09", "0x0a", 10 | "0x0b", "0x0d", "0x0f", "0x11", 11 | "0x13", "0x17", "0x1b", "0x1f", 12 | "0x23", "0x2b", "0x33", "0x3b", 13 | "0x43", "0x53", "0x63", "0x73", 14 | "0x83", "0xa3", "0xc3", "0xe3"], 15 | "on_match" : { 16 | "threshold" : 50, 17 | "type" : "symbol", 18 | "name" : "zinflate_lengthStarts" 19 | } 20 | } -------------------------------------------------------------------------------- /modules/plugin_cryptoscan.py: -------------------------------------------------------------------------------- 1 | import binaryninja as bn 2 | from .CryptoScan import CryptoScan 3 | 4 | def run_plugin(bv): 5 | # Just run everything until we have something tangible for IL signature detection 6 | ## For now this will reload configs on every run, might be desirable. 7 | options = {'static' : True, 'signature' : False, 'il': True} 8 | ## static_scan = bn.ChoiceField('Scan for constants', ['Yes', 'No']) 9 | ## signature_scan = bn.ChoiceField('Scan IL signatures', ['Yes', 'No']) 10 | ## bn.get_form_input([None, static_scan, None, signature_scan], 'Scanning options') 11 | if any(option for option in options.values()): 12 | cs = CryptoScan(bv, options) 13 | cs.start() 14 | 15 | -------------------------------------------------------------------------------- /scans/sha224_h.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "SHA224_h", 4 | "description" : "Detects SHA224_h", 5 | "family" : "SHA224", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xc1", "0x05", "0x9e", "0xd8", 9 | "0x36", "0x7c", "0xd5", "0x07", 10 | "0x30", "0x70", "0xdd", "0x17", 11 | "0xf7", "0x0E", "0x59", "0x39", 12 | "0xff", "0xc0", "0x0b", "0x31", 13 | "0x68", "0x58", "0x15", "0x11", 14 | "0x64", "0xf9", "0x8f", "0xa7", 15 | "0xbe", "0xfa", "0x4f", "0xa4"], 16 | "on_match" : { 17 | "threshold" : 50, 18 | "type" : "symbol", 19 | "name" : "SHA224_h" 20 | } 21 | } -------------------------------------------------------------------------------- /scans/sha256_h.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "SHA256_h", 4 | "description" : "Detects SHA256_h", 5 | "family" : "SHA256", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x6a", "0x09", "0xe6", "0x67", 9 | "0xbb", "0x67", "0xae", "0x85", 10 | "0x3c", "0x6e", "0xf3", "0x72", 11 | "0xa5", "0x4f", "0xf5", "0x3a", 12 | "0x51", "0x0e", "0x52", "0x7f", 13 | "0x9b", "0x05", "0x68", "0x8c", 14 | "0x1f", "0x83", "0xd9", "0xab", 15 | "0x5b", "0xe0", "0xcd", "0x19"], 16 | "on_match" : { 17 | "threshold" : 50, 18 | "type" : "symbol", 19 | "name" : "SHA256_h" 20 | } 21 | } -------------------------------------------------------------------------------- /scans/zlib_distancestarts.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "zinflate_distanceStarts", 4 | "description" : "Detects zinflate_distanceStarts", 5 | "family" : "zlib", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x01", "0x02", "0x03", "0x04", 9 | "0x05", "0x07", "0x09", "0x0d", 10 | "0x11", "0x19", "0x21", "0x31", 11 | "0x41", "0x61", "0x81", "0xc1", 12 | "0x01", "0x81", "0x01", "0x01", 13 | "0x01", "0x01", "0x01", "0x01", 14 | "0x01", "0x01", "0x01", "0x01"], 15 | "on_match" : { 16 | "threshold" : 50, 17 | "type" : "symbol", 18 | "name" : "zinflate_distanceStarts" 19 | } 20 | } -------------------------------------------------------------------------------- /scans/sha256_k.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "SHA256_K", 4 | "description" : "Detects SHA256_K", 5 | "family" : "SHA256", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x42", "0x8a", "0x2f", "0x98", 9 | "0x71", "0x37", "0x44", "0x91", 10 | "0xb5", "0xc0", "0xfb", "0xcf", 11 | "0xe9", "0xb5", "0xdb", "0xa5", 12 | "0x39", "0x56", "0xc2", "0x5b", 13 | "0x59", "0xf1", "0x11", "0xf1", 14 | "0x92", "0x3f", "0x82", "0xa4", 15 | "0xab", "0x1c", "0x5e", "0xd5", 16 | "0xd8", "0x07", "0xaa", "0x98", 17 | "0x12", "0x83", "0x5b", "0x01"], 18 | "on_match" : { 19 | "threshold" : 50, 20 | "type" : "symbol", 21 | "name" : "SHA256_K" 22 | } 23 | } -------------------------------------------------------------------------------- /scans/IKE_prime.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 80, 3 | "name" : "IKE_prime", 4 | "family" : "IKE", 5 | "description" : "Internet Key Exchange, shared modular expansion prime", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xff", "0xff", "0xff", "0xff", "0xff", 9 | "0xff", "0xff", "0xff", "0xc9", "0x0f", 10 | "0xda", "0xa2", "0x21", "0x68", "0xc2", 11 | "0x34", "0xc4", "0xc6", "0x62", "0x8b", 12 | "0x80", "0xdc", "0x1c", "0xd1", "0x29", 13 | "0x02", "0x4e", "0x08", "0x8a", "0x67", 14 | "0xcc", "0x74", "0x02", "0x0b", "0xbe", 15 | "0xa6", "0x3b", "0x13", "0x9b", "0x22", 16 | "0x51", "0x4a", "0x08", "0x79", "0x8e", 17 | "0x34", "0x04", "0xdd", "0xef", "0x95", 18 | "0x19", "0xb3", "0xcd", "0x3a", "0x43" ], 19 | "on_match" : { 20 | "type" : "symbol", 21 | "name" : "IKE_prime" 22 | } 23 | } -------------------------------------------------------------------------------- /scans/blake_384_init.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Blake_384_init", 4 | "description" : "Detects Blake_384_init", 5 | "family" : "BLAKE", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0xcb", "0xbb", "0x9d", "0x5d", "0xc1", "0x05", "0x9e", "0xd8", 9 | "0x62", "0x9a", "0x29", "0x2a", "0x36", "0x7c", "0xd5", "0x07", 10 | "0x91", "0x59", "0x01", "0x5a", "0x30", "0x70", "0xdd", "0x17", 11 | "0x15", "0x2f", "0xec", "0xd8", "0xf7", "0x0e", "0x59", "0x39", 12 | "0x67", "0x33", "0x26", "0x67", "0xff", "0xc0", "0x0b", "0x31", 13 | "0x8e", "0xb4", "0x4a", "0x87", "0x68", "0x58", "0x15", "0x11", 14 | "0xdb", "0x0c", "0x2e", "0x0d", "0x64", "0xf9", "0x8f", "0xa7", 15 | "0x47", "0xb5", "0x48", "0x1d", "0xbe", "0xfa", "0x4f", "0xa4"], 16 | "on_match" : { 17 | "type" : "symbol", 18 | "name" : "Blake_384_init" 19 | } 20 | } -------------------------------------------------------------------------------- /scans/blake_512_init.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "Blake_512_init", 4 | "description" : "Detects Blake_512_init", 5 | "family" : "BLAKE", 6 | "type" : "static", 7 | "size" : 1, 8 | "flags" : [ "0x6a", "0x09", "0xe6", "0x67", "0xf3", "0xbc", "0xc9", "0x08", 9 | "0xbb", "0x67", "0xae", "0x85", "0x84", "0xca", "0xa7", "0x3b", 10 | "0x3c", "0x6e", "0xf3", "0x72", "0xfe", "0x94", "0xf8", "0x2b", 11 | "0xa5", "0x4f", "0xf5", "0x3a", "0x5f", "0x1d", "0x36", "0xf1", 12 | "0x51", "0x0e", "0x52", "0x7f", "0xad", "0xe6", "0x82", "0xd1", 13 | "0x9b", "0x05", "0x68", "0x8c", "0x2b", "0x3e", "0x6c", "0x1f", 14 | "0x1f", "0x83", "0xd9", "0xab", "0xfb", "0x41", "0xbd", "0x6b", 15 | "0x5b", "0xe0", "0xcd", "0x19", "0x13", "0x7e", "0x21", "0x79"], 16 | "on_match" : { 17 | "type" : "symbol", 18 | "name" : "Blake_512_init" 19 | } 20 | } -------------------------------------------------------------------------------- /scans/crc32_lzma_table_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "lzma_crc32_table_0", 4 | "description" : "Detects lzma_crc32_table_0", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x96", "0x30", "0x07", "0x77", 9 | "0x2c", "0x61", "0x0e", "0xee", 10 | "0xba", "0x51", "0x09", "0x99", 11 | "0x19", "0xc4", "0x6d", "0x07", 12 | "0x8f", "0xf4", "0x6a", "0x70", 13 | "0x35", "0xa5", "0x63", "0xe9", 14 | "0xa3", "0x95", "0x64", "0x9e", 15 | "0x32", "0x88", "0xdb", "0x0e", 16 | "0xa4", "0xb8", "0xdc", "0x79", 17 | "0x1e", "0xe9", "0xd5", "0xe0", 18 | "0x88", "0xd9", "0xd2", "0x97", 19 | "0x2b", "0x4c", "0xb6", "0x09", 20 | "0xbd", "0x7c", "0xb1", "0x7e", 21 | "0x07", "0x2d", "0xb8", "0xe7"], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "lzma_crc32_table_0" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_lzma_table_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "lzma_crc32_table_2", 4 | "description" : "Detects lzma_crc32_table_2", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x37", "0x6a", "0xc2", "0x01", 9 | "0x6e", "0xd4", "0x84", "0x03", 10 | "0x59", "0xbe", "0x46", "0x02", 11 | "0xdc", "0xa8", "0x09", "0x07", 12 | "0xeb", "0xc2", "0xcb", "0x06", 13 | "0xb2", "0x7c", "0x8d", "0x04", 14 | "0x85", "0x16", "0x4f", "0x05", 15 | "0xb8", "0x51", "0x13", "0x0e", 16 | "0x8f", "0x3b", "0xd1", "0x0f", 17 | "0xd6", "0x85", "0x97", "0x0d", 18 | "0xe1", "0xef", "0x55", "0x0c", 19 | "0x64", "0xf9", "0x1a", "0x09", 20 | "0x53", "0x93", "0xd8", "0x08", 21 | "0x0a", "0x2d", "0x9e", "0x0a"], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "lzma_crc32_table_2" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_lzma_table_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "lzma_crc32_table_3", 4 | "description" : "Detects lzma_crc32_table_3", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x65", "0x67", "0xbc", "0xb8", 9 | "0x8b", "0xc8", "0x09", "0xaa", 10 | "0xee", "0xaf", "0xb5", "0x12", 11 | "0x57", "0x97", "0x62", "0x8f", 12 | "0x32", "0xf0", "0xde", "0x37", 13 | "0xdc", "0x5f", "0x6b", "0x25", 14 | "0xb9", "0x38", "0xd7", "0x9d", 15 | "0xef", "0x28", "0xb4", "0xc5", 16 | "0x8a", "0x4f", "0x08", "0x7d", 17 | "0x64", "0xe0", "0xbd", "0x6f", 18 | "0x01", "0x87", "0x01", "0xd7", 19 | "0xb8", "0xbf", "0xd6", "0x4a", 20 | "0xdd", "0xd8", "0x6a", "0xf2", 21 | "0x33", "0x77", "0xdf", "0xe0"], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "lzma_crc32_table_3" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_lzma_table_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "lzma_crc32_table_5", 4 | "description" : "Detects lzma_crc32_table_5", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xa5", "0xd3", "0x5c", "0xcb", 9 | "0x0b", "0xa1", "0xc8", "0x4d", 10 | "0xae", "0x72", "0x94", "0x86", 11 | "0x16", "0x42", "0x91", "0x9b", 12 | "0xb3", "0x91", "0xcd", "0x50", 13 | "0x1d", "0xe3", "0x59", "0xd6", 14 | "0xb8", "0x30", "0x05", "0x1d", 15 | "0x6d", "0x82", "0x53", "0xec", 16 | "0xc8", "0x51", "0x0f", "0x27", 17 | "0x66", "0x23", "0x9b", "0xa1", 18 | "0xc3", "0xf0", "0xc7", "0x6a", 19 | "0x7b", "0xc0", "0xc2", "0x77", 20 | "0xde", "0x13", "0x9e", "0xbc", 21 | "0x70", "0x61", "0x0a", "0x3a"], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "lzma_crc32_table_5" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_lzma_table_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "lzma_crc32_table_6", 4 | "description" : "Detects lzma_crc32_table_6", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xb4", "0x0b", "0x77", "0xa6", 9 | "0x29", "0x11", "0x9f", "0x97", 10 | "0x9d", "0x1a", "0xe8", "0x31", 11 | "0x13", "0x24", "0x4f", "0xf4", 12 | "0xa7", "0x2f", "0x38", "0x52", 13 | "0x3a", "0x35", "0xd0", "0x63", 14 | "0x8e", "0x3e", "0xa7", "0xc5", 15 | "0x67", "0x4e", "0xef", "0x33", 16 | "0xd3", "0x45", "0x98", "0x95", 17 | "0x4e", "0x5f", "0x70", "0xa4", 18 | "0xfa", "0x54", "0x07", "0x02", 19 | "0x74", "0x6a", "0xa0", "0xc7", 20 | "0xc0", "0x61", "0xd7", "0x61", 21 | "0x5d", "0x7b", "0x3f", "0x50"], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "lzma_crc32_table_6" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_lzma_table_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "lzma_crc32_table_7", 4 | "description" : "Detects lzma_crc32_table_7", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x9e", "0x00", "0xaa", "0xcc", 9 | "0x7d", "0x07", "0x25", "0x42", 10 | "0xe3", "0x07", "0x8f", "0x8e", 11 | "0xfa", "0x0e", "0x4a", "0x84", 12 | "0x64", "0x0e", "0xe0", "0x48", 13 | "0x87", "0x09", "0x6f", "0xc6", 14 | "0x19", "0x09", "0xc5", "0x0a", 15 | "0xb5", "0x1b", "0xe5", "0xd3", 16 | "0x2b", "0x1b", "0x4f", "0x1f", 17 | "0xc8", "0x1c", "0xc0", "0x91", 18 | "0x56", "0x1c", "0x6a", "0x5d", 19 | "0x4f", "0x15", "0xaf", "0x57", 20 | "0xd1", "0x15", "0x05", "0x9b", 21 | "0x32", "0x12", "0x8a", "0x15"], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "lzma_crc32_table_7" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_lzma_table_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "lzma_crc32_table_4", 4 | "description" : "Detects lzma_crc32_table_4", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xb0", "0x29", "0x60", "0x3d", 9 | "0x60", "0x53", "0xc0", "0x7a", 10 | "0xd0", "0x7a", "0xa0", "0x47", 11 | "0xc0", "0xa6", "0x80", "0xf5", 12 | "0x70", "0x8f", "0xe0", "0xc8", 13 | "0xa0", "0xf5", "0x40", "0x8f", 14 | "0x10", "0xdc", "0x20", "0xb2", 15 | "0xc1", "0x4b", "0x70", "0x30", 16 | "0x71", "0x62", "0x10", "0x0d", 17 | "0xa1", "0x18", "0xb0", "0x4a", 18 | "0x11", "0x31", "0xd0", "0x77", 19 | "0x01", "0xed", "0xf0", "0xc5", 20 | "0xb1", "0xc4", "0x90", "0xf8", 21 | "0x61", "0xbe", "0x30", "0xbf" ], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "lzma_crc32_table_4" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_ms_table_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "ms_pst_crc32_table_1", 4 | "description" : "Detects ms_pst_crc32_table_1", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x01", "0xc2", "0x6a", "0x37", 9 | "0x03", "0x84", "0xd4", "0x6e", 10 | "0x02", "0x46", "0xbe", "0x59", 11 | "0x07", "0x09", "0xa8", "0xdc", 12 | "0x06", "0xcb", "0xc2", "0xeb", 13 | "0x04", "0x8d", "0x7c", "0xb2", 14 | "0x05", "0x4f", "0x16", "0x85", 15 | "0x0e", "0x13", "0x51", "0xb8", 16 | "0x0f", "0xd1", "0x3b", "0x8f", 17 | "0x0d", "0x97", "0x85", "0xd6", 18 | "0x0c", "0x55", "0xef", "0xe1", 19 | "0x09", "0x1a", "0xf9", "0x64", 20 | "0x08", "0xd8", "0x93", "0x53", 21 | "0x0a", "0x9e", "0x2d", "0x0a" ], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "ms_pst_crc32_table_1" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_ms_table_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "ms_pst_crc32_table_2", 4 | "description" : "Detects ms_pst_crc32_table_2", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xb8", "0xbc", "0x67", "0x65", 9 | "0xaa", "0x09", "0xc8", "0x8b", 10 | "0x12", "0xb5", "0xaf", "0xee", 11 | "0x8f", "0x62", "0x97", "0x57", 12 | "0x37", "0xde", "0xf0", "0x32", 13 | "0x25", "0x6b", "0x5f", "0xdc", 14 | "0x9d", "0xd7", "0x38", "0xb9", 15 | "0xc5", "0xb4", "0x28", "0xef", 16 | "0x7d", "0x08", "0x4f", "0x8a", 17 | "0x6f", "0xbd", "0xe0", "0x64", 18 | "0xd7", "0x01", "0x87", "0x01", 19 | "0x4a", "0xd6", "0xbf", "0xb8", 20 | "0xf2", "0x6a", "0xd8", "0xdd", 21 | "0xe0", "0xdf", "0x77", "0x33" ], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "ms_pst_crc32_table_2" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_ms_table_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "ms_pst_crc32_table_3", 4 | "description" : "Detects ms_pst_crc32_table_3", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x3d", "0x60", "0x29", "0xb0", 9 | "0x7a", "0xc0", "0x53", "0x60", 10 | "0x47", "0xa0", "0x7a", "0xd0", 11 | "0xf5", "0x80", "0xa6", "0xc0", 12 | "0xc8", "0xe0", "0x8f", "0x70", 13 | "0x8f", "0x40", "0xf5", "0xa0", 14 | "0xb2", "0x20", "0xdc", "0x10", 15 | "0x30", "0x70", "0x4b", "0xc1", 16 | "0x0d", "0x10", "0x62", "0x71", 17 | "0x4a", "0xb0", "0x18", "0xa1", 18 | "0x77", "0xd0", "0x31", "0x11", 19 | "0xc5", "0xf0", "0xed", "0x01", 20 | "0xf8", "0x90", "0xc4", "0xb1", 21 | "0xbf", "0x30", "0xbe", "0x61" ], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "ms_pst_crc32_table_3" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_ms_table_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "ms_pst_crc32_table_4", 4 | "description" : "Detects ms_pst_crc32_table_4", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xcb", "0x5c", "0xd3", "0xa5", 9 | "0x4d", "0xc8", "0xa1", "0x0b", 10 | "0x86", "0x94", "0x72", "0xae", 11 | "0x9b", "0x91", "0x42", "0x16", 12 | "0x50", "0xcd", "0x91", "0xb3", 13 | "0xd6", "0x59", "0xe3", "0x1d", 14 | "0x1d", "0x05", "0x30", "0xb8", 15 | "0xec", "0x53", "0x82", "0x6d", 16 | "0x27", "0x0f", "0x51", "0xc8", 17 | "0xa1", "0x9b", "0x23", "0x66", 18 | "0x6a", "0xc7", "0xf0", "0xc3", 19 | "0x77", "0xc2", "0xc0", "0x7b", 20 | "0xbc", "0x9e", "0x13", "0xde", 21 | "0x3a", "0x0a", "0x61", "0x70" ], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "ms_pst_crc32_table_4" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_ms_table_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "ms_pst_crc32_table_5", 4 | "description" : "Detects ms_pst_crc32_table_5", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xa6", "0x77", "0x0b", "0xb4", 9 | "0x97", "0x9f", "0x11", "0x29", 10 | "0x31", "0xe8", "0x1a", "0x9d", 11 | "0xf4", "0x4f", "0x24", "0x13", 12 | "0x52", "0x38", "0x2f", "0xa7", 13 | "0x63", "0xd0", "0x35", "0x3a", 14 | "0xc5", "0xa7", "0x3e", "0x8e", 15 | "0x33", "0xef", "0x4e", "0x67", 16 | "0x95", "0x98", "0x45", "0xd3", 17 | "0xa4", "0x70", "0x5f", "0x4e", 18 | "0x02", "0x07", "0x54", "0xfa", 19 | "0xc7", "0xa0", "0x6a", "0x74", 20 | "0x61", "0xd7", "0x61", "0xc0", 21 | "0x50", "0x3f", "0x7b", "0x5d" ], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "ms_pst_crc32_table_5" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_ms_table_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "ms_pst_crc32_table_6", 4 | "description" : "Detects ms_pst_crc32_table_6", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0xcc", "0xaa", "0x00", "0x9e", 9 | "0x42", "0x25", "0x07", "0x7d", 10 | "0x8e", "0x8f", "0x07", "0xe3", 11 | "0x84", "0x4a", "0x0e", "0xfa", 12 | "0x48", "0xe0", "0x0e", "0x64", 13 | "0xc6", "0x6f", "0x09", "0x87", 14 | "0x0a", "0xc5", "0x09", "0x19", 15 | "0xd3", "0xe5", "0x1b", "0xb5", 16 | "0x1f", "0x4f", "0x1b", "0x2b", 17 | "0x91", "0xc0", "0x1c", "0xc8", 18 | "0x5d", "0x6a", "0x1c", "0x56", 19 | "0x57", "0xaf", "0x15", "0x4f", 20 | "0x9b", "0x05", "0x15", "0xd1", 21 | "0x15", "0x8a", "0x12", "0x32"], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "ms_pst_crc32_table_6" 26 | } 27 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /modules/ScanMatch.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class ScanMatch: 4 | 5 | def __init__(self, scan): 6 | self.scan = scan 7 | 8 | 9 | class DataConstantScanMatch(ScanMatch): 10 | 11 | def __init__(self, scan, address): 12 | ScanMatch.__init__(self, scan) 13 | self.address = address 14 | 15 | class ILConstantScanMatch(ScanMatch): 16 | 17 | def __init__(self, scan, instruction, flag_chunk): 18 | ScanMatch.__init__(self, scan) 19 | self.instruction = instruction 20 | self.address = instruction.address 21 | self.flag_chunks = [] 22 | self.chunk_ids_found = [] 23 | # We always add the initial chunk 24 | self.add_matched_chunk(flag_chunk, 0) 25 | 26 | def add_matched_chunk(self, flag_chunk, chunk_index): 27 | self.flag_chunks.extend(flag_chunk) 28 | # Clunky way of detecting previous chunks, could just use 29 | # the flags themselves 30 | self.chunk_ids_found.append(chunk_index) 31 | 32 | def found_chunk_id(self, chunk_id): 33 | return chunk_id in self.chunk_ids_found 34 | -------------------------------------------------------------------------------- /modules/ScanConfig.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class ScanConfig: 4 | 5 | def __init__(self, config): 6 | self.name = config['name'] 7 | self.threshold = config['threshold'] 8 | self.family = config['family'] 9 | self.enabled = True # Might be useful later if we let users individually en/disable scans 10 | self.description = config['description'] 11 | self.type = config['type'] 12 | self.size = config['size'] 13 | self.flags = config['flags'] 14 | self.inverse_flags = self._calculate_inverse_flags() 15 | self.match_type = config['on_match']['type'] 16 | self.match_label = config['on_match']['name'] 17 | # Primarily for chunked scan hits to be easily retrieved 18 | self.found = False 19 | 20 | def _calculate_inverse_flags(self): 21 | if self.size == 1: 22 | return self.flags 23 | # Break into self.sized chunks 24 | chunks = [self.flags[i * self.size:(i+1) * self.size] for i in range((len(self.flags) + self.size - 1) // self.size)] 25 | # Recompose with reverse ordered 26 | return [flag for chunk in chunks for flag in reversed(chunk)] 27 | 28 | -------------------------------------------------------------------------------- /scans/crc32_m_tab_be.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "CRC32_m_tab_be", 4 | "description" : "Detects CRC32_m_tab_be", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x96", "0x30", "0x07", "0x77", 9 | "0x2c", "0x61", "0x0e", "0xee", 10 | "0xba", "0x51", "0x09", "0x99", 11 | "0x19", "0xc4", "0x6d", "0x07", 12 | "0x8f", "0xf4", "0x6a", "0x70", 13 | "0x35", "0xa5", "0x63", "0xe9", 14 | "0xa3", "0x95", "0x64", "0x9e", 15 | "0x32", "0x88", "0xdb", "0x0e", 16 | "0xa4", "0xb8", "0xdc", "0x79", 17 | "0x1e", "0xe9", "0xd5", "0xe0", 18 | "0x88", "0xd9", "0xd2", "0x97", 19 | "0x2b", "0x4c", "0xb6", "0x09", 20 | "0xbd", "0x7c", "0xb1", "0x7e", 21 | "0x07", "0x2d", "0xb8", "0xe7", 22 | "0x91", "0x1d", "0xbf", "0x90", 23 | "0x64", "0x10", "0xb7", "0x1d", 24 | "0xf2", "0x20", "0xb0", "0x6a", 25 | "0x48", "0x71", "0xb9", "0xf3"], 26 | "on_match" : { 27 | "threshold" : 50, 28 | "type" : "symbol", 29 | "name" : "CRC32_m_tab_be" 30 | } 31 | } -------------------------------------------------------------------------------- /scans/crc32_m_tab_le.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "CRC32_m_tab_le", 4 | "description" : "Detects CRC32_m_tab_le", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x77", "0x07", "0x30", "0x96", 9 | "0xee", "0x0e", "0x61", "0x2c", 10 | "0x99", "0x09", "0x51", "0xba", 11 | "0x07", "0x6d", "0xc4", "0x19", 12 | "0x70", "0x6a", "0xf4", "0x8f", 13 | "0xe9", "0x63", "0xa5", "0x35", 14 | "0x9e", "0x64", "0x95", "0xa3", 15 | "0x0e", "0xdb", "0x88", "0x32", 16 | "0x79", "0xdc", "0xb8", "0xa4", 17 | "0xe0", "0xd5", "0xe9", "0x1e", 18 | "0x97", "0xd2", "0xd9", "0x88", 19 | "0x09", "0xb6", "0x4c", "0x2b", 20 | "0x7e", "0xb1", "0x7c", "0xbd", 21 | "0xe7", "0xb8", "0x2d", "0x07", 22 | "0x90", "0xbf", "0x1d", "0x91", 23 | "0x1d", "0xb7", "0x10", "0x64", 24 | "0x6a", "0xb0", "0x20", "0xf2", 25 | "0xf3", "0xb9", "0x71", "0x48" ], 26 | "on_match" : { 27 | "threshold" : 50, 28 | "type" : "symbol", 29 | "name" : "CRC32_m_tab_le" 30 | } 31 | } -------------------------------------------------------------------------------- /scans/crc32_lzma_table_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "lzma_crc32_table_1", 4 | "description" : "Detects lzma_crc32_table_1", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x41", "0x31", "0x1b", "0x19", 9 | "0x82", "0x62", "0x36", "0x32", 10 | "0xc3", "0x53", "0x2d", "0x2b", 11 | "0x04", "0xc5", "0x6c", "0x64", 12 | "0x45", "0xf4", "0x77", "0x7d", 13 | "0x86", "0xa7", "0x5a", "0x56", 14 | "0xc7", "0x96", "0x41", "0x4f", 15 | "0x08", "0x8a", "0xd9", "0xc8", 16 | "0x49", "0xbb", "0xc2", "0xd1", 17 | "0x8a", "0xe8", "0xef", "0xfa", 18 | "0xcb", "0xd9", "0xf4", "0xe3", 19 | "0x0c", "0x4f", "0xb5", "0xac", 20 | "0x4d", "0x7e", "0xae", "0xb5", 21 | "0x8e", "0x2d", "0x83", "0x9e", 22 | "0xcf", "0x1c", "0x98", "0x87", 23 | "0x51", "0x12", "0xc2", "0x4a", 24 | "0x10", "0x23", "0xd9", "0x53", 25 | "0xd3", "0x70", "0xf4", "0x78"], 26 | "on_match" : { 27 | "threshold" : 50, 28 | "type" : "symbol", 29 | "name" : "lzma_crc32_table_1" 30 | } 31 | } -------------------------------------------------------------------------------- /scans/sha512_k.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "SHA512_K", 4 | "description" : "Detects SHA512_K", 5 | "family" : "SHA512", 6 | "type" : "static", 7 | "size" : 8, 8 | "flags" : [ "0x42", "0x8a", "0x2f", "0x98", "0xd7", "0x28", "0xae", "0x22", 9 | "0x71", "0x37", "0x44", "0x91", "0x23", "0xef", "0x65", "0xcd", 10 | "0xb5", "0xc0", "0xfb", "0xcf", "0xec", "0x4d", "0x3b", "0x2f", 11 | "0xe9", "0xb5", "0xdb", "0xa5", "0x81", "0x89", "0xdb", "0xbc", 12 | "0x39", "0x56", "0xc2", "0x5b", "0xf3", "0x48", "0xb5", "0x38", 13 | "0x59", "0xf1", "0x11", "0xf1", "0xb6", "0x05", "0xd0", "0x19", 14 | "0x92", "0x3f", "0x82", "0xa4", "0xaf", "0x19", "0x4f", "0x9b", 15 | "0xab", "0x1c", "0x5e", "0xd5", "0xda", "0x6d", "0x81", "0x18", 16 | "0xd8", "0x07", "0xaa", "0x98", "0xa3", "0x03", "0x02", "0x42", 17 | "0x12", "0x83", "0x5b", "0x01", "0x45", "0x70", "0x6f", "0xbe", 18 | "0x24", "0x31", "0x85", "0xbe", "0x4e", "0xe4", "0xb2", "0x8c", 19 | "0x55", "0x0c", "0x7d", "0xc3", "0xd5", "0xff", "0xb4", "0xe2", 20 | "0x72", "0xbe", "0x5d", "0x74", "0xf2", "0x7b", "0x89", "0x6f", 21 | "0x80", "0xde", "0xb1", "0xfe", "0x3b", "0x16", "0x96", "0xb1" ], 22 | "on_match" : { 23 | "threshold" : 50, 24 | "type" : "symbol", 25 | "name" : "SHA512_K" 26 | } 27 | } -------------------------------------------------------------------------------- /scans/crc32_ms_table_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "threshold" : 50, 3 | "name" : "ms_pst_crc32_table_0", 4 | "description" : "Detects ms_pst_crc32_table_0", 5 | "family" : "CRC32", 6 | "type" : "static", 7 | "size" : 4, 8 | "flags" : [ "0x19", "0x1b", "0x31", "0x41", 9 | "0x32", "0x36", "0x62", "0x82", 10 | "0x2b", "0x2d", "0x53", "0xc3", 11 | "0x64", "0x6c", "0xc5", "0x04", 12 | "0x7d", "0x77", "0xf4", "0x45", 13 | "0x56", "0x5a", "0xa7", "0x86", 14 | "0x4f", "0x41", "0x96", "0xc7", 15 | "0xc8", "0xd9", "0x8a", "0x08", 16 | "0xd1", "0xc2", "0xbb", "0x49", 17 | "0xfa", "0xef", "0xe8", "0x8a", 18 | "0xe3", "0xf4", "0xd9", "0xcb", 19 | "0xac", "0xb5", "0x4f", "0x0c", 20 | "0xb5", "0xae", "0x7e", "0x4d", 21 | "0x9e", "0x83", "0x2d", "0x8e", 22 | "0x87", "0x98", "0x1c", "0xcf", 23 | "0x4a", "0xc2", "0x12", "0x51", 24 | "0x53", "0xd9", "0x23", "0x10", 25 | "0x78", "0xf4", "0x70", "0xd3", 26 | "0x61", "0xef", "0x41", "0x92", 27 | "0x2e", "0xae", "0xd7", "0x55", 28 | "0x37", "0xb5", "0xe6", "0x14", 29 | "0x1c", "0x98", "0xb5", "0xd7", 30 | "0x05", "0x83", "0x84", "0x96"], 31 | "on_match" : { 32 | "threshold" : 50, 33 | "type" : "symbol", 34 | "name" : "ms_pst_crc32_table_0" 35 | } 36 | } -------------------------------------------------------------------------------- /__main__.py: -------------------------------------------------------------------------------- 1 | from binaryninja import BinaryViewType 2 | from modules.CryptoScan import CryptoScan 3 | import sys 4 | 5 | import argparse 6 | parser = argparse.ArgumentParser(description='Scan binaries for crypto related contents') 7 | static_parser = parser.add_mutually_exclusive_group(required=False) 8 | static_parser.add_argument('--static', dest='static', action='store_true') 9 | static_parser.add_argument('--no-static', dest='static', action='store_false') 10 | parser.set_defaults(static=True) 11 | 12 | signature_parser = parser.add_mutually_exclusive_group(required=False) 13 | signature_parser.add_argument('--signature', dest='signature', action='store_true') 14 | signature_parser.add_argument('--no-signature', dest='signature', action='store_false') 15 | parser.set_defaults(signature=True) 16 | 17 | il_parser = parser.add_mutually_exclusive_group(required=False) 18 | il_parser.add_argument('--il', dest='il', action='store_true') 19 | il_parser.add_argument('--no-il', dest='il', action='store_false') 20 | parser.set_defaults(il=True) 21 | 22 | parser.add_argument('filenames', nargs='+') 23 | 24 | args = parser.parse_args() 25 | 26 | try: 27 | options = parser.parse_args() 28 | except: 29 | parser.print_help() 30 | sys.exit(0) 31 | 32 | options = {'static' : args.static, 'signature' : args.signature, 'il': args.il} 33 | 34 | if any(option for option in options.values()): 35 | for filename in args.filenames: 36 | bv = BinaryViewType.get_view_of_file(filename) 37 | cs = CryptoScan(bv, options) 38 | cs.start() 39 | -------------------------------------------------------------------------------- /plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginmetadataversion" : 2, 3 | "name": "cryptoscan", 4 | "type": ["ui", "binaryview"], 5 | "api": ["python2", "python3"], 6 | "description": "A plugin to detect several common crypto constructs and magic vars.", 7 | "installinstructions" : { 8 | "Darwin" : "No additional installation required.", 9 | "Linux" : "No additional installation required.", 10 | "Windows" : "No additional installation required." 11 | }, 12 | "longdescription": "A plugin to detect several common crypto constructs and magic vars.", 13 | "license": { 14 | "name": "MIT", 15 | "text": "Copyright (c) 2018 Ben Pottier\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." 16 | }, 17 | "platforms" : ["Darwin", "Linux", "Windows"], 18 | "dependencies": {}, 19 | "version": "1.2", 20 | "author": "Ben Pottier", 21 | "minimumbinaryninjaversion": 4526 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BinaryNinja CryptoScan 2 | ====================== 3 | Plugin for [Binary Ninja](https://binary.ninja/) platform 4 | 5 | ## General 6 | This Binja plugin is effectively trying to replicate [findcrypt](https://github.com/you0708/ida/tree/master/idapython_tools/findcrypt) functionality. It supports a larger range of constants. 7 | 8 | ## Features 9 | ### Overview 10 | The plugin registers a single call that is accessible from the 'Tools' menu or by right-clicking in the main binary view window. 11 | 12 | Scan configurations are reloaded on _every_ call to the scan function. This means you can CRUD json config files and rescan immediately. 13 | 14 | The plugin supports the following types of scans: 15 | 16 | - Scanning for constants in data 17 | - Scanning for constants in the IL 18 | 19 | Will additionally add a tag at each identified location with the family name as the data. 20 | 21 | ### Supported cryptography 22 | 23 | The following constants are defined in scan configurations: 24 | 25 | - AES: sboxes, td0-4, te0-4 26 | - ARIA: sbox2, sbox4 (1 and 3 are equal to Rijndael) 27 | - BLAKE: 224, 256, 384 and 512 inits 28 | - Blowfish: p_array and sbox 29 | - CRC32: lzma tables 0-7, m_tab_le and m_tab_be, ms_table0-6 30 | - DES: p32i, pc1_left, pc1_right, pc2, sbox1-8 31 | - DFC: sbox 32 | - Elliptic Curves: p-192, p-224, p-256, p-384, p-521, Curve25519 33 | - IKE: modp group shared component 34 | - KASUMI: key expansion mod, sbox_s7, sbox_s9 35 | - MD5: initstate and md5_t 36 | - NewDES: sbox 37 | - RC5/RC6: combined constant 38 | - Salsa20: sigma and tau 39 | - SHA1: h 40 | - SHA224: h 41 | - SHA256: both k and h 42 | - SHA512: h 43 | - SM3: init 44 | - SM4: sbox, ck and fk 45 | - TEA: delta 46 | - Mersenne Twister: 19937 edition 47 | - Zlib: distance_starts, distance_extrabits, length_starts, length_extrabits 48 | 49 | ### Reporting 50 | If any matches are identified a Markdown (for GUI) or text (for CLI) report will be shown, listing which scans were matched, what family they belong to as well as the address in the binary. 51 | The aim of the report was to allow easy copy-pasting of the address for use with the 'Go to address...' function. 52 | 53 | Whilst data matches only contain the address at which the constant is defined, IL matches will also indicate the function they were discovered in. 54 | 55 | ### Configuration 56 | Individual scan configurations are kept in the scans subfolder. The following fields are required in the JSON: 57 | 58 | - name: short name for the scan 59 | - description: long name or description, only for author's quality of life 60 | - threshold: for multi-byte constants, minimum amount of n-sized chunks that must be found (e.g. when loading chunked in registers) 61 | - type: static or signature (signatures are currently not implemented though) 62 | - flags: array of single byte strings, usually 4 bytes but no upper bound is set. You can now add null bytes. 63 | - on_match: object with subfields 64 | - type: symbol is the only supported value right now, adds a symbol at the detected address 65 | - name: name to give to the symbol 66 | 67 | ## TODO 68 | - [x] Add more constants 69 | - [x] Make CryptoScan run in the background 70 | - [x] Deal with null bytes in the flags better 71 | - [ ] Flesh out how signature detection will work 72 | - [ ] Refactor data scanning to improve speed on very large binaries 73 | -------------------------------------------------------------------------------- /modules/ScanReport.py: -------------------------------------------------------------------------------- 1 | from .ScanMatch import ILConstantScanMatch, DataConstantScanMatch 2 | 3 | class ScanReport: 4 | 5 | def __init__(self, raw_results, was_cancelled): 6 | self.raw_results = raw_results 7 | self.title = '{prefix}CryptoScan report - found {count} match{plural}'.format( 8 | count = len(raw_results), 9 | prefix = 'Partial ' if was_cancelled else '', 10 | plural = 'es' if len(raw_results) != 1 else '') 11 | self.text_report, self.markdown_report = self._compile_report() 12 | 13 | def _compile_report(self): 14 | text = self._compile_text_report() 15 | markdown = self._compile_markdown_report() 16 | return text, markdown 17 | 18 | def _compile_text_report(self): 19 | text = [] 20 | data_results = [result for result in self.raw_results if isinstance(result, DataConstantScanMatch)] 21 | if len(data_results) != 0: 22 | text.append('Data Constants') 23 | text.append('--------------') 24 | text.append('') 25 | 26 | for result in data_results: 27 | text.append('Name: {name}\nFamily: {family}\nFlags: {flags}\nAddress: {address}\n'.format( 28 | name = result.scan.name, 29 | family = result.scan.family, 30 | flags = '-'.join(result.scan.flags[:4]), 31 | address = hex(result.address).rstrip("L"))) 32 | text.append('') 33 | 34 | il_results = [result for result in self.raw_results if isinstance(result, ILConstantScanMatch)] 35 | if len(il_results) != 0: 36 | text.append('IL Constants') 37 | text.append('------------') 38 | text.append('') 39 | 40 | for result in il_results: 41 | text.append('Name: {name}\nFamily: {family}\nFlags: {flags}\n' + 42 | 'Address: {address}\nFunction: {function}\n'.format( 43 | name = result.scan.name, 44 | family = result.scan.family, 45 | flags = '{flags} {summary}'.format(flags = '-'.join(result.flag_chunks[:4]), 46 | summary = ' + {count} more'.format( 47 | count = len(result.flag_chunks))), 48 | address = hex(result.instruction.address).rstrip("L"), 49 | function = result.instruction.function.source_function)) 50 | 51 | text.append('') 52 | 53 | # text.append('Signatures') 54 | # text.append('----------') 55 | # text.append('') 56 | # Todo: how do we report on signature matches? Function names? Addresses? TBD 57 | # text.append('No results found.') 58 | 59 | return '\n'.join(text) 60 | 61 | def _compile_markdown_report(self): 62 | md = [] 63 | 64 | data_results = [result for result in self.raw_results if isinstance(result, DataConstantScanMatch)] 65 | if len(data_results) != 0: 66 | md.append('## Data Constants') 67 | md.append('') 68 | md.append('| Name | Family | Flags | Address |') 69 | md.append('|:----------------- |:-------:|:-----:| -------:|') 70 | 71 | for result in data_results: 72 | md.append('| {name} | {family} | `{flags}` | [{address}](binaryninja://?expr={address}) |'.format( 73 | name = result.scan.name, 74 | family = result.scan.family, 75 | flags = '-'.join(result.scan.flags[:4]), 76 | address = hex(result.address).rstrip('L'))) 77 | 78 | md.append('') 79 | 80 | il_results = [result for result in self.raw_results if isinstance(result, ILConstantScanMatch)] 81 | if len(il_results) != 0: 82 | md.append('## IL Constants') 83 | md.append('') 84 | md.append('| Name | Family | Flags | Address | Function |') 85 | md.append('|:----------------- |:-------:|:-----:| -------:|:--------:|') 86 | 87 | for result in il_results: 88 | md.append('| {name} | {family} | `{flags}` | [{address}](binaryninja://?expr={address}) | {function} |'.format( 89 | name = result.scan.name, 90 | family = result.scan.family, 91 | flags = '{flags} {summary}'.format(flags = '-'.join(result.flag_chunks[:4]), 92 | summary = ' + {count} more'.format( 93 | count = len(result.flag_chunks))), 94 | address = hex(result.instruction.address).rstrip("L"), 95 | function = '{name} @ {address}'.format( 96 | name = result.instruction.function.source_function.name, 97 | address = hex(result.instruction.function.source_function.symbol.address).rstrip('L')))) 98 | 99 | md.append('') 100 | 101 | # md.append('## Signatures') 102 | # md.append('') 103 | # Todo: how do we report on signature matches? Function names? Addresses? TBD 104 | # md.append('No results found.') 105 | 106 | return '\n'.join(md) 107 | -------------------------------------------------------------------------------- /modules/CryptoScan.py: -------------------------------------------------------------------------------- 1 | import binaryninja as bn 2 | from binaryninja.plugin import BackgroundTaskThread 3 | import os, json, binascii 4 | from .ScanConfig import ScanConfig 5 | from .ScanMatch import DataConstantScanMatch, ILConstantScanMatch 6 | from .ScanReport import ScanReport 7 | 8 | 9 | class CryptoScan(BackgroundTaskThread): 10 | 11 | debug_address = None 12 | 13 | def __init__(self, bv, options): 14 | BackgroundTaskThread.__init__(self, 'Beginning scan for crypto constructs...', True) 15 | self.bv = bv 16 | self.options = options 17 | self.br = bn.BinaryReader(self.bv, bn.Endianness.LittleEndian) 18 | self.log_info('Initialising Plugin') 19 | self.scanconfigs = [] 20 | self.load_configs() 21 | self.log_info('Loaded {count} configurations'.format(count = len(self.scanconfigs))) 22 | 23 | def load_configs(self): 24 | cwd = os.path.dirname(os.path.realpath(__file__)) 25 | config_path = os.path.join(cwd, '..', 'scans') 26 | json_files = [json_file for json_file in os.listdir(config_path) if json_file.endswith('.json')] 27 | for f in json_files: 28 | with open(os.path.join(config_path, f)) as json_file: 29 | json_config = json.load(json_file) 30 | if all(option in json_config for option in ['name', 31 | 'description', 32 | 'size', 33 | 'threshold', 34 | 'type', 35 | 'flags', 36 | 'on_match']): 37 | config = ScanConfig(json_config) 38 | self.scanconfigs.append(config) 39 | else: 40 | self.log_error('Invalid config file: {filename}'.format(filename = json_file)) 41 | 42 | def run(self): 43 | results = [] 44 | 45 | if self.options['static']: 46 | self.log_progress('Running data constant scans...') 47 | results.extend(self.run_data_constant_scans()) 48 | 49 | if self.options['il'] and not self.cancelled: 50 | self.log_progress('Running IL constant scans...') 51 | results.extend(self.run_il_constant_scans()) 52 | 53 | if self.options['signature'] and not self.cancelled: 54 | self.log_progress('Running signature scans') 55 | results.extend(self.run_signature_scans()) 56 | 57 | # Proceed to results, if cancelled display notification 58 | if self.cancelled: 59 | self.log_progress('Cancelling scan, checking for partial results...') 60 | 61 | results = self.prune_results(results) 62 | if len(results) != 0: 63 | self.log_progress('Scan found {count} match{plural}'.format(count = len(results), 64 | plural = '' if len(results) == 1 else 'es')) 65 | self.apply_symbols(results) 66 | self.apply_tags(results) 67 | self.display_results(results) 68 | elif not self.cancelled: 69 | self.log_progress('No scan results found') 70 | # Temporarily disabled pending better way to not block multiple command-line output 71 | #bn.show_message_box('CryptoScan results', 72 | # 'No crypto constructs identified.', 73 | # bn.MessageBoxButtonSet.OKButtonSet, 74 | # bn.MessageBoxIcon.InformationIcon) 75 | 76 | # Todo: move to dedicated class for scanners 77 | def run_il_constant_scans(self): 78 | results = [] 79 | const_instructions = [] 80 | scans = [scan for scan in self.scanconfigs if scan.type == 'static' and scan.enabled] 81 | 82 | # Because of potential deep trees this isn't a true reflection of progress 83 | progress_trigger = 5 84 | num_instructions = len(list(self.bv.mlil_instructions)) 85 | self.log_progress('Finding constants defined in IL') 86 | for instr_index, instruction in enumerate(self.bv.mlil_instructions): 87 | percentage = instr_index*100 / num_instructions 88 | if percentage >= progress_trigger: 89 | progress_trigger += 5 90 | while progress_trigger < percentage: 91 | progress_trigger += 5 92 | self.log_progress('Finding constants defined in IL ({percentage:.3f}%)'.format(percentage = percentage)) 93 | const_instructions.extend(self.recurse_retrieve_consts(instruction)) 94 | 95 | # Second pass, actually evaluate the found constants 96 | self.log_progress('Evaluating found IL constants') 97 | progress_trigger = 5 98 | num_consts = len(const_instructions) 99 | for const_index, instr in enumerate(const_instructions): 100 | percentage = const_index*100 / num_consts 101 | if percentage >= progress_trigger: 102 | progress_trigger += 5 103 | while progress_trigger < percentage: 104 | progress_trigger += 5 105 | self.log_progress('Evaluating found IL constants ({percentage:.3f}%)'.format(percentage = percentage)) 106 | # Skip constants that aren't at least several bytes, or we will get tons of false positives 107 | if not instr.size > 1: 108 | continue 109 | for scan in scans: 110 | # Some constants are broken up across multiple instructions. 111 | # This chunking will detect all of them 112 | chunks = [scan.flags[i * instr.size:(i+1) * instr.size] for i in range((len(scan.flags) + 3) // 4)] 113 | for chunk_index, chunk in enumerate(chunks): 114 | if len(chunk) == instr.size: 115 | flag_value = ''.join((flag.replace('0x', '') for flag in chunk)) 116 | const_value = '{:x}'.format(instr.constant) 117 | if const_value == flag_value: 118 | # We found a hit, did we previously find a chunk from this scan? 119 | if scan.found: 120 | for index, result in enumerate(results): 121 | if scan.name == result.scan.name and \ 122 | result.instruction.function.source_function.name == \ 123 | instr.function.source_function.name and \ 124 | not result.found_chunk_id(chunk_index): 125 | result.add_matched_chunk(list(chunk), chunk_index) 126 | results[index] = result 127 | else: 128 | scan.found = True 129 | results.append(ILConstantScanMatch(scan, instr, chunk)) 130 | 131 | return results 132 | 133 | def recurse_retrieve_consts(self, instruction): 134 | results = [] 135 | if instruction.operation == bn.MediumLevelILOperation.MLIL_CONST: 136 | results.append(instruction) 137 | else: 138 | for operand in instruction.operands: 139 | if type(operand) == bn.MediumLevelILInstruction: 140 | results.extend(self.recurse_retrieve_consts(operand)) 141 | return results 142 | 143 | # Todo: move to dedicated class for scanners 144 | def run_data_constant_scans(self): 145 | results = [] 146 | 147 | scans = [scan for scan in self.scanconfigs if scan.type == 'static' and scan.enabled] 148 | # We use the first int as a trigger to investigate any scan further 149 | triggers = [scan.flags[0] for scan in scans] 150 | 151 | # Where implementations can be multi-byte, we should check opposite byte order too 152 | multi_byte_scans = [scan for scan in self.scanconfigs if scan.size > 1] 153 | inverse_triggers = [scan.inverse_flags[0] for scan in multi_byte_scans] 154 | 155 | progress_trigger = 5 156 | start_offset = self.br.offset 157 | total_distance = self.bv.length 158 | 159 | while not self.br.eof and not self.cancelled: 160 | debug = False 161 | 162 | if self.debug_address is not None and self.br.offset == int(self.debug_address, 16): 163 | self.log_info('At debug address') 164 | debug = True 165 | 166 | b = self.next_byte() 167 | 168 | percentage = (self.br.offset - start_offset)*100 / total_distance 169 | if percentage >= progress_trigger: 170 | progress_trigger += 5 171 | while progress_trigger < percentage: 172 | progress_trigger += 5 173 | self.log_progress('Scanning data for constants ({percentage:.3f}%)'.format(percentage = percentage)) 174 | 175 | if b is None: 176 | break 177 | 178 | for index, trigger in enumerate(triggers): 179 | if debug: 180 | self.log_info('Checking trigger {} for scan {} against byte {}'.format(trigger, 181 | scans[index].name, hex(b))) 182 | # TODO: refactor this, null-byte triggers will chew up an inordinate amount of time 183 | # Possible solutions include caching temporarily when hits are detected, grouping triggers 184 | # and terminating early if we check flag bytes 1 by 1 185 | if b == int(trigger, 16): 186 | 187 | if debug: 188 | self.log_info('Trigger match at debug address for scan {}'.format(scans[index].name)) 189 | 190 | scan = scans[index] 191 | # See how many more values we need 192 | flag_count = len(scan.flags) - 1 193 | 194 | # Fetch them 195 | test_bytes = [] 196 | bytes_read = 0 197 | for i in range(flag_count): 198 | null_wanted = False 199 | if int(scan.flags[i+1], 16) == 0: 200 | null_wanted = True 201 | test_byte, count = self.seek_next_byte(allow_null = null_wanted) 202 | bytes_read += count 203 | if test_byte is not None: 204 | test_bytes.append(test_byte) 205 | 206 | # Sanity check we got enough bytes and confirm the match 207 | if len(test_bytes) == flag_count and test_bytes == [int(tb, 16) for tb in scan.flags[1:]]: 208 | # Save the match with the address 209 | address = self.br.offset - (bytes_read+1) 210 | result = DataConstantScanMatch(scan, address) 211 | results.append(result) 212 | 213 | # Track back irrespective 214 | self.br.offset -= bytes_read 215 | 216 | # And reverse byte order 217 | for index, trigger in enumerate(inverse_triggers): 218 | if debug: 219 | self.log_info('Checking inverse trigger {} for scan {} against byte {}' 220 | .format(trigger, multi_byte_scans[index].name, hex(b))) 221 | if b == int(trigger, 16): 222 | 223 | if debug: 224 | self.log_info('Inverse trigger match at debug address for scan {}' 225 | .format(multi_byte_scans[index].name)) 226 | 227 | scan = multi_byte_scans[index] 228 | # See how many more values we need 229 | flag_count = len(scan.inverse_flags) - 1 230 | 231 | # Fetch them 232 | test_bytes = [] 233 | bytes_read = 0 234 | for i in range(flag_count): 235 | null_wanted = False 236 | if int(scan.inverse_flags[i+1], 16) == 0: 237 | null_wanted = True 238 | test_byte, count = self.seek_next_byte(allow_null = null_wanted) 239 | bytes_read += count 240 | if test_byte is not None: 241 | test_bytes.append(test_byte) 242 | 243 | # Sanity check we got enough bytes and confirm the match 244 | if len(test_bytes) == flag_count and test_bytes == [int(tb, 16) for tb in scan.inverse_flags[1:]]: 245 | # Save the match with the address 246 | address = self.br.offset - (bytes_read+1) 247 | result = DataConstantScanMatch(scan, address) 248 | results.append(result) 249 | 250 | # Track back irrespective 251 | self.br.offset -= bytes_read 252 | 253 | return results 254 | 255 | def prune_results(self, results): 256 | valid_results = [] 257 | for result in results: 258 | if isinstance(result, ILConstantScanMatch): 259 | max_match_len = len(result.scan.flags) 260 | matched_len = len(result.flag_chunks) 261 | match_rate = (100*matched_len) / max_match_len 262 | if match_rate >= result.scan.threshold: 263 | valid_results.append(result) 264 | else: 265 | self.log_info("Scan {name} had match rate of {rate:.3f} vs threshold {threshold:.3f}".format( 266 | name = result.scan.name, 267 | rate = match_rate, 268 | threshold = result.scan.threshold 269 | )) 270 | else: 271 | # data constants are a straight pass 272 | # we only chunk during IL scans 273 | valid_results.append(result) 274 | return valid_results 275 | 276 | def run_signature_scans(self): 277 | results = [] 278 | for scan in [scan for scan in self.scanconfigs if scan.type == 'signature']: 279 | ''' Magic goes here - probably ask Josh some more ''' 280 | return results 281 | 282 | def display_results(self, results): 283 | report = ScanReport(results, self.cancelled) 284 | self.bv.show_markdown_report(report.title, report.markdown_report, report.text_report) 285 | 286 | def apply_tags(self, results): 287 | tag_types = {} 288 | for result in results: 289 | family = result.scan.family 290 | if family not in tag_types: 291 | tag_types[family] = self.bv.create_tag_type(family, "🔐") 292 | self.bv.add_tag(result.address, family, result.scan.name) 293 | 294 | def apply_symbols(self, results): 295 | for result in results: 296 | self.set_symbol(result.address, result.scan.match_label) 297 | 298 | def set_symbol(self, address, label): 299 | if self.bv.is_valid_offset(address): 300 | symbol = bn.Symbol(bn.SymbolType.ImportedDataSymbol, address, label) 301 | self.bv.define_user_symbol(symbol) 302 | else: 303 | self.log_error('Invalid address for symbol: {address}'.format(address = address)) 304 | 305 | def seek_next_byte(self, max_dist = 15, allow_null = False): 306 | # Finds the next non-zero byte, up to max_dist 307 | # Default is 15 to allow up to 128 bit offsets 308 | # However, if we allow nulls (presumably because we're looking for one) 309 | # then we increase this limit as we will return early 310 | if allow_null: 311 | max_dist = (max_dist * 2) + 1 312 | while not self.bv.is_valid_offset(self.br.offset) and not self.br.eof: 313 | self.br.seek_relative(1) 314 | dist = 0 315 | while not self.br.eof and dist <= max_dist: 316 | dist += 1 317 | byte = self.br.read(1) 318 | if byte is None: 319 | self.br.seek_relative(1) 320 | continue 321 | byte = int(binascii.hexlify(byte), 16) 322 | if byte != 0 or allow_null: 323 | return byte, dist 324 | return None, dist 325 | 326 | def next_byte(self): 327 | while not self.bv.is_valid_offset(self.br.offset) and not self.br.eof: 328 | self.br.seek_relative(1) 329 | if self.br.eof: 330 | return None 331 | byte = self.br.read(1) 332 | return int(binascii.hexlify(byte), 16) 333 | 334 | def log_progress(self, msg): 335 | self.progress = '[CryptoScan] {message}'.format(message = msg) 336 | 337 | def log_info(self, msg): 338 | bn.log_info('[CryptoScan] {message}'.format(message = msg)) 339 | 340 | def log_error(self, msg): 341 | bn.log_error('[CryptoScan] {message}'.format(message = msg)) 342 | --------------------------------------------------------------------------------