سؤال

نقوم حاليًا ببناء تطبيق ينفذ عددًا من الأدوات الخارجية.غالبًا ما يتعين علينا تمرير المعلومات التي أدخلها المستخدمون إلى نظامنا إلى هذه الأدوات.

من الواضح أن هذا كابوس أمني كبير ينتظر حدوثه.

لسوء الحظ، لم نعثر بعد على أي فئات في .NET Framework تقوم بتنفيذ برامج سطر الأوامر مع توفير نفس النوع من الحماية ضد هجمات الحقن كما تفعل كائنات IDbCommand لقواعد البيانات.

في الوقت الحالي، نحن نستخدم استبدال سلسلة بدائيًا للغاية وأظن أنه غير كافٍ إلى حد ما:

protected virtual string Escape(string value)
{
      return value
        .Replace(@"\", @"\\")
        .Replace(@"$", @"\$")
        .Replace(@"""", @"\""")
        .Replace("`", "'")
      ;
}

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

بعض التوضيحات:

  • بعض هذه الأدوات لا تحتوي على واجهات برمجة التطبيقات (APIs) التي يمكننا البرمجة ضدها.لو فعلوا ذلك، لما واجهنا هذه المشكلة.
  • لا يختار المستخدمون أدوات للتنفيذ، بل يقومون بإدخال البيانات الوصفية التي تستخدمها الأدوات التي اخترناها (على سبيل المثال، إدخال بيانات التعريف مثل إشعارات حقوق الطبع والنشر في الملفات المستهدفة).
هل كانت مفيدة؟

المحلول

هل تقوم بتنفيذ البرامج مباشرة أم تمر عبر الصدفة؟إذا كنت تقوم دائمًا بتشغيل برنامج خارجي عن طريق إعطاء اسم المسار الكامل للملف القابل للتنفيذ وترك الصدفة خارج المعادلة، فأنت لست عرضة لأي نوع من حقن سطر الأوامر.

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

نصائح أخرى

عندما انت العملية.ابدأ عملية جديدة، قم بتوفير المعلمات في وسيطة المعلمات الخاصة بها بدلاً من بناء سطر الأوامر بالكامل بنفسك.

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

سوف اختبار هذا غدا.

يحرر: آه، شخص ما سبقني إلى ذلك مرة أخرى.ولكن هنا نقطة أخرى:حاول استخدام Console.InputStream (لا أستطيع تذكر الاسم الدقيق) لتوفير البيانات بدلاً من تمرير المعلمات، هل هذا حل ممكن؟مثل إصلاح الأمر بحيث تتم قراءته من جهاز CON ثم تقوم بتوفير البيانات عبر دفق الإدخال بدلاً من ذلك.

في C++ على شبابيك, ، ما عليك سوى الهروب \ و" عند الحاجة، اقتبس الوسيطة وقم بتنفيذها Shell.بعد ذلك، يجب التعامل مع كل شيء داخل علامات الاقتباس كنص.

وينبغي أن يوضح هذا:


#include <iostream>
#include <string>
#include <windows.h>
#include <cstdlib>
using namespace std;

// Escape and quote string for use as Windows command line argument
string qEscape(const string& s) {
    string result("\"");
    for (string::const_iterator i = s.begin(); i != s.end(); ++i) {
        const char c = *i;
        const string::const_iterator next = i + 1;
        if (c == '"' || (c == '\\' && (next == s.end() || *next == '"'))) {
            result += '\\';
        }
        result += c;
    }
    result += '"';
    return result;
}

int main() {
    // Argument value to pass: c:\program files\test\test.exe
    const string safe_program = qEscape("c:\\program files\\test\\test.exe");
    cout << safe_program << " ";

    // Argument value to pass: You're the "best" around.
    const string safe_arg0 = qEscape("You're the \"best\" around.");

    // Argument value to pass: "Nothing's" gonna ever keep you down.
    const string safe_arg1 = qEscape("\"Nothing's\" gonna ever keep you down.");

    const string safe_args = safe_arg0 + " " + safe_arg1;
    cout << safe_args << "\n\n";

    // c:\program files\test\  to pass.
    const string bs_at_end_example = qEscape("c:\\program files\\test\\");
    cout << bs_at_end_example << "\n\n";

    const int result = reinterpret_cast<int>(ShellExecute(NULL, "open", safe_program.c_str(), safe_args.c_str(), NULL, SW_SHOWNORMAL));
    if (result < 33) {
        cout << "ShellExecute failed with Error code " << result << "\n";
        return EXIT_FAILURE;
    }
}

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

لا تستخدم القائمة السوداء لمنع الحقن.اذا كان هناك ن طرق لحقن التعليمات البرمجية، سوف تفكر فيها ن - م أين م > 0.

استخدم القائمة البيضاء للمعلمات (أو الأنماط) المقبولة.إنها أكثر تقييدًا بطبيعتها، لكن هذه هي طبيعة الأمن.

حسنًا، إذا كان بإمكانك استدعاء الأدوات برمجيًا بدون سطر الأوامر، فمن المحتمل أن يكون هذا هو الخيار الأفضل لك.بخلاف ذلك، من المحتمل أن تقوم بتنفيذ أداة سطر الأوامر عبر مستخدم ليس لديه حق الوصول على الإطلاق لفعل أي شيء (ربما باستثناء دليل واحد لا يمكنه إحداث أي ضرر به)...على الرغم من أن ذلك قد يؤدي إلى كسر الأداة، اعتمادًا على ما تفعله الأداة.

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

أمم...

يبدو أن لديك قائمة بالأوامر الصالحة التي يستطيع المستخدمون تنفيذها.لكنك لا تريد منهم أن ينفذوا كل منهم.

يمكنك محاولة استخدام سطر الأوامر الفعلي والتحقق من وجود الملف في الموقع "الآمن" على الأقل.

يمكنك أيضًا حل المشكلة من خلال المزيد من الواجهة، وتوفير قائمة منسدلة للأوامر والمعلمات التي يمكنهم استخدامها.إنه المزيد من العمل من جانبك، ولكنه يساعد المستخدمين في النهاية.

هل تقوم بتنفيذ البرامج مباشرة أم تمر عبر الصدفة؟إذا كنت تقوم دائمًا بتشغيل برنامج خارجي عن طريق إعطاء اسم المسار الكامل للملف القابل للتنفيذ وترك الصدفة خارج المعادلة، فأنت لست عرضة لأي نوع من حقن سطر الأوامر.

@ كيرت هاغنلوشر يمكن أن يقتلك backtick.إذا كان إعداد نظام Windows "خاطئًا"، أو كان نظام Unix يسمح بذلك، فإن dir &bt;del *&bt;سيتم أولاً تنفيذ الأمر del * ثم استخدام الإخراج بدلاً من del *، والذي في هذه الحالة لن يهم لأنه لا يوجد شيء لـ dir (أو ls)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top