8chan spamming tool

New About Yours API Help
8.3 KB, Plain text
from bs4 import BeautifulSoup
from time import sleep
import requests
import configparser
import webbrowser
import random
import base64
import uuid
import glob
import sys
import re
import os
import requests.sessions
from typing import Dict, List, Pattern, TextIO, Union
posts = 0  # type: int
config = configparser.ConfigParser()  # type: configparser.ConfigParser
if not os.path.exists("config.ini"):
    config["Posting defaults"] = {
        "Name": "",
        "Email": "",
        "Subject": "",
        "Comment": "This is an example. Multiline comments are supported, but each newline after the first that contains text must be preceded by a single space. If a line will not contain text, use a single newline, then on your next newline, follow the single-space rule. You may use variables in this comment which will choose from a list of substitutions that you define. Variables take the form of #var1& and #var2& and should be defined in the [Substitutions] section of config.ini",
        "Password": "",
        "Delay": "0",
    }
    config["Identification"] = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0",
        "Proxy": "True",
    }
    config["File upload"] = {
        "Directory": os.path.dirname(os.path.realpath(__file__)),
        "Extensions": "jpg,jpeg,png,gif,webm,mp4",
        "UUID": "True",
        "Evade": "True",
    }
    config["Substitutions"] = {
        "var1": "comment,separated,substitutions",
        "var2": "will,be,used",
    }
    with open("config.ini", "w") as configfile:
        config.write(configfile)
    sys.exit(
        "config.ini was not found, it has been created for you. Please customize and re-run this program."
    )
else:
    print("config.ini found! Using provided configuration.")
    config.read("config.ini")
s = requests.Session()  # type: requests.sessions.Session
s.headers["User-Agent"] = config["Identification"]["User-Agent"]
s.headers["Referer"] = "https://8ch.net/"
if not os.path.exists("boards.txt"):
    print("Did not find boards.txt! Creating...")
    j = s.get("https://8ch.net/boards.json").json()  # type: List[Dict[str, str]]
    with open("boards.txt", "w") as f:
        for board in j:
            f.write("%s\n" % board["uri"])
    print("boards.txt created!")
else:
    print("boards.txt found! Using existing data.")
    BOARDS = [line.strip() for line in open("boards.txt", "r")]  # type: List[str]
USE_PROXY = config["Identification"]["Proxy"] == "True"  # type: bool
USE_UUID = config["File upload"]["UUID"] == "True"  # type: bool
TRY_MD5_EVADE = config["File upload"]["Evade"] == "True"  # type: bool
subbed = {}  # type: Dict[str, str]
SUBS = {}  # type: Dict[str, List[str]]
for substitution in config["Substitutions"]:
    SUBS[substitution] = config["Substitutions"][substitution].split(",")
NAME = config["Posting defaults"]["Name"]  # type: str
EMAIL = config["Posting defaults"]["Email"]  # type: str
SUBJECT = config["Posting defaults"]["Subject"]  # type: str
BODY = config["Posting defaults"]["Comment"]  # type: str
PASSWORD = config["Posting defaults"]["Password"]  # type: str
DIRECTORY = config["File upload"]["Directory"]  # type: str
EXTENSIONS = [
    ".%s" % ext for ext in config["File upload"]["Extensions"].split(",")
]  # type: List[str]
files = []  # type: List[str]
for ext in EXTENSIONS:
    files += glob.glob("%s/*%s" % (DIRECTORY, ext))
if USE_PROXY:
    if not os.path.exists("proxies.txt"):
        with open("proxies.txt", "w") as f:
            f.write("protocol://addresss:port\n")
            f.write("socks5://127.0.0.1:9050\n")
        sys.exit(
            "Did not find proxies.txt! An example file will be created for you. Please customize and re-run this program."
        )
    else:
        print("Using information from proxies.txt")
        with open("proxies.txt", "r") as f:
            PATTERN = r"(https?|socks5)://.+:\d+"  # type: str
            r = re.compile(PATTERN)  # type: Pattern
            PROXIES = [line.strip() for line in f if r.match(line)]  # type: List[str]
else:
    print("No proxy will be used.")
def new_proxy() -> None:
    p = random.choice(PROXIES)  # type: Union[str, Dict[str, str]]
    p = {"http": p, "https": p}
    s.proxies = p
def get_captcha() -> None:
    try:
        soup = BeautifulSoup(
            s.get("https://8ch.net/dnsbls_bypass.php").content, "html.parser"
        )  # type: BeautifulSoup
    except requests.exceptions.ProxyError as e:
        print("Encountered an exception trying GET /dnsbls_bypass.php")
        print("Exception: %s" % e)
    image = soup.select("image")[0].get("src")[22:]  # type: str
    with open("captcha_image.png", "wb") as f:
        f.write(base64.b64decode(image))
    # print("This line is directly after where the captcha image gets saved. If you see this, the file should exist.")
    webbrowser.open("file://%s" % os.path.realpath("captcha_image.png"))
    answer = input("Enter captcha text: ")  # type: str
    captcha_cookie = soup.select("input.captcha_cookie")[0].get("value")  # type: str
    try:
        r = s.post(
            "https://8ch.net/dnsbls_bypass.php",
            data={"captcha_text": answer, "captcha_cookie": captcha_cookie},
        )  # type: requests.models.Response
    except requests.exceptions.ProxyError as e:
        print(
            "Encountered an exception trying POST challenge data to /dnsbls_bypass.php"
        )
        print("Exception: %s" % e)
    if "You may now go back and make your post." not in r.text:
        get_captcha()
    else:
        print("Captcha successfully solved for this IP address!")
        global posts
        posts = 50
    # os.remove("captcha_image.png")
def try_post() -> None:
    NUM_NULLS = b"\0" * random.randint(1, 1000)  # type: bytes
    if TRY_MD5_EVADE and USE_UUID:
        print(
            s.post(
                "https://8ch.net/post.php",
                data=data,
                files={
                    "file": (
                        "%s%s" % (uuid.uuid4(), e),
                        open(f, "rb").read() + NUM_NULLS,
                    )
                },
            ).text
        )
    elif TRY_MD5_EVADE and not USE_UUID:
        print(
            s.post(
                "https://8ch.net/post.php",
                data=data,
                files={"file": open(f, "rb").read() + NUM_NULLS},
            ).text
        )
    elif not TRY_MD5_EVADE and USE_UUID:
        print(
            s.post(
                "https://8ch.net/post.php",
                data=data,
                files={"file": ("%s%s" % (uuid.uuid4(), e), open(f, "rb"))},
            ).text
        )
    elif not TRY_MD5_EVADE and not USE_UUID:
        print(
            s.post(
                "https://8ch.net/post.php", data=data, files={"file": open(f, "rb")}
            ).text
        )
    sleep(float(config["Posting defaults"]["Delay"]))
orig_data = {
    "page": "1",
    "name": NAME,
    "email": EMAIL,
    "subject": SUBJECT,
    "body": BODY,
    "password": PASSWORD,
    "json_response": "1",
    "post": "New Thread",
}  # type: Dict[str, str]
data = {}  # type: Dict[str, str]
def do_substitutions() -> None:
    for key in orig_data:
        data[key] = orig_data[key]
        subbed[key] = orig_data[key]
        for substitution in config["Substitutions"]:
            subbed[key] = subbed[key].replace(
                "#%s&" % substitution, random.choice(SUBS[substitution])
            )
    data["body"] = subbed["body"]
    data["subject"] = subbed["subject"]
    data["name"] = subbed["name"]
    data["email"] = subbed["email"]
    data["password"] = subbed["password"]
if USE_PROXY:
    new_proxy()
try:
    get_captcha()
except ConnectionRefusedError:
    # this should probably not happen since get_captcha() is handling ProxyError exceptions, but just to be safe
    print("Connection was refused by proxy server. Trying new one.")
    print("Bad proxy used by session object: %s" % s.proxies)
    new_proxy()
for board in BOARDS:
    data["board"] = board
    do_substitutions()
    f = random.choice(files)  # type: Union[str, TextIO]
    e = os.path.splitext(f)[1]  # type: str
    if posts > 0:
        try_post()
    else:
        if USE_PROXY:
            new_proxy()
        get_captcha()
    posts -= 1
Pasted 1 month ago — Expires in 330 days
URL: http://dpaste.com/1MQ34BV