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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
BridgeHead — ADWS를 통한 Active Directory에 대한 네이티브 C++ 접근, .NET, WCF, HTTP 스택 불필요. | Kitploit
도구/GitHubGitHub/zakipedio/bridgehead
Authentication & AuthorizationScripting & AutomationInformation GatheringNetwork SecurityPenetration TestingUtilities & FrameworksIdentity & Access Management (IAM)Red Teaming
GitHubzakipedio/bridgehead

BridgeHead

ADWS를 통한 Active Directory에 대한 네이티브 C++ 접근, .NET, WCF, HTTP 스택 불필요.

저장소 보기
823445개월 전Kitploit 검토 완료

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

BridgeHead

ADWS를 통한 Active Directory에 대한 네이티브 C++ 접근, .NET, WCF, HTTP 스택 없음.

BridgeHead는 TCP 위에서 직접 Active Directory Web Services (ADWS) 프로토콜 스택 전체를 구현하는 C++20 정적 라이브러리입니다. 디렉터리 트래픽이 흐르는 게이트웨이인 AD 브리지헤드 서버의 이름을 따서 명명되었으며, PowerShell의 Get-ADUser와 Get-ADComputer가 내부적으로 사용하는 9389 포트에 대한 동일한 저수준 접근을 C++ 코드에 제공합니다.

목차

  • 프로토콜 스택
  • 빠른 시작
  • API 참조
  • 빌드
  • 통합
  • 플랫폼 지원
  • 종속성
  • 알려진 제한 사항
  • 프로토콜 참조
  • 라이선스

프로토콜 스택

전송 계층은 공통 bridgehead::transport::IByteStream 인터페이스를 통해 하위 계층을 래핑합니다. NbfseCodec은 AdwsClient가 호출하는 코덱 유틸리티로, 프레이밍 전후에 SOAP 메시지를 인코딩/디코딩합니다.``` AdwsClient WS-Enumeration + WS-Transfer [MS-ADDM] ├── NbfseCodec .NET Binary Format for SOAP [MC-NBFSE] (encode/decode) └── NmfFramer .NET Message Framing [MC-NMF] (send/receive frames) └── NnsSession .NET NegotiateStream [MS-NNS] └── TcpSocket raw TCP/IP

root@kitploit:~
소비자를 위한 진입점은 `bridgehead::adws::AdwsClient`입니다.

---

## 빠른 시작

### 사용자 조회 및 열거```cpp
#include "bridgehead/adws/AdwsClient.hpp"

// NTLM (works on any host)
auto client = bridgehead::adws::AdwsClient::EnumerationClient(
    "192.168.1.10",     // DC IP or hostname
    "DC01.corp.local",  // DC FQDN, used in NMF Via header and Kerberos SPN
    "CORP",             // NetBIOS domain name
    "Administrator",    // username
    "Passw0rd"          // password
);

// Kerberos (username hidden on the wire; requires DC reachable on port 88)
auto client = bridgehead::adws::AdwsClient::EnumerationClient(
    "192.168.1.10", "DC01.corp.local", "CORP",
    "Administrator", "Passw0rd",
    bridgehead::adws::AuthPackage::Kerberos
);

auto users = client.Query(
    "(objectClass=user)",
    {"sAMAccountName", "distinguishedName", "memberOf"}
);

for (auto& obj : users)
    std::cout << obj.FirstValue("sAMAccountName") << '\n';

대규모 결과 집합 스트리밍```cpp

client.Enumerate( "(objectClass=computer)", {"dNSHostName", "operatingSystem"}, "", // empty = domain root base DN [](const bridgehead::adws::LdapObject& obj) { std::cout << obj.FirstValue("dNSHostName") << '\n'; return true; // return false to stop early (sends wsen:Release) } );

root@kitploit:~
### 범위 및 페이지 매김```cpp
// OneLevel scope, 50 objects per Pull round-trip
client.Query(
    "(objectClass=user)",
    {"sAMAccountName"},
    "OU=Admins,DC=corp,DC=local",
    50,
    bridgehead::adws::SearchScope::OneLevel
);

이진 속성, objectGUID, objectSid```cpp

auto objs = client.Query("(objectClass=user)", {"objectGUID", "objectSid"}); for (auto& obj : objs) { if (auto* b = obj.FirstBytes("objectGUID")) std::cout << bridgehead::adws::ParseGuid(b) << '\n'; // {XXXXXXXX-...} if (auto b = obj.FirstBytes("objectSid")) std::cout << bridgehead::adws::ParseSid(*b) << '\n'; // S-1-5-... }

root@kitploit:~
### 보안 설명자 디코딩```cpp
#include "bridgehead/adws/SecurityDescriptor.hpp"

auto objs = client.Query("(objectClass=user)", {"nTSecurityDescriptor"});
if (auto* raw = objs[0].FirstBytes("nTSecurityDescriptor")) {
    auto sd = bridgehead::adws::ParseSecurityDescriptor(*raw);
    std::cout << "Owner: " << sd.ownerSid << '\n';
    for (auto& ace : sd.dacl.aces)
        std::cout << "  type=" << (int)ace.type
                  << " mask=0x" << std::hex << ace.mask
                  << " sid="   << ace.sid << '\n';
}

속성 쓰기 (리소스 엔드포인트)```cpp

auto rc = bridgehead::adws::AdwsClient::ResourceClient( "192.168.1.10", "DC01.corp.local", "CORP", "Administrator", "Passw0rd");

// Modify attributes rc.Put("CN=Alice,OU=Users,DC=corp,DC=local", { {"description", {"managed by bridgehead"}}, {"telephoneNumber", {"555-1234"}}, });

// Clear an attribute (both values and bytes empty = delete) rc.Put("CN=Alice,OU=Users,DC=corp,DC=local", { {"telephoneNumber", {}}, });

// Read back auto obj = rc.Get("CN=Alice,OU=Users,DC=corp,DC=local", {"description", "telephoneNumber"});

// Delete object rc.Delete("CN=TempUser,OU=Users,DC=corp,DC=local");

root@kitploit:~
### LDAP 수정 유형, Add / Replace / Delete

`Put`은 기본적으로 `Replace`로 설정됩니다 (모든 기존 값을 덮어씁니다). 다중 값 속성에 대한 세밀한 제어를 위해 `ModifyOperation`을 사용하세요:```cpp
using bridgehead::adws::LdapModification;
using bridgehead::adws::ModifyOperation;

rc.Put("CN=Alice,OU=Users,DC=corp,DC=local", {
    // Append a value to an existing multi-valued attribute
    LdapModification{"otherTelephone", {"555-9999"}, {}, ModifyOperation::Add},

    // Remove one specific value (leave others intact)
    LdapModification{"otherTelephone", {"555-0000"}, {}, ModifyOperation::Delete},

    // Replace is the default, explicit here for clarity
    LdapModification{"description", {"updated"}, {}, ModifyOperation::Replace},
});

이동 / 이름 변경```cpp

// Move to a different OU rc.Move( "CN=Alice,OU=OldOU,DC=corp,DC=local", // current DN "CN=Alice,OU=NewOU,DC=corp,DC=local" // new DN );

// Rename in place (same parent, new CN) rc.Move( "CN=Alice,OU=Users,DC=corp,DC=local", "CN=AliceSmith,OU=Users,DC=corp,DC=local" );

root@kitploit:~
### 이진 속성 쓰기

이진 값은 `LdapModification`의 `bytes` 필드에 제공합니다. 자동으로 와이어에서 base64로 인코딩됩니다.```cpp
std::vector<uint8_t> thumbnail = loadFile("photo.jpg");

rc.Put("CN=Alice,OU=Users,DC=corp,DC=local", {
    LdapModification{"thumbnailPhoto", {}, {thumbnail}},
});

객체 생성 (ResourceFactory 엔드포인트)```cpp

auto rf = bridgehead::adws::AdwsClient::ResourceFactoryClient( "192.168.1.10", "DC01.corp.local", "CORP", "Administrator", "Passw0rd");

rf.Create( "CN=NewUser,OU=Users,DC=corp,DC=local", "user", {{"sAMAccountName", {"newuser"}}, {"userAccountControl", {"512"}}} );

root@kitploit:~
### Async 작업```cpp
#include "bridgehead/adws/AdwsClientAsync.hpp"

auto ac = bridgehead::adws::AdwsClientAsync::EnumerationClient(
    "192.168.1.10", "DC01.corp.local", "CORP", "Administrator", "Passw0rd");

auto future = ac.QueryAsync("(objectClass=user)", {"sAMAccountName"});

// ... do other work while the query runs ...

auto users = future.get();  // blocks until complete; re-throws any exception

느린 DC에서의 시간 초과:```cpp if (future.wait_for(std::chrono::seconds(5)) == std::future_status::timeout) { // query is still running }

root@kitploit:~
모든 작업에는 비동기 변형이 있습니다: `QueryAsync`, `EnumerateAsync`, `GetAsync`, `PutAsync`, `DeleteAsync`, `CreateAsync`, `MoveAsync`.

### 연결 풀 (고빈도 / 멀티스레드 작업 부하)```cpp
#include "bridgehead/adws/AdwsClientPool.hpp"

// Enumeration pool, Query / Enumerate
bridgehead::adws::AdwsClientPool pool({
    .host = "192.168.1.10", .fqdn = "DC01.corp.local",
    .domain = "CORP", .username = "Administrator", .password = "Passw0rd",
    .maxSize = 4,   // up to 4 concurrent authenticated sessions
});

auto users = pool.Query("(objectClass=user)", {"sAMAccountName"});

// Resource pool, Get / Put / Delete
bridgehead::adws::AdwsClientPool resPool({
    .host = "192.168.1.10", .fqdn = "DC01.corp.local",
    .domain = "CORP", .username = "Administrator", .password = "Passw0rd",
    .maxSize = 4,
    .endpoint = bridgehead::adws::PoolEndpoint::Resource,
});
auto obj = resPool.Get("CN=Alice,OU=Users,DC=corp,DC=local", {"mail"});
resPool.Put("CN=Alice,OU=Users,DC=corp,DC=local", {{"mail", {"[email protected]"}}});

// ResourceFactory pool, Create
bridgehead::adws::AdwsClientPool rfPool({
    .host = "192.168.1.10", .fqdn = "DC01.corp.local",
    .domain = "CORP", .username = "Administrator", .password = "Passw0rd",
    .endpoint = bridgehead::adws::PoolEndpoint::ResourceFactory,
});
rfPool.Create("CN=NewUser,OU=Users,DC=corp,DC=local", "user",
              {{"sAMAccountName", {"newuser"}}});

API 참조

모든 공개 헤더는 include/bridgehead/에 있습니다. 전체 API 문서는 Doxygen으로 생성할 수 있습니다(Build 참조).

bridgehead::adws::AdwsClient

bridgehead::adws::AdwsClientAsync

std::future 기반 비동기 래퍼. AdwsClient와 동일한 팩토리 메서드; 각 작업은 std::future<T>를 반환합니다.```cpp std::future<std::vector> f = ac.QueryAsync(...); std::future e = ac.EnumerateAsync(filter, attrs, baseDN, callback); std::future g = ac.GetAsync(...); std::future h = ac.PutAsync(...); std::future i = ac.DeleteAsync(...); std::future j = ac.CreateAsync(...); std::future k = ac.MoveAsync(...);

root@kitploit:~
여러 연결에 걸친 동시 쿼리를 위해 `AdwsClientPool`을 사용하세요.

### `bridgehead::adws::AdwsClientPool`

사전 인증된 세션의 스레드 안전 풀입니다. 연결은 지연 생성되고 호출 간에 재사용됩니다.```cpp
pool.IdleCount();   // sessions currently idle
pool.TotalCount();  // idle + checked-out
pool.MaxSize();     // configured maximum pool size
pool.Move(dn, newDn);  // Move/rename (Resource pool)

`bridgehead::adws::SearchScope````cpp

enum class SearchScope { Base, OneLevel, Subtree /default/ };

root@kitploit:~
### `bridgehead::adws::LdapObject` / `LdapAttribute````cpp
struct LdapAttribute {
    std::string name;
    std::string syntax;                         // LdapSyntax OID, empty if absent
    std::vector<std::string>          values;   // text values (raw base64 for binary)
    std::vector<std::vector<uint8_t>> bytes;    // decoded binary; parallel to values
};

struct LdapObject {
    std::vector<LdapAttribute>  attributes;                          // all returned attributes
    const LdapAttribute*        Find(const std::string& name) const;  // case-insensitive
    std::string                 FirstValue(const std::string& name) const;
    const std::vector<uint8_t>* FirstBytes(const std::string& name) const;
};

바이너리 헬퍼```cpp

std::string ParseGuid(const std::vector<uint8_t>& bytes); // → "{XXXXXXXX-XXXX-...}" std::string ParseSid (const std::vector<uint8_t>& bytes); // → "S-1-5-..."

root@kitploit:~
### `FilterValue` 및 필터 빌더 도우미

`FilterValue`는 RFC 4515 §3 메타문자(`\`, `*`, `(`, `)`, NUL)를 생성 시 이스케이프하는 타입 안전 래퍼입니다. 빌더 도우미와 함께 사용하면 LDAP 인젝션이 구조적으로 불가능해집니다:```cpp
// UNSAFE, raw string concatenation, easy to forget escaping
client.Query("(sAMAccountName=" + username + ")", ...);

// SAFE, FilterValue escapes on construction; FilterEq composes the assertion
FilterValue user = username;
client.Query(FilterEq("sAMAccountName", user), ...);

// Compose complex filters
client.Query(
    FilterAnd({
        FilterEq("objectClass", FilterValue::Raw("user")),  // Raw() for safe literals
        FilterOr({
            FilterEq("sAMAccountName", user),
            FilterEq("mail", FilterValue(email)),
        }),
        FilterNot(FilterPresent("userAccountControl")),
    }), {"sAMAccountName", "mail"}
);

EscapeLdapFilter(str)는 필터 문자열을 수동으로 빌드해야 할 때 사용할 수 있는 저수준 프리미티브로 계속 제공됩니다.

DnValue 및 DN 빌더 도우미

FilterValue와 동일한 패턴이지만, Distinguished Name RDN 값(RFC 4514 §2.4)에 대한 것입니다. ,, +, ", \, <, >, ;, NUL, 그리고 앞/뒤의 #와 공백을 이스케이프합니다.```cpp // UNSAFE, comma injection breaks the DN structure rc.Get("CN=" + username + ",OU=Users,DC=corp,DC=local", attrs);

// SAFE DnValue cn = username; // auto-escaped auto dn = BuildDn({DnAttr("CN", cn), "OU=Users", "DC=corp", "DC=local"}); rc.Get(dn, attrs);

// DnValue::Raw() for values you control auto dn2 = BuildDn({DnAttr("CN", DnValue::Raw("Service Account")), "OU=SvcAccounts", "DC=corp", "DC=local"});

root@kitploit:~
### `bridgehead::adws::SecurityDescriptor````cpp
SecurityDescriptor ParseSecurityDescriptor(const std::vector<uint8_t>& bytes);

struct SecurityDescriptor {
    uint16_t    control;       // SdControl::* flags
    std::string ownerSid;
    std::string groupSid;
    bool hasDacl; Acl dacl;
    bool hasSacl; Acl sacl;
};
struct Acl { std::vector<Ace> aces; };
struct Ace {
    uint8_t     type;                  // AceType::*
    uint8_t     flags;                 // AceFlags::*
    uint32_t    mask;
    std::string sid;
    std::string objectType;            // GUID string, object ACEs only
    std::string inheritedObjectType;   // GUID string, object ACEs only
};

Constant namespaces: AceType::*, AceFlags::*, SdControl::*.

bridgehead::ConnectionError / AuthenticationError / ProtocolError

include/bridgehead/Exceptions.hpp에 정의됨 (AdwsClient.hpp에 의해 간접적으로 포함됨). 세 가지 모두 std::runtime_error를 확장합니다:

유형발생 조건
ConnectionErrorTCP 수준 실패: 연결 거부, 시간 초과, I/O 오류
AuthenticationErrorNTLM/Kerberos 협상 실패
ProtocolError프로토콜 계층에서 잘못된 형식의 서버 응답
try {
root@kitploit:~
auto client = bridgehead::adws::AdwsClient::EnumerationClient(...);
auto users  = client.Query(...);

} catch (const bridgehead::ConnectionError& e) { // unreachable DC, wrong port, timeout } catch (const bridgehead::AuthenticationError& e) { // bad credentials, KDC unreachable } catch (const bridgehead::ProtocolError& e) { // unexpected server response } catch (const bridgehead::adws::SoapFault& e) { // DC returned a SOAP fault (e.g. invalid filter) } // or coarse-grained: // } catch (const std::runtime_error& e) { ... }

root@kitploit:~
### `bridgehead::adws::SoapFault`

모든 `s:Fault` 응답에 대해 일반적인 `std::runtime_error` 대신 발생합니다:```cpp
struct SoapFault : std::runtime_error {
    std::string code;     // e.g. "Sender"
    std::string subcode;  // e.g. "InvalidEnumerationContext", empty if absent
    std::string reason;   // human-readable text
};

bridgehead::adws::LdapModification

Put 및 Create에 의해 사용됨:```cpp enum class ModifyOperation { Replace /default/, Add, Delete };

struct LdapModification { std::string name; std::vectorstd::string values; // text values std::vector<std::vector<uint8_t>> bytes; // binary values (base64-encoded on the wire) ModifyOperation operation = ModifyOperation::Replace; };

root@kitploit:~
`values`와 `bytes`가 모두 비어 있으면 `operation`에 관계없이 속성이 지워지거나 삭제됩니다.

### `bridgehead::adws::ProtocolLimits`

모든 팩토리 메서드, `AdwsClientAsync` 팩토리 및 `AdwsClientPool::Config::limits`의 선택적 마지막 매개변수입니다. 모든 필드에는 안전한 기본값이 있으므로 특정 요구 사항이 있는 경우에만 변경하십시오:```cpp
struct ProtocolLimits {
    uint32_t nmfMaxFrameBytes   = 64 * 1024 * 1024;  // max NMF frame (default 64 MiB)
    uint32_t nnsMaxPayloadBytes = 16 * 1024 * 1024;  // max NNS packet (default 16 MB)
    int tcpKeepaliveIdleSec     = 60;   // idle seconds before first probe
    int tcpKeepaliveIntervalSec = 10;   // seconds between probes
    int tcpKeepaliveProbeCount  = 5;    // probes before declaring dead (POSIX only)
};

nmfMaxFrameBytes / nnsMaxPayloadBytes 값을 높이십시오: 비정상적으로 큰 이진 속성을 가진 객체를 읽을 때만 해당됩니다 (예: 많은 ACE가 포함된 nTSecurityDescriptor 또는 큰 thumbnailPhoto). 유휴 연결이 적극적으로 종료되는 클라우드/NAT 환경에서는 keepalive 필드를 낮추십시오.

명명된 생성자 도우미(인라인 정적 팩토리):```cpp LdapModification::Replace(name, values) // Replace with text values (default) LdapModification::ReplaceBinary(name, bytes) // Replace with binary values LdapModification::Append(name, values) // Add to multi-valued attribute LdapModification::Remove(name, values={}) // Remove specific values (or all) LdapModification::Clear(name) // Delete the attribute entirely

root@kitploit:~
---

## 빌드

**요구 사항:** CMake 3.25+ 및 C++20 호환 컴파일러 (MSVC 2022+, GCC 12+, Clang 15+).```bash
# Configure and build (unit tests only, no live AD needed)
cmake -B build -A x64
cmake --build build --config Release

# Run unit tests
ctest --test-dir build -C Release --output-on-failure

# With integration tests (requires a live Domain Controller)
cmake -B build -A x64 -DBRIDGEHEAD_INTEGRATION_TESTS=ON
cmake --build build --config Release
./build/tests/Release/bridgehead_integration_tests.exe

# With CLI tool (adws_list, browse AD objects from the command line)
cmake -B build -A x64 -DBRIDGEHEAD_BUILD_TOOLS=ON
cmake --build build --config Release --target adws_list
./build/tools/Release/adws_list.exe --host <dc-ip> --fqdn <dc-fqdn> --domain <domain> --user <user>

# Generate API reference docs (requires Doxygen)
cmake --build build --target docs
# or directly:
doxygen Doxyfile
# Output: docs/doxygen/html/index.html

CMake 옵션


통합

옵션 A, CMake 하위 디렉터리 (설치 불필요)```cmake

add_subdirectory(bridgehead) target_link_libraries(my_target PRIVATE bridgehead::bridgehead)

root@kitploit:~
### 옵션 B, 설치된 패키지 (find_package)```bash
cmake --install build --prefix /usr/local   # or any install prefix
  • 비율 조정: 위저드 시스템 내에서 다양한 색상 팔레트와 스타일을 실험하여 원하는 모양을 얻으세요.
  • 통합 기능: 다른 도구(예: Seclists, PayloadsAllTheThings)의 요소를 통합하여 리소스를 풍부하게 만드세요.

구현 전략

root@kitploit:~
git clone https://github.com/example/wizard-poc.git
cd wizard-poc
python3 setup.py install

위저드 시스템

위저드 시스템은 사용자가 단계별 지침을 통해 구성 프로세스를 안내받을 수 있도록 설계되었습니다. 동적 입력 유효성 검사와 오류 처리를 지원합니다.

주요 기능

  • 상황별 도움말: 옵션 위에 마우스를 올리면 자세한 설명이 제공됩니다.
  • 템플릿 엔진: 미리 정의된 템플릿을 기반으로 구성을 생성합니다.
  • 로깅: 디버깅 및 감사를 위한 상세한 로그를 제공합니다.```cmake find_package(bridgehead REQUIRED) target_link_libraries(my_target PRIVATE bridgehead::bridgehead)
root@kitploit:~
`pugixml`, `ws2_32`, `secur32` (Windows) / `gssapi_krb5` (Linux/macOS)는 모두 전이적으로 포함됩니다.

---

## 플랫폼 지원

| 플랫폼 | 인증 백엔드 | 상태 |
|----------|-------------|--------|
| Windows | SSPI (`secur32.dll`), NTLM 및 Kerberos | **작동 중** |
| Linux / macOS | GSSAPI (`libgssapi_krb5`), SPNEGO / Kerberos | 컴파일됨; 아직 통합 테스트되지 않음 |

`AuthPackage::Ntlm`과 `AuthPackage::Kerberos`는 모두 Windows에서 작동합니다. Kerberos는 전송 중 사용자 이름을 숨기며 프로덕션 환경에서 선호됩니다. NTLM은 KDC(포트 88)에 연결할 수 없을 때 대체 수단입니다.

Linux/macOS에서 GSSAPI 백엔드는 SPNEGO와 Kerberos를 사용합니다. NTLM 지원을 위해 `gss-ntlmssp` 플러그인을 설치하십시오:```bash
apt install libgss-ntlmssp   # Debian / Ubuntu
dnf install gssntlmssp       # Fedora / RHEL

플러그인이 없으면 서버는 Kerberos로 협상합니다. 명시적인 사용자/비밀번호 자격 증명은 gss_acquire_cred_with_password(MIT Kerberos 1.9+)를 사용하며, 기본 자격 증명 캐시(kinit)를 사용하려면 빈 문자열을 전달합니다. GSSAPI 경로는 깔끔하게 컴파일되며 설계상 올바르지만, 실제 DC에 대해 종단간 검증이 아직 이루어지지 않았으므로 Linux/macOS 지원은 베타로 간주하십시오.

암호화 참고: 포트 9389의 ADWS는 NNS 계층(NTLM 세션 키 또는 Kerberos AES-256)에서 암호화되며, TLS가 아닙니다. 이는 설계상 의도된 것이며, DC는 이 포트에서 TLS를 제공하지 않습니다. 인증서 기반 서버 인증이 필요한 경우 LDAPS(포트 636)가 대안입니다.


종속성

cmake/Dependencies.cmake를 통해 구성 시 자동으로 가져오므로 수동 설치가 필요하지 않습니다:

라이브러리버전용도
Catch2v3.5.2단위 테스트 프레임워크(테스트 대상만 해당)
pugixmlv1.14XML DOM(ADWS 응답 구문 분석만 해당)

OpenSSL 없음. Asio 없음. Boost 없음.


알려진 제한 사항

  • Linux/macOS의 NTLM은 gss-ntlmssp GSSAPI 플러그인이 필요합니다(플랫폼 지원 참조). 이 플러그인이 없으면 서버는 대신 Kerberos로 협상합니다. Windows의 NTLM은 SSPI를 통해 기본적으로 작동합니다.

  • pugixml DOM, 각 SOAP 응답은 결과가 반환되기 전에 메모리 내 XML 트리로 완전히 구문 분석됩니다. 이는 maxElements 페이지 크기(기본적으로 Pull당 256개 개체)에 의해 제한되므로 전체 결과 집합이 한 번에 메모리에 저장되지 않습니다. 메모리는 매우 큰 페이지 크기나 많은 ACE가 있는 개체의 nTSecurityDescriptor와 같은 큰 이진 속성을 가진 개체의 경우에만 문제가 됩니다. SAX/스트리밍 접근 방식이 이를 해결할 수 있지만 현재 계획되어 있지 않습니다.


프로토콜 참조

  • [MS-ADDM], Active Directory Web Services: 데이터 모델 및 공통 요소
  • [MS-NNS], .NET NegotiateStream 프로토콜
  • [MC-NMF], .NET 메시지 프레이밍
  • [MC-NBFSE], .NET 이진 형식: SOAP 확장
  • [MS-DTYP], Windows 데이터 형식(SECURITY_DESCRIPTOR, ACL, ACE, SID, GUID)
  • [MS-ADTS], Active Directory 기술 사양(LDAP 필터/속성)

모든 사양은 Microsoft의 Open Specifications 문서에서 확인할 수 있습니다.


특별 감사

이 프로젝트에 영감과 연구, 그리고 공개적으로 공유된 작업을 제공해 주신 IBM X-Force와 SoaPy 프로젝트에 특별히 감사드립니다. 또한 IBM X-Force Red의 SoaPy 창시자인 Logan Goins에게도 그 작업을 가능하게 한 노력과 통찰력에 감사를 표합니다.


라이선스

자세한 내용은 LICENSE를 참조하십시오.

도구 다운로드
메서드엔드포인트설명
EnumerationClient(host, fqdn, domain, user, pass [, auth, timeoutMs, opTimeoutMs, limits])/Enumeration팩토리, 연결 및 인증
ResourceClient(...)/ResourceGet / Put / Delete / Move를 위한 팩토리
ResourceFactoryClient(...)/ResourceFactory생성을 위한 팩토리
Query(filter, attrs [, baseDN, maxElems, scope])Enumeration모든 결과를 vector로 수집
Enumerate(filter, attrs, baseDN, callback [, maxElems, scope])Enumeration콜백을 통해 결과 스트리밍
Get(dn, attrs)Resource단일 객체의 속성 읽기
Put(dn, modifications)Resource속성 수정
Delete(dn)Resource객체 삭제
Create(dn, objectClass, attrs)ResourceFactory새 객체 생성
Move(dn, newDn)Resource기존 객체 이동 또는 이름 변경
옵션기본값설명
BRIDGEHEAD_BUILD_TESTSON단위 테스트 스위트 빌드
BRIDGEHEAD_INTEGRATION_TESTSOFF통합 테스트 빌드 (활성 DC 필요)
BRIDGEHEAD_BUILD_TOOLSOFFadws_list CLI 도구 빌드