كيفية التحقق من طول صفيف البايت المستلم ، وهو ما لم يتم إنهاء فارغ؟

StackOverflow https://stackoverflow.com/questions/3608953

سؤال

لدي رمز c c ++ يتلقى بنية عبر الشبكة ، من هذا النموذج:

struct DataStruct
{
int DataLen;
BYTE* Data;
}

الرمز الذي أديره Data في حلقة DataLen مرات ومعالجة البيانات.

...المشكلة:

بعد وصول الكود إلى خبراء الأمن لاختبارات الاختراق ، أعدوا تطبيقًا مزيفًا يرسل هذا الهيكل DataLen أكبر من الطول الحقيقي Data. هذا يسبب ، بالطبع ، استثناء انتهاك الوصول.

لذا ، فإن السؤال هو - كيف يمكنني التحقق من الطول الحقيقي للمستلم Data؟ هل هو ممكن دون تغيير الهيكل؟

شكرا لك مقدما.

هل كانت مفيدة؟

المحلول

خبراء أمن لطيف! أتمنى أن يكون لشركتي قسم من هذا القبيل.

عندما يتم استلام البيانات من الشبكة ، يبلغ الشبكة IO عن عدد البايتات المكتوبة فعليًا إلى المخزن المؤقت ، سواء كنت تستخدم read(2), recv(2), ، أو boost::asio::async_read أو أي شيء آخر رأيته. حالة الاستخدام النموذجي عندما يكون هناك حقل "عدد من البايتات لمتابعة" في رأس بنية البيانات الخاصة بك ، تتمثل في استدعاء القراءة/recv/etc بشكل متكرر حتى يتم استلام العديد وإرجاع البيانات الخاصة بك (أو خطأ الإبلاغ).

نصائح أخرى

أنت تعرف مقدار البايتات التي تلقيتها ، لذا قارنها فقط DataLen.

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

الفساد سهل إذا لم يكن لديك أي قيود جوهرية.

ستكون بعض آليات الحماية:

  • حاول realloc() المخزن المؤقت ، ضمن بعض الحجم المقبول (إذا Data ديناميكي)
  • استثناءات نكون الأصدقاء: الاستخدام SIGSEGV في signal(2), signal(7) و setjmp(2) للقيام ببعض مفيد حاول/تمسك هيكل الكود. يرى الجمع بين setjmp ()/longjmp () ومعالجة الإشارات للحصول على مقدمة سريعة حول هذا الموضوع. يستخدم sigaction(2) للانتقال إلى أعمق (عن طريق الحصول على العنوان المعيب ؛).
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top