HCL AppScan Standard安全漏洞扫描及处理漏洞

扫描漏洞

下载AppScan

https://bigcy.jb51.net/202205/tools/HCLAppScanStandardpjb_jb51.rar

安装

首先执行 Appscan_Setup_10071.exe 安装软件, 选择自己需要安装的语言, 这里选择 中文(简体)。

选择安装目录,可以使用默认目录,也可以点击更改自定义安装目录,选择完成后点击安装

 安装完成后将 nGen_Crack 目录下的两个 dll 文件替换到安装目录下, 启动应用, 点击 帮助->许可证 可以看到到期日期为永久, 至此,AppScan安装完成。

 使用

创建 Web应用程序, 文件->新建->Web应用程序扫描, 填写起始URL,下方显示绿色字体已连接到服务器表示填写的URL有效 ,点击下一步配置登录策略。

如果没有特殊要求的话,我们登录方法选择无,当然这个按需设置就好,并不是说都得选择无,我们选择登录:

 登录后点“我已登录到站点”

 测试策略和测试优化项如无特殊要求的话,我们都选择默认值。

配置完成,选择启动扫描,点击完成开始漏洞扫描。

 扫描完成后,可以看到问题分类,如下所示

有需要的话可以创建扫描报告,里面会有详细的问题分类及解决建议(仅供参考) 

 处理漏洞

API成批分配
package com.daasan.modules.sys.interceptor;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

/**
 **序列化和反序列化处理漏洞:API成批分配
 * @create 2024/6/6 15:50
 **/
@Configuration
public class JacksonConverters {

    @Bean
    public HttpMessageConverters customConverters() {
        // 创建一个ObjectMapper对象,用于配置JSON的序列化和反序列化
        ObjectMapper objectMapper = new ObjectMapper();

        // 配置ObjectMapper,使其在反序列化时遇到未知属性时抛出异常
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);

        // 创建一个MappingJackson2HttpMessageConverter对象,用于处理HTTP请求和响应中的JSON数据
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();

        // 将配置好的ObjectMapper设置到MappingJackson2HttpMessageConverter中
        mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);

        // 创建一个HttpMessageConverters对象,并传入我们自定义的MappingJackson2HttpMessageConverter
        // HttpMessageConverters是一个集合,可以包含多个HttpMessageConverter,但这里我们只添加了一个
        HttpMessageConverters converters = new HttpMessageConverters(mappingJackson2HttpMessageConverter);

        // 返回配置好的HttpMessageConverters对象,Spring框架在需要处理HTTP消息时会使用它
        return converters;
    }
}
恶意参数注入

增加拦截器拦截恶意请求参数


import com.demo.common.core.exception.BsException;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 **校验参数中是否包含 命令执行、sql注入、恶意编码 等危险内容的拦截器
 * @create 2024/6/4 14:11
 **/
@Component
public class ParameterInjectionInterceptor implements HandlerInterceptor, Ordered {
  
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String parameterName = parameterNames.nextElement();
            String[] parameterValues = request.getParameterValues(parameterName);

            for (String parameterValue : parameterValues) {
                if (containsDangerousContent(parameterValue)) {
                    System.out.println("拦截到危险内容。。。。。。。。。。。。。。。");
                    response.sendError(403);
                    return false; // 停止后续拦截器和处理器执行
                }
            }
        }

        return true; // 继续执行后续拦截器和处理器  
    }

    /**
     **使用正则表达式来检测危险内容
     * @param input
     * @return boolean
     * @author yinqi
     * @create 2024/6/4 14:16
     **/
    private boolean containsDangerousContent(String input) {
        ArrayList<String> patterns = new ArrayList<>();
        // 命令执行尝试(如Unix shell命令)
        patterns.add("(\\b(cmd|sh|bash|powershell|eval|exec|system)\\b)|([;>&|])");
        // SQL注入尝试(如常见的SQL关键字)
        patterns.add("(select|insert|update|delete|drop|truncate|exec|declare|char|or |and)");
        // 跨站脚本(XSS)尝试(如常见的JavaScript关键字和HTML标签)
        patterns.add("<script\\b|\\balert\\b|on(load|error|mouseover|click|mousemove|mouseout|keydown|keypress|keyup|dblclick|click|blur|focus|contextmenu|dragstart|dragenter|dragover|dragleave|drag|drop|dragend)|javascript:|livescript:|vbscript:|mocha:|charset=|window\\.|\\.innerHTML|<iframe|<frameset|<frame|<script|<xss|data:text\\/html");
        // 可能的路径遍历尝试(如../)
        patterns.add("(\\.\\./|\\.\\.)");
        // 可能的编码绕过尝试(如%00、%25等)
        patterns.add("(%[0-9a-fA-F]{2})+");

        // 使用Pattern和Matcher类来检查输入字符串是否匹配任何危险模式
        for (String pattern : patterns) {
            Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
            Matcher m = p.matcher(input);
            if (m.find()) {
                System.out.println("危险内容:"+input);
                throw new BsException("危险内容:"+input);
            }
        }

        return false; // 没有发现危险内容
    }
  
    // 实现Ordered接口以设置顺序  
    @Override  
    public int getOrder() {  
        return 1; // 较低的数字表示较高的优先级  
    }  
  
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
  
    @Autowired
    private ParameterInjectionInterceptor firstInterceptor;
  
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(firstInterceptor)  
                .addPathPatterns("/**"); // 设置拦截路径
    }
}
API 功能级授权中断

请求的接口返回了系统异常的错误提示且定义的状态为400,但实际上返回给浏览器的状态为200导致HCL appscan扫描工具误以为成功访问了应用程序/API ,所以记录了该漏洞。

处理办法:返回给浏览器的状态也要改为400:

import com.demo.common.core.api.R;
import com.demo.common.core.exception.BsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;
import java.util.regex.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 全局拦截异常处理器
 * @date 2024/3/7
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 定义正则表达式,匹配所有连续的汉字
     */
    Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+");

    /**
     * 拦截抛出的 bsException 异常
     * @param bsException
     * @param request
     * @return
     */
    @ExceptionHandler(BsException.class)
    public R<?> bsException(BsException bsException, HttpServletRequest request, HttpServletResponse response) {
        String requestURI = request.getRequestURI();
        bsException.printStackTrace();
        log.error("请求地址'{}',发生BsException异常:'{}'",requestURI,bsException.getMessage());
        // TODO 匹配 bsException.getMessage() 是否为汉字,如果是,那么返回汉字。不是汉字返回 系统异常
        String res = bsException.getMessage();
        Matcher matcher = pattern.matcher(res);
        if( !matcher.find() ) {
            res = "系统异常";
        }
        try {
            response.sendError(400);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.failure(res);
    }

    /**
     * 拦截抛出的 runtimeException 异常
     * @param runtimeException
     * @param request
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public R<?> runtimeException(RuntimeException runtimeException, HttpServletRequest request, HttpServletResponse response) {
        String requestURI = request.getRequestURI();
        runtimeException.printStackTrace();
        log.error("请求地址'{}',发生RuntimeException异常:'{}'",requestURI,runtimeException.getMessage());

        try {
            response.sendError(400);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.failure("系统异常");
    }

    /**
     * 兜底方法,拦截抛出的所有异常
     * @param exception
     * @param request
     * @return
     */
    @ExceptionHandler(Exception.class)
    public R<?> exception(Exception exception, HttpServletRequest request, HttpServletResponse response) {
        String requestURI = request.getRequestURI();
        exception.printStackTrace();
        log.error("请求地址'{}',拦截到兜底异常:'{}'",requestURI,exception.getMessage());

        try {
            response.sendError(400);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.failure("系统异常");
    }

}
前端页面漏洞1

 访问不存在的路径时,系统跳转到了首页,但是给浏览器返回的状态是200,导致扫描工具误以为成功访问了应用程序/API 而记录了漏洞。

解决办法:nginx.conf配置文件中的server--> location /{}中注释“try_files $uri $uri/ /index.html;”,访问错误时不跳转到index.html页面。

        location / {
            root   html;
            index  index.html;
            # 用于配合 browserHistory 使用
            #try_files $uri $uri/ /index.html;
        }
前端页面漏洞二

访问一个不存在的静态js文件,系统跳转到了首页,但是给浏览器返回的状态是200,导致扫描工具误以为成功访问了应用程序/API 而记录了漏洞。

 解决办法:nginx.conf配置文件中的server中增加配置,访问的静态资源不存在时返回404

        #访问的静态资源不存在时返回404
        location ~* \.(?:gif|jpg|jpeg|png|ico|css|js|woff|woff2|ttf|otf|eot|svg|mp4|webm|wav|mp3|m4a|aac|oga)$ {  
            try_files $uri =404; # 如果文件不存在,直接返回404  
        }
        error_page 404 /404.html; # 如果需要自定义404页面,请确保404.html文件存在 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值