T00ls 每日 TuBi + 2


0x01 脚本介绍

套用国光大佬的 t00ls 每日签到脚本,整合了钉钉和邮件通知。

0x02 完善脚本

以下是博主个人在原脚本代码的基础上做的一些内容修改。

1、修复域名查询参数

在原脚本中97行左右,从站长之家查询com域名的参数错误,修复代码如下:

修改前:
search_data = 'ix=.com&suffix=.cn&c_suffix=&time=1&startDay=&endDay='
修改后:
search_data = 'suffix=.com&suffix=.cn&c_suffix=&time=1&startDay=&endDay='

2、完善域名提取规则

原脚本中提取的域名也会把站长之家查询页面中的邮箱(例如:admin@admin.com)给提取进来,需要对这些邮箱域名进行过滤。在原脚本105行左右,修改代码如下:

修改前:
if '.' in i.string and '*' not in i.string:
修改后:
if '.' in i.string and '*' not in i.string and '@' not in i.string:

3、 增加查询容错率

原脚本中是先从站长之家提取最新域名,再随机从提取的域名中抽取一个域名到T00ls上查询,很容易出现一个域名多次查询的现象。再加上原脚本中尝试查询域名次数太少了,也很容易出现T00ls查询域名重复,导致还没查询新域名成功就结束的现象。为了增加T00ls查询容错率,修改代码大概121行左右如下:

while not query_status and query_count < len(domains):
    for i in domains:
        domain = i
        query_data = f'domain={domain}&formhash={t00ls_hash}&querydomainsubmit=%E6%9F%A5%E8%AF%A2'
        try:
            response_query = requests.post(url=query_url, headers=req_headers, data=query_data, cookies=t00ls_cookies)
        except Exception:
            pass

        if domain in response_query.text:
            response_tb = requests.get('https://www.t00ls.cc/members-tubilog.json', cookies=t00ls_cookies)
            if domain in response_tb.text:
                print(f'[+] 域名查询成功:{domain}  TuBi + 1 ')
                content += f'[+] 域名查询成功: {domain}   TuBi + 1\n\n'
                query_status = True
                break
            else:
                print(f'[-] 域名查询重复:{domain}')
                content += f'[-] 域名查询重复:{domain}\n'
                query_count += 1
                print(f'[+] 随机延时 5-10 秒,继续第 {query_count} 次查询')
                content += f'[+] 随机延时 5-10 秒,继续第 {query_count} 次查询\n\n'
                time.sleep(random.randint(5, 10))
        else:
            print(f'[-] 域名查询失败: {domain}')
            content += f'[-] 域名查询失败: {domain}\n'
            query_count += 1
            print(f'[+] 随机延时 5-10 秒,继续第 {query_count} 次查询')
            content += f'[+] 随机延时 5-10 秒,继续第 {query_count} 次查询\n\n'
            time.sleep(random.randint(5, 10))
        if query_count == len(domains):
            print('[-] 重试查询次数已达上限 终止查询')
            content += '[-] 重试查询次数已达上限 终止查询\n\n'

4、 优化显示效果

终端显示效果如下:

邮件推送效果如下:

5、最终脚本代码

import time
import json
import random
import smtplib
import requests
from bs4 import BeautifulSoup
from email.mime.text import MIMEText
from email.utils import formataddr

# t00ls 账号配置
username = '1uckyMe'  # 帐号
password = 'xxxxxxxxxxd0xxx8'  # 密码MD5 32位(小写)
question_num = 7  # 安全提问 参考下面
question_answer = 'xxxx'  # 安全提问答案

# 0 = 没有安全提问
# 1 = 母亲的名字
# 2 = 爷爷的名字
# 3 = 父亲出生的城市
# 4 = 您其中一位老师的名字
# 5 = 您个人计算机的型号
# 6 = 您最喜欢的餐馆名称
# 7 = 驾驶执照的最后四位数字


# 选择提醒方式
notice = 1  # 0 = 钉钉  1 = 邮件 2 = 全部

# 如果选择钉钉通知的话 请配置下方信息
webhook = 'https://oapi.dingtalk.com/robot/send?access_token=***' # 钉钉机器人的 webhook

# 如果选择邮件通知的话 请配置下方信息
sender = '16463223@qq.com'  # 发件人邮箱账号
sender_pass = 'zxxxxxxxxxxj'  # 发件人邮箱授权密码,不是QQ密码
receiver = '16463223@qq.com'  # 收件人邮箱账号

req_headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36'
}

def t00ls_login(u_name, u_pass, q_num, q_ans):
    """
    t00ls 登录函数
    :param u_name: 用户名
    :param u_pass: 密码的 md5 值 32 位小写
    :param q_num: 安全提问类型
    :param q_ans: 安全提问答案
    :return: 签到要用的 hash 和 登录后的 Cookies
    """

    login_data = {
        'action': 'login',
        'username': u_name,
        'password': u_pass,
        'questionid': q_num,
        'answer': q_ans
    }
    response_login = requests.post('https://www.t00ls.cc/login.json', data=login_data, headers=req_headers)
    response_login_json = json.loads(response_login.text)

    if response_login_json['status'] != 'success':
        return None
    else:
        print('[+] 用户登录成功:', username)
        formhash = response_login_json['formhash']
        t00ls_cookies = response_login.cookies
        return formhash, t00ls_cookies


def t00ls_sign(t00ls_hash, t00ls_cookies):
    """
    t00ls 签到函数
    :param t00ls_hash: 签到要用的 hash
    :param t00ls_cookies: 登录后的 Cookies
    :return: 签到后的 JSON 数据
    """
    sign_data = {
        'formhash': t00ls_hash,
        'signsubmit': "true"
    }
    response_sign = requests.post('https://www.t00ls.cc/ajax-sign.json', data=sign_data, cookies=t00ls_cookies,
                                  headers=req_headers)
    return json.loads(response_sign.text)


def t00ls_domain(t00ls_hash, t00ls_cookies):
    """
    t00ls 域名查询函数
    :param t00ls_hash: 签到要用的 hash
    :param t00ls_cookies: 登录后的 Cookies
    :return: 查询相关的日志信息
    """
    content = ''
    # 使用站长之家查询今天注册的域名
    start_time = time.time()

    china_url = 'https://whois.chinaz.com/suffix'
    search_data = 'suffix=.com&suffix=.cn&c_suffix=&time=1&startDay=&endDay='
    req_headers['Content-Type'] = 'application/x-www-form-urlencoded'
    response_domains = requests.post(url=china_url, headers=req_headers, data=search_data, timeout=10)

    # Bs4 解析器 简单规则过滤一下放入到 domains 的列表中
    soup = BeautifulSoup(response_domains.text, 'html.parser')
    domains = []
    for i in soup.select('.listOther a'):
        if '.' in i.string and '*' not in i.string and '@' not in i.string:
            domains.append(i.string)
    domain = random.sample(domains, 1)[0]  # 随机抽取一个 幸运儿
    end_time = time.time()
    print(f'[+] 站长之家抽取域名耗时: {end_time - start_time:.4f}秒')
    content += f'\n[+] 站长之家抽取域名耗时: {end_time - start_time:.4f}秒\n\n'

    start_time = time.time()

    query_url = 'https://www.t00ls.cc/domain.html'
    query_data = f'domain={domain}&formhash={t00ls_hash}&querydomainsubmit=%E6%9F%A5%E8%AF%A2'
    query_status = False
    query_count = 1  # 查询重试次数

    # 如果 t00ls 查询没有成功的话 就一直查询
    print(domains)
    while not query_status and query_count < len(domains):
        for i in domains:
            domain = i
            query_data = f'domain={domain}&formhash={t00ls_hash}&querydomainsubmit=%E6%9F%A5%E8%AF%A2'
            try:
                response_query = requests.post(url=query_url, headers=req_headers, data=query_data, cookies=t00ls_cookies)
            except Exception:
                pass

            if domain in response_query.text:
                response_tb = requests.get('https://www.t00ls.cc/members-tubilog.json', cookies=t00ls_cookies)
                if domain in response_tb.text:
                    print(f'[+] 域名查询成功:{domain}  TuBi + 1 ')
                    content += f'[+] 域名查询成功: {domain}   TuBi + 1\n\n'
                    query_status = True
                    break
                else:
                    print(f'[-] 域名查询重复:{domain}')
                    content += f'[-] 域名查询重复:{domain}\n'
                    query_count += 1
                    print(f'[+] 随机延时 5-10 秒,继续第 {query_count} 次查询')
                    content += f'[+] 随机延时 5-10 秒,继续第 {query_count} 次查询\n\n'
                    time.sleep(random.randint(5, 10))
            else:
                print(f'[-] 域名查询失败: {domain}')
                content += f'[-] 域名查询失败: {domain}\n'
                query_count += 1
                print(f'[+] 随机延时 5-10 秒,继续第 {query_count} 次查询')
                content += f'[+] 随机延时 5-10 秒,继续第 {query_count} 次查询\n\n'
                time.sleep(random.randint(5, 10))
            if query_count == (len(domains)+1):
                print('[-] 重试查询次数已达上限 终止查询')
                content += '[-] 重试查询次数已达上限 终止查询\n\n'
    end_time = time.time()
    print(f'[+] t00ls 域名查询耗时: {end_time - start_time:.4f}秒')
    content += f'[+] t00ls 域名查询耗时: {end_time - start_time:.4f}秒\n'
    return content


def dingtalk(content):
    """
    钉钉通知函数
    :param content: 要通知的内容
    :return: none
    """
    webhook_url = webhook
    dd_headers = {
        "Content-Type": "application/json",
        "Charset": "UTF-8"
    }
    dd_message = {
        "msgtype": "text",
        "text": {
            "content": f'T00ls 签到通知\n{content}'
        }
    }
    r = requests.post(url=webhook_url, headers=dd_headers, data=json.dumps(dd_message))


def mail(content):
    """
    邮件通知函数
    :param content: 要通知的内容
    :return: none
    """
    msg = MIMEText(content, 'plain', 'utf-8')
    msg['From'] = formataddr(["T00ls 签到提醒", sender])
    msg['To'] = formataddr(["", receiver])
    msg['Subject'] = "T00ls 每日签到提醒"

    server = smtplib.SMTP_SSL("smtp.qq.com", 465)
    server.login(sender, sender_pass)
    server.sendmail(sender, [receiver, ], msg.as_string())
    server.quit()


def main():
    content = ''
    response_login = t00ls_login(username, password, question_num, question_answer)
    if response_login:
        response_sign = t00ls_sign(response_login[0], response_login[1])
        if response_sign['status'] == 'success':
            print('[+] 签到成功 TuBi + 1')
            content += '\n[+] 签到成功 TuBi + 1\n'

            verbose_log = t00ls_domain(response_login[0], response_login[1])
            content += verbose_log

            if notice == 0:
                try:
                    dingtalk(content)
                except Exception:
                    print('[!] 请检查钉钉配置是否正确')
            elif notice == 1:
                try:
                    mail(content)
                except Exception:
                    print('[!] 请检查邮件配置是否正确')
            else:
                try:
                    dingtalk(content)
                except Exception:
                    print('[!] 请检查钉钉配置是否正确')
                try:
                    mail(content)
                except Exception:
                    print('[!] 请检查邮件配置是否正确')
        elif response_sign['message'] == 'alreadysign':
            print('[+] 已经签到成功')
            content += '\n[+] 已经签到成功\n'

            verbose_log = t00ls_domain(response_login[0], response_login[1])
            content += verbose_log

            if notice == 0:
                try:
                    dingtalk(content)
                except Exception:
                    print('[!] 请检查钉钉配置是否正确')
            elif notice == 1:
                try:
                    mail(content)
                except Exception:
                    print('[!] 请检查邮件配置是否正确')
            else:
                try:
                    dingtalk(content)
                except Exception:
                    print('[!] 请检查钉钉配置是否正确')
                try:
                    mail(content)
                except Exception:
                    print('[!] 请检查邮件配置是否正确')
        else:
            print('[-] 出现玄学问题了 签到失败')
    else:
        print('[!] 登入失败 请检查输入资料是否正确')

if __name__ == '__main__':
    main()

0x03 定时任务

Linux下的定时任务命令

# 查看定时任务
crontab -l

# 编辑定时任务
crontab -e

编辑定时任务,一行一个任务,填写内容如下:

# 表示每天5点30分自动执行签到脚本
30 5 * * * /usr/bin/python3 /root/tools/t00ls/TuBi.py>&1

注意:不要设定时间在每日的00:00,那会儿站长之家每日最新数据可能有延迟,不能正常提取域名导致脚本执行不成功。建议设置定时任务在其他时间段,避免出现在T00ls与他人重复查询新域名,无法增加TuBi值从而需要重新执行脚本的概率。

参考文章


文章作者: LuckySec
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LuckySec !
评论
  目录