Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
BridgeHead — وصول أصلي بلغة C++ إلى Active Directory عبر ADWS، بدون .NET، بدون WCF، بدون حزمة HTTP. | Kitploit
أدوات/GitHubGitHub/zakipedio/bridgehead
المصادقة والترخيصالبرمجة النصية والأتمتةجمع المعلوماتأمن الشبكاتاختبار الاختراقالأدوات والمكوناتإدارة الهوية والوصول (IAM)الفريق الأحمر
GitHubzakipedio/bridgehead

BridgeHead

وصول أصلي بلغة C++ إلى Active Directory عبر ADWS، بدون .NET، بدون WCF، بدون حزمة HTTP.

عرض المستودع
82344منذ 5 أشهرتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

BridgeHead

وصول أصلي بلغة C++ إلى Active Directory عبر ADWS، بدون .NET، بدون WCF، بدون مكدس HTTP.

BridgeHead هي مكتبة ثابتة بلغة C++20 تنفذ مكدس بروتوكول Active Directory Web Services (ADWS) بالكامل مباشرة عبر TCP. سميت على اسم خادم جسر AD (Bridgehead)، وهي البوابة التي تمر من خلالها حركة مرور الدليل، وتمنح كود C++ الخاص بك نفس الوصول منخفض المستوى إلى المنفذ 9389 الذي تستخدمه أوامر PowerShell مثل Get-ADUser و Get-ADComputer تحت الغطاء.

جدول المحتويات

  • مكدس البروتوكول
  • البدء السريع
  • مرجع 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:~
The entry point for consumers is `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، إضافة / استبدال / حذف

يستخدم `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:~
### كتابة السمات الثنائية

قم بتوفير القيم الثنائية في حقل `bytes` من `LdapModification`. يتم ترميزها بـ base64 تلقائيًا على الشبكة:```cpp
std::vector<uint8_t> thumbnail = loadFile("photo.jpg");

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

إنشاء الكائنات (ResourceFactory endpoint)```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:~
### العمليات غير المتزامنة```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 (انظر البناء).

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، ولكن لقيم 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
};

مساحات الأسماء الثابتة: AceType::*, AceFlags::*, SdControl::*.

bridgehead::ConnectionError / AuthenticationError / ProtocolError

مُعرَّفة في include/bridgehead/Exceptions.hpp (مُضمَّنة بشكل غير مباشر بواسطة AdwsClient.hpp). تمتد الثلاثة جميعها من std::runtime_error:

النوعيُرمى عند
ConnectionErrorفشل على مستوى TCP: رفض، مهلة، خطأ إدخال/إخراج
AuthenticationErrorفشل التفاوض NTLM/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` من DC بدلاً من `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 فقط إذا كنت تقرأ كائنات ذات سمات ثنائية كبيرة بشكل غير عادي (مثل nTSecurityDescriptor مع العديد من ACEs، أو thumbnailPhoto كبير). اخفض حقول keepalive في البيئات السحابية/NAT حيث يتم قطع الاتصالات الخاملة بشكل عدواني.

مساعدات البناء المسماة (مصانع ثابتة مضمنة):```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:~
### الخيار ب، الحزمة المثبتة (`find_package`)```bash
cmake --install build --prefix /usr/local   # or any install prefix

أما إذا كنت تستخدم macOS، فسوف تحتاج إلى أن تفعل شيئا في أكثر من ذلك بقليل لأن النظام قمت بتثبيته مع النقطة لا يبدو أن يكون له نفس المالك مثل الجهاز الافتراضي. في حالة تحتاج إلى تشغيل الأوامر التالية. لاحظ أن هذه المقالة تحتوي على مسار يختلف وفقا لإعداداتك. لذا ينبغي استخدام الصياغة التالية:

sudo chown -R $(whoami) $(brew --prefix)/*

root@kitploit:~
pip3 install mitmproxy2swagger
mitmproxy2swagger -h

🏛️ اختيار إطار العمل

يتوفر إطار عمل أوكولو بثلاثة توزيعات: الإصدار الأساسي، إصدار Pro، وإصدار Enterprise. كما في الرسم التخطيطي أدناه، تقدم التوزيعات نفس الوظائف الأساسية ولكنها تختلف في قابلية التوسع والمرونة الإضافية. يمكنك اختيار أحد هذه التوزيعات بناءً على احتياجاتك الفعلية.

root@kitploit:~
# سير عمل إطار العمل
# قم بتثبيت إطار العمل
# استيراد وحدة التحكم
# بدء التحكم
# نشر الوظائف
# إجراء الاستعلام

إصدار المجتمع

إصدار المجتمع هو إصدار مجاني مفتوح المصدر بالكامل يهدف إلى البدء السريع، والتكامل السهل، والتوزيع البسيط، ذو قابلية توسع محدودة. وهو مناسب للفرق الصغيرة، الفرق متوسطة الحجم، وحالات الاستخدام الفردية.

تحذير: تم تصميم إصدار المجتمع فقط لعزل كود العمل والتجارب الوظيفية في بيئة تطوير محلية (غير موثوقة). يُرجى عدم استخدامه في بيئة إنتاج بطريقة مباشرة. إذا كنت ترغب في الحصول على إصدار عبر الإنترنت من إطار العمل لبيئة الإنتاج، يُرجى الاطلاع على إصدار Pro وإصدار Enterprise.

التثبيت

في الوقت الحالي، أسهل وأسرع طريقة لتثبيت إطار عمل أوكولو هي استخدام pip. الجملة كالتالي:

root@kitploit:~
pip install okulo

كيفية الحصول على pip

إذا قمت بتثبيت Python 2 >= 2.7.9 أو Python 3 >= 3.4 من python.org، فسيكون لديك بالفعل pip مثبتًا، لكنك ستحتاج إلى ترقية pip باستخدام الأوامر التالية:

root@kitploit:~
# macOS/Linux
python -m pip install --upgrade pip

# Windows
python -m pip install --upgrade pip

بخلاف ذلك، تحقق من التعليمات هنا إذا كان منزلك ينقصه فعلا.

بمجرد تثبيت pip بشكل صحيح، يمكنك الحصول على مجتمع أوكولو عن طريق تشغيل الأمر:

root@kitploit:~
pip install okulo

مستودعات إصدارات مختلفة لأوكولو

بقدر ما يتعلق الأمر بالإصدارات، يحتوي إطار عمل أوكولو حاليًا على ثلاث قنوات إصدار (وكذلك توافقات مع Python) لتتناسب مع سيناريوهات مختلفة:


إصدار Pro

إصدار Pro هو توزيع موصى به لبيئة الإنتاج في أوكولو. وهو نسخة كاملة الميزات مع آلية ترقية مدمجة، وأكثر ثباتًا واستقرارًا.

ملاحظة: تستمر أنشطة تطوير إصدار المجتمع على GitHub releases. إصدار Pro هو إصدار عبر الإنترنت يمكن استخدامه في بيئة الإنتاج، متوافق تمامًا مع واجهات برمجة التطبيقات لوحدة التحكم في إصدار المجتمع.

🔐 كيفية الحصول على إصدار Pro

إصدار Pro حاليًا تحت التطوير النشط. حيث أن بعض الميزات قد لا تعمل بعد. يُرجى البقاء على تواصل مع فريقنا على GitHub، ويمكنك أن تصبح مطورًا معتمدًا لتجربة الميزات الجديدة.

التوافق:

إصدار Pro متوافق مع جميع التوزيعات الرئيسية (عائلة RHEL، عائلة Debian، عائلة macOS، عائلة FreeBSD، Windows+WSL2). نشر إصدار Pro سهل مثل:

root@kitploit:~
pip install okulo-pro

🚀 البدء

للتجربة السريعة، يمكنك التوجه إلى صفحة العرض التوضيحي ورؤية النتائج على الفور! (هذه صفحة ثابتة مصممة للعرض التوضيحي، وعرضها محدود.)

بخلاف ذلك، يمكنك أيضًا تشغيل إطار عمل أوكولو محليًا في 5 دقائق فقط مع 4 خطوات.


متطلبات النظام الأساسي لأوكولو:

  • CPython 3.6+ لأوكولو المجتمع
  • Pyston 2.3.x لأوكولو Pro
  • Python 3.7+ أو Pyston 2.3.x لأوكولو Enterprise

نظام التشغيل:

  • Linux: متوافق تمامًا مع توزيعات Linux التالية:
    • Red Hat Enterprise Linux 7 أو إصدارات أعلى (RHEL)
    • CentOS 7 أو إصدارات أعلى
    • أوبونتو 18.04 أو إصدارات أعلى (LTS)
    • دبيان 10 أو إصدارات أعلى
    • SUSE Enterprise Linux 12 أو إصدارات أعلى
    • OpenSUSE 15 أو إصدارات أعلى
    • Alpine Linux 3.12 أو إصدارات أعلى
  • macOS: macOS 10.15 Catalina أو إصدارات أعلى
  • Windows: Win 8.1 أو Win 10 مع WSL2 مثبت

ملاحظة للمستخدمين على أنظمة غير Linux: أوصي باستخدام مستودعات آمنة (مثل Homebrew) لتثبيت أوكولو. على macOS، تتم تغطية التبعيات الخاصة بـ cchardet بشكل جيد عبر Homebrew.


الخطوة 1 - التحقق من تثبيت Python

تحتاج إلى التحقق من حصولك على إصدار مناسب من Python مثبت:

root@kitploit:~
$ python3 --version

إذا لم يكن لديك Python 3.6+، قم بتثبيته (انظر إصدار Python في قسم "متطلبات النظام الأساسي لأوكولو").

تثبيت Python على macOS

إذا كنت تستخدم macOS، فإن أفضل طريقة للحصول على Python 3 هي تثبيته عبر Homebrew:

root@kitploit:~
brew install python3

تثبيت Python على Windows

إذا كنت تستخدم Windows، فمن المستحسن تثبيت Python من python.org. لا تنس تحديد المربع "إضافة Python إلى PATH". بديلاً عن ذلك، يمكنك أيضًا استخدام مدير حزم مثل Chocolatey.

root@kitploit:~
choco install python

تثبيت Python على Linux

في معظم توزيعات Linux، يمكنك تثبيت Python 3 باستخدام مدير الحزم الخاص بالتوزيعة. على سبيل المثال، على Ubuntu/Debian:

root@kitploit:~
sudo apt-get update
sudo apt-get install python3 python3-pip python3-venv python3-wheel
``````cmake
find_package(bridgehead REQUIRED)
target_link_libraries(my_target PRIVATE bridgehead::bridgehead)

pugixml، و ws2_32، و secur32 (ويندوز) / gssapi_krb5 (لينكس / ماك) يتم سحبها جميعًا بشكل غير مباشر.


دعم المنصة

المنصةالواجهة الخلفية للمصادقةالحالة
ويندوزSSPI (secur32.dll)، NTLM و Kerberosيعمل
لينكس / ماكGSSAPI (libgssapi_krb5)، SPNEGO / Kerberosتم التجميع؛ لم يتم اختبار التكامل بعد

كلا من AuthPackage::Ntlm و AuthPackage::Kerberos يعملان على ويندوز. يقوم Kerberos بإخفاء اسم المستخدم عبر الشبكة وهو مفضل في الإنتاج؛ بينما NTLM هو البديل عندما يكون KDC (المنفذ 88) غير قابل للوصول.

على لينكس / ماك، تستخدم الواجهة الخلفية لـ GSSAPI بروتوكول SPNEGO مع Kerberos. لتشغيل دعم NTLM، قم بتثبيت الإضافة gss-ntlmssp:```bash apt install libgss-ntlmssp # Debian / Ubuntu dnf install gssntlmssp # Fedora / RHEL

root@kitploit:~
بدون المكوّن الإضافي، سيتفاوض الخادم مع Kerberos. تستخدم بيانات اعتماد المستخدم/كلمة المرور الصريحة `gss_acquire_cred_with_password` (MIT Kerberos 1.9+)؛ مرّر سلاسل فارغة لاستخدام ذاكرة التخزين المؤقت الافتراضية للبيانات (`kinit`). يتم تجميع مسار GSSAPI بشكل نظيف وصحيح من الناحية التصميمية، ولكن لم يتم التحقق من صحته من طرف إلى طرف مقابل DC حي بعد؛ تعامل مع دعم Linux/macOS كإصدار تجريبي.

> **ملاحظة التشفير:** يتم تشفير ADWS على المنفذ 9389 على طبقة NNS (مفتاح جلسة NTLM أو Kerberos AES-256)، وليس TLS. هذا حسب التصميم، لا يقدم DC خدمة TLS على هذا المنفذ. إذا كان المصادقة المستندة إلى الشهادة مطلوبة، فإن LDAPS (المنفذ 636) هو البديل.

---

## التبعيات

يتم جلبها تلقائياً في وقت التهيئة عبر `cmake/Dependencies.cmake`، لا حاجة إلى تثبيت يدوي:

| المكتبة | الإصدار | الغرض |
|---------|---------|---------|
| [Catch2](https://github.com/catchorg/Catch2) | v3.5.2 | إطار اختبار الوحدة (أهداف الاختبار فقط) |
| [pugixml](https://github.com/zeux/pugixml) | v1.14 | DOM لـ XML (تحليل استجابة ADWS فقط) |

لا توجد مكتبة OpenSSL ولا Asio ولا Boost.

---

## القيود المعروفة

- **NTLM على Linux/macOS** يتطلب المكوّن الإضافي GSSAPI `gss-ntlmssp` (انظر [دعم المنصة](#platform-support)). بدونه سيتفاوض الخادم مع Kerberos بدلاً من ذلك. يعمل NTLM على Windows بطبيعته عبر SSPI.

- **DOM لـ pugixml**، يتم تحليل كل استجابة SOAP بالكامل إلى شجرة XML في الذاكرة قبل إرجاع أي نتائج. هذا محدود بحجم الصفحة `maxElements` (الافتراضي 256 كائنًا لكل Pull)، لذا لا يتم الاحتفاظ بمجموعة النتائج الكاملة في الذاكرة مرة واحدة. يصبح الذاكرة مصدر قلق فقط مع أحجام الصفحات الكبيرة جدًا أو الكائنات التي تحمل سمات ثنائية كبيرة (مثل `nTSecurityDescriptor` على الكائنات التي تحتوي على العديد من ACEs). النهج القائم على 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](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-winprotlp/).

---

## شكر خاص

شكر خاص لشركة IBM X-Force ومشروع SoaPy على إلهامهم وأبحاثهم وعملهم المشترك الذي ساعد في إثراء هذا المشروع. كما أود أن أشكر Logan Goins، مبتكر SoaPy في IBM X-Force Red، على الجهد والرؤية التي جعلت هذا العمل ممكنًا.

---

## الترخيص

انظر [LICENSE](https://github.com/zakipedio/bridgehead/blob/main/LICENSE) للحصول على التفاصيل.
تنزيل الأداة
الطريقةنقطة النهايةالوصف
EnumerationClient(host, fqdn, domain, user, pass [, auth, timeoutMs, opTimeoutMs, limits])/Enumerationمصنع، اتصال ومصادقة
ResourceClient(...)/Resourceمصنع لـ Get / Put / Delete / Move
ResourceFactoryClient(...)/ResourceFactoryمصنع لـ Create
Query(filter, attrs [, baseDN, maxElems, scope])Enumerationجمع جميع النتائج في vector
Enumerate(filter, attrs, baseDN, callback [, maxElems, scope])Enumerationتدفق النتائج عبر callback
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_TOOLSOFFبناء أداة CLI adws_list
قناة الإصدارإصدار Pythonما إذا كان يتم التحديث تلقائيًا إلى أحدث إصدارما إذا كان سيتم إخطار المستخدمين بالثغرات الأمنيةالحالة
إصدار المجتمعCPython 3.8لالاغير موصى به لبيئة الإنتاج
إصدار ProPyston 2.3.xنعم (تلقائي من داخل إطار العمل)نعم (تلقائي من داخل إطار العمل)موصى به لبيئة الإنتاج
إصدار Enterpriseإطار عمل مخصصنعمنعمالتوزيع الأكثر تقدمًا، الأنسب للهندسة المعمارية واسعة النطاق