it-swarm.asia

كيف يعطل Facebook أدوات المطور المتكاملة للمتصفح؟

على ما يبدو بسبب عمليات الاحتيال الأخيرة ، يتم استغلال أدوات المطور من قبل الأشخاص لنشر الرسائل غير المرغوب فيها وحتى استخدامها "لاختراق" الحسابات. لقد قام Facebook بحظر أدوات المطورين ، ولا يمكنني حتى استخدام وحدة التحكم.

Enter image description here

كيف فعلوا ذلك؟؟ ادعى منشور One Stack Overflow أنه غير ممكن ، لكن Facebook أثبت خطأهم.

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

كيف يكون هذا ممكنا؟

قاموا حتى بحظر الإكمال التلقائي في وحدة التحكم:

Enter image description here

1617
Derek 朕會功夫

أنا مهندس أمن في Facebook وهذا خطأي. إننا نقوم باختبار ذلك لبعض المستخدمين لمعرفة ما إذا كان يمكن أن يبطئ بعض الهجمات حيث يتم خداع المستخدمين بلصق شفرة JavaScript (الضارة) في وحدة تحكم المستعرض.

لكي نكون واضحين: محاولة منع المتسللين من جانب العميل هي فكرة سيئة بشكل عام ؛ هذا لحماية ضد هجوم الهندسة الاجتماعية محددة .

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

يشبه الرمز الفعلي إلى حد كبير رابط @ joeldixon66 ؛ لنا هو أكثر تعقيدا قليلا دون سبب وجيه.

يلتف Chrome بجميع رموز وحدة التحكم

with ((console && console._commandLineAPI) || {}) {
  <code goes here>
}

... لذلك يعيد الموقع تعريف console._commandLineAPI للرمي:

Object.defineProperty(console, '_commandLineAPI',
   { get : function() { throw 'Nooo!' } })

هذه ليست كافية (جربها!) ، ولكن هذه هي الحيلة الرئيسية.


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

2357
Alf

حددت النص البرمجي لوحدة التحكم في Facebook باستخدام أدوات مطوّر برامج Chrome. هنا هو البرنامج النصي مع تغييرات طفيفة لسهولة القراءة. لقد أزلت البتات التي لم أستطع فهمها:

Object.defineProperty(window, "console", {
    value: console,
    writable: false,
    configurable: false
});

var i = 0;
function showWarningAndThrow() {
    if (!i) {
        setTimeout(function () {
            console.log("%cWarning message", "font: 2em sans-serif; color: yellow; background-color: red;");
        }, 1);
        i = 1;
    }
    throw "Console is disabled";
}

var l, n = {
        set: function (o) {
            l = o;
        },
        get: function () {
            showWarningAndThrow();
            return l;
        }
    };
Object.defineProperty(console, "_commandLineAPI", n);
Object.defineProperty(console, "__commandLineAPI", n);

مع هذا ، تفشل عملية الإكمال التلقائي لوحدة التحكم بصمت بينما تفشل تنفيذ العبارات المكتوبة في وحدة التحكم (سيتم تسجيل الاستثناء).

المراجع:

78
Salman A

لم أستطع الحصول عليها لتحريك ذلك على أي صفحة. وهناك نسخة أكثر قوة من هذا من شأنه أن يفعل ذلك:

window.console.log = function(){
    console.error('The developer console is temp...');
    window.console.log = function() {
        return false;
    }
}

console.log('test');

لنمط الإخراج: الألوان في وحدة تحكم JavaScript

تحرير التفكير @ joeldixon66 لديه الفكرة الصحيحة: تعطيل تنفيذ JavaScript من وحدة التحكم «::: KSpace :::

40
Will

إلى جانب إعادة تعريف console._commandLineAPI ، هناك بعض الطرق الأخرى لاقتحام InjectedScriptHost على متصفحات WebKit ، لمنع أو تغيير تقييم التعبيرات المدخلة في وحدة تحكم المطور.

تحرير:

لقد أصلح Chrome هذا في إصدار سابق. - التي يجب أن تكون قبل فبراير 2015 ، حيث أنشأت Gist في ذلك الوقت} _

لذلك هنا احتمال آخر. هذه المرة ، نربط ، المستوى أعلاه ، مباشرة بـ InjectedScript بدلاً من InjectedScriptHost بدلاً من الإصدار السابق.

وهو نوع لطيف ، حيث يمكنك مباشرة قراءة رمز القرد InjectedScript._evaluateAndWrap بدلاً من الاضطرار إلى الاعتماد على InjectedScriptHost.evaluate لأن ذلك يمنحك المزيد من التحكم الدقيق فيما يجب أن يحدث.

شيء آخر مثير للاهتمام هو أنه يمكننا اعتراض النتيجة الداخلية عند تقييم تعبير و {إرجاع ذلك للمستخدم بدلاً من السلوك العادي.

في ما يلي الشفرة ، التي تفعل ذلك بالضبط ، تُرجع النتيجة الداخلية عندما يقوم المستخدم بتقييم شيء ما في وحدة التحكم.

var is;
Object.defineProperty(Object.prototype,"_lastResult",{
   get:function(){
       return this._lR;
   },
   set:function(v){
       if (typeof this._commandLineAPIImpl=="object") is=this;
       this._lR=v;
   }
});
setTimeout(function(){
   var ev=is._evaluateAndWrap;
   is._evaluateAndWrap=function(){
       var res=ev.apply(is,arguments);
       console.log();
       if (arguments[2]==="completion") {
           //This is the path you end up when a user types in the console and autocompletion get's evaluated

           //Chrome expects a wrapped result to be returned from evaluateAndWrap.
           //You can use `ev` to generate an object yourself.
           //In case of the autocompletion chrome exptects an wrapped object with the properties that can be autocompleted. e.g.;
           //{iGetAutoCompleted: true}
           //You would then go and return that object wrapped, like
           //return ev.call (is, '', '({test:true})', 'completion', true, false, true);
           //Would make `test` pop up for every autocompletion.
           //Note that syntax as well as every Object.prototype property get's added to that list later,
           //so you won't be able to exclude things like `while` from the autocompletion list,
           //unless you wou'd find a way to rewrite the getCompletions function.
           //
           return res; //Return the autocompletion result. If you want to break that, return nothing or an empty object
       } else {
           //This is the path where you end up when a user actually presses enter to evaluate an expression.
           //In order to return anything as normal evaluation output, you have to return a wrapped object.

           //In this case, we want to return the generated remote object. 
           //Since this is already a wrapped object it would be converted if we directly return it. Hence,
           //`return result` would actually replicate the very normal behaviour as the result is converted.
           //to output what's actually in the remote object, we have to stringify it and `evaluateAndWrap` that object again.`
           //This is quite interesting;
           return ev.call (is, null, '(' + JSON.stringify (res) + ')', "console", true, false, true)
       }
   };
},0);

إنه مطوّل قليلاً ، لكنني اعتقدت أنني وضعت بعض التعليقات فيه

لذلك عادةً ، إذا قام أحد المستخدمين ، على سبيل المثال ، بتقييم [1,2,3,4] ، فستتوقع الإخراج التالي:

 enter image description here

بعد monkeypatching InjectedScript._evaluateAndWrap تقييم التعبير نفسه ، يعطي الإخراج التالي:

 enter image description here

كما ترى ، فإن السهم الصغير الأيسر ، يشير إلى الإخراج ، لا يزال موجودًا ، لكن هذه المرة نحصل على كائن. عندما تكون نتيجة التعبير ، يتم تمثيل الصفيف [1,2,3,4] ككائن بكل خصائصه الموصوفة.

أوصي بمحاولة تقييم هذا التعبير وهذا التعبير ، بما في ذلك تلك التي تولد أخطاء. انها مثيرة للاهتمام للغاية.

بالإضافة إلى ذلك ، ألق نظرة على كائن is- InjectedScriptHost -. يوفر بعض الطرق للعب والحصول على بعض نظرة ثاقبة الداخلية للمفتش.

بالطبع ، يمكن أن تعترض كل هذه المعلومات وتظل تعيد النتيجة الأصلية إلى المستخدم.

ما عليك سوى استبدال عبارة الإرجاع في المسار الآخر بعلامة console.log (res) بعد return res. ثم ينتهي بك الأمر مع ما يلي.

 enter image description here

نهاية التحرير


هذا هو الإصدار السابق الذي تم إصلاحه بواسطة Google. وبالتالي ليست وسيلة ممكنة بعد الآن.

واحد منها هو تثبيت في Function.prototype.call

يقوم Chrome بتقييم التعبير الذي تم إدخاله بواسطة calling وظيفته eval باستخدام InjectedScriptHost كـ thisArg

var result = evalFunction.call(object, expression);

نظرًا لهذا ، يمكنك الاستماع إلى thisArg الخاص بـ call الذي هو evaluate والحصول على مرجع للوسيطة الأولى (InjectedScriptHost)

if (window.URL) {
    var ish, _call = Function.prototype.call;
    Function.prototype.call = function () { //Could be wrapped in a setter for _commandLineAPI, to redefine only when the user started typing.
        if (arguments.length > 0 && this.name === "evaluate" && arguments [0].constructor.name === "InjectedScriptHost") { //If thisArg is the evaluate function and the arg0 is the ISH
            ish = arguments[0];
            ish.evaluate = function (e) { //Redefine the evaluation behaviour
                throw new Error ('Rejected evaluation of: \n\'' + e.split ('\n').slice(1,-1).join ("\n") + '\'');
            };
            Function.prototype.call = _call; //Reset the Function.prototype.call
            return _call.apply(this, arguments);  
        }
    };
}

هل يمكن على سبيل المثال رمي خطأ ، أن تم رفض التقييم.

enter image description here

هنا مثال حيث يتم تمرير التعبير الذي تم إدخاله إلى برنامج التحويل البرمجي CoffeeScript قبل تمريره إلى دالة evaluate.

28
Moritz Roessler

تطبق Netflix أيضًا هذه الميزة

(function() {
    try {
        var $_console$$ = console;
        Object.defineProperty(window, "console", {
            get: function() {
                if ($_console$$._commandLineAPI)
                    throw "Sorry, for security reasons, the script console is deactivated on netflix.com";
                return $_console$$
            },
            set: function($val$$) {
                $_console$$ = $val$$
            }
        })
    } catch ($ignore$$) {
    }
})();

لقد تجاوزوا console._commandLineAPI لرمي خطأ الأمان.

22
Fizer Khan

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

شاهد هذا: كيف يقوم Facebook بتعطيل أدوات المطور المتكاملة للمتصفح؟

لن يحدث هذا كثيرًا على الرغم من وجود طرق أخرى لتجاوز هذا النوع من الأمان من جانب العميل.

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

إذا لم يكن لديك الكثير من المستخدمين مثل Facebook ، فلا أعتقد أن هناك حاجة للقيام بما يفعله Facebook.

حتى إذا قمت بتعطيل Javascript في وحدة التحكم ، فلا يزال تشغيل جافا سكريبت عبر شريط العناوين ممكنًا.

 enter image description here

 enter image description here

وإذا عطل المتصفح javascript في شريط العناوين ، (عند لصق الرمز إلى شريط العنوان في Google Chrome ، فإنه يحذف عبارة "javascript:") لا يزال لصق javascript في أحد الروابط عبر عنصر الاستقصاء ممكنًا.

فحص المرساة:

 enter image description here

رمز اللصق في href:

 enter image description here

 enter image description here

 enter image description here

خلاصة القول هي التحقق من جانب الخادم والأمان يجب أن يكون أولا ، ثم القيام من جانب العميل بعد.

20
Jomar Sevillejo

لقد تغير Chrome كثيرًا نظرًا لأن الأوقات التي يمكن لـ facebook تعطيل وحدة التحكم ...

حسب مارس 2017 ، هذا لا يعمل بعد الآن.

أفضل ما يمكنك فعله هو تعطيل بعض وظائف وحدة التحكم ، على سبيل المثال:

if(!window.console) window.console = {};
var methods = ["log", "debug", "warn", "info", "dir", "dirxml", "trace", "profile"];
for(var i=0;i<methods.length;i++){
    console[methods[i]] = function(){};
}
7
Alpha2k

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

  Object.getOwnPropertyNames(console).filter(function(property) {
     return typeof console[property] == 'function';
  }).forEach(function (verb) {
     console[verb] =function(){return 'Sorry, for security reasons...';};
  });
6
Dusan Krstic

داخليا devtools حقن IIFE المسمى getCompletions في الصفحة ، ودعا عندما يتم الضغط على مفتاح داخل وحدة التحكم Devtools.

بالنظر إلى مصدر هذه الوظيفة ، فإنه يستخدم بعض الوظائف العالمية التي يمكن الكتابة عليها.

باستخدام Error منشئ ، من الممكن الحصول على مكدس الاستدعاء ، والذي سيشمل getCompletions عند استدعائه بواسطة Devtools.


مثال:

const disableDevtools = callback => {
  const original = Object.getPrototypeOf;

  Object.getPrototypeOf = (...args) => {
    if (Error().stack.includes("getCompletions")) callback();
    return original(...args);
  };
};

disableDevtools(() => {
  console.error("devtools has been disabled");

  while (1);
});
3
samdd

حل بسيط!

setInterval(()=>console.clear(),1500);
2
Mohmmad Ebrahimi Aval

سأذهب في طريق:

Object.defineProperty(window, 'console', {
  get: function() {

  },
  set: function() {

  }
});
0
Zibri

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

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

إذا كان لديك js file one للتحقق من تغييرات <element> على العناصر المهمة و js file two و js file three فتتأكد من وجود هذا الملف في كل فترة فستتوفر لك الاستعادة الكاملة للنزاهة على الصفحة خلال الفترة.

لنأخذ مثالا على الملفات الأربعة وأريك ما أقصده.

index.html

   <!DOCTYPE html>
   <html>
   <head id="mainhead">
   <script src="ks.js" id="ksjs"></script>
   <script src="mainfile.js" id="mainjs"></script>
   <link rel="stylesheet" href="style.css" id="style">
   <meta id="meta1" name="description" content="Proper mitigation against script kiddies via Javascript" >
   </head>
   <body>
   <h1 id="heading" name="dontdel" value="2">Delete this from console and it will refresh. If you change the name attribute in this it will also refresh. This is mitigating an attack on attribute change via console to exploit vulnerabilities. You can even try and change the value attribute from 2 to anything you like. If This script says it is 2 it should be 2 or it will refresh. </h1>
   <h3>Deleting this wont refresh the page due to it having no integrity check on it</h3>

   <p>You can also add this type of error checking on meta tags and add one script out of the head tag to check for changes in the head tag. You can add many js files to ensure an attacker cannot delete all in the second it takes to refresh. Be creative and make this your own as your website needs it. 
   </p>

   <p>This is not the end of it since we can still enter any tag to load anything from everywhere (Dependent on headers etc) but we want to prevent the important ones like an override in meta tags that load headers. The console is designed to edit html but that could add potential html that is dangerous. You should not be able to enter any meta tags into this document unless it is as specified by the ks.js file as permissable. <br>This is not only possible with meta tags but you can do this for important tags like input and script. This is not a replacement for headers!!! Add your headers aswell and protect them with this method.</p>
   </body>
   <script src="ps.js" id="psjs"></script>
   </html>

mainfile.js

   setInterval(function() {
   // check for existence of other scripts. This part will go in all other files to check for this file aswell. 
   var ksExists = document.getElementById("ksjs"); 
   if(ksExists) {
   }else{ location.reload();};

   var psExists = document.getElementById("psjs");
   if(psExists) {
   }else{ location.reload();};

   var styleExists = document.getElementById("style");
   if(styleExists) {
   }else{ location.reload();};


   }, 1 * 1000); // 1 * 1000 milsec

ps.js

   /*This script checks if mainjs exists as an element. If main js is not existent as an id in the html file reload!You can add this to all js files to ensure that your page integrity is perfect every second. If the page integrity is bad it reloads the page automatically and the process is restarted. This will blind an attacker as he has one second to disable every javascript file in your system which is impossible.

   */

   setInterval(function() {
   // check for existence of other scripts. This part will go in all other files to check for this file aswell. 
   var mainExists = document.getElementById("mainjs"); 
   if(mainExists) {
   }else{ location.reload();};

   //check that heading with id exists and name tag is dontdel.
   var headingExists = document.getElementById("heading"); 
   if(headingExists) {
   }else{ location.reload();};
   var integrityHeading = headingExists.getAttribute('name');
   if(integrityHeading == 'dontdel') {
   }else{ location.reload();};
   var integrity2Heading = headingExists.getAttribute('value');
   if(integrity2Heading == '2') {
   }else{ location.reload();};
   //check that all meta tags stay there
   var meta1Exists = document.getElementById("meta1"); 
   if(meta1Exists) {
   }else{ location.reload();};

   var headExists = document.getElementById("mainhead"); 
   if(headExists) {
   }else{ location.reload();};

   }, 1 * 1000); // 1 * 1000 milsec

ks.js

   /*This script checks if mainjs exists as an element. If main js is not existent as an id in the html file reload! You can add this to all js files to ensure that your page integrity is perfect every second. If the page integrity is bad it reloads the page automatically and the process is restarted. This will blind an attacker as he has one second to disable every javascript file in your system which is impossible.

   */

   setInterval(function() {
   // check for existence of other scripts. This part will go in all other files to check for this file aswell. 
   var mainExists = document.getElementById("mainjs"); 
   if(mainExists) {
   }else{ location.reload();};
   //Check meta tag 1 for content changes. meta1 will always be 0. This you do for each meta on the page to ensure content credibility. No one will change a meta and get away with it. Addition of a meta in spot 10, say a meta after the id="meta10" should also be covered as below.
   var x = document.getElementsByTagName("meta")[0];
   var p = x.getAttribute("name");
   var s = x.getAttribute("content");
   if (p != 'description') {
   location.reload();
   }
   if ( s != 'Proper mitigation against script kiddies via Javascript') {
   location.reload();
   }
   // This will prevent a meta tag after this meta tag @ id="meta1". This prevents new meta tags from being added to your pages. This can be used for scripts or any tag you feel is needed to do integrity check on like inputs and scripts. (Yet again. It is not a replacement for headers to be added. Add your headers aswell!)
   var lastMeta = document.getElementsByTagName("meta")[1];
   if (lastMeta) {
   location.reload();
   }
   }, 1 * 1000); // 1 * 1000 milsec

style.css

الآن هذا فقط لإظهار أنه يعمل على جميع الملفات والعلامات كذلك

   #heading {
   background-color:red;
   }

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

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

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

0
user9374996