Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
clroxide — Библиотека на Rust, которая позволяет размещать CLR и выполнять dotnet-бинарники. | Kitploit
Инструменты/GitHubGitHub/yamakadi/clroxide
Пост-эксплуатацияRed TeamingРазработка Полезной Нагрузки
GitHubyamakadi/clroxide

clroxide

Библиотека на Rust, которая позволяет размещать CLR и выполнять dotnet-бинарники.

Репозиторий
236221 год назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

ClrOxide

ClrOxide — это библиотека на Rust, которая позволяет размещать CLR и динамически выполнять dotnet-бинарники.

Я хотел назвать её Kepler без особой причины, но в cargo уже есть пакет с именем kepler. :(

Я работал над размещением CLR с помощью Rust с перерывами в течение двух лет, и наконец две недели назад что-то щёлкнуло!

Эта библиотека была бы невозможна без следующих проектов:

  • NimPlant и его реализация execute assembly
    • Элегантность, с которой winim/clr позволяет перезаписывать буфер вывода для Console.Write и получать результат! Стремление к той же элегантности — единственная причина, по которой библиотека создавалась два года. Как я могу убедить Cas заняться Rust, если он не сможет повторить это!? Моя работа над rust-имплантом для NimPlant — это также то, с чего я вообще попал в эту кроличью нору.
  • go-clr от ropnop
    • Особая благодарность ropnop! Вся эта библиотека — результат трёх дней работы благодаря тому, что в go-clr наконец всё для меня встало на свои места!
  • dinvoke_rs от Kudaes
    • Как и go-clr, проект dinvoke_rs от Kurosh также прояснил некоторые тонкости взаимодействия Rust и win32 и позволил проекту двигаться дальше.
  • Различные rust-библиотеки, связанные с CLR
    • https://github.com/ZerothLaw/mscorlib-rs-sys
    • https://github.com/ZerothLaw/mscoree-rs
    • и, вероятно, ещё несколько...

Ограничения архитектуры

ClrOxide

ClrOxide работает только при компиляции для x86_64-pc-windows-gnu или x86_64-pc-windows-msvc.

Компиляция для i686-pc-windows-gnu не удаётся из-за известных проблем с размоткой паники (panic unwinding) в Rust. Возможно, она заработает с i686-pc-windows-msvc, но я сам этого не пробовал.

Сборка

Хотя я сам не сталкивался с этой проблемой, могут быть случаи, когда вам нужно компилировать вашу сборку именно как x64, а не Any CPU.

Ограничения дизайна

В крейте windows не было определений типов для mscoree.dll до нескольких недель назад. Похоже, определения для mscoree.dll попали в крейт windows в версии 0.48.0. Однако эти определения, судя по всему, работают некорректно. Например, запись в vtable, которая должна указывать на функцию внутри потока CLR (скажем, по адресу 0x7ffef16821a0), каким-то образом возвращает адрес, совершенно выходящий за пределы диапазона (0x750003cac9053b48).

Крейт windows делает много хитрых вещей с vtable ради безопасности, но, по иронии судьбы, именно они, скорее всего, вызывают указанное выше нарушение доступа. Или происходит что-то ещё... Я намеревался использовать официальные определения для V2, чтобы снять с себя бремя поддержки, но это неприемлемо.

Использование

Больше примеров можно найти в папке examples/.

Запуск сборки и получение её вывода

assembly_arch

ClrOxide загрузит CLR в текущий процесс, разрешит mscorlib и перенаправит вывод для System.Console, затем загрузит и запустит ваш исполняемый файл и вернёт его вывод в виде строки.

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

root@kitploit:~
use clroxide::clr::Clr;
use std::{env, fs, process::exit};

fn main() -> Result<(), String> {
    let (path, args) = prepare_args();

    let contents = fs::read(path).expect("Unable to read file");
    let mut clr = Clr::new(contents, args)?;

    let results = clr.run()?;

    println!("[*] Results:\n\n{}", results);

    Ok(())
}

fn prepare_args() -> (String, Vec<String>) {
    let mut args: Vec<String> = env::args().collect();

    if args.len() < 2 {
        println!("Please provide a path to a dotnet executable");

        exit(1)
    }

    let mut command_args: Vec<String> = vec![];

    if args.len() > 2 {
        command_args = args.split_off(2)
    }

    let path = args[1].clone();

    println!("[+] Running `{}` with given args: {:?}", path, command_args);

    return (path, command_args);
}

Использование пользовательского домена приложения

assembly_arch

Вы можете изменить контекст, чтобы использовать пользовательский домен приложения. Это может быть полезно, если вы хотите избежать DefaultDomain. Подробности смотрите в examples/custom_app_domain.rs.

root@kitploit:~
...

  let app_domain = clr.using_runtime_host(|host| {
      let app_domain = unsafe { (*host).create_domain("CustomDomain")? };

      Ok(app_domain)
  })?;

  clr.use_app_domain(app_domain)?;

...

Использование пользовательского загрузчика для mscoree.dll

Нам нужно загрузить функцию CreateInterface из mscoree.dll, чтобы запустить CLR. Вы можете предоставить собственный загрузчик, отключив стандартные возможности.

Сначала добавьте default-features = false в объявление зависимости.

root@kitploit:~
clroxide = { version = "1.0.6", default-features = false }

Затем предоставьте функцию с сигнатурой fn() -> Result<isize, String>, которая возвращает указатель на функцию CreateInterface при создании экземпляра Clr.

root@kitploit:~
litcrypt::use_litcrypt!();

fn load_function() -> Result<isize, String> {
  let library = custom_load_library_a(lc!("mscoree.dll\0"));

  if library == 0 {
    return Err("Failed".into());
  }
  
  let function = custom_get_process_address(library, lc!("CreateInterface\0"));
  
  if function == 0 {
    return Err("Failed".into());
  }
  
  Ok(function)
}

fn main() -> Result<(), String> {
 
  // ...

  let mut context = Clr::new(contents, args, load_function)?;

  // ...
  
}

Патч System.Environment.Exit, чтобы он не завершал процесс

assembly_arch

Вы можете использовать строительные блоки, предоставляемые ClrOxide, для патча System.Environment.Exit, как описано в «Massaging your CLR: предотвращение Environment.Exit во встроенных .NET-сборках» от MDSec.

Вы можете посмотреть эталонную реализацию в examples/patch_exit.rs. Поскольку для этого требуется использование VirtualProtect или NtProtectVirtualMemory, я не собираюсь добавлять это в качестве функции в ClrOxide.

Скачать инструмент