Beispiel #1
0
def netbios_scan(ipaddress_list, timeout=0.5):
    TYPE_UNKNOWN = 0x01
    TYPE_WORKSTATION = 0x00
    TYPE_CLIENT = 0x03
    TYPE_SERVER = 0x20
    TYPE_DOMAIN_MASTER = 0x1B
    TYPE_DOMAIN_CONTROLLER = 0x1C
    TYPE_MASTER_BROWSER = 0x1D
    TYPE_BROWSER = 0x1E
    TYPE_NETDDE = 0x1F
    TYPE_STATUS = 0x21
    format_str = "{:<16}{:<20}{:<20}{:<20}{}".format("IPAddress", "DOMAIN",
                                                     "NetbiosName", "MAC",
                                                     "Nets")
    logger.info(format_str)
    for ipaddress in ipaddress_list:
        n = NetBIOS()
        result = {
            "ip": ipaddress,
            "domain": None,
            "name": None,
            "nets": [],
            "mac": None
        }
        try:
            entries = n.getnodestatus('*', ipaddress, timeout=timeout)
            result['mac'] = n.getmacaddress()
        except Exception as E:
            continue
        for entrie in entries:
            if entrie["TYPE"] == TYPE_SERVER:
                result["name"] = entrie["NAME"].strip().decode('latin-1')
            elif entrie["TYPE"] == TYPE_WORKSTATION:
                result["domain"] = entrie["NAME"].strip().decode('latin-1')
            elif entrie["TYPE"] == TYPE_CLIENT:
                result["TYPE_CLIENT"] = entrie["NAME"].strip().decode(
                    'latin-1')
            elif entrie["TYPE"] == TYPE_DOMAIN_MASTER:
                result["TYPE_DOMAIN_MASTER"] = entrie["NAME"].strip().decode(
                    'latin-1')
            elif entrie["TYPE"] == TYPE_DOMAIN_CONTROLLER:
                result["TYPE_DOMAIN_CONTROLLER"] = entrie["NAME"].strip(
                ).decode('latin-1')
            elif entrie["TYPE"] == TYPE_MASTER_BROWSER:
                result["TYPE_MASTER_BROWSER"] = entrie["NAME"].strip().decode(
                    'latin-1')
            elif entrie["TYPE"] == TYPE_STATUS:
                result["TYPE_STATUS"] = entrie["NAME"].strip().decode(
                    'latin-1')

        try:
            if result.get("name") is not None:
                resp = n.name_query_request(result.get("name"), ipaddress)
                result["nets"].extend(resp.entries)
        except Exception as e:
            pass
        format_str = "{:<16}{:<20}{:<20}{:<20}{}".format(
            ipaddress, result.get("domain"), result.get("name"),
            result.get("mac"), result.get("nets"))
        logger.warning(format_str)
Beispiel #2
0
    def logger_website(self, portScan_result, website, title, wappalyzer_list,
                       response):
        tech_list = []
        for one in wappalyzer_list:
            tech_list.append("{}:{}".format(one.get("name"),
                                            one.get("version")))
        try:
            vendorproductname = portScan_result.get("data").get(
                "versioninfo").get("vendorproductname")[0]
            if len(
                    portScan_result.get("data").get("versioninfo").get(
                        "version")) > 0:
                version = portScan_result.get("data").get("versioninfo").get(
                    "version")[0]
            else:
                version = None
            tech_list.append("{}:{}".format(vendorproductname, version))
        except Exception as E:
            pass

        logger.warning("WebSite   : {}".format(website))
        logger.warning("StatusCode: {}".format(response.status_code))
        logger.warning("Title     : {}".format(title.encode("utf-8")))
        logger.warning("Tech      : {}".format(tech_list))
        logger.warning("----------------------------------------------")
Beispiel #3
0
    async def parse(self, ctx, msg, settings):
        role_converter = RoleConverter()
        new_roles = []
        roles = settings.roles_dict
        for match in re.finditer(self.pattern, msg.content):
            try:
                role = await role_converter.convert(ctx, match['role'])
            except CommandError:
                logger.warning(f"'{match['role']}' doesn't seem to be a role")
                continue
            if match['nick']:
                new_roles.append((match.group('nick').lower(), role.id))
            else:
                new_roles.append((role.name.lower(), role.id))
        if new_roles == []:
            raise ValueError
        for role in new_roles:
            if role[1] in roles.values():  # if role already in dict
                if role[0] not in roles:  # in dict with a different nick
                    roles = {k: v for k, v in roles.items() if v != role[1]}
                    roles[role[0]] = role[1]
                else:                     # in dict with the same nick
                    roles = {k: v for k, v in roles.items() if v != role[1]}
            else:                         # new role
                roles[role[0]] = role[1]

        return roles
Beispiel #4
0
def ms17010scan(ipaddress, port=445, timeout=3):
    try:
        s = socket.socket(AF_INET, SOCK_STREAM)
        s.settimeout(timeout)
        s.connect((str(ipaddress), port))
        s.send(packetms17010)
        nativeos = ""
        try:
            while True:
                data = s.recv(1024)
                if data[8:10] == "\x73\x00":
                    nativeos = data[45:100].split(b'\x00' * 1)[0]
                if data[8:10] == "\x25\x05":
                    if data[9:13] == "\x05\x02\x00\xc0":
                        format_str = "{:<16}{:<7}{:<25}{}".format(ipaddress, port, "VULNERABLE to MS17-010", nativeos)
                        logger.warning(format_str)
                s.send(handle(data, str(ipaddress)))
        except Exception as E:
            pass
            s.close()
    except Exception as msg:
        # print("[+] Can't connecto to "+str(targets))
        try:
            s.close()
        except Exception as E:
            pass
Beispiel #5
0
    def format_log(self, ipaddress, port, data):
        if data.get(u"number") is not None:
            # 根据端口猜测fingerprint
            format_str = "{:<16}{:<7}{:<20}".format(ipaddress, port, data.get("service") + "?")
            store_str = "{},{},{}".format(ipaddress, port, data.get("service") + "?")
        else:
            versioninfo = ""
            try:
                versioninfo = versioninfo + data.get("versioninfo").get("vendorproductname")[0] + "  "
            except Exception as E:
                pass
            try:
                versioninfo = versioninfo + data.get("versioninfo").get("version")[0] + "  "
            except Exception as E:
                pass
            try:
                versioninfo = versioninfo + data.get("versioninfo").get("operatingsystem")[0] + "  "
            except Exception as E:
                pass
            try:
                versioninfo = versioninfo + data.get("versioninfo").get("info")[0] + "  "
            except Exception as E:
                pass
            try:
                versioninfo = versioninfo + data.get("versioninfo").get("hostname")[0] + "  "
            except Exception as E:
                pass

            format_str = "{:<16}{:<7}{:<20}{}".format(ipaddress, port, data.get("service"), versioninfo)
            store_str = "{},{},{}".format(ipaddress, port, data.get("service"))
        logger.warning(format_str)
        ipportservicelogger.info(store_str)
Beispiel #6
0
 async def on_emoji_renamed(self, before, after) -> None:
     """updates our version of an emoji that just got renamed"""
     logger.debug(f'renamed emoji {before.name}->{after.name}')
     e = next((e for e in self.emojis if before.id == e.discord_id), None)
     if e is None:
         logger.warning(
             f"someone renamed an emoji that I don't know about! {after.name}:{after.id}"
         )
     else:
         e.update_from_discord(after)
         await self._update_emojis_db((e, ))
Beispiel #7
0
 async def list_guilds(self):
     """Update the manager with the guilds that we know about"""
     await self.wait_until_ready()
     while not self.is_closed():
         logger.info("Current guilds:")
         for guild in self.guilds:
             if guild.me.display_name == 'archit.us':
                 try:
                     await guild.me.edit(nick='architus')
                 except discord.Forbidden:
                     logger.warning(f"couldn't change nickname in {guild.name}")
             logger.info("{} - {} ({})".format(guild.name, guild.id, guild.member_count))
         await asyncio.sleep(600)
Beispiel #8
0
def netbios_scan(ipaddress, timeout):
    n = NetBIOS()
    result = {
        "ip": ipaddress,
        "domain": None,
        "name": None,
        "nets": [],
        "mac": None
    }
    try:
        entries = n.getnodestatus('*', ipaddress, timeout=timeout)
        result['mac'] = n.getmacaddress()

    except Exception as E:
        return
    for entrie in entries:
        if entrie["TYPE"] == TYPE_SERVER:
            result["name"] = entrie["NAME"].strip().decode('latin-1')
        elif entrie["TYPE"] == TYPE_WORKSTATION:
            result["domain"] = entrie["NAME"].strip().decode('latin-1')
        elif entrie["TYPE"] == TYPE_CLIENT:
            result["TYPE_CLIENT"] = entrie["NAME"].strip().decode('latin-1')
        elif entrie["TYPE"] == TYPE_DOMAIN_MASTER:
            result["TYPE_DOMAIN_MASTER"] = entrie["NAME"].strip().decode(
                'latin-1')
        elif entrie["TYPE"] == TYPE_DOMAIN_CONTROLLER:
            result["TYPE_DOMAIN_CONTROLLER"] = entrie["NAME"].strip().decode(
                'latin-1')
        elif entrie["TYPE"] == TYPE_MASTER_BROWSER:
            result["TYPE_MASTER_BROWSER"] = entrie["NAME"].strip().decode(
                'latin-1')
        elif entrie["TYPE"] == TYPE_STATUS:
            result["TYPE_STATUS"] = entrie["NAME"].strip().decode('latin-1')

    try:
        if result.get("name") is not None:
            resp = n.name_query_request(result.get("name"),
                                        ipaddress,
                                        timeout=timeout)
            result["nets"].extend(resp.entries)

    except Exception as e:
        pass
    format_str = "{:<16}{:<20}{:<20}{:<20}{}".format(ipaddress,
                                                     result.get("domain"),
                                                     result.get("name"),
                                                     result.get("mac"),
                                                     result.get("nets"))
    logger.warning(format_str)
Beispiel #9
0
 async def cache_guild(self, guild):
     '''cache interesting information about all the messages in a guild'''
     logger.debug(f"Downloading messages in {len(guild.channels)} channels for '{guild.name}'...")
     for channel in guild.text_channels:
         try:
             await self.cache_channel(channel)
         except Forbidden:
             logger.warning(f"Insuffcient permissions to download messages from '{guild.name}.{channel.name}'")
         except HTTPException as e:
             logger.error(f"Caught {e} when downloading '{guild.name}.{channel.name}'")
             logger.error("trying again in 10 seconds...")
             await asyncio.sleep(10)
             try:
                 await self.cache_channel(channel)
             except Exception:
                 logger.exception("failed to download channel a second time, giving up :(")
Beispiel #10
0
    async def schedule(self, ctx, *argst):
        '''
        Start an event poll.
        Timezone is based on your servers voice zone.
        '''
        args = list(argst)
        logger.debug(args)
        # event bot's id
        if ctx.guild.get_member(476042677440479252):
            logger.warning("not scheduling cause event bot exists")
            return
        region = ctx.guild.region
        tz = pytz.timezone(self.get_timezone(region))
        # ct = datetime.datetime.now(tz=tz)
        title = []
        parsed_time = None
        for i in range(len(args)):
            with suppress(ValueError):
                parsed_time = dateutil.parser.parse(' '.join(args))
                # parsed_time = tz.localize(parsed_time)
                break
            with suppress(ValueError):
                parsed_time = dateutil.parser.parse(' '.join(args[:-1]))
                # parsed_time = tz.localize(parsed_time)
                break
            title.append(args[0])
            del args[0]
        else:
            parsed_time = await self.prompt_date(ctx, ctx.author)
            if not parsed_time:
                return
            parsed_time = tz.localize(parsed_time)

        if len(title) == 0:
            title_str = await self.prompt_title(ctx, ctx.author)
            if not title_str:
                return
        else:
            title_str = ' '.join(title)

        msg = await ctx.channel.send(
            self.render_schedule_text(title_str, parsed_time, [], [], []))
        await msg.add_reaction(self.YES_EMOJI)
        await msg.add_reaction(self.NO_EMOJI)
        await msg.add_reaction(self.MAYBE_EMOJI)
        self.schedule_messages[msg.id] = ScheduleEvent(msg, title_str,
                                                       parsed_time)
Beispiel #11
0
    async def api_entry(self, method_name, *args, **kwargs):
        """Callback method for the rpc server

        :param method_name: name of the method to execute
        :param *args: args to pass through
        :param **kwargs: kwargs to pass through
        """
        try:
            assert not method_name.startswith('_')
            method = getattr(self, method_name)
        except (AttributeError, AssertionError):
            logger.warning(f"Someone tried to call '{method}' but it doesn't exist (or is private)")
            return {"message": "No such method"}, sc.NOT_FOUND_404

        try:
            return await method(*args, **kwargs)
        except Exception as e:
            logger.exception(f"caught exception while handling remote request")
            return {"message": f"'{e}'"}, sc.INTERNAL_SERVER_ERROR_500
Beispiel #12
0
 def check_website_url(self, website=None, urls=[]):
     for url in urls:
         if website.startswith('https://') or website.startswith('http://'):
             entireUrl = "{}/{}".format(website, url)
         else:
             entireUrl = "http://{}/{}".format(website, url)
         try:
             logging.captureWarnings(True)
             response = requests.get(entireUrl,
                                     verify=False,
                                     headers=self.headers,
                                     timeout=3)
             response.encoding = response.apparent_encoding
         except Exception as E:
             continue
         if response.ok:
             logger.warning("WebSite   : {}".format(website))
             logger.warning("StatusCode: {}".format(response.status_code))
             logger.warning("Url       : {}".format(url))
             logger.warning("Maybe this is your target !!!")
             logger.warning(
                 "----------------------------------------------")
Beispiel #13
0
def http_scan(url):
    # confluence
    try:
        s = CVE_2019_3396(url)
        if s.check():
            format_str = "{:<25} VULNERABLE to CVE_2019_3396".format(url)
            logger.warning(format_str)
    except Exception as E:
        pass

    # jboss
    try:
        s = CVE_2017_12149(url)
        if s.check():
            format_str = "{:<25} VULNERABLE to CVE_2017_12149".format(url)
            logger.warning(format_str)

    except Exception as E:
        pass

    # struts2
    try:
        s = S2_015(url)
        if s.check():
            format_str = "{:<25} VULNERABLE to S2_015".format(url)
            logger.warning(format_str)
    except Exception as E:
        pass

    try:
        s = S2_016(url)
        if s.check():
            format_str = "{:<25} VULNERABLE to S2_016".format(url)
            logger.warning(format_str)
            format_str = "{:<25} Webpath: {}".format(url, s.get_path())
            logger.warning(format_str)
    except Exception as E:
        pass

    try:
        s = S2_045(url)
        if s.check():
            format_str = "{:<25} VULNERABLE to S2_045".format(url)
            logger.warning(format_str)
            format_str = "{:<25} Webpath: {}".format(url, s.get_path())
            logger.warning(format_str)
    except Exception as E:
        pass

    # tomcat
    try:
        s = CVE_2017_12615(url)
        if s.check():
            format_str = "{:<25} VULNERABLE to CVE_2017_12615".format(url)
            logger.warning(format_str)
            format_str = "{:<25} Webshell: {}".format(url, s.confirm_info())
            logger.warning(format_str)
    except Exception as E:
        pass

    try:
        s = WeakPassword(url)
        if s.check():
            format_str = "{:<25} VULNERABLE to WeakPassword".format(url)
            logger.warning(format_str)
    except Exception as E:
        pass

    # weblogic
    try:
        s = CVE_2017_10271(url)
        if s.check():
            format_str = "{:<25} VULNERABLE to CVE_2017_10271".format(url)
            logger.warning(format_str)
    except Exception as E:
        pass

    try:
        s = CVE_2018_2894(url)
        if s.check():
            format_str = "{:<25} VULNERABLE to CVE_2018_2894".format(url)
            logger.warning(format_str)
    except Exception as E:
        pass
    try:
        s = CVE_2019_2729(url)
        if s.check():
            format_str = "{:<25} VULNERABLE to CVE_2019_2729".format(url)
            logger.warning(format_str)

    except Exception as E:
        pass
Beispiel #14
0
def read_squad_examples(input_file, is_training):
    """Read a SQuAD json file into a list of SquadExample."""
    with open(input_file, "r", encoding="utf-8") as reader:
        input_data = json.load(reader)["data"]

    #
    examples = []
    for entry in input_data:
        for paragraph in entry["paragraphs"]:
            paragraph_text = paragraph["context"]
            raw_doc_tokens = customize_tokenizer(
                paragraph_text, do_lower_case=cf.do_lower_case)
            doc_tokens = []
            char_to_word_offset = []
            prev_is_whitespace = True

            k = 0
            temp_word = ""
            for c in paragraph_text:
                if is_whitespace(c):
                    char_to_word_offset.append(k - 1)
                    continue
                else:
                    temp_word += c
                    char_to_word_offset.append(k)
                if cf.do_lower_case:
                    temp_word = temp_word.lower()
                if temp_word == raw_doc_tokens[k]:
                    doc_tokens.append(temp_word)
                    temp_word = ""
                    k += 1

            assert k == len(raw_doc_tokens)

            for qa in paragraph["qas"]:
                qas_id = qa["id"]
                question_text = qa["question"]
                start_position = None
                end_position = None
                orig_answer_text = None

                if is_training:
                    answer = qa["answers"][0]
                    orig_answer_text = answer["text"]

                    if orig_answer_text not in paragraph_text:
                        logger.warning("Could not find answer")
                    else:
                        answer_offset = paragraph_text.index(orig_answer_text)
                        answer_length = len(orig_answer_text)
                        start_position = char_to_word_offset[answer_offset]
                        end_position = char_to_word_offset[answer_offset +
                                                           answer_length - 1]

                        # Only add answers where the text can be exactly recovered from the
                        # document. If this CAN'T happen it's likely due to weird Unicode
                        # stuff so we will just skip the example.
                        #
                        # Note that this means for training mode, every example is NOT
                        # guaranteed to be preserved.
                        actual_text = "".join(
                            doc_tokens[start_position:(end_position + 1)])
                        cleaned_answer_text = "".join(
                            whitespace_tokenize(orig_answer_text))
                        if cf.do_lower_case:
                            cleaned_answer_text = cleaned_answer_text.lower()
                        if actual_text.find(cleaned_answer_text) == -1:
                            # pdb.set_trace()
                            logger.warning(
                                "Could not find answer: '%s' vs. '%s'",
                                actual_text, cleaned_answer_text)
                            continue

                example = SquadExample(qas_id=qas_id,
                                       question_text=question_text,
                                       doc_tokens=doc_tokens,
                                       orig_answer_text=orig_answer_text,
                                       start_position=start_position,
                                       end_position=end_position)
                examples.append(example)
    logger.info("**********read_squad_examples complete!**********")

    return examples
Beispiel #15
0
def bruteforce_interface(portScan_result_list, timeout, no_default_dict, proto_list, pool):
    password_total = Password_total()
    password_total.init(no_default_dict)
    try:
        import psycopg2
        tasksQueue = Queue.Queue()
        postgreSQL_login = PostgreSQL_login()
        for one_portscan_result in portScan_result_list:
            service = one_portscan_result.get("service").lower()
            ipaddress = one_portscan_result.get("ipaddress")
            port = one_portscan_result.get("port")
            if "postgresql" in service and "postgresql" in proto_list:
                tasksQueue.put(
                    (postgreSQL_login.login, (ipaddress, port, password_total.PostgreSQL_user_passwd_pair_list)))

        runner = Runer(100)
        runner.taskQueue = tasksQueue
        runner.start()
    except Exception as E:
        logger.warning("Can not import OpenSSL,PostgreSQL pass")

    # 协程扫描
    patch_all()
    try:
        import gevent_openssl
        gevent_openssl.monkey_patch()
        from bruteforce.rdp_check import check_rdp
        SSL_FLAG = True
    except Exception as E:
        logger.error("Can not import OpenSSL,RDP pass")
        SSL_FLAG = False

    if SSL_FLAG:
        rdp_login = RDP_login(timeout)  # 1.07500004768

    smb_login = SMB_login(timeout)  # 1.08800005913
    ssh_login = SSH_login(timeout)  # 30.617000103
    ftp_login = FTP_login(timeout)  # 9.10599994659
    mysql_login = MySQL_login(timeout)  # 15.7749998569
    mssql_login = MSSQL_login(timeout)  # 1.04799985886
    redis_login = Redis_login(timeout)  # 12.3710000515
    mongo_login = MongoDB_login(timeout)  # 12.9830000401
    memcached_login = Memcached_login(timeout)  # 2.07899999619
    vnc_login = VNC_login(timeout)  # 6.06700015068
    pool = pool
    tasks = []
    for one_portscan_result in portScan_result_list:
        service = one_portscan_result.get("service").lower()
        ipaddress = one_portscan_result.get("ipaddress")
        port = one_portscan_result.get("port")

        # 快的扫描
        if SSL_FLAG:
            if ("ms-wbt-server" in service or "rdp" in service) and "rdp" in proto_list and SSL_FLAG:
                task = pool.spawn(rdp_login.login, ipaddress, port, password_total.RDP_user_passwd_pair_list)
                tasks.append(task)

        if "ssh" in service and "ssh" in proto_list:  # 原生支持协程,直接扫描
            ssh_login.login_with_pool(ipaddress, port, password_total.SSH_user_passwd_pair_list, pool.size)

        if "mongodb" in service and "mongodb" in proto_list:
            task = pool.spawn(mongo_login.login, ipaddress, port, password_total.MongoDB_user_passwd_pair_list)
            tasks.append(task)
        if "ftp" in service and "ftp" in proto_list:
            task = pool.spawn(ftp_login.login, ipaddress, port, password_total.FTP_user_passwd_pair_list)
            tasks.append(task)
        if "microsoft-ds" in service and "smb" in proto_list:
            task = pool.spawn(smb_login.login, ipaddress, port, password_total.SMB_user_passwd_pair_list)
            tasks.append(task)
        if "mysql" in service and "mysql" in proto_list:
            task = pool.spawn(mysql_login.login, ipaddress, port, password_total.MYSQL_user_passwd_pair_list)
            tasks.append(task)
        if "ms-sql-s" in service and "mssql" in proto_list:
            task = pool.spawn(mssql_login.login, ipaddress, port, password_total.MSSQL_user_passwd_pair_list)
            tasks.append(task)
        if "redis" in service and "redis" in proto_list:
            task = pool.spawn(redis_login.login, ipaddress, port, password_total.Redis_user_passwd_pair_list)
            tasks.append(task)
        if "memcached" in service and "memcached" in proto_list:
            task = pool.spawn(memcached_login.login, ipaddress, port, password_total.Memcached_user_passwd_pair_list)
            tasks.append(task)
        if "vnc" in service and "vnc" in proto_list:
            task = pool.spawn(vnc_login.login, ipaddress, port, password_total.VNC_user_passwd_pair_list)
            tasks.append(task)
    gevent.joinall(tasks)
Beispiel #16
0
    async def gulag(self, ctx, comrade: discord.Member):
        '''
        Starts a vote to move a member to the gulag.
        Each vote over the threshold will add additional time.
        '''
        settings = self.bot.settings[ctx.guild]
        filtered = filter(lambda role: role.name == "kulak", ctx.guild.roles)
        try:
            gulag_role = next(filtered)
            gulag_emoji = settings.gulag_emoji
            assert gulag_emoji is not None
        except Exception:
            logger.warning("gulag role/emoji not found")
            await ctx.send(
                "Please create a role called `kulak` and an emoji called `gulag` to use this feature."
            )
            return
        if comrade == self.bot.user:
            await ctx.channel.send(file=discord.File('res/treason.gif'))
            comrade = ctx.author

        t_end = time.time() + 60 * 30
        user_list = []
        timer_msg = None
        timer_msg_gulag = None
        generated = False
        msg = await ctx.send(
            f"{settings.gulag_threshold} more {gulag_emoji}'s to gulag {comrade.display_name}"
        )
        await msg.add_reaction(gulag_emoji)
        while time.time() < t_end:
            user = None

            def check(r, u):
                return r.message.id == msg.id and str(r.emoji) == gulag_emoji

            with suppress(asyncio.TimeoutError):
                react, user = await self.bot.wait_for('reaction_add',
                                                      timeout=5,
                                                      check=check)

            if user and user not in user_list and user != self.bot.user:
                user_list.append(user)
                await msg.edit(
                    content=
                    f"{max(0, (settings.gulag_threshold - len(user_list)))} more {gulag_emoji}'s "
                    f"to gulag {comrade.display_name}")
                t_end += int((settings.gulag_severity / 2) * 60)
            if len(
                    user_list
            ) >= settings.gulag_threshold and gulag_role not in comrade.roles:
                try:
                    logger.debug(comrade.avatar_url)
                    img = gulaggen.generate(await comrade.avatar_url_as(
                        format='png', size=1024).read())
                    generated = True
                except Exception:
                    logger.exception("gulag generator error")
                    pass
                if generated:
                    await ctx.channel.send(file=discord.File(
                        img,
                        filename=f'{self.bot.hoarfrost_gen.generate()}.png'))
                else:
                    await ctx.channel.send(f"gulag'd {comrade.display_name}")

                timer_msg = await ctx.channel.send(
                    f"⏰ {int(settings.gulag_severity * 60)} seconds")
                with suppress(AttributeError):
                    timer_msg_gulag = await (
                        discord.utils.get(ctx.guild.text_channels,
                                          name='gulag')
                    ).send(
                        f"⏰ {int(settings.gulag_severity * 60)} seconds, {comrade.display_name}"
                    )
                await comrade.add_roles(gulag_role)

                t_end = time.time() + int(60 * settings.gulag_severity)

            elif timer_msg or timer_msg_gulag:
                await timer_msg.edit(
                    content=f"⏰ {int(max(0, t_end - time.time()))} seconds")
                with suppress(AttributeError):
                    await timer_msg_gulag.edit(
                        content=f"⏰ {int(max(0, t_end - time.time()))} seconds,"
                        f" {comrade.display_name}")

        if gulag_role not in comrade.roles:
            await msg.edit(
                content=f"Vote for {comrade.display_name} failed to pass")

        await comrade.remove_roles(gulag_role)
        logger.info('ungulag\'d ' + comrade.display_name)