V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ksc010
V2EX  ›  程序员

网站注册页面的短信验证接口被利用了,有一个思路

  •  1
     
  •   ksc010 · 2020-05-25 15:36:16 +08:00 · 4834 次点击
    这是一个创建于 1404 天前的主题,其中的信息可能已经有所发展或是发生改变。
    今天刚发现看了下日志 每天发送几千条短信,都是恶意的,手机号应该是随机生成的
    用了代理 ip

    我现在有一个思路是 在注册页面执行一个耗费资源的 js 计算(比如 1-3s )
    计算后得到一个结果,这个结果可以传递到后端,并且后端很容易能做出校验
    目的就是增加对方破解的难度
    最好是能利用一些 浏览器环境信息,还有用户行为啥的 (后端能验证下是否是机器人)
    不知道这样可行么
    第 1 条附言  ·  2020-05-25 16:22:03 +08:00
    1. 目前是有验证码 相对来说挺复杂的(有混淆)但是现有的 dama 平台是可以破解的
    2. 限制了单个 ip 单个手机号的发送次数,但是对方用了代理 手机号也不重复(前几位都是固定的几组 比如 1863321 这样的 后几位随机)

    目前通过一些简单的手段暂时 暂时识别出来对方“身份”,然后返回发送成功(实际没有发送短信)
    但这个不是长久方法,一旦对方反应过来,这个方法就失效了
    第 2 条附言  ·  2020-05-25 18:42:48 +08:00
    我真是服了

    排查了下发现 原来一个同事代码写错了

    有一个判断 特殊情况下 不需要发送验证码(增加了时间限制 ,短期内有效)

    但是 他把 代码写成了

    if (!is_xxxx){
    执行验证码验证逻辑
    }

    对 我们用的是 php,is_xxxx 这个变量没有加$
    然后就一直是 false
    第 3 条附言  ·  2020-05-25 19:17:59 +08:00
    最后根据大家的回复,在现有方案上总结几点优化方案

    0. 增加图形验证码,并确定有效
    1. 校验图形验证码获取和校验的时间间隔 不能太短也不能太长
    2. 校验图形验证码获取和校验时候的 ip 是否一样 一般用户不会频繁切换 ip
    3. 校验 session 存活时间 是否 合理
    4. 校验是否请求了必定会请求的页面(图片,css 等都可以)
    5. 不提示具体验证错误原因
    43 条回复    2020-05-25 18:44:52 +08:00
    Croxx
        1
    Croxx  
       2020-05-25 15:38:20 +08:00 via iPhone
    lz 验证码呢?
    ksc010
        2
    ksc010  
    OP
       2020-05-25 15:39:29 +08:00
    @Croxx 有验证码的 杂色 划线 干扰字符 都有
    sunziren
        3
    sunziren  
       2020-05-25 15:39:48 +08:00
    发短信之前先填写验证码,完了之后才可以输入手机号码如何?
    whitev2
        4
    whitev2  
       2020-05-25 15:40:10 +08:00
    挖矿 5s ?
    wbrobot
        5
    wbrobot  
       2020-05-25 15:40:14 +08:00
    验证邮箱免费
    ksc010
        6
    ksc010  
    OP
       2020-05-25 15:40:32 +08:00
    @sunziren 现在就是这样子的
    Cmdhelp
        7
    Cmdhelp  
       2020-05-25 15:48:06 +08:00
    滑块
    labulaka521
        8
    labulaka521  
       2020-05-25 15:49:32 +08:00 via Android
    验证码估计很简单
    kucy
        9
    kucy  
       2020-05-25 15:50:22 +08:00
    imaning
        10
    imaning  
       2020-05-25 15:51:14 +08:00
    我用的极验
    iamverylovely
        11
    iamverylovely  
       2020-05-25 15:52:27 +08:00
    感觉验证码没起到作用啊,必须输入验证码,验证码正确,才能发短信,一次失效,应该是不会有这种问题的吧
    wanwaneryide
        12
    wanwaneryide  
       2020-05-25 16:02:45 +08:00
    手机号不一定是随机的,有可能被拿来做短信轰炸了,基本上这类软件都是这样的。
    ychost
        13
    ychost  
       2020-05-25 16:06:34 +08:00
    挖矿吧,前端挖 0.00001 个 ETH,然后才给验证码,这样既满足了楼主的需求,还能浪费电
    zpfhbyx
        14
    zpfhbyx  
       2020-05-25 16:08:00 +08:00
    比如加载某个比较小的图片.. 改成后端数据流渲染,然后 js 判断是否是无头浏览器, 如果没有加载图片,就认为是机器呗,验证码不实际发送,返回发送成功,后台记录就好
    brader
        15
    brader  
       2020-05-25 16:08:08 +08:00   ❤️ 1
    可提供如下参考思路:
    一:接口设计加一个 sign 字段,sign 不对的都为非法请求(这条只能拦截初级程序员,网页端源码较容易看到,APP 端需要反编译,能稍微提高一定的技术门槛吧)。
    二:限制每个 IP 每天发送短信的频率。
    三:增加一些技术成熟的验证码功能(如:极验)。
    四:表单请求中,附带 token,避免重复提交。
    五:APP 的话,可以要求前端传递设备唯一标识号。
    六:后端捕获到客户端频繁、严重违反上诉行为的,直接封 IP 、封设备、封账号。
    七:对于违反上诉行为的,后端不要返回具体错误原因给客户端,返回一个模糊错误即可,这样能增加客户端猜解接口报错原因的难度。
    coolcoffee
        16
    coolcoffee  
       2020-05-25 16:10:08 +08:00
    我觉得还是加个图形验证码或者交互验证码作为前置吧,万一攻击者拿其他肉鸡作为运算机器呢。
    ksc010
        17
    ksc010  
    OP
       2020-05-25 16:15:52 +08:00
    @iamverylovely 目前验证码相对来说挺复杂的(有混淆)但是先有的 dama 平台是可以破解的
    早就限制了 单个 ip 单个手机号的发送次数,但是对方用了代理 手机号也不重复
    @wanwaneryide 是随机的 前几位都是固定的几组 比如 1863321 这样的
    brader
        18
    brader  
       2020-05-25 16:18:16 +08:00
    另外,还有一些巧妙的防御思路,自己可以花点心思琢磨:
    比如:接口调用顺序(一般用户去你网址注册,会先去首页,再点注册),你发现这个客户端,直接就调用注册接口的,就可归类为非法请求。前提也是不要抛出具体错误原因给客户端,让客户端猜不出什么原因造成的非法请求。

    其实,短信的攻防没有完美的解决方案,在于攻击你的人愿不愿意付出更多的成本来攻击你,也就是从你那里获得的回报要能大于他的付出,控制好这个点就 ok 了,你做了图片验证,他使用 OCR 和打码平台也是需要成本的,当成本高于收益,他自然不会干这种傻事
    shiny
        19
    shiny  
       2020-05-25 16:23:52 +08:00
    对于这条:1. 目前是有验证码 相对来说挺复杂的(有混淆)但是现有的 dama 平台是可以破解的

    破解也要花钱,如果成本和短信持平,那就没有动力来利用你的接口了。
    ksc010
        20
    ksc010  
    OP
       2020-05-25 16:24:52 +08:00
    @brader 对 这个方法也想来
    同时加上 session 存活时间等等的判断
    tankren
        21
    tankren  
       2020-05-25 16:41:46 +08:00
    手势验证?
    ksc010
        22
    ksc010  
    OP
       2020-05-25 16:57:52 +08:00
    @tankren 我这是网站 咋手势验证
    Vegetable
        23
    Vegetable  
       2020-05-25 17:04:37 +08:00
    打码平台是有成本的啊,谁没事闲的花钱搞你?
    是不是验证码太简单了,可以考虑付费的验证码
    d5
        24
    d5  
       2020-05-25 17:08:27 +08:00   ❤️ 1
    试试 recaptcha
    ksc010
        25
    ksc010  
    OP
       2020-05-25 17:13:26 +08:00
    @Vegetable 怀疑是竞品
    id7368
        26
    id7368  
       2020-05-25 17:17:09 +08:00 via iPhone
    挂个门罗币挖矿脚本岂不美滋滋😂😂😂
    gz911122
        27
    gz911122  
       2020-05-25 17:17:33 +08:00   ❤️ 2
    终极办法,
    改成上行验证码, 用户发送短信到你指定的号码.
    就微信那样.
    arthas2234
        28
    arthas2234  
       2020-05-25 17:19:12 +08:00
    教你一个小技巧,无论是否验证成功,在接口那都返回成功,但是不发短信
    COKETSANG
        29
    COKETSANG  
       2020-05-25 17:21:12 +08:00   ❤️ 1
    1.在你网站上面跳转注册页面的时候中间加一次跳转到一个你指定的地址
    2.发送请求接口里面可以判断 HTTP_REFERER 是否来自你 1 指定的地址

    更复杂的话可以在这个中间地址加上一个随机秘钥,中间地址跳转到注册页面的时候把这个随机秘钥传递到注册页面,用中间地址传递的秘钥生成 TOKEN 传给后端做匹配校验。

    简单说还是增加了破解的复杂程度跟尽可能排除机器人。
    d5
        30
    d5  
       2020-05-25 17:31:23 +08:00   ❤️ 3
    大改特改去对抗真的很累,而且不够一劳永逸,站在巨人的肩膀上就很舒服。

    google recaptcha v3 开通 1 分钟、前端接入 5 分钟、后端校验逻辑函数 15 分钟、发送接口函数加一个 if 判断,判断下人机验证接口返回的值就行。

    =============

    另外,我这里有一个 1 核 614M 主机搭建的演示站,平时做演示用的,用了 cloudflare 和 recapthca v3,欢迎大佬来 battle 来交流。
    https://airdrop.tonystark.io/
    diferent
        31
    diferent  
       2020-05-25 17:36:50 +08:00   ❤️ 1
    其实很简单, 先使用微信扫码关注公众号, 再绑定手机发短信.
    diferent
        32
    diferent  
       2020-05-25 17:37:35 +08:00   ❤️ 1
    或者直接微信公众号上行数据, 走上行短信的思路
    LeeSeoung
        33
    LeeSeoung  
       2020-05-25 17:44:21 +08:00
    限制次数+验证码,要么改成发送短信验证 前端做太多只是徒劳
    Vegetable
        34
    Vegetable  
       2020-05-25 17:48:42 +08:00
    @d5 确认一下,这个服务国内的产品是能用的吗?
    d5
        35
    d5  
       2020-05-25 17:49:30 +08:00
    @Vegetable 截止目前能,域名替换成 recaptcha.net
    cquyf
        36
    cquyf  
       2020-05-25 17:50:12 +08:00
    这个还有人盗用啊
    zgzhang
        37
    zgzhang  
       2020-05-25 17:51:17 +08:00
    @ksc010 看你的描述 已经做了基本防御但还是被刷了,一般来说短信轰炸接口不会使用带有验证码的接口,是否是批量注册呢?可以关注下这批用户的后续行为。
    damngoto
        38
    damngoto  
       2020-05-25 18:00:35 +08:00
    前端防护都是治标不治本,最重要的是后台防护。
    damngoto
        39
    damngoto  
       2020-05-25 18:02:18 +08:00
    几千条都不算真正的攻击,我们一天被刷过几万块,😁
    pws22
        40
    pws22  
       2020-05-25 18:14:14 +08:00
    把验证码弄得更复杂吧..
    或者在页面上加个前置条件 比如暗暗的加个前置链接, xxxx.gif 这样的,不易发现的那种,在这个请求后台接受到后,加个 ip 标志,下次发验证码的时候 先判断有没有这个 ip 标志,有就真的发,一次失效, 前段不管怎么样 都返回 success
    superrichman
        41
    superrichman  
       2020-05-25 18:15:53 +08:00 via iPhone
    发个你的验证码的图片看看?
    zhzbql
        42
    zhzbql  
       2020-05-25 18:19:07 +08:00
    应该不是通过打码平台,打码平台识别一条验证码比你发一条短信的成本都高,估计还是验证码不够复杂可以通过机器识别。不然就是铁了心不计成本要搞你
    ksc010
        43
    ksc010  
    OP
       2020-05-25 18:44:52 +08:00
    @zgzhang
    @pws22
    @superrichman
    @zhzbql
    我排查了日志 发下 都是直接请求的发送短信接口
    没有请求验证码的记录
    又仔细看了代码 发现是代码错误 。。。。具体 append 上去了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2410 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 15:57 · PVG 23:57 · LAX 08:57 · JFK 11:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.