Monkeypatch in support for binding sessions to random IPs using an IP list

master
Sven Slootweg 11 years ago
parent cacbd735b7
commit e7e6cba90f

@ -1,4 +1,4 @@
import re, oursql, requests, sys, json, shlex, argparse, os import re, oursql, requests, sys, json, shlex, argparse, os, random
from sources.nzbindex import NzbindexSpider from sources.nzbindex import NzbindexSpider
from sources.binsearch import BinsearchSpider from sources.binsearch import BinsearchSpider
@ -8,7 +8,7 @@ parser = argparse.ArgumentParser(description="Automatically download NZBs for re
parser.add_argument("--config", dest="config", action="store", help="Use a configuration file to match against the database as source") parser.add_argument("--config", dest="config", action="store", help="Use a configuration file to match against the database as source")
parser.add_argument("--list", dest="list", action="store", help="Use a newline-delimited list of releases as source") parser.add_argument("--list", dest="list", action="store", help="Use a newline-delimited list of releases as source")
parser.add_argument("--target", dest="target", action="store", help="Where to save the NZBs (only needed in list mode)") parser.add_argument("--target", dest="target", action="store", help="Where to save the NZBs (only needed in list mode)")
parser.add_argument("--iplist", dest="list", action="store", help="Bind every request to a random IP from a newline-delimited list") parser.add_argument("--iplist", dest="iplist", action="store", help="Bind every request to a random IP from a newline-delimited list")
args = parser.parse_args() args = parser.parse_args()
if args.config is not None: if args.config is not None:
@ -18,6 +18,12 @@ elif args.list is not None:
else: else:
sys.stderr.write("You must specify either a configuration file or a release list.\n") sys.stderr.write("You must specify either a configuration file or a release list.\n")
exit(1) exit(1)
if args.iplist is not None:
iplist_file = open(args.iplist, "r")
iplist = iplist_file.read().splitlines()
else:
iplist = [""]
if mode == "config": if mode == "config":
try: try:
@ -111,11 +117,11 @@ for release in releases:
pass pass
try: try:
spider = NzbindexSpider() spider = NzbindexSpider(random.choice(iplist))
results = spider.find(release_name) results = spider.find(release_name)
except NotFoundException, e: except NotFoundException, e:
try: try:
spider = BinsearchSpider() spider = BinsearchSpider(random.choice(iplist))
results = spider.find(release_name) results = spider.find(release_name)
except NotFoundException, e: except NotFoundException, e:
sys.stderr.write("Could not find release %s\n" % release_name) sys.stderr.write("Could not find release %s\n" % release_name)

@ -1,4 +1,4 @@
import requests, random import requests, random, socket
# These are just some random useragents, you can replace these with a different list # These are just some random useragents, you can replace these with a different list
user_agents = [ user_agents = [
@ -16,10 +16,47 @@ user_agents = [
class NotFoundException(Exception): class NotFoundException(Exception):
pass pass
# Very nasty monkeypatching ahead!
socket.real_create_connection = socket.create_connection
class ModifiedSession(requests.Session): class ModifiedSession(requests.Session):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
try:
self.bound_ip = kwargs['bound_ip']
del kwargs['bound_ip']
except KeyError, e:
self.bound_ip = ""
requests.Session.__init__(self, *args, **kwargs) requests.Session.__init__(self, *args, **kwargs)
self.headers['user-agent'] = random.choice(user_agents) self.headers['user-agent'] = random.choice(user_agents)
def patch_socket(self):
socket.create_connection = get_patched_func(self.bound_ip)
def unpatch_socket(self):
socket.create_connection = socket.real_create_connection
def get(self, *args, **kwargs):
self.patch_socket()
response = requests.Session.get(self, *args, **kwargs)
self.unpatch_socket()
return response
def post(self, *args, **kwargs):
self.patch_socket()
response = requests.Session.get(self, *args, **kwargs)
self.unpatch_socket()
return response
def get_patched_func(bind_addr):
def set_src_addr(*args):
address, timeout = args[0], args[1]
source_address = (bind_addr, 0)
return socket.real_create_connection(address, timeout, source_address)
return set_src_addr
# You're looking at duct tape and tie-wraps. It's like your local Home
# Depot, except in Python.
def download_file(request, target): def download_file(request, target):
if request.status_code == 200: if request.status_code == 200:

@ -2,9 +2,12 @@ from shared import NotFoundException, ModifiedSession, download_file
import requests, re, HTMLParser import requests, re, HTMLParser
class BinsearchSpider(object): class BinsearchSpider(object):
def __init__(self, bound_ip):
self.bound_ip = bound_ip
def find(self, name): def find(self, name):
parser = HTMLParser.HTMLParser() parser = HTMLParser.HTMLParser()
self.session = ModifiedSession() self.session = ModifiedSession(bound_ip=self.bound_ip)
response = self.session.get("https://binsearch.info/index.php", params={ response = self.session.get("https://binsearch.info/index.php", params={
"q": name, "q": name,

@ -2,9 +2,12 @@ from shared import NotFoundException, ModifiedSession, download_file
import requests, re, HTMLParser import requests, re, HTMLParser
class NzbindexSpider(object): class NzbindexSpider(object):
def __init__(self, bound_ip):
self.bound_ip = bound_ip
def find(self, name): def find(self, name):
parser = HTMLParser.HTMLParser() parser = HTMLParser.HTMLParser()
self.session = ModifiedSession() self.session = ModifiedSession(bound_ip=self.bound_ip)
self.session.post("https://nzbindex.com/agree/", data={"agree": "I agree"}, verify=False) self.session.post("https://nzbindex.com/agree/", data={"agree": "I agree"}, verify=False)
response = self.session.get("https://nzbindex.com/search/", params={ response = self.session.get("https://nzbindex.com/search/", params={

Loading…
Cancel
Save