如何用grep匹配回车符(CR)或行尾的私钥起始字符串?
查找硬编码私钥的grep命令问题
我需要在数千个文件中查找硬编码的私钥以识别恶意文件,同时跳过将该字符串定义为变量的合法文件。要求匹配所有包含-----BEGIN PRIVATE KEY-----且其后接0个或1个回车符(CR)并到行尾的文件,但尝试多种grep命令均未成功:
# grep -iIREn "BEGIN PRIVATE KEY-----\r" /tmp/hck-bck/ grep: warning: stray \ before r # grep -iIREn "BEGIN PRIVATE KEY-----" /tmp/hck-bck/ /tmp/hck-bck/style.php:123:$privateKey = '-----BEGIN PRIVATE KEY----- # grep -iIREn "BEGIN PRIVATE KEY-----( )" /tmp/hck-bck/ grep: warning: stray \ before r # grep -iIREn "BEGIN PRIVATE KEY-----[[:cntrl:]]" /tmp/hck-bck/ # grep -iIREn "BEGIN PRIVATE KEY-----[[:cntrl:]]?$" /tmp/hck-bck/ # grep -iIREn "BEGIN PRIVATE KEY-----.$" /tmp/hck-bck/ # grep -iIREn "BEGIN PRIVATE KEY-----\$" /tmp/hck-bck/ # grep -iIREn 'BEGIN PRIVATE KEY-----[\r]' /tmp/hck-bck/ # grep -iIREn 'BEGIN PRIVATE KEY-----[[:cntrl:]]?$' /tmp/hck-bck/ # grep -iIREn "BEGIN PRIVATE KEY-----\\r" /tmp/hck-bck/ grep: warning: stray \ before r #
不加后缀会出现大量误报;用[:cntrl:]理论上能匹配控制字符但无输出;用\r会报错且无匹配,尝试单双引号、替换-P/-E均无效,还会匹配部分PHP文件中的字面量\r。
查看目标文件内容(cat -A显示控制字符):
#cat -A style.php .... }^M$ $privateKey = '-----BEGIN PRIVATE KEY-----^M$ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC30w49ItOfldQ6^M$ dB+0gEbeeW6BEClcx+NZzmpX2YcRHFV80BurCWBavPFehV8Sy9yL2u/y3mv3QJJ+^M$ x2kKvly8zKx4GbXPbsWJk6Ho0Rxq49oXkBarQBOqROZeaFF3Mzpd/PdLSsxEvG1M^M$ tQd2wOx5r6XD86jyfN7LAJUUVvbJvn1CHo03nFH12k1KYwLnQfzQI5nX7yQLa0jt^M$ fG5TA34Fm0EMbFdHWjAN/VdEjoJI6it4PCQP5wk4ga2BvVquQkuPbsbr8364d3I6^M$ GuGAKDR0wfkT20n0E6kAmDI3ol2bfa0rQncqUS3OU3INpxOZS8eKCIgC3bM81mdi^M$ MQ6TsAQ9AgMBAAECggEAJLGSlA2RpLdpx8lKUuOQQfSHZGfveb/E2DZl7+dSGM5J^M$ .............
该文件明确包含回车符(^M即CR)和行尾,为何[:cntrl:]无匹配输出?如何正确指定最后一个短横线后的回车符实现精准匹配?
补充尝试的命令输出:
# grep -ERn $'BEGIN PRIVATE KEY-----\r?$' /tmp/hck-bck/ # grep -ERn $'BEGIN PRIVATE KEY-----.$' /tmp/hck-bck/ # grep -ERn $'BEGIN PRIVATE KEY-----' /tmp/hck-bck/ /tmp/hck-bck/style.php:123:$privateKey = '-----BEGIN PRIVATE KEY----- #
问题分析与解决方法
1. 命令失效原因
\r解析问题:普通grep默认不识别字符串中的\r为回车符,需用bash的ANSI-C引用($'...')或启用PCRE模式(-P)才能正确解析。-I选项干扰:你之前的命令加了-I(忽略二进制文件),如果文件含特殊字符(如CR),grep可能误判为二进制文件直接跳过,导致[:cntrl:]无输出。- 行尾匹配逻辑:grep默认以LF(
\n)作为行结束符,CRLF格式的文件中,CR(\r)会留在行尾,此时$匹配的是LF前的位置,需明确匹配这个可选的CR。
2. 正确匹配命令
方法一:使用ANSI-C引用(bash/zsh支持)
grep -ERn $'-----BEGIN PRIVATE KEY-----\r?$' /tmp/hck-bck/
$'...'让bash将\r解析为真实的回车符\r?匹配0或1个回车符- 去掉
-I选项,避免文件被误判为二进制跳过
方法二:启用PCRE模式(需grep支持-P)
grep -PRn '-----BEGIN PRIVATE KEY-----\r?$' /tmp/hck-bck/
-P启用Perl正则表达式,直接支持\r表示回车符
3. 排除合法变量定义
如果要跳过类似$privateKey = '...'的合法行,可添加反向匹配:
# 方法1:管道过滤 grep -ERn $'-----BEGIN PRIVATE KEY-----\r?$' /tmp/hck-bck/ | grep -v '\$privateKey =' # 方法2:正则负向前瞻(需-P模式) grep -PRn '(?!\$privateKey = )-----BEGIN PRIVATE KEY-----\r?$' /tmp/hck-bck/
(?!...)是负向前瞻,排除前面包含$privateKey =的行
内容的提问来源于stack exchange,提问作者DenisZ
相关产品推荐
相关产品推荐

