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-бинарники.

Репозиторий
2362241 год назадПроверено 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.

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