用户
搜索
  • TA的每日心情
    擦汗
    2020-12-24 15:20
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    11

    主题

    14

    帖子

    337

    魔法币
    收听
    0
    粉丝
    4
    注册时间
    2017-11-14

    i春秋签约作者

    发表于 2021-1-12 16:27:53 3119272

    前台XSS:

    此CMS前台有很多XSS,但多数点都有过滤,过滤代码如下:

            content = JFlyFoxUtils.delScriptTag(content);
            title = HtmlUtils.delHTMLTag(title);
            tags = HtmlUtils.delHTMLTag(tags);

    通过函数名就知道这东西过滤得并不全,跟进去后发现果然如此:

        private static final String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式
        private static final String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; // 定义style的正则表达式
        private static final String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
    
        public static String delScriptTag(String htmlStr) {
            Pattern p_script = Pattern.compile("<script[^>]*?>[\\s\\S]*?<\\/script>", 2);
            Matcher m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll("");
            Pattern p_style = Pattern.compile("<style[^>]*?>[\\s\\S]*?<\\/style>", 2);
            Matcher m_style = p_style.matcher(htmlStr);
            htmlStr = m_style.replaceAll("");
            return htmlStr.trim();
        }
    
            public static String delHTMLTag(String htmlStr) {
            Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
            Matcher m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤script标签
    
            Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
            Matcher m_style = p_style.matcher(htmlStr);
            htmlStr = m_style.replaceAll(""); // 过滤style标签
    
            Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
            Matcher m_html = p_html.matcher(htmlStr);
            htmlStr = m_html.replaceAll(""); // 过滤html标签
    
            return htmlStr.trim(); // 返回文本字符串
        }
    

    绕过得方案太多了,我就不一一列举了,这里找到一个前台反馈的点:

        public void save() {
            JSONObject json = new JSONObject();
            json.put("status", 2);// 失败
    
            // 获取验证码
            String imageCode = getSessionAttr(ImageCode.class.getName());
            String checkCode = this.getPara("imageCode");
    
            if (StrUtils.isEmpty(imageCode) || !imageCode.equalsIgnoreCase(checkCode)) {
                json.put("msg", "验证码错误!");
                renderJson(json.toJSONString());
                return;
            }
    
            SysUser user = (SysUser) getSessionUser();
            if (user==null) {
                json.put("msg", "请先登录再填写意见反馈!");
                renderJson(json.toJSONString());
                return;
            }
    
            TbAdviceFeedback model = getModel(TbAdviceFeedback.class);
    
            int userid = user.getInt("userid");
            String now = getNow();
            model.setUsername(user.getUserName());
            model.setUserid(userid);
            model.set("create_id", userid);
            model.set("create_time", now);
            model.save();
            UserCache.init(); // 设置缓存
            SysUser newUser = SysUser.dao.findById(userid);
            setSessionUser(newUser); // 设置session
            json.put("status", 1);// 成功
    
            renderJson(json.toJSONString());
        }

    这里通过反射拿到了客户端传过来的数据:

    TbAdviceFeedback model = getModel(TbAdviceFeedback.class);

    函数内部:

    public class TbAdviceFeedback extends BaseProjectModel<TbAdviceFeedback> {
    
        private static final long serialVersionUID = 1L;
        public static final TbAdviceFeedback dao = new TbAdviceFeedback();
    
        // columns START
        private String ID = "id"; // 主键
        private String USERID = "userid"; // 用户ID
        private String USERNAME = "username"; // 用户名
        private String QQ = "qq"; // qq
        private String EMAIL = "email"; // email
        private String TELPHONE = "telphone"; // 手机号
        private String CONTENT = "content"; // 意见反馈内容
        private String REMARK = "remark"; // 备注
        private String IS_READ = "is_read"; // 是否已读
        private String CREATE_TIME = "create_time"; // 创建时间
        private String CREATE_ID = "create_id"; // 创建者
    
        public TbAdviceFeedback setId(java.lang.Integer value) {
            set(ID, value);
            return this;
        }
    
        public java.lang.Integer getId() {
            return get(ID);
        }
    
        public TbAdviceFeedback setUserid(java.lang.Integer value) {
            set(USERID, value);
            return this;
        }
    
        public java.lang.Integer getUserid() {
            return get(USERID);
        }
    
        public TbAdviceFeedback setUsername(java.lang.String value) {
            set(USERNAME, value);
            return this;
        }
    
        public java.lang.String getUsername() {
            return get(USERNAME);
        }
    
        public TbAdviceFeedback setQq(java.lang.String value) {
            set(QQ, value);
            return this;
        }
    
        public java.lang.String getQq() {
            return get(QQ);
        }
    
        public TbAdviceFeedback setEmail(java.lang.String value) {
            set(EMAIL, value);
            return this;
        }
    
        public java.lang.String getEmail() {
            return get(EMAIL);
        }
    
        public TbAdviceFeedback setTelphone(java.lang.String value) {
            set(TELPHONE, value);
            return this;
        }
    
        public java.lang.String getTelphone() {
            return get(TELPHONE);
        }
    
        public TbAdviceFeedback setContent(java.lang.String value) {
            set(CONTENT, value);
            return this;
        }
    
        public java.lang.String getContent() {
            return get(CONTENT);
        }
    
        public TbAdviceFeedback setRemark(java.lang.String value) {
            set(REMARK, value);
            return this;
        }
    
        public java.lang.String getRemark() {
            return get(REMARK);
        }
    
        public TbAdviceFeedback setIsRead(java.lang.Integer value) {
            set(IS_READ, value);
            return this;
        }
    
        public java.lang.Integer getIsRead() {
            return get(IS_READ);
        }
    
        public TbAdviceFeedback setCreateTime(java.lang.String value) {
            set(CREATE_TIME, value);
            return this;
        }
    
        public java.lang.String getCreateTime() {
            return get(CREATE_TIME);
        }
    
        public TbAdviceFeedback setCreateId(java.lang.Integer value) {
            set(CREATE_ID, value);
            return this;
        }
    
        public java.lang.Integer getCreateId() {
            return get(CREATE_ID);
        }
    
        @Override
        public String toString() {
            String log = "";
            log += "[id:" + getId() + "]";
            log += "[userid:" + getUserid() + "]";
            log += "[username:" + getUsername() + "]";
            log += "[qq:" + getQq() + "]";
            log += "[email:" + getEmail() + "]";
            log += "[telphone:" + getTelphone() + "]";
            log += "[content:" + getContent() + "]";
            log += "[remark:" + getRemark() + "]";
            log += "[isRead:" + getIsRead() + "]";
            log += "[createTime:" + getCreateTime() + "]";
            log += "[createId:" + getCreateId() + "]";
            return log;
        }
    }

    可以发现并没有什么过滤,然后就放入了数据库进行保存:

    model.save();

    函数内部:

        public boolean save() {
            filter(FILTER_BY_SAVE);
    
            Config config = _getConfig();
            Table table = _getTable();
    
            StringBuilder sql = new StringBuilder();
            List<Object> paras = new ArrayList<Object>();
            config.dialect.forModelSave(table, attrs, sql, paras);
            // if (paras.size() == 0)   return false;   // The sql "insert into tableName() values()" works fine, so delete this line
    
            // --------
            Connection conn = null;
            PreparedStatement pst = null;
            int result = 0;
            try {
                conn = config.getConnection();
                if (config.dialect.isOracle()) {
                    pst = conn.prepareStatement(sql.toString(), table.getPrimaryKey());
                } else {
                    pst = conn.prepareStatement(sql.toString(), Statement.RETURN_GENERATED_KEYS);
                }
                config.dialect.fillStatement(pst, paras);
                result = pst.executeUpdate();
                config.dialect.getModelGeneratedKey(this, pst, table);
                _getModifyFlag().clear();
                return result >= 1;
            } catch (Exception e) {
                throw new ActiveRecordException(e);
            } finally {
                config.close(pst, conn);
            }
        }
    

    效果验证:

    然后去后台查看留言:

    后台文件内容修改:


    游客,如果您要查看本帖隐藏内容请回复

    6666666666666666666666666666666666666666666666666
    使用道具 举报 回复
    6666666666666666666666666666666666666666666666666
    使用道具 举报 回复
    66666666666666666666666666666666666666
    使用道具 举报 回复
    666666666666666666666666666666666666
    使用道具 举报 回复
    finalCMS前台组合拳GetShell [修改]
    使用道具 举报 回复
    ddddddddddddddddddddddddddddd
    使用道具 举报 回复
    这套组合拳,看出老哥扎实的功底!
    使用道具 举报 回复
    jfinalCMS前台组合拳GetShell
    使用道具 举报 回复
    看大佬秀操作
    欢迎关注我的个人公众号:黑客前沿
    使用道具 举报 回复
    看看因此撒
    使用道具 举报 回复
    学习了学习了
    使用道具 举报 回复
    组合拳讲究
    使用道具 举报 回复
    发表于 2021-1-12 21:36:42
    来跟老哥学习了
    使用道具 举报 回复
    发表于 2021-1-13 11:40:27
    111112312312312312312
    使用道具 举报 回复
    发表于 2021-1-13 15:46:37
    小透明师傅tql  
    使用道具 举报 回复
    发表于 2021-1-13 21:51:57
    f'g'd'g
    Team:http://xeip.club/
    使用道具 举报 回复
    nb nb nb nb nbb
    使用道具 举报 回复
    tqltqltqltql
    使用道具 举报 回复
    123下一页
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册