Внедрение кода. Добавление новой секции. Часть 7.

Дата публикации 5 апр 2019 | Редактировалось 2 окт 2019
Основной алгоритм добавления новой секции
Решение проблемы доступного пространства при помощи добавления новой секции имеет некоторые недостатки. Практически все антивирусы опознают нестандартные секции, и если, к тому же, там есть полный набор флагов на чтение/запись/выполнение, то эта ситуация выглядит еще более подозрительно. Но такой способ дает огромное преимущество в объеме внедренного кода.
В начале проведения внедрения необходимо получить общие сведения о файле: определение языка программирования (или компилятора), разрядности архитектуры (32/64), название упаковщика или криптора. Для этого надо использовать программы-анализаторы РЕ-файла, например CFF Explorer, PeStudio или др.

В общем случае алгоритм добавления новой секции может быть таким:
  1. При помощи программ-анализаторов РЕ-файла.
    • определяем язык программирования, название упаковщика или криптора;
    • определяем объем свободных ячеек основной секции кода для вставки команды jmp перехода на новый блок;
    • добавляем новую секцию, проставляем ее физический и виртуальный размеры, а также флаги секции
  2. При помощи шестнадцатеричного редактора, например FlexHex, заполняем ячейки нового блока нулями.
  3. При помощи отладчика кода, например x64Dbg, перемещаем одну или две команды по адресу новой ячейки и на освободившееся место поставить команду перехода jmp на этот адрес.
    В новой секции пишем новый блок кода, последней командой которого должна быть команда возврата jmp на продолжение кода в основной секции.

Добавление новой секции
Рассмотрим добавление новой секции на конкретном примере. Предположим, что существует программа (программа 6.1), написанная в среде masm64 с использованием команд SSE, которая вычисляет математическое уравнение. В эту программу необходимо внедрить свое сообщение функцией MessageBox и добавить его в новую секцию.

Программа 6.1. Сложение 32-разрядных дробных чисел одного массива с использованием команд SSE
Код (ASM):
  1. ; masm64.
  2. include win64a.inc  ;  подключаемые библиотеки
  3. .data
  4.  mas1 dd 1.,2.,3.,4.
  5. tit0 db "Сложение чисел массива ",0 ;
  6. inf0 db "Использование SSE команд",0
  7. titl1 db "Сложение чисел массива ",0 ;
  8. fmt db "Сложение 32-разрядных дробных чисел одного массива",10,
  9. "с использованием команд SSE",10,
  10. "mas1:  1., 2., 3., 4.", 10,13, "Сумма: %d",10,
  11. "Автор: Рысованый А.Н., каф. ВТП, фак. КИТ, НТУ ХПИ",10,
  12. 9,"Сайт:  http://blogs.kpi.kharkov.ua/v2/asm/",0
  13. buf1 dq 0,0 ; буфер
  14. .code
  15. WinMain proc
  16. sub rsp,28h; cтек: 28h=32d+8; 8 - возврат
  17. mov rbp,rsp
  18. invoke MessageBox,0,addr inf0,ADDR tit0,0
  19. movaps XMM0,mas1  ; XMM0:= 4. 3. 2. 1.
  20. movaps XMM1,XMM0     ; XMM1:= 4. 3. 2. 1.
  21. shufps XMM1,XMM1,11111001b ; XMM1:= 4. 4. 3. 2.
  22. addss XMM0,XMM1    ; XMM0:= 4. 3. 2. 3.
  23. shufps XMM1,XMM1,11111001b ; XMM1:= 4. 4. 4. 3.
  24. addss XMM0,XMM1    ; XMM0:= 4. 3. 2. 6.
  25. shufps XMM1,XMM1,11111001b ; XMM1:= 4. 4. 4. 4.
  26. addss XMM0,XMM1    ; XMM0:= 4. 3. 2. 10.
  27. cvttss2si eax,xmm0
  28. movsxd r15,eax
  29. invoke wsprintf,addr buf1,addr fmt,r15
  30. invoke MessageBox,0,addr buf1,ADDR titl1,MB_ICONINFORMATION
  31. invoke RtlExitUserProcess,0 ; invoke ExitProcess,0
  32. WinMain endp
  33. end
Результатами выполнения программы являются последовательно появляющиеся окна сообщений (рис. ).

upload_2019-4-5_16-24-37.png upload_2019-4-5_16-24-43.png

Рассмотрим процесс добавления новой секции кода и внедрение сообщения при помощи функции MessageBox между двумя функциями MessageBox.
Этапы внедрения рассмотрим по пунктам.
  1. Определяем объем свободных ячеек основной секции кода для вставки команды jmp перехода на новый блок. Для этого в программе-анализаторе РЕ-кода LordPE выполняем действия:
    • открываем исследуемый файл;
    • нажимаем на кнопку меню Sections;
    • выделяем мышкой секцию кода text;
    • нажимаем правую клавишу мышки и выбираем кнопку меню hex edit section…
    • подсчитываем объем свободных ячеек основной секции кода. Содержимое выделенной секции выводится на черном фоне. Для расчета необходимо из начального адреса следующей секции вычитаем адрес первой свободной ячейки после окончания кода:
      600h – 482h = 17Еh = 382 байта.
  2. Добавляем новую секцию кода. Для этого в программе-анализаторе РЕ-кода LordPE выполняем действия:
    • нажимаем на кнопку меню Sections (рис. );

      upload_2019-4-5_16-25-5.png
    • выделяем любую секцию и добавляем новую секцию при помощи кнопки меню add section header (рис. );
      upload_2019-4-5_16-25-23.png
    • в появившемся окне выделяем новую секцию и для изменения свойств новой секции нажимаем на кнопку меню edit section header… (рис. ).
      upload_2019-4-5_16-25-54.png

      При этом необходимо запомнить смещение ROffset новой секции. В рассматриваемом случае оно равно 00000А00h;

      Если предполагается использовать почти весь объем секции, то и виртуальный размер VSize должен быть таким же как и физический или больше чтобы не тормозить запись и чтение данных секции (рис. );
      upload_2019-4-5_16-26-14.png
    • для изменения признаков секции выбираем кнопку меню Flags (рис. ).
    upload_2019-4-5_16-26-36.png

    Если после проведенных действий попытаться открыть ехе-файл исследуемой программы в отладчике x64Dbg, то такая попытка не завершится успешно. Дело в том, что новая секция объявлена, в ней проставлены признаки, но ничего не записано (даже нули).
  3. Заполняем ячейки нового блока нулями.
    Для записи в новую секцию нулей необходимо использовать 16-ричный редактор. Выберем, например редактор FlexHex. Открываем программу с новой секцией в редакторе FlexHex и перемещаемся в конец секции.

    Ищем место в секции, где расположена (объявлена) новая секция. А она начинается с адреса RawOffset (ROffset). В нашем случае – это адрес 00000А00h (рис. ).

    upload_2019-4-5_16-27-5.png

    Ставим курсор на первый байт новой секции (по адресу 00000А00h).
    Выбираем пункты меню Edit / Insert Zero Block.
    • в появившемся окне проставляем размер новой секции: Block Size = 200h (рис. );

      upload_2019-4-5_16-27-28.png
    • сохраняем изменения;
    • желательно проверить готовность новой секции программой-анализатором LordPE. Для этого необходимо выбрать новую секцию, нажать правую клавишу мышки и нажать пункт меню hex edit section. В появившемся окне memory buffer выбранная секция выделится темным цветом (рис. ).

    upload_2019-4-5_16-28-10.png

    При нажатии левой клавиши мышки на любом окне программы LordPE темный фон исчезает.
  4. Вносим изменения в код, используя отладчик x64Dbg.
    В отладчике x64Dbg открываем исследуемую программу и еще раз убеждаемся, что новая секция готова к использованию. Для этого выбираем последнюю строку основного меню и в ней пункт Карта памяти (рис. ).

    upload_2019-4-5_16-28-28.png


    Если выделить новую секцию и дважды нажать на левую клавишу мышки, то можно вносить изменения в эту секцию.
  5. Проанализируем исследуемую программу в отладчике x64Dbg. Внешний вид кода показан на рис.

    upload_2019-4-5_16-29-3.png


    Между двумя функциями MessageBox необходимо вставить новую функцию MessageBox. По заданию новая функция MessageBox должна размещаться в новой секции, которую мы уже создали. Для перехода на эту секцию кода надо в исследуемую программу вставить команду jmp на адрес этой секции.
  6. Освободим место для команды jmp. Выберем команду
    Код (ASM):
    1. movaps xmm0, xmmword ptr ds:[0x00007FF65DE13000]
    Дважды выделяем эту строку (рис. ) и ее копируем (нажимаем Ctrl + C).

    upload_2019-4-5_16-29-27.png
  7. Затем в последней строке основного меню выбираем пункт Карта памяти (см. рис. 6.10). Подводим курсор к строке с названием новой секции и дважды нажимаем на этой строке.
    Попадаем в новую секцию. Нажимаем на первую строчку кода, появляется окно (рис. 6.13),
    upload_2019-4-5_16-29-55.png

    в которое вставляем перенесенную строку при помощи сочетания клавиш Ctrl+V (рис. 6.14).

    upload_2019-4-5_16-30-5.png
  8. Копируем адрес первой строки, чтобы на нее поставить команду перехода jmp в основной секции кода. Для этого, на первой строке секции выбираем кнопки меню Копировать/Адрес.
  9. Переходим на основную секцию кода. Для этого в нижней (последней) строке основного меню выбираем пункт Карта памяти (см. рис. 6.10). После этого подводим курсор на строку кода с названием основной секции кода text, дважды нажимаем на этой строке и попадаем в основную секцию.

    Дважды нажимаем на строку кода, которую уже перенесли в новую секцию, пишем слово jmp, а затем вставляем из буфера Ctrl+V (рис. 6.15).

    upload_2019-4-5_16-30-47.png
  10. В качестве примера вставки выбираем вторую функцию MessageBox и построчно переносим сначала параметры функции, а затем и вызов самой функции в новую секцию. Для этого, для каждой переносимой строчки выполняем последовательность действий:
    • копируем строчку кода. На выбранной строчке кода дважды нажимаем левую клавишу мышки и нажимаем Ctrl+C;
    • выбираем пункт Карта памяти;
    • дважды нажимаем на строчке кода с названием новой секции;
    • выбираем место для вставки кода и нажимаем Ctrl+V.
    Результат переноса параметров и самой функции показан на рис. 6.17.

    upload_2019-4-5_16-31-4.png

  11. Последней командой должна быть команда возврата jmp на адрес продолжения кода в основной секции. Для этого перейдем на основную секцию и скопируем адрес на неизмененную строку кода (рис. 6.18).

    upload_2019-4-5_16-31-15.png
  12. Правим содержимое параметров функции MessageBox.
    Меняем адреса ячеек в параметрах. Будем выводить в титуле и окне функции MessageBox одну и туже информацию. Для этого выделяем первую свободную строку новой секции кода (после последней команды jmp), нажимаем правую клавишу мышки и выбираем пункты меню Копировать/Адрес.
    Последовательно выделяем строки кода с передачей параметров через регистры rdx и r8 и заменяем адреса (Ctrl+V).
    Изменяем содержимое ячеек памяти через дамп. Для этого на строке кода, например регистра rdx, нажимаем правую клавишу мышки и выбираем пункты меню Перейти к дампу/Константа.
    После этого ставим курсор на начальный байт в дампе памяти отладчика, нажимаем правую клавишу мышки и выбираем меню Двоичные операции/Редактировать. В появившемся окне в строке ASCII пишем текст (рис. 6.19).

    upload_2019-4-5_16-31-31.png
  13. Сохраняем все изменения.
    Для этого можно выбрать пиктограмму с названием Исправления, нажать на кнопку Исправить файл, а далее новое имя и расширение ехе.
После сохранения файла под новым именем с расширением ехе выведется окно сообщения (рис. 6.20).

upload_2019-4-5_16-31-45.png

Добавление новой секции и внедрение в нее успешно осуществлено.

1 4.816
Alex81524

Alex81524
New Member

Регистрация:
12 фев 2008
Публикаций:
5

Комментарии


      1. Jupiter 30 июн 2019
        "шестнадцатеричный редактор" и "16-разрядный редактор", есть разница )
        Jupiter поправлено