it-swarm-tr.com

Facebook, tarayıcının entegre Geliştirici Araçlarını nasıl devre dışı bırakır?

Öyleyse, görünüşe göre son aldatmacalar nedeniyle, geliştirici araçları, spam göndermek için insanlar tarafından sömürülmekte ve hatta hesapları "kesmek" için kullanılmaktadır. Facebook geliştirici araçlarını engelledi ve konsolu bile kullanamıyorum.

Enter image description here

Bunu nasıl yaptılar?? Bir Yığın Taşması postası mümkün olmadığını iddia etti , ancak Facebook onları yanlış yaptı.

Sadece Facebook'a gidin ve geliştirici araçlarını açın, konsola bir karakter yazın ve bu uyarı açılır. Ne koyduğun önemli değil, idam edilmeyecek.

Bu nasıl mümkün olabilir?

Konsolda otomatik tamamlamayı bile engellediler:

Enter image description here

1602
Derek 朕會功夫

Facebook'ta güvenlik mühendisi ve bu benim hatam. Bunu bazı kullanıcılar için, kullanıcıların tarayıcı konsoluna (kötü amaçlı) JavaScript kodunu yapıştırmaya kandırıldıkları bazı saldırıları yavaşlatıp yavaşlatamayacağını test ediyoruz.

Sadece açık olmak gerekirse: bilgisayar korsanlarını engellemeye çalışmak, müşteri tarafında, genel olarak kötü bir fikirdir ; bu, belirli bir sosyal mühendislik saldırısına karşı korumaktır.

Test grubuna dahil olduysanız ve bundan rahatsızsanız, üzgünüm. Eski çıkma sayfasını (şimdi yardım sayfası ) olabildiğince basitleştirmeye çalışırken en azından durduracak kadar korkutucu olmasına rağmen bazı kurban.

Gerçek kod @ joeldixon66'ın bağlantısına benzer. Bizimki, hiçbir sebep olmadan biraz daha karmaşık.

Chrome, tüm konsol kodunu içeri

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

... bu nedenle site console._commandLineAPI öğesini atmak için yeniden tanımlar:

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

Bu yeterince değil (deneyin!) , ama asıl püf noktası.


Epilogue: Chrome ekibi, konsolu kullanıcı tarafı JS'den yenmenin bir hata olduğuna ve sorunu çözdüğüne karar verdi , bu tekniği geçersiz kıldı. Ardından, kullanıcıları self-xss'den korumak için ek koruma eklendi.

2384
Alf

Facebook'un konsol buster komut dosyasını Chrome geliştirici araçlarını kullanarak buldum. İşte okunabilirlik için küçük değişiklikler içeren komut dosyası. Anlayamadığım bitleri çıkardım:

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);

Bununla konsolda otomatik tamamlama sessizce başarısız olur, oysa konsolda yazılan ifadeler çalıştırılamaz (istisna günlüğe kaydedilir).

Referanslar:

78
Salman A

Bunu herhangi bir sayfada tetikleyemedim. Bunun daha sağlam bir versiyonu bunu yapar:

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

console.log('test');

Çıktıya stil vermek için: JavaScript konsolunda renkler

Edit Düşünme @ joeldixon66 doğru bir fikri vardır: JavaScript çalıştırmayı konsoldan devre dışı bırak «::: KSpace :::

38
Will

console._commandLineAPI öğesinin yeniden tanımlanmasının yanı sıra, geliştirici konsoluna girilen ifadelerin değerlendirmesini önlemek veya değiştirmek için WebKit tarayıcılarda InjectedScriptHost'a girmenin başka yolları da vardır.

Düzenleme:

Chrome bunu önceki bir sürümde düzeltti. - O zaman Gist’i oluştururken Şubat 2015’ten önce olması gereken

Yani burada başka bir olasılık. Bu sefer, yukarıdaki düzeyin aksine InjectedScript yerine doğrudan bir seviyeye InjectedScriptHost'e bağlanıyoruz.

Bu da bir nevi Nice, InjectedScript._evaluateAndWrap'e güvenmek yerine direk olarak maymun ekleyebildiğiniz için InjectedScriptHost.evaluate size ne olacağı konusunda daha iyi kontrol sahibi olmanızı sağlıyor.

Oldukça ilginç olan bir başka şey de, bir ifade değerlendirildiğinde iç sonucu engelleyebilmemiz ve normal davranış yerine kullanıcıya döndürebilmemizdir.

İşte tam olarak bunu yapan kod, kullanıcı konsoldaki bir şeyi değerlendirdiğinde dahili sonucu döndürür.

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);

Biraz ayrıntılı, ama içine bazı yorumlar koyduğumu sandım

Normalde, eğer bir kullanıcı, örneğin, [1,2,3,4] değerlendirirse, aşağıdaki çıktıyı beklersiniz:

enter image description here

Maymun toplamasından sonra, InjectedScript._evaluateAndWrap, aynı ifadeyi değerlendirirken, aşağıdaki çıktıyı verir:

enter image description here

Gördüğünüz gibi, solu gösteren ok, çıktıyı gösterir, hala oradadır, ancak bu sefer bir nesne elde ediyoruz. İfadenin sonucunun bulunduğu yerde, [1,2,3,4] dizisi, tüm özellikleri açıklanan bir nesne olarak temsil edilir.

Hata oluşturanlar da dahil olmak üzere bunu ve bu ifadeyi değerlendirmeye çalışmayı tavsiye ederim. Bu oldukça ilginç.

Ayrıca, is - InjectedScriptHost - nesnesine bir bakın. Müfettişin içindekilerle oynamak ve biraz bilgi edinmek için bazı yöntemler sunar.

Tabii ki, tüm bu bilgileri engelleyebilir ve yine de orijinal sonucu kullanıcıya geri verebilirsiniz.

Başka bir yoldaki return ifadesini, return res ifadesinin ardından console.log (res) ile değiştirin. O zaman aşağıdakilerle bitirdin.

enter image description here

Düzenleme Sonu


Bu, Google tarafından düzeltilen önceki sürümdür. Dolayısıyla artık mümkün bir yol değil.

Bunlardan biri Function.prototype.call içine takılıyor

Chrome, girilen ifadeyi call ile değerlendirir ve eval işlevini InjectedScriptHost olarak thisArg olarak

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

Buna bakılırsa, thisArg __ call __evaluate olup dinleyebilir ve ilk argümana bir referans alabilirsiniz (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);  
        }
    };
}

Örneğin değerlendirme reddedildi, bir hata atmak.

enter image description here

Burada bir örnek girilen ifadenin evaluate işlevine geçmeden önce bir CoffeeScript derleyicisine iletildiği yer.

28
Moritz Roessler

Netflix de bu özelliği uygular

(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$$) {
    }
})();

Güvenlik hatası atmak için console._commandLineAPI komutunu geçersiz kılar.

22
Fizer Khan

Aslında Facebook bunu yapabildi çünkü bu gerçekten mümkün . Peki, gerçek web geliştirici araçları değil, Javascript’in konsolda uygulanması.

Şuna bakın: Facebook, tarayıcının tümleşik Geliştirici Araçlarını nasıl devre dışı bırakır?

Bu tür bir istemci tarafı güvenliği atlamanın başka yolları olduğu için bu gerçekten çok fazla bir şey yapmaz.

İstemci tarafı olduğunu söylediğinizde, sunucunun kontrolü dışında gerçekleşir, bu yüzden yapabileceğiniz fazla bir şey yoktur. Neden Facebook'un hala bunu yaptığını soruyorsanız, bu gerçekten güvenlik amaçlı değil, javascript'i tanımayan normal kullanıcıları (nasıl okumayı bilmediklerini) konsola girmekten korumaktır. Bu, sizden istediklerinizi yaptıktan sonra otomatik olarak beğenme hizmeti veya diğer Facebook işlevselliği botları vaat eden siteler için yaygındır, çoğu durumda, konsolda çalıştırmanız için bir javascript bilgisi verir.

Facebook kadar kullanıcınız yoksa, o zaman Facebook'un yaptığı şeyi yapmanın bir gereği olmadığını sanmıyorum.

Javascript'i konsolda devre dışı bıraksanız bile, javascript'i adres çubuğu üzerinden çalıştırmak hala mümkündür.

 enter image description here

 enter image description here

ve tarayıcı adres çubuğunda javascript'i devre dışı bırakırsa, (Google Chrome'daki adres çubuğuna kodu yapıştırdığınızda, 'javascript:' ifadesini siler) javascript'i inceleme öğesiyle bağlantılardan birine yapıştırmak yine de mümkündür.

Çapayı inceleyin:

 enter image description here

Kodu href içinde yapıştır:

 enter image description here

 enter image description here

 enter image description here

Alt satır sunucu tarafında doğrulama ve güvenlik önce olmalı, sonra istemci tarafında yapın.

20
Jomar Sevillejo

Facebook'un konsolu devre dışı bırakabildiğinden beri Chrome çok değişti ... 

Mart 2017 itibariyle bu artık işe yaramıyor. 

Yapabileceğiniz en iyi, bazı konsol işlevlerini devre dışı bırakmaktır, örneğin:

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

Benim basit yolum, ama bu konuda daha fazla varyasyon için yardımcı olabilir .. __Tüm yöntemleri listeleyin ve bunları işe yaramaz hale getirin.

  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

Dahili olarak devtools, Devtools konsolunun içinde bir tuşa basıldığında çağrılan, sayfaya getCompletions adlı bir IIFE ekler. 

Bu işlevin kaynağı öğesine bakıldığında, üzerine yazılabilecek birkaç genel işlev kullanılır.

Error yapıcısını kullanarak, Devtools tarafından çağrıldığında getCompletions içerecek olan çağrı yığınını elde etmek mümkündür.


Örnek:

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

basit bir çözüm!

setInterval(()=>console.clear(),1500);

Ben yol boyunca giderdim:

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

  },
  set: function() {

  }
});
0
Zibri

Bu, zayıf kodun katılımsız bırakılması için bir güvenlik önlemi değildir. Bu stratejiyi uygulamadan önce her zaman zayıf kod için kalıcı bir çözüm bulun ve web sitenizi düzgün bir şekilde güvence altına alın

Bilgime göre en iyi araç, içeriği yenileyerek veya değiştirerek sayfanın bütünlüğünü normale döndüren çoklu javascript dosyaları eklemek olacaktır. Bu geliştirici aracını devre dışı bırakmak en iyi fikir olmaz, çünkü kod atma tarayıcının bir parçası olduğundan ve sunucu işlemeyi gerçekleştirmediğinden her zaman sorgulama söz konusu olduğu için kırılabilir. 

js file one önemli öğelerde <element> değişiklikleri olup olmadığını ve js file two ve js file three bu dosyanın periyot başına olup olmadığını kontrol etmelisiniz. 

4 dosyadan oluşan bir örneği ele alalım ve ne demek istediğimi gösterelim. 

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

Şimdi bu sadece tüm dosyalar ve etiketler üzerinde de çalıştığını göstermek için.

   #heading {
   background-color:red;
   }

Tüm bu dosyaları bir araya getirirseniz ve örneği oluşturursanız, bu önlemin işlevini görürsünüz. Bu, özellikle PHP ile çalışırken, bazı görünmeyen enjeksiyonları, indeks dosyanızdaki tüm önemli unsurlara doğru şekilde uygulamanız durumunda önler.

Öznitelik başına normal değere dönmek yerine yeniden yüklemeyi seçtim, bazı saldırganların web sitesinin başka bir bölümüne önceden yapılandırılmış ve hazır olabileceği ve kod miktarını azalttığı gerçeğidir. Yeniden yükleme, saldırganın zorlu çalışmalarını kaldıracak ve muhtemelen daha kolay bir yere oynayacaktır.

Başka bir not: Bu çok fazla kod olabilir, bu yüzden temiz tutun ve gelecekte düzenlemeleri kolaylaştırmak için ait oldukları yerlere tanımları eklediğinizden emin olun. Ayrıca, büyük sayfalarda 1 saniyelik aralıklarla istediğiniz miktarı saniye olarak ayarlayın ziyaretçilerinizin kullanabileceği eski bilgisayarlarda şiddetli etkileri olabilir

0
user9374996