"短信轰炸机",是别人通过爬虫或者其他抓取手段在网路上收集那些公司平台短信业务接口的一个集成程序,可能只需要输入一个手机号,对方一整天都会收到各大平台的注册或提醒短信,就是手机在那里响个不停。因为现在手机只能对单方的多条短信进行屏蔽,而这种是多平台同时进行发送,很难拦截。

而被他们收集接口的乙方公司,可能一天短信的消耗量就比过一周的量,造成公司财产损失。其实相比以前我们遇到的被刷“提现”接口可以直接获取金钱,刷短信接口的行为,开始我很是想不通,就单纯为了消耗别人公司的短信费,他也得不到什么好处,为什么要这样做。当时也没想对方是出于什么理由,只是先把短信接口重新整改,防止的手法在下面介绍。

这种行为我也是最近才了解,原来网上也存在像周星驰电影"整蛊专家"的人,收取别人的钱开展对自己客户提供的人进行骚扰等业务,而短信就是其中一种,网上还有通过输入手机号,对方手机一天全部是陌生人来电的“呼死你”软件,心理承受力差的可能就抑郁,好点的话至少一天的心情都不好。

我们公司现在短信的用处主要还是注册/登陆验证码,找回密码,绑银行卡,修改支付密码,所以一天的量并不大。但那一天充了钱,不出几分钟,直接刷到没有,还好发现的早,解决的也早。

解决方法,在PC端可以在发短信验证码时,加上图形验证码校验,最好是要能和用户互动的,比如拖动或算术的,因为如果是静态的图形验证也不是很安全,毕竟现在的图片识别接口也很多。而在移动端,加图形验证体验不是很好,可以和前端通过约定密钥实现,而在H5上,就很尴尬了,而且还遇到一个只有必须绕弯路的事情。

一,APP端

1.IP和手机号黑名单(ip的例子)

<?php
   $Ip    = $request->ip();
   $Iplist = ['180.137.97.10'];
   if (in_array($Ip, $Iplist)) {
       return $this->sendError(1, '业务限流', 200);
   }    

2.限制指定的user_agent

<?php
   $string = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"; 
    if ($Agent == $string) {
        return $this->sendError(1, '业务限流', 200);
    }

3.限制多久后才能发

(1).获取指定键的一个缓存是否存在,存在则返回
$is_msgtime = cache($mobile.'_msgtimes');
if (!empty($is_mesgtime)) {
   return $this->sendError(1, '60秒后才能继续发', 200);
}
(2).在短信发送成功时,存下该键名,并缓存60秒(按需求指定时间)
cache($mobile.'_msgtimes', 1, 60);

4.限制单号单日发送的个数限制

(1)获取缓存指定键名的值为多少(number),并与最大限制比较
$Daytimes = intval(cache($mobile.'_daytimes')) ? intval(cache($mobile.'_daytimes')) : 0;
if(Daytimes>3) {
   return ^^^^^^^^^
} (2)短信发送成功记录并累加该号该日发送量
if ($Daytimes > 0) {
   $nextday = strtotime("today") + 24 * 60 * 60;
   $expires = $nextday - time();
   Cache::set($mobile.'_daytimes', $Daytimes + 1, $expires);
 } else {
     $nextday = strtotime("today") + 24 * 60 * 60;
     $expires = $nextday - time();
     Cache::set($mobile.'_daytimes', 1, $expires);
 }

以上部分是没用,因为ip和手机号,user_agent都可以通过特殊手段伪造,并且上面只是对单号码进行拦截,所以问题就是别人通过很多号码对接口请求,这样一样的可以刷。

5.接口添加复杂性,增加签名请求等方式

(1).请求接口时,除了手机号参数,还需带上签名(一个不可逆加密方式处理的字符串,前后端约定一个key),和时间戳.

(2).后端根据约定的key和手机号也做相应的加密与传过来的签名匹配,并和时间戳和当前服务器时间做比较,时间戳最好也作为签名加密,加密方式多种,不管是DES,RSA还是MD5看个人。

$timestamp = input('get.timestamp') ? input('get.timestamp') : 0;  // 时间戳
$sign = input('get.app_sign') ? input('get.app_sign') : '';        // 请求签名
$terminal = input('get.term') ? input('get.term') : '';            // 终端标识 1.app 2.web
$veryify_code = mt_rand(100000, 999999);                           // 6位数的验证码 $priKey = "paobuqianjinzhf..20181029";                // 加密秘钥 // 判断终端
if(!empty($terminal) && ($terminal == 'app')) {
 $signAuth = md5($priKey.$mobile.$timestamp); if($timestamp > time()+10 || $timestamp<time()-60*10) {
  return $this->sendError(1, '请求已过期', 200);
} if($sign != $signAuth) {
 return $this->sendError(1, '签名匹配失败', 200);
}

短语短信发送,最好用一张表记录一下,不管成功与否,以后查起来也方便,到底这接口发了哪些号码,什么时候发的等等

二,H5端

在h5上,上面的通过key撒盐的方式传参就行不通了,因为网页可以查看代码,如果把key放在前端传上来,可以看的很清楚。但是可以在后端生成一个串分配到网页请求的时候传上来就可以啊,就想表单令牌一样。但是我们这个H5是纯静态,没有后台程序,接口都只是跨域ajax请求。所以分配字符串到页面行不通,通过接口请求签名也行不通,因为别人抓到了这些接口,还是一样的可以通过一样的方式实现一遍。无奈只能通过图形验证码。

<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/10/29 0029
* Time: 16:15
*/ namespace Admin\Controller; use Think\Controller;
use Think\Verify;       // 验证码类
use Admin\Model; class RegisterController extends Controller    // 控制器:用户登录
{    // 登陆控制器的入口函数
   public function index()
   {        $this->redirect('Admin/Register/userRegister');
   }    // 用户注册界面
   public function userRegister()
   {
//        $parm=I('get.');
       $ajax = new AjaxController();
       $this->assign('loginurl', $ajax->getAjaxUrl('ajaxuserloginexe'));        $token=md5('paobuqianjinzhf..20181029'.time());        $this->assign('token',$token);
       $this->display('user_register');
   }    // 生成登陆验证码
   public function verfyCode() {
       $config =    array(
           'fontSize'    =>    50,    // 验证码字体大小
           'length'      =>    4,     // 验证码位数
           //'useNoise'    =>    false, // 关闭验证码杂点
       );
       $Verify = new \Think\Verify($config);
       $Verify->entry();
   }    // 检测验证码
   public function checkVerifyCode() {        $code = I('code');
       $mobile = I('mobile');
       $term = 'app';
       $timestamp =time();
       $prikey='paobuqianjinzhf..20181029';
       $app_sign = md5($prikey.$mobile.$timestamp);
       if (empty($mobile)){
           $result_data['state']  = 0;
           $result_data['string'] = '手机号必填写';
           returnjsontojs($result_data);
       }
       if(!check_verify($code,false)) {
           $result_data['state']  = 0;
           $result_data['string'] = '验证码不正确';
           returnjsontojs($result_data);
       }
       $Agent = $_SERVER['HTTP_USER_AGENT'];
//        $url ="http://www.api.com/v1/ThirdParty/sendMsg?mobile=".$mobile.'&term='.$term.'&app_sign='.$app_sign.'&timestamp='.$timestamp;
       $url ="https://api.runmoneyin.com/v1/ThirdParty/sendMsg?mobile=".$mobile.'&term='.$term.'&app_sign='.$app_sign.'&timestamp='.$timestamp;
//        $url ="https://api.runmoneyin.com/v1/ThirdParty/sendMsg?mobile=".$mobile;
       $curl = curl_init();
            //设置抓取的url
     curl_setopt($curl, CURLOPT_URL, $url);
     //设置头文件的信息作为数据流输出
     curl_setopt($curl, CURLOPT_HEADER, 1);
     //设置获取的信息以文件流的形式返回,而不是直接输出。
       //
     curl_setopt($curl,CURLOPT_USERAGENT,$Agent);
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
     //执行命令
      $data = curl_exec($curl);
      $body='';
      $result_data['state']  = false;
       if (curl_getinfo($curl, CURLINFO_HTTP_CODE) == '200') {
           $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
           $header = substr($data, 0, $headerSize);
           $body = json_decode(substr($data, $headerSize),true);
       }
       //关闭URL请求
      curl_close($curl);        if ($body['error']==0){
           $result_data['state']  = true;
       }
       $result_data['string']=$body['message'];
       returnjsontojs($result_data);
   } }

以上我是在另一个系统下放了那个H5页面,因为静态页面也无法做图形验证码,获取验证码时先判断图形验证码是否正确,正确再通过CURL请求真正的短信接口,跟APP一样的请求方式传参。

但是这个进行到后面却发现,我们那个H5页面的地址已经做了固定域名二维码并打印了上万张,现在把H5的地址换掉的话,也就是域名变了,也就意味着那些打印的二维码全都没用了,于是想到一个办法: 在原来静态H5的地址,加上一个访问a.html会默认访问a.php,然后在a.php做一个跳转,跳转到我们修改图形验证码的域名就可以了,这样还是访问原来的地址,但是会重定向到新系统的地址。因为我们只是对a.html起效,其他同目录的b.html不做处理,如果是在服务器上做重定向,整个域名下的都会被重定向,

1.在a.html目录下新建a.php,并新建一个.htaccess文件

2.对a.html的服务器能支持支持.htaccess

打开apache安装目录下的httpd.conf文件,把

AllowOverride None 改为AllowOverride All ,如图

去掉下面的注释 #

LoadModule rewrite_module modules/mod_rewrite.so,如图

3.htaccess文件修改为

<IFMODULE mod_rewrite.c>

RewriteEngine On

RewriteBase /

RewriteRule (.*)\a.html$ $1\a.php [QSA,PT,L]

</IFMODULE>

个人公众号:ZERO开发

键盘上的"整蛊专家",如何防止短信轰炸机的更多相关文章

  1. 使用Selennium实现短信轰炸机

    前言 可以用来轰炸一下骗子,但最好不要乱用.本来初学Python,仅当学习. selenium和ChromeDriver的安装与配置 可参考这篇博客,这里不再赘述. 程序实现 短信轰炸机的原理是利用一 ...

  2. Python3实现短信轰炸机

    短信轰炸机的基本原理:利用某些限制不严格的网站短信注册接口,用Python模拟请求,传入被炸人手机号码,实现轰炸 实现方式:利用requests模块.time模块.完成请求模拟 模块安装: 在终端窗口 ...

  3. python短信轰炸机版本smsbomb----------部分(post)

    用一些用手机号注冊且须要发送验证码的站点的漏洞.能够向不论什么人的手机号发送短信,当然短信内容,我们无法控制.所以主要工作还是寻找这种站点.然后利用Fiddler或者HttpWatch分析请求.使用p ...

  4. python版的短信轰炸机smsbomb----------下篇(get)

    在上一篇介绍的是post方式发送数据,可是有点站点是get方式发送数据,比如:http://www.oupeng.com/download,事实上方法差点儿相同. import httplib,url ...

  5. Python 实现短信轰炸机

    原理其实很简单,就是利用selenium包打开各种网站的注册页,输入轰炸的号码,实现轰炸.其实也算是利用了注册漏洞.申明:仅娱乐使用,禁止️用于非法用途!若用于非法用途,后果及法律责任博主一律不承担 ...

  6. android: 接收和发送短信

    8.2    接收和发送短信 收发短信应该是每个手机最基本的功能之一了,即使是许多年前的老手机也都会具备这 项功能,而 Android 作为出色的智能手机操作系统,自然也少不了在这方面的支持.每个 A ...

  7. Android 编程下短信监听在小米手机中失效的解决办法

    相信很多人写的短信监听应用在小米手机上是拦截不到短信的,这是因为小米对短信的处置权优先分给了系统.我们可以在短信的[设置]→[高级设置]→[系统短信优先]中发现短信的优先处理权默认是分给系统的,只要关 ...

  8. Android短信监听软件

    本案例是在android手机中运行,是一个没有界面的短信监听软件.主要是用BroadcastReceiver来接受短信广播,当接收到短信后就跳转到service中来转发短信.哈哈,不是用来干坏事的.这 ...

  9. android4.4短信新概念

    android4.4对短信引入了一个全新的概念:默认短信应用.即android用户可以在系统设置里面选择一个默认的短信应用,只有这个应用才能进行手机的基本短信操作.按照google自己的解释这样做的原 ...

随机推荐

  1. 【安富莱专题教程第7期】终极调试组件Event Recorder,各种Link通吃,支持时间和功耗测量,printf打印,RTX5及中间件调试

    说明:1.继前面的专题教程推出SEGGER的RTT,JScope,Micrium的uC/Probe之后,再出一期终极调试方案Event Recoder,之所以叫终极解决方案,是因为所有Link通吃.  ...

  2. [Swift]LeetCode735. 行星碰撞 | Asteroid Collision

    We are given an array asteroids of integers representing asteroids in a row. For each asteroid, the ...

  3. [Swift]LeetCode798. 得分最高的最小轮调 | Smallest Rotation with Highest Score

    Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], A[K+1 ...

  4. Java中的数组添加,数组相关代码

    private static void demo() {  // TODO Auto-generated method stub  /**   * @author square 凉   * @功能 实 ...

  5. 当使用vue的按键修饰符不起效果的时候怎么办?如@keyup.enter = '' ;

    这个问题困扰了我一个多小时,各种测bug !始终测不出来! 直接上代码(错误示范) <el-form-item prop="password"> <el-inpu ...

  6. 『最长等差数列 线性DP』

    最长等差数列(51nod 1055) Description N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括两项的不 ...

  7. Solr 02 - 最详细的solrconfig.xml配置文件解读

    目录 1 luceneMatchVersion - 指定Lucene版本 2 lib - 配置扩展jar包 3 dataDir - 索引数据路径 4 directoryFactory - 索引存储工厂 ...

  8. Educational Codeforces Round 48 (Rated for Div. 2)——A. Death Note ##

    A. Death Note time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  9. 免费IPv6访问收费IPv4,校园网免流量

    软件:马上6 介绍: “可以让用户在免费的IPv6网络环境,有具备访问收费的IPv4互联网内容的能力!节省校园网流量!使用马上6客户端软件之后可以访问的IPv4互联网的内容(包括视频.游戏.音乐.学习 ...

  10. SpringMvc通过@Value( ) 给静态变量注入值

    spring 不允许/不支持把值注入到静态变量中,如: @Value("${ES.CLUSTER_NAME}")private static String CLUSTER_NAME ...