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

curve25519 shellcode

slender

floppy-диск
Пользователь
Регистрация
22.04.2015
Сообщения
9
Реакции
0
Однажды мне понадобилось использовать эллиптическую криптографию в коде на ассемблере (FASM). Мой взор пал на легкую либу curve25519 с исходником на C. Нужен был чистый код, без зависимостей (а их там аж три штуки: умножение 64-битных чисел, memset и memcpy). Было решено просто рипнуть скомпилированный код (ибо делать имплементацию этого чуда на ассемблере совсем лениво), и собрать с учетом некоторых правок, что я и сделал.

main.asm (curve_lib.inc лежит в аттаче)
Код:
    format pe console

    entry start

    include 'win32a.inc'


section '.data' data readable writeable

    priv                    db 'private: ',      0
    publ                    db ' public: ',      0
    shar                    db ' shared: ',      0
    frmt                    db '%02X',           0
    next_line               db 13, 10,           0


;       uint8_t basepoint[32] = {9};
    basepoint               db 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
                            db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

    private_key_1           db 0x50, 0xA9, 0xB2, 0x19, 0x0B, 0xC3, 0x71, 0x44, 0x12, 0xEB, 0x2E, 0xEB, 0x80, 0x03, 0xC3, 0x69
                            db 0xEC, 0x60, 0x90, 0x44, 0x57, 0x24, 0xF5, 0x0D, 0x08, 0xD3, 0x23, 0xD3, 0x18, 0x9D, 0x6D, 0xFD

    private_key_2           db 0x38, 0x77, 0x55, 0xD6, 0x8C, 0xA4, 0xA0, 0x2A, 0xAB, 0x00, 0x50, 0xAE, 0x13, 0xAE, 0x2E, 0x1B
                            db 0x09, 0x9E, 0x34, 0x8E, 0xC6, 0x7C, 0xA4, 0xFA, 0x8A, 0x59, 0x60, 0x45, 0xEC, 0xDC, 0x21, 0x89

    public_key_1            rb 32
    public_key_2            rb 32

    shared_key_1            rb 32
    shared_key_2            rb 32


section '.text' code readable executable

;       Шеллкод curve25519-donna.
    include 'curve_lib.inc'


;       От нас требуют:
;           "...
;           To generate a private key, generate 32 random bytes and:
;
;           mysecret[0] &= 248;
;           mysecret[31] &= 127;
;           mysecret[31] |= 64;
;           ..."
    proc prepare_private_key, key
        mov esi, [key]
        and byte[esi], 248
        mov al, byte[esi + 31]
        and al, 127
        or al, 64
        mov byte[esi + 31], al

        ret
    endp


;       Вывод значений.
    proc print, szLabel, pBuffer
        cinvoke printf, [szLabel]
        mov esi, [pBuffer]
        xor ecx, ecx

    @@: movzx eax, byte[esi]

        push ecx
        cinvoke printf, frmt, eax
        pop ecx

        inc ecx
        inc esi

        cmp ecx, 32
        jne @b

        cinvoke printf, next_line

        ret
    endp

start:

;   ---------------------------------------------------------------------------------

    stdcall prepare_private_key, private_key_1
    stdcall prepare_private_key, private_key_2

;   ---------------------------------------------------------------------------------

    stdcall curve25519_donna, public_key_1, private_key_1, basepoint
    stdcall curve25519_donna, public_key_2, private_key_2, basepoint

    stdcall curve25519_donna, shared_key_1, private_key_1, public_key_2
    stdcall curve25519_donna, shared_key_2, private_key_2, public_key_1

;   ---------------------------------------------------------------------------------

    stdcall print, priv, private_key_1
    stdcall print, priv, private_key_2

    cinvoke printf, next_line

    stdcall print, publ, public_key_1
    stdcall print, publ, public_key_2

    cinvoke printf, next_line

    stdcall print, shar, shared_key_1
    stdcall print, shar, shared_key_2

;   ---------------------------------------------------------------------------------

    cinvoke getchar
    xor eax, eax
    ret


section '.idata' import data readable writeable

    library msvcrt, 'msvcrt.dll'

    import  msvcrt,\
            printf, 'printf',\
            getchar, 'getchar'

Результат работы:
private: 50A9B2190BC3714412EB2EEB8003C369EC6090445724F50D08D323D3189D6D7D
private: 387755D68CA4A02AAB0050AE13AE2E1B099E348EC67CA4FA8A596045ECDC2149

public: CB0647D9457C536DB7FB18C8044E4B8DAA9E811166C830D8B72803D4E1498E21
public: 54D0057FBC4A08B30266DFA0B6702C91960811AC7F45C95064911A73B8AAAD58

shared: 47AAB98094C63AA159F5444E0C502FBC6425D6E175749AB73C3C3C085FDAC153
shared: 47AAB98094C63AA159F5444E0C502FBC6425D6E175749AB73C3C3C085FDAC153

Размер пи-кода составляет 7004 байт.

Также подчеркну интересную особенность в ходе работы: так как компиляция производится "студийным" компилятором, рипнутый код необходимо ассемблировать microsoft'ным ассемблером. Мы можем собрать и FASM'ом, но на выходе получим неожиданный результат - любая пара будет вычислять неверный shared-ключ. Вся проблема заключается в разнице генерируемых опкодов.

082ef3251526b949bc514a64e784c98d.png


Вот такой камень преткновения при ассемблировании сложного кода после умного компилятора.

Скачать -
 

Вложения

  • lib.rar
    10.8 КБ · Просмотры: 71


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