如何在Bash脚本中测试受密码保护的密钥文件并解决报错?
问题:Bash脚本密码测试时出现"Illegal option"错误
我正在编写一个Bash脚本,需求是从Linux根目录搜索带有.p12、.jks、.pfx、.pem、.ppk扩展名的文件,将路径存入文本文件后,用通用密码列表测试这些受密码保护文件的密码强度。目前搜索功能正常,但实现自动密码测试逻辑时遇到问题:原本手动输入密码可以正常运行,修改为自动读取密码列表后出现“Illegal option”错误,密码被误识别为命令选项。
原脚本
#!/bin/bash #This script, in theory, should search an entire linux instance for files with extensions #.p12, .jks, .pfx, .pem, .ppk. Any found files will be saved to a text doc. For each file in said #doc, we will attempt to open the file with a list of generic passwds. If there are any #successes, we will save that file and the passwd to a different flag doc to be addressed. #This should search a named directory for the file extensions and save to output file find / -name *.p12 -o -name *.jks > keytoolFile.txt #As a test, iterate over the output file and name them keyFile=$(cat keytoolFile.txt) passFile=$(cat pass.txt) for i in $keyFile; do for j in $passFile; do echo -e "Attempting $j on $i" keytool -list -keystore $line -storepass $j done done #This next bit should go through the next set of file extensions and test them find / -name *.pfx -o -name *.pem -o -name *.ppk > sshFile.txt hostFile=$(cat sshFile.txt) passFile=$(cat pass.txt) for i in $hostFile; do for j in $passFile; do echo -e "Attempting $j on $i" ssh-keygen -f -y $i -P $j done done
报错信息
Attempting 1qaz)OKM2wsx(IJN on <path/to/file/file.p12 Illegal option: 1qaz!QAZ2wsx@WSX
错误原因分析
- 变量未加引号导致特殊字符解析错误:密码中的
!、@、)等特殊字符会被Shell解析为命令历史替换、位置参数展开或语法符号,进而被当成命令选项处理。 - 循环变量引用错误:第一个循环中使用了未定义的
$line变量,实际应该用循环变量$i,这会导致-keystore参数为空,密码被错误识别为命令选项。 - ssh-keygen参数顺序错误:
ssh-keygen的-y选项需要放在-f之前,且-f必须紧跟文件名,原脚本参数顺序颠倒后,文件名被当成选项解析。 - 文件读取方式不严谨:直接将
cat输出赋值给变量再循环,会把文件名中的空格、换行符当成分隔符,导致文件名被拆分,无法正确识别文件路径。
修复后的脚本
#!/bin/bash # 搜索.p12和.jks文件,用-print0和xargs处理含特殊字符的文件名 find / \( -name "*.p12" -o -name "*.jks" \) -print0 | xargs -0 > keytoolFile.txt # 逐行读取文件和密码,避免特殊字符解析问题 while IFS= read -r key_path; do while IFS= read -r password; do echo "Attempting password '$password' on file '$key_path'" # 变量加双引号,修正循环变量引用,重定向冗余输出 keytool -list -keystore "$key_path" -storepass "$password" >/dev/null 2>&1 # 记录成功破解的结果 if [ $? -eq 0 ]; then echo "SUCCESS: Password '$password' works for $key_path" >> successful_keys.txt fi done < pass.txt done < keytoolFile.txt # 搜索.pfx、.pem、.ppk文件,同样处理特殊文件名 find / \( -name "*.pfx" -o -name "*.pem" -o -name "*.ppk" \) -print0 | xargs -0 > sshFile.txt while IFS= read -r ssh_path; do while IFS= read -r password; do echo "Attempting password '$password' on file '$ssh_path'" # 修正ssh-keygen参数顺序,变量加双引号 ssh-keygen -y -f "$ssh_path" -P "$password" >/dev/null 2>&1 if [ $? -eq 0 ]; then echo "SUCCESS: Password '$password' works for $ssh_path" >> successful_keys.txt fi done < pass.txt done < sshFile.txt
额外注意事项
- 用
while IFS= read -r读取文件,能正确处理含空格、特殊字符的文件名和密码。 - 给所有变量加上双引号,避免Shell解析特殊字符。
- 重定向
keytool和ssh-keygen的输出到/dev/null,避免冗余信息干扰脚本输出,只记录成功结果。 find命令中用括号分组条件,确保逻辑正确,同时用-print0配合xargs -0处理含特殊字符的文件名。
内容的提问来源于stack exchange,提问作者rootkit_nick
相关产品推荐
相关产品推荐

