当前位置:   article > 正文

记录一次小项目中的重放攻击与解决方案_重放攻击怎么解决

重放攻击怎么解决

欢迎各位 前(提)来(出)讨(意)论(见)。

1、重放攻击简介

重放攻击(Replay Attacks)又称重播攻击、回放攻击,是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。

  • 举个简单的小例子。

我们往系统里面插入一条数据,如果此次操作的数据包被攻击者获取,又恰巧后台没有对重复内容进行验证,那么攻击者就可以利用该数据包重复的发起请求,无限制的往数据库插入数据,即使请求包是加密的也不影响,从而造成资源浪费。

再可能用户支取了一笔存款,攻击者完全可以多次发送这条消息从而偷窃存款。

2、重放攻击演示

  • 使用工具:Fiddler:一款用于抓包的工具
  • 重放演示

(1)首先在系统添加一条记录
在这里插入图片描述
(2)使用抓包工具检测到该记录,获取到数据包
在这里插入图片描述
(3)抓包工具上选中该记录,点击“Replay”,也就是进行数据重放。处理完成后会再次生成一个数据包,这就是模拟了在系统中添加数据进行了一次重放操作。

选中该记录,点击“Replay”,进行数据重放
在这里插入图片描述
(4)返回系统进行查询,发现多了一条重放的记录
在这里插入图片描述

3、解决方案

百度搜索了一下,可以通过加随机数、时间戳或者是加流水号的方式进行处理(三种方式可以单独使用也可以组合使用)。
在这里插入图片描述
此次记录在项目中使用加时间戳的方式进行处理。

  • 处理逻辑

    (1)前台在发送HTTP请求时在Header中添加时间戳认证;

    (2)后台在处理请求时获取该认证的时间戳,判断该请求是否在短时间内进行了重复请求。

  • 前台改动

    找到处理http请求的地方,在请求头中Header中添加时间戳。

    config.headers['_time'] = new Date().getTime()
    
    • 1

在这里插入图片描述

  • 后台改动

在这里插入图片描述

 // 重放攻击漏洞 解决
            // 获取http请求类型
            String type = ((HttpServletRequest) servletRequest).getMethod().toLowerCase();
            // 获取添加的时间戳
            String timeForHeader = ((HttpServletRequest) servletRequest).getHeader("_time");
            if (!"get".equals(type) && !StringUtils.isEmpty(timeForHeader)) {
                String requestUri = httpServletRequest.getRequestURI();
                // 将uri、时间戳、token值作为单用户的请求识别,作为key,进行验证
                String replayKey = String.format("replay_%s_%s_%s", requestUri, timeForHeader, token);
                if (redisUtils.hasKey(replayKey)) {
                    // 如果存在 表示重放攻击的
                    log.info("检测到请求可能是重放攻击,不进行处理");
                    return;
                } else {
                    // 如果不存在,将时间戳值作为value放到redis中, 避免redis存储越来越多,可将该记录值设为临时的
                    redisUtils.set(replayKey, timeForHeader, 1, TimeUnit.MINUTES);
                }
            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

(1)在过滤器Filter中获取请求头中指定的认证“_time”的值,也就是前台赋值的时间戳;

(2)将uri、时间戳、token组成key,时间戳为value;

(3)验证该key在redis库中是否存在,如果存在,当成重放攻击的请求,不予处理。不存在则将该key与value存放到redis缓存中,该类型的记录设定1分钟的缓存时间,避免数据增多造成存储浪费。

(4)上面代码中的处理不够严谨,将基于请求的uri、时间戳和token值缓存到redis中,由于缓存时间设置了1分钟,1分钟后该记录在redis库中会被删除,那么在1分钟后再次进行重放攻击还是可以插入成功数据的。这里可以在检查完redis的缓存后,将时间戳的值转换为时间,再与当前时间进行比较,如果两个时间差大于1分钟,同样视为重放攻击,不予处理即可。

4、重放攻击验证

在这里插入图片描述
再次选中添加记录的数据包,点击“Replay”,进行重放试验,查询页面数据,依然是两条记录(其中一条是开始未改动前重放进去的记录)。

在这里插入图片描述

OK,成功了!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/141806
推荐阅读
相关标签
  

闽ICP备14008679号