Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
clroxide — CLR을 호스팅하고 dotnet 바이너리를 실행할 수 있는 Rust 라이브러리입니다. | Kitploit
도구/GitHubGitHub/yamakadi/clroxide
Post-ExploitationRed TeamingPayload Development
GitHubyamakadi/clroxide

clroxide

CLR을 호스팅하고 dotnet 바이너리를 실행할 수 있는 Rust 라이브러리입니다.

저장소 보기
236221년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

ClrOxide

ClrOxide는 CLR을 호스팅하고 dotnet 바이너리를 동적으로 실행할 수 있게 해주는 rust 라이브러리입니다.

특별한 이유 없이 Kepler라고 부르고 싶었지만, cargo에 이미 kepler라는 패키지가 있습니다. :(

지난 2년 동안 rust로 CLR 호스팅 작업을 틈틈이 해왔는데, 마침내 2주 전에 뭔가가 맞물리기 시작했습니다!

이 라이브러리는 다음 프로젝트들이 없었다면 불가능했을 것입니다:

  • NimPlant 및 그 execute assembly 구현
    • winim/clr이 Console.Write의 출력 버퍼를 덮어쓰고 출력을 가져오는 방식의 우아함! 그 동일한 우아함을 추구한 것이 이 라이브러리가 2년이나 걸린 유일한 이유입니다. Cas가 이것을 재현할 수 없다면 어떻게 그를 설득해서 rust를 만져보게 할 수 있겠습니까!? NimPlant용 rust 임플란트 작업도 제가 이 토끼굴에 빠지게 된 계기였습니다.
  • ropnop의 go-clr
    • 여기서 ropnop에게 특별히 감사드립니다! 이 전체 라이브러리는 go-clr의 어떤 부분 덕분에 모든 것이 맞물려 3일 만에 완성된 결과물입니다!
  • Kudaes의 dinvoke_rs
    • go-clr과 유사하게 Kurosh의 dinvoke_rs 프로젝트 역시 일부 rust/win32의 복잡한 부분을 명확히 해주었고 프로젝트를 진행할 수 있게 해주었습니다.
  • 다양한 CLR 관련 rust 라이브러리
    • 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로 컴파일하면 rust 패닉 언와인딩(panic unwinding)의 알려진 문제로 인해 실패합니다. i686-pc-windows-msvc에서는 동작할 수도 있지만, 직접 시도해보지는 않았습니다.

Assembly

제가 직접 이 문제를 겪은 것은 아니지만, 어셈블리를 Any CPU 대신 x64로 특별히 컴파일해야 하는 경우가 있을 수 있습니다.

설계 제약 사항

windows 크레이트는 몇 주 전까지만 해도 mscoree.dll에 대한 타입 정의가 없었습니다. mscoree.dll에 대한 정의가 0.48.0 버전의 windows 크레이트에 포함된 것으로 보입니다. 그러나 이러한 정의는 제대로 작동하지 않는 것 같습니다. 예를 들어, CLR 스레드 내의 함수(예: 주소 0x7ffef16821a0)를 가리켜야 하는 vtable 항목이 범위를 크게 벗어난 주소(0x750003cac9053b48)를 반환합니다.

windows 크레이트는 안전성을 위해 vtable에 많은 멋진 작업을 수행하지만, 아이러니하게도 이것이 위의 액세스 위반(access violation)을 일으키는 것 같습니다. 아니면 다른 무언가가 일어나고 있는 것일 수도 있습니다... V2에서는 유지보수 부담을 덜기 위해 공식 정의를 사용하려고 했지만, 이것은 결정적인 문제입니다.

사용법

더 많은 예제는 examples/ 폴더에서 찾을 수 있습니다.

어셈블리 실행 및 출력 캡처

assembly_arch

ClrOxide는 현재 프로세스에 CLR을 로드하고, mscorlib를 해석(resolve)하며, 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용 사용자 지정 로더 사용

CLR을 시작하려면 mscoree.dll에서 CreateInterface 함수를 로드해야 합니다. 기본 기능(default features)을 비활성화하여 사용자 지정 로더를 제공할 수 있습니다.

먼저 종속성 선언에 default-features = false를 추가하세요.

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

그런 다음 Clr 인스턴스를 생성할 때 CreateInterface 함수에 대한 포인터를 반환하는 fn() -> Result<isize, String> 시그니처의 함수를 제공하세요.

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

MDSec의 Massaging your CLR: Preventing Environment.Exit in In-Process .NET Assemblies에 설명된 대로 ClrOxide가 제공하는 구성 요소를 사용하여 System.Environment.Exit를 패치할 수 있습니다.

참조 구현은 examples/patch_exit.rs에서 확인할 수 있습니다. 이 작업에는 VirtualProtect 또는 NtProtectVirtualMemory 사용이 필요하므로 ClrOxide에 이 기능을 추가할 의도는 없습니다.

도구 다운로드