summaryrefslogtreecommitdiffstats
path: root/module/plugins/internal/CaptchaService.py
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins/internal/CaptchaService.py')
-rw-r--r--module/plugins/internal/CaptchaService.py267
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'],