diff options
Diffstat (limited to 'module')
-rw-r--r-- | module/plugins/internal/CaptchaService.py | 267 |
1 files changed, 142 insertions, 125 deletions
diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py index 1cd261698..db31bd1bd 100644 --- a/module/plugins/internal/CaptchaService.py +++ b/module/plugins/internal/CaptchaService.py @@ -2,16 +2,17 @@ import re import time -import base64 -from random import random,randint +from base64 import b64encode +from random import random, randint +from urlparse import urljoin, urlparse from module.common.json_layer import json_loads class CaptchaService: __name__ = "CaptchaService" - __version__ = "0.17" + __version__ = "0.18" __description__ = """Base captcha service plugin""" __license__ = "GPLv3" @@ -46,7 +47,7 @@ class CaptchaService: return None - def challenge(self, key=None): + def challenge(self, key=None, html=None): raise NotImplementedError @@ -56,14 +57,15 @@ class CaptchaService: class ReCaptcha(CaptchaService): __name__ = "ReCaptcha" - __version__ = "0.08" + __version__ = "0.09" __description__ = """ReCaptcha captcha service plugin""" __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org")] + __authors__ = [("pyLoad Team", "admin@pyload.org"), + ("zapp-brannigan", "fuerst.reinje@web.de")] - KEY_PATTERN = r'recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=([\w-]+)' + KEY_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\']|recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=)([\w-]+)' KEY_AJAX_PATTERN = r'Recaptcha\.create\s*\(\s*["\']([\w-]+)' @@ -86,9 +88,23 @@ class ReCaptcha(CaptchaService): return None - def challenge(self, key=None): + def challenge(self, key=None, html=None): + if not html: + if hasattr(self.plugin, "html") and self.plugin.html: + html = self.plugin.html + else: + errmsg = _("ReCaptcha html not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + challenge = "challenge_%s" % 'new' if re.search(r'sitekey', html) else 'old' + + return getattr(self, challenge)(key, html) + + + def challenge_old(self, key=None, html=None): if not key: - if self.detect_key(): + if self.detect_key(html): key = self.key else: errmsg = _("ReCaptcha key not found") @@ -99,14 +115,15 @@ class ReCaptcha(CaptchaService): try: challenge = re.search("challenge : '(.+?)',", html).group(1) server = re.search("server : '(.+?)',", html).group(1) - except: + + except AttributeError: errmsg = _("ReCaptcha challenge pattern not found") self.plugin.fail(errmsg) - raise ValueError(errmsg) + raise AttributeError(errmsg) self.plugin.logDebug("ReCaptcha challenge: %s" % challenge) - return challenge, self.result(server, challenge) + return self.result(server, challenge), challenge def result(self, server, challenge): @@ -121,126 +138,122 @@ class ReCaptcha(CaptchaService): return result -class ReCaptchaV2(CaptchaService): - __name__ = "ReCaptchaV2" - __version__ = "0.01" + def _collectApiInfo(self): + html = self.plugin.req.load("http://www.google.com/recaptcha/api.js") + a = re.search(r'po.src = \'(.*?)\';', html).group(1) + vers = a.split("/")[5] - __description__ = """ReCaptchaV2 captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org")] + self.plugin.logDebug("ReCaptcha API version: %s" %vers) + language = a.split("__")[1].split(".")[0] - KEY_PATTERN = r'data-sitekey="(.*?)">' + self.plugin.logDebug("ReCaptcha API language: %s" % language) + html = self.plugin.req.load("https://apis.google.com/js/api.js") + b = re.search(r'"h":"(.*?)","', html).group(1) + jsh = b.decode('unicode-escape') - def detect_key(self, html=None): - if not html: - if hasattr(self.plugin, "html") and self.plugin.html: - html = self.plugin.html - else: - errmsg = _("ReCaptcha html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) + self.plugin.logDebug("ReCaptcha API jsh-string: %s" % jsh) - m = re.search(self.KEY_PATTERN, html) - if m: - self.key = m.group(1).strip() - self.plugin.logDebug("ReCaptcha key: %s" % self.key) - return self.key - else: - self.plugin.logDebug("ReCaptcha key not found") - return None + return vers, language, jsh - def collectApiInfo(self): - html = self.plugin.req.load("http://www.google.com/recaptcha/api.js",cookies=True) - a = re.search("po.src = '(.*?)';",html).group(1) - vers = a.split("/")[5] - self.plugin.logDebug("API version: %s" %vers) - language = a.split("__")[1].split(".")[0] - self.plugin.logDebug("API language: %s" %language) + def _prepareTimeAndRpc(self): + self.plugin.req.load("http://www.google.com/recaptcha/api2/demo") - html = self.plugin.req.load("https://apis.google.com/js/api.js",cookies=True) - b = re.search('"h":"(.*?)","',html).group(1) - jsh = b.decode('unicode-escape') - self.plugin.logDebug("API jsh-string: %s" %jsh) + millis = int(round(time.time() * 1000)) - return vers,language,jsh + self.plugin.logDebug("ReCaptcha time: %s" % millis) - def prepareTimeAndRpc(self): - html = self.plugin.req.load("http://www.google.com/recaptcha/api2/demo",cookies=True) + rand = randint(1, 99999999) + a = "0.%s" % str(rand * 2147483647) + rpc = int(100000000 * float(a)) - millis = int(round(time.time() * 1000)) - self.plugin.logDebug("Systemtime in milliseconds: %s" %str(millis)) + self.plugin.logDebug("ReCaptcha rpc-token: %s" % rpc) - rand = randint(1,99999999) - a = "0.%s"%str(rand*2147483647) - rpc = int(100000000*float(a)) - self.plugin.logDebug("Self-generated rpc-token: %s" %str(rpc)) + return millis, rpc - return millis,rpc - def doTheCaptcha(self, host): - self.plugin.logDebug("Parent host: %s" %host) - botguardstring = "!A" - sitekey = self.detect_key() - vers,language,jsh = self.collectApiInfo() - millis,rpc = self.prepareTimeAndRpc() + def challenge_new(self, key=None, html=None): + if not key: + if self.detect_key(html): + key = self.key + else: + errmsg = _("ReCaptcha key not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + try: + parent = urljoin("http://", urlparse(self.plugin.pyfile.url).netloc) + + except Exception: + parent = "" + + botguardstring = "!A" + vers, language, jsh = self._collectApiInfo() + millis, rpc = self._prepareTimeAndRpc() html = self.plugin.req.load("https://www.google.com/recaptcha/api2/anchor", - get={"k":sitekey, - "hl":language, - "v":vers, - "usegapi":"1", - "jsh":jsh+"#id=IO_"+str(millis), - "parent":"http://"+host, - "pfname":"", - "rpctoken":rpc}, - cookies=True) - recaptchatoken = re.search('id="recaptcha-token" value="(.*?)">',html) - self.plugin.logDebug("Captchatoken #1: %s" %recaptchatoken.group(1)) - - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/frame", get={"c":recaptchatoken.group(1), - "hl":language, - "v":vers, - "bg":botguardstring, - "usegapi":"1", - "jsh":jsh}, - cookies=True) - html = html.decode('unicode-escape') - recaptchatoken2 = re.search('"finput","(.*?)",',html) - self.plugin.logDebug("Captchatoken #2: %s" %recaptchatoken2.group(1)) - recaptchatoken3 = re.search('."asconf".\s.\s,"(.*?)".',html) - self.plugin.logDebug("Captchatoken #3: %s" %recaptchatoken3.group(1)) - - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/reload", post={"c":recaptchatoken2.group(1), - "reason":"fi", - "fbg":recaptchatoken3.group(1)}, - cookies=True) - recaptchatoken4 = re.search('"rresp","(.*?)",',html) - self.plugin.logDebug("Captchatoken #4: %s" %recaptchatoken4.group(1)) + get={'k' : key, + 'hl' : language, + 'v' : vers, + 'usegapi' : "1", + 'jsh' : "%s#id=IO_%s" % (jsh, millis), + 'parent' : parent, + 'pfname' : "", + 'rpctoken': rpc}) + + token1 = re.search(r'id="recaptcha-token" value="(.*?)">', html) + self.plugin.logDebug("ReCaptcha token #1: %s" % token1.group(1)) + + html = self.plugin.req.load("https://www.google.com/recaptcha/api2/frame", + get={'c' : token1.group(1), + 'hl' : language, + 'v' : vers, + 'bg' : botguardstring, + 'usegapi': "1", + 'jsh' : jsh}).decode('unicode-escape') + + token2 = re.search(r'"finput","(.*?)",', html) + self.plugin.logDebug("ReCaptcha token #2: %s" % token2.group(1)) + + token3 = re.search(r'."asconf".\s.\s,"(.*?)".', html) + self.plugin.logDebug("ReCaptcha token #3: %s" % token3.group(1)) + + html = self.plugin.req.load("https://www.google.com/recaptcha/api2/reload", + post={'c' : token2.group(1), + 'reason': "fi", + 'fbg' : token3.group(1)}) + + token4 = re.search(r'"rresp","(.*?)",', html) + self.plugin.logDebug("ReCaptcha token #4: %s" % token4.group(1)) millis_captcha_loading = int(round(time.time() * 1000)) - captcha_response = self.plugin.decryptCaptcha("https://www.google.com/recaptcha/api2/payload", get={"c":recaptchatoken4.group(1)},forceUser=True) - respone_encoded = base64.b64encode('{"response":"%s"}' %captcha_response) - self.plugin.logDebug("Encoded result: %s" %respone_encoded) + captcha_response = self.plugin.decryptCaptcha("https://www.google.com/recaptcha/api2/payload", + get={'c':token4.group(1)}, forceUser=True) + response = b64encode('{"response":"%s"}' % captcha_response) + + self.plugin.logDebug("ReCaptcha result: %s" % response) - timeToSolve = int(round(time.time() * 1000)) - millis_captcha_loading - timeToSolveMore = timeToSolve + int(float("0."+str(randint(1,99999999))) * 500) - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/userverify", cookies=True, post={"c":recaptchatoken4.group(1), - "response":respone_encoded, - "t":timeToSolve, - "ct":timeToSolveMore, - "bg":botguardstring}) - recaptchatoken5 = re.search('"uvresp","(.*?)",',html) - self.plugin.logDebug("Captchatoken #5: %s" %recaptchatoken5.group(1)) + timeToSolve = int(round(time.time() * 1000)) - millis_captcha_loading + timeToSolveMore = timeToSolve + int(float("0." + str(randint(1, 99999999))) * 500) - return recaptchatoken5.group(1) + html = self.plugin.req.load("https://www.google.com/recaptcha/api2/userverify", + post={'c' : token4.group(1), + 'response': response, + 't' : timeToSolve, + 'ct' : timeToSolveMore, + 'bg' : botguardstring}) + + token5 = re.search(r'"uvresp","(.*?)",', html) + self.plugin.logDebug("ReCaptcha token #5: %s" % token5.group(1)) + + return token5.group(1), None class AdsCaptcha(CaptchaService): __name__ = "AdsCaptcha" - __version__ = "0.06" + __version__ = "0.07" __description__ = """AdsCaptcha captcha service plugin""" __license__ = "GPLv3" @@ -271,9 +284,9 @@ class AdsCaptcha(CaptchaService): return None - def challenge(self, key=None): + def challenge(self, key=None, html=None): if not key: - if self.detect_key(): + if self.detect_key(html): key = self.key else: errmsg = _("AdsCaptcha key not found") @@ -286,14 +299,15 @@ class AdsCaptcha(CaptchaService): try: challenge = re.search("challenge: '(.+?)',", html).group(1) server = re.search("server: '(.+?)',", html).group(1) - except: + + except AttributeError: errmsg = _("AdsCaptcha challenge pattern not found") self.plugin.fail(errmsg) - raise ValueError(errmsg) + raise AttributeError(errmsg) self.plugin.logDebug("AdsCaptcha challenge: %s" % challenge) - return challenge, self.result(server, challenge) + return self.result(server, challenge), challenge def result(self, server, challenge): @@ -309,7 +323,7 @@ class AdsCaptcha(CaptchaService): class SolveMedia(CaptchaService): __name__ = "SolveMedia" - __version__ = "0.06" + __version__ = "0.07" __description__ = """SolveMedia captcha service plugin""" __license__ = "GPLv3" @@ -319,9 +333,9 @@ class SolveMedia(CaptchaService): KEY_PATTERN = r'api\.solvemedia\.com/papi/challenge\.(?:no)?script\?k=(.+?)["\']' - def challenge(self, key=None): + def challenge(self, key=None, html=None): if not key: - if self.detect_key(): + if self.detect_key(html): key = self.key else: errmsg = _("SolveMedia key not found") @@ -333,14 +347,15 @@ class SolveMedia(CaptchaService): challenge = re.search(r'<input type=hidden name="adcopy_challenge" id="adcopy_challenge" value="([^"]+)">', html).group(1) server = "http://api.solvemedia.com/papi/media" - except: + + except AttributeError: errmsg = _("SolveMedia challenge pattern not found") self.plugin.fail(errmsg) - raise ValueError(errmsg) + raise AttributeError(errmsg) self.plugin.logDebug("SolveMedia challenge: %s" % challenge) - return challenge, self.result(server, challenge) + return self.result(server, challenge), challenge def result(self, server, challenge): @@ -353,7 +368,7 @@ class SolveMedia(CaptchaService): class AdYouLike(CaptchaService): __name__ = "AdYouLike" - __version__ = "0.02" + __version__ = "0.03" __description__ = """AdYouLike captcha service plugin""" __license__ = "GPLv3" @@ -384,9 +399,9 @@ class AdYouLike(CaptchaService): return None - def challenge(self, key=None): + def challenge(self, key=None, html=None): if not key: - if self.detect_key(): + if self.detect_key(html): key = self.key else: errmsg = _("AdYouLike key not found") @@ -405,10 +420,11 @@ class AdYouLike(CaptchaService): 'callback': callback}) try: challenge = json_loads(re.search(callback + r'\s*\((.+?)\)', html).group(1)) - except: + + except AttributeError: errmsg = _("AdYouLike challenge pattern not found") self.plugin.fail(errmsg) - raise ValueError(errmsg) + raise AttributeError(errmsg) self.plugin.logDebug("AdYouLike challenge: %s" % challenge) @@ -435,10 +451,11 @@ class AdYouLike(CaptchaService): try: instructions_visual = challenge['translations'][server['all']['lang']]['instructions_visual'] result = re.search(u'«(.+?)»', instructions_visual).group(1).strip() - except: + + except AttributeError: errmsg = _("AdYouLike result not found") self.plugin.fail(errmsg) - raise ValueError(errmsg) + raise AttributeError(errmsg) result = {'_ayl_captcha_engine' : "adyoulike", '_ayl_env' : server['all']['env'], |