コード例 #1
0
    def decrypt(self, pyfile):
        fs_filename = os.fsencode(pyfile.url)
        with open(fs_filename, mode="rb") as fp:
            torrent_content = fp.read()

        time_ref = "{:.2f}".format(time.time())[-6:].replace(".", "")
        pack_name = "torrent {}".format(time_ref)

        if pyfile.url.endswith(".magnet"):
            if torrent_content.startswith(b"magnet:?"):
                self.packages.append((pyfile.package().name, [to_str(torrent_content)], pyfile.package().folder))

        elif pyfile.url.endswith(".torrent"):
            m = re.search(rb"name(\d+):", torrent_content)
            if m:
                m = re.search(
                    b"".join((b"name", m.group(1), b":(.{", m.group(1), b"})")),
                    torrent_content
                )
                if m:
                    pack_name = safename(to_str(m.group(1)))

            torrent_filename = os.path.join(
                self.pyload.tempdir, "tmp_{}.torrent".format(pack_name)
            )
            with open(torrent_filename, mode="wb") as fp:
                fp.write(torrent_content)

            self.packages.append(
                (
                    pack_name,
                    ["file://{}".format(urllib.request.pathname2url(torrent_filename))],
                    pack_name,
                )
            )
コード例 #2
0
    def repair(self):
        p = self.call_cmd("rc", self.filename)

        #: Communicate and retrieve stderr
        self.progress(p)
        out, err = (to_str(r, "utf-16").strip() if r else ""
                    for r in p.communicate())

        if err or p.returncode:
            p = self.call_cmd("r", self.filename)

            # communicate and retrieve stderr
            self.progress(p)
            out, err = (to_str(r, "utf-16").strip() if r else ""
                        for r in p.communicate())

            if err or p.returncode:
                return False

            else:
                dir = os.path.dirname(self.filename)
                name = self._RE_FIXNAME.search(out).group(1)

                self.filename = os.path.join(dir, name)

        return True
コード例 #3
0
    def run(self):
        #: Connect to IRC etc.
        self.sock = socket.socket()
        host = self.config.get("host")
        self.sock.connect((host, self.config.get("port")))

        if self.config.get("ssl"):
            self.sock = ssl.wrap_socket(
                self.sock,
                cert_reqs=ssl.CERT_NONE)  # TODO: support certificate

        nick = self.config.get("nick")
        self.log_info(self._("Connecting as"), nick)
        self.sock.send(to_bytes("NICK {}\r\n".format(nick)))
        self.sock.send(
            to_bytes("USER {} {} bla :{}\r\n".format(nick, host, nick)))
        self.log_info(self._("Connected to"), host)
        for t in self.config.get("owner").split():
            if t.startswith("#"):
                self.sock.send(to_bytes("JOIN {}\r\n".format(t)))
                self.log_info(self._("Joined channel {}").format(to_str(t)))
        self.log_info(self._("Switching to listening mode!"))
        try:
            self.main_loop()

        except IRCError:
            self.sock.send(b"QUIT :byebye\r\n")
            self.sock.close()
コード例 #4
0
    def api_info(cls, url):
        info = {}

        for _ in range(5):
            html = get_url(
                "http://uploaded.net/api/filemultiple",
                get={
                    "apikey": cls.API_KEY,
                    "id_0": re.match(cls.__pattern__, url).group("ID"),
                },
                decode=False,
            )

            html = to_str(html, 'latin1')
            if html != "can't find request":
                api = html.split(",", 4)
                if api[0] == "online":
                    info.update({
                        "name": api[4].strip(),
                        "size": api[2],
                        "status": 2,
                        "sha1": api[3],
                    })
                else:
                    info["status"] = 1
                break
            else:
                time.sleep(3)

        return info
コード例 #5
0
    def handle_CNL(self):
        links = []

        m = re.search(self.CNL_LINK_PATTERN, self.data)
        if m is not None:
            html = self.load(m.group(1))
            _, inputs = parse_html_form("/flash/", html)
            if inputs is not None:
                #: Get key
                key = bytes.fromhex(re.search(r"'(\w+)'", inputs['jk']).group(1))
                crypted = inputs["crypted"]

                #: Decrypt
                #Key = key
                #IV = key
                cipher = Cipher(
                    algorithms.AES(key), modes.CBC(key), backend=default_backend()
                )
                decryptor = cipher.decryptor()
                text = decryptor.update(base64.b64decode(crypted)) + decryptor.finalize()

                #: Extract links
                text = to_str(text).replace("\x00", "").replace("\r", "")
                links = filter(bool, text.split('\n'))

        return links
コード例 #6
0
def addcrypted2():
    package = flask.request.form.get(
        "package",
        flask.request.form.get("source", flask.request.form.get("referer")))
    crypted = flask.request.form["crypted"]
    jk = flask.request.form["jk"]

    crypted = standard_b64decode(unquote(crypted.replace(" ", "+")))
    jk = eval_js(f"{jk} f()")

    try:
        IV = key = bytes.fromhex(jk)
    except Exception:
        return "Could not decrypt key", 500

    cipher = Cipher(algorithms.AES(key),
                    modes.CBC(IV),
                    backend=default_backend())
    decryptor = cipher.decryptor()
    decrypted = decryptor.update(crypted) + decryptor.finalize()
    urls = to_str(decrypted).replace("\x00", "").replace("\r", "").split("\n")
    urls = [url for url in urls if url.strip()]

    api = flask.current_app.config["PYLOAD_API"]
    try:
        if package:
            api.add_package(package, urls, 0)
        else:
            api.generate_and_add_packages(urls, 0)
    except Exception:
        return "failed can't add", 500
    else:
        return "success\r\n"
コード例 #7
0
    def extract(self, password=None):
        command = "x" if self.fullpath else "e"

        p = self.call_cmd(command, self.filename, self.dest, password=password)

        #: Communicate and retrieve stderr
        self.progress(p)
        out, err = (to_str(r).strip() if r else "" for r in p.communicate())

        if err:
            if self._RE_BADPWD.search(err):
                raise PasswordError

            elif self._RE_BADCRC.search(err):
                raise CRCError(err)

            elif self.config.get("ignore_warnings", False) and err.startswith(
                "WARNING:"
            ):
                pass

            else:  #: Raise error if anything is on stderr
                raise ArchiveError(err)

        if p.returncode:
            raise ArchiveError(self._("Process return code: {}").format(p.returncode))

        return self.list(password)
コード例 #8
0
    def list(self, password=None):
        command = "v" if self.fullpath else "l"

        p = self.call_cmd(command, "-v", self.filename, password=password)
        out, err = (to_str(r, "utf-16").strip() if r else ""
                    for r in p.communicate())

        if "Cannot open" in err:
            raise ArchiveError(self._("Cannot open file"))

        if err:  #: Only log error at this point
            self.log_error(err)

        files = set()
        f_grp = 5 if float(self.VERSION) >= 5 else 1
        for groups in self._RE_FILES.findall(out):
            f = groups[f_grp].strip()
            if not self.fullpath:
                f = os.path.basename(f)

            files.add(os.path.join(self.dest, f))

        self.files = list(files)

        return self.files
コード例 #9
0
 def _parse_links(start_node):
     return [
         to_str(
             base64.b64decode(
                 node.getElementsByTagName("url")[0].firstChild.data))
         for node in start_node.getElementsByTagName("file")
     ]
コード例 #10
0
    def find(cls):
        try:
            if os.name == "nt":
                cls.CMD = os.path.join(PKGDIR, "lib", "RAR.exe")
            else:
                cls.CMD = "rar"

            p = subprocess.Popen([cls.CMD],
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            out, err = (to_str(r).strip() if r else ""
                        for r in p.communicate())
            # cls.__name__ = "RAR"
            cls.REPAIR = True

        except OSError:
            try:
                if os.name == "nt":
                    cls.CMD = os.path.join(PKGDIR, "lib", "UnRAR.exe")
                else:
                    cls.CMD = "unrar"

                p = subprocess.Popen([cls.CMD],
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
                out, err = (to_str(r).strip() if r else ""
                            for r in p.communicate())

            except OSError:
                return False

        m = cls._RE_VERSION.search(out)
        if m is not None:
            cls.VERSION = m.group(1)
            cls._RE_FILES = cls._RE_FILES_V4 if float(
                cls.VERSION) < 5 else cls._RE_FILES_V5
            return True

        else:
            return False
コード例 #11
0
    def decrypt(self, data):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        data = data.strip()

        data += b"=" * (-len(data) % 4)

        dlc_key = data[-88:]
        dlc_data = base64.b64decode(data[:-88])
        dlc_content = self.plugin.load(self.API_URL.format(to_str(dlc_key)))

        try:
            rc = base64.b64decode(
                re.search(r"<rc>(.+)</rc>", dlc_content, re.S).group(1))[:16]

        except AttributeError:
            raise BadDLC

        cipher = Cipher(algorithms.AES(self.KEY),
                        modes.CBC(self.IV),
                        backend=default_backend())
        decryptor = cipher.decryptor()
        key = iv = decryptor.update(rc) + decryptor.finalize()

        cipher = Cipher(algorithms.AES(key),
                        modes.CBC(iv),
                        backend=default_backend())
        decryptor = cipher.decryptor()
        xml_data = to_str(
            base64.b64decode(
                decryptor.update(dlc_data) + decryptor.finalize()))

        root = xml.dom.minidom.parseString(xml_data).documentElement
        content_node = root.getElementsByTagName("content")[0]

        packages = DLCDecrypter._parse_packages(content_node)

        return packages
コード例 #12
0
def parse_irc_msg(line):
    """
    Breaks a message from an IRC server into its origin, command, and arguments.
    """
    origin = ''
    if not line:
        return None, None, None

    if line[0:1] == b':':
        origin, line = line[1:].split(b' ', 1)

    if line.find(b' :') != -1:
        line, trailing = line.split(b' :', 1)
        args = line.split()
        args.append(trailing)

    else:
        args = line.split()

    command = args.pop(0)

    return to_str(origin), to_str(command), [to_str(arg) for arg in args]
コード例 #13
0
    def verify(self, password=None):
        p = self.call_cmd("l", "-v", self.filename, password=password)
        out, err = (to_str(r).strip() if r else "" for r in p.communicate())

        if self._RE_BADPWD.search(err):
            raise PasswordError

        if self._RE_BADCRC.search(err):
            raise CRCError(err)

        #: Output is only used to check if password protected files are present
        for groups in self._RE_FILES.findall(out):
            if groups[0] == "*":
                raise PasswordError
コード例 #14
0
    def verify(self, password=None):
        #: 7z can't distinguish crc and pw error in test
        p = self.call_cmd("l", "-slt", self.filename)
        out, err = (to_str(r).strip() if r else "" for r in p.communicate())

        if self._RE_BADPWD.search(out):
            raise PasswordError

        elif self._RE_BADPWD.search(err):
            raise PasswordError

        elif self._RE_BADCRC.search(out):
            raise CRCError(self._("Header protected"))

        elif self._RE_BADCRC.search(err):
            raise CRCError(err)
コード例 #15
0
    def _get_links(self, crypted, jk):
        #: Get key and iv
        key = iv = bytes.fromhex(jk)

        #: Decrypt
        cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
        decryptor = cipher.decryptor()
        text = to_str(
            decryptor.update(base64.b64decode(crypted)) + decryptor.finalize()
        )

        #: Extract links
        text = text.replace("\x00", "").replace("\r", "")
        links = [link for link in text.split("\n") if link]

        return links
コード例 #16
0
    def call_cmd(self, command, *xargs, **kwargs):
        args = []

        #: Use UTF8 for console encoding
        args.append("-scsUTF-8")
        args.append("-sccUTF-8")

        #: Progress output
        if self.VERSION and float(self.VERSION) >= 15.08:
            #: Disable all output except progress and errors
            args.append("-bso0")
            args.append("-bsp1")

        #: Overwrite flag
        if self.overwrite:
            if self.VERSION and float(self.VERSION) >= 15.08:
                args.append("-aoa")

            else:
                args.append("-y")

        else:
            if self.VERSION and float(self.VERSION) >= 15.08:
                args.append("-aos")

        #: Exclude files
        for word in self.excludefiles:
            args.append("-xr!{}".format(word.strip()))

        #: Set a password
        password = kwargs.get("password")

        if password:
            args.append("-p{}".format(password))
        else:
            args.append("-p-")

        # NOTE: return codes are not reliable, some kind of threading, cleanup whatever issue
        call = [self.CMD, command] + args + list(xargs)
        self.log_debug("EXECUTE " + " ".join(call))

        call = [to_str(cmd) for cmd in call]
        p = subprocess.Popen(call, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        renice(p.pid, self.priority)

        return p
コード例 #17
0
    def call_cmd(self, command, *xargs, **kwargs):
        args = []

        #: Specify UTF-16 encoding
        args.append("-scu")

        #: Overwrite flag
        if self.overwrite:
            args.append("-o+")
        else:
            args.append("-o-")
            args.append("-or")

        for word in self.excludefiles:
            args.append("-x{}".format(word.strip()))

        #: Assume yes on all queries
        args.append("-y")

        #: Disable comments show
        args.append("-c-")

        #: Set a password
        password = kwargs.get("password")

        if password:
            args.append("-p{}".format(password))
        else:
            args.append("-p-")

        if self.keepbroken:
            args.append("-kb")

        # NOTE: return codes are not reliable, some kind of threading, cleanup
        # whatever issue
        call = [self.CMD, command] + args + list(xargs)
        self.log_debug("EXECUTE " + " ".join(call))

        call = [to_str(cmd) for cmd in call]
        p = subprocess.Popen(call,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)

        renice(p.pid, self.priority)

        return p
コード例 #18
0
    def find(cls):
        try:
            if os.name == "nt":
                cls.CMD = os.path.join(PKGDIR, "lib", "7z.exe")

            p = subprocess.Popen(
                [cls.CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE
            )
            out, err = (to_str(r).strip() if r else "" for r in p.communicate())

        except OSError:
            return False

        else:
            m = cls._RE_VERSION.search(out)
            if m is not None:
                cls.VERSION = m.group(1)

            return True
コード例 #19
0
    def list(self, password=None):
        p = self.call_cmd("l", self.filename, password=password)

        out, err = (to_str(r).strip() if r else "" for r in p.communicate())

        if any(e in err for e in ("Can not open", "cannot find the file")):
            raise ArchiveError(self._("Cannot open file"))

        if p.returncode > 1:
            raise ArchiveError(self._("Process return code: {}").format(p.returncode))

        files = set()
        for groups in self._RE_FILES.findall(out):
            f = groups[-1].strip()
            if not self.fullpath:
                f = os.path.basename(f)
            files.add(os.path.join(self.dest, f))

        self.files = list(files)

        return self.files
コード例 #20
0
    def extract(self, password=None):
        command = "x" if self.fullpath else "e"

        p = self.call_cmd(command, "-o" + self.dest, self.filename, password=password)

        #: Communicate and retrieve stderr
        self.progress(p)
        out, err = (to_str(r).strip() if r else "" for r in p.communicate())

        if err:
            if self._RE_BADPWD.search(err):
                raise PasswordError

            elif self._RE_BADCRC.search(err):
                raise CRCError(err)

            else:  #: Raise error if anything is on stderr
                raise ArchiveError(err)

        if p.returncode > 1:
            raise ArchiveError(self._("Process return code: {}").format(p.returncode))
コード例 #21
0
    def scan(self, pyfile, thread):
        avfile = os.fsdecode(self.config.get("avfile"))
        avargs = os.fsdecode(self.config.get("avargs").strip())

        if not os.path.isfile(avfile):
            self.fail(self._("Antivirus executable not found"))

        scanfolder = self.config.get("avtarget") == "folder"

        if scanfolder:
            dl_folder = self.pyload.config.get("general", "storage_folder")
            package_folder = (pyfile.package().folder
                              if self.pyload.config.get(
                                  "general", "folder_per_package") else "")
            target = os.path.join(dl_folder, package_folder, pyfile.name)
            target_repr = "Folder: " + package_folder or dl_folder
        else:
            target = os.fsdecode(pyfile.plugin.last_download)
            target_repr = "File: " + os.path.basename(
                pyfile.plugin.last_download)

        if not exists(target):
            return

        thread.add_active(pyfile)
        pyfile.set_custom_status(self._("virus scanning"))
        pyfile.set_progress(0)

        try:
            p = subprocess.Popen([avfile, avargs, target])

            out, err = (to_str(x).strip() for x in p.communicate())

            if out:
                self.log_info(target_repr, out)

            if err:
                self.log_warning(target_repr, err)
                if not self.config.get("ignore-err"):
                    self.log_debug(
                        "Delete/Quarantine task aborted due scan error")
                    return

            if p.returncode:
                action = self.config.get("action")

                if scanfolder:
                    if action == "Antivirus default":
                        self.log_warning(
                            self.
                            _("Delete/Quarantine task skipped in folder scan mode"
                              ))
                    return

                pyfile.error = self._("Infected file")

                try:
                    if action == "Delete":
                        if not self.config.get("deltotrash"):
                            os.remove(target)

                        else:
                            try:
                                send2trash.send2trash(target)

                            except NameError:
                                self.log_warning(
                                    self.
                                    _("Send2Trash lib not found, moving to quarantine instead"
                                      ))
                                pyfile.set_custom_status(self._("file moving"))
                                shutil.move(target, self.config.get("quardir"))

                            except Exception as exc:
                                self.log_warning(
                                    self.
                                    _("Unable to move file to trash: {}, moving to quarantine instead"
                                      ).format(exc))
                                pyfile.set_custom_status(self._("file moving"))
                                shutil.move(target, self.config.get("quardir"))

                            else:
                                self.log_debug(
                                    "Successfully moved file to trash")

                    elif action == "Quarantine":
                        pyfile.set_custom_status(self._("file moving"))
                        shutil.move(target, self.config.get("quardir"))

                except (IOError, shutil.Error) as exc:
                    self.log_error(target_repr, action + " action failed!",
                                   exc)

            elif not err:
                self.log_debug(target_repr, "No infected file found")

        finally:
            pyfile.set_progress(100)
            thread.finish_file(pyfile)
コード例 #22
0
    def decrypt_image(
        self, img, input_type="jpg", output_type="textual", ocr=False, timeout=120
    ):
        """
        Loads a captcha and decrypts it with ocr, plugin, user input.

        :param img: image raw data
        :param get: get part for request
        :param post: post part for request
        :param cookies: True if cookies should be enabled
        :param input_type: Type of the Image
        :param output_type: 'textual' if text is written on the captcha\
        or 'positional' for captcha where the user have to click\
        on a specific region on the captcha
        :param ocr: if True, builtin ocr is used. if string, the OCR plugin name is used

        :return: result of decrypting
        """
        result = None
        time_ref = "{:.2f}".format(time.time())[-6:].replace(".", "")

        with open(
            os.path.join(
                self.pyload.tempdir,
                "captcha_image_{}_{}.{}".format(
                    self.pyfile.plugin.__name__, time_ref, input_type
                ),
            ),
            "wb",
        ) as img_f:
            img_f.write(img)

        if ocr:
            self.log_info(self._("Using OCR to decrypt captcha..."))

            if isinstance(ocr, str):
                _OCR = self.pyload.plugin_manager.load_class(
                    "anticaptcha", ocr
                )  #: Rename `captcha` to `ocr` in 0.6.x
                result = _OCR(self.pyfile).recognize(img_f.name)
            else:
                result = self.recognize(img_f.name)

                if not result:
                    self.log_warning(self._("No OCR result"))

        if not result:
            captcha_manager = self.pyload.captcha_manager
            timeout = max(timeout, 50)

            try:
                params = {
                    "src": "data:image/{};base64,{}".format(
                        input_type, to_str(base64.standard_b64encode(img))
                    ),
                    "file": img_f.name,
                    "captcha_plugin": self.__name__,
                    "plugin": self.pyfile.plugin.__name__,
                }
                self.task = captcha_manager.new_task(input_type, params, output_type)

                captcha_manager.handle_captcha(self.task, timeout)

                while self.task.is_waiting():
                    self.pyfile.plugin.check_status()
                    time.sleep(1)

            finally:
                captcha_manager.remove_task(self.task)

            result = self.task.result

            if self.task.error:
                if not self.task.handler and not self.pyload.is_client_connected():
                    self.log_warning(
                        self._("No Client connected for captcha decrypting")
                    )
                    self.fail(self._("No Client connected for captcha decrypting"))
                else:
                    self.pyfile.plugin.retry_captcha(msg=self.task.error)

            elif self.task.result:
                self.log_info(self._("Captcha result: `{}`").format(result))

            else:
                self.pyfile.plugin.retry_captcha(
                    msg=self._(
                        "No captcha result obtained in appropriate timing ({}s)"
                    ).format(timeout)
                )

        if not self.pyload.debug:
            self.remove(img_f.name, try_trash=False)

        return result
コード例 #23
0
 def _parse_packages(start_node):
     return [(to_str(base64.b64decode(node.getAttribute("name"))),
              DLCDecrypter._parse_links(node))
             for node in start_node.getElementsByTagName("package")]