CVE-2017-7529 Nginx整数溢出漏洞分析2
漏洞原理
补丁发布的日期是2017年7月11日15:48:23
所以我们可以到 github
上去查找修改的地方
可以看到做了一定的限制
- 图一修改,防止因为end的问题,导致
content_length-end
后的结果为负数,最后的结果无论如何都是0,而不会是负数了,对cache文件的读取也只能从0开始 - 图二修改,防止溢出后小于了size后绕过判断
正常情况下,如果我们 传入一串完整的range,那么他会检查 start
,保证不会溢出为负值
假如我们传入的范围是 1-1000
那么这里就是将 -
前后的两个数字分出来,分别赋值给 start
和 end
这两个函数,同时这里做了判断,不能是字符,同时也不能是负数,所以要动手脚的话,只能在后面运算的地方做
如果我们传入的end的值,是比 content_length
,文件内容的值大的,那么相减,start的值就是负数
在这种情况下,因为end的值会设定成centent_length-1,所以在后面的判断里肯定为 假
,因为range的范围早就超过了 content_length
if (size > content_length) {
return NGX_DECLINED;
}
正常情况来说,因为 -1
的关系,range的长度肯定是小于原始文件的长度的,所以一旦到了这一步,就直接原始文件返回,不进行range处理,为了绕过if判断,就需要将size整数溢出了
-----分割线-----
我们在测试的时候,需要将start的值设置为负数,这样在读取的时候,nginx才会将缓存文件前面的内容读取出来
假设我们的值为 7877
,那么为了读取前面的值,就得7877加上600=8477
我们给它第一个值为 -8477
,这个值是函数 end
的值,在运算的时候,start就等于了文件总长度7877减去end的值8477,最后等于负数-600,而end就等于8476
第一个值计算过后,此时的size值本应该不为8477的(下面为size的计算方法)
size += end - start
但是注意到第 362行
的一个判断
因为前面算的end的值是大于文件长度的,所以在这里会被强行等于原始文件的长度,那么到后面计算的时候
就会变成了 7877-(-600)=7877+600=8477
因为需要整数溢出,所以最后size的值得是 0x8000000000000000
,所以我们给的第二个range值要在这个基础上计算
那么 0x8000000000000000-8477
的值就是range2的值了
这里计算出来的结果是 9223372036854767331
第二个值进入的时候,因为size是+=
所以就相当于是 range2+range1,最后的值刚好就能整数溢出了
于是便绕过了这个判断,最后请求的range范围便是-600到文件结束,从而导致信息泄露
if (size > content_length) {
return NGX_DECLINED;
}
- Spring Cloud中如何保证各个微服务之间调用的安全性
- Spring Boot Actuator监控页面报错解决
- Spring Cloud中如何优雅的使用Feign调用接口
- Spring Cloud Eureka 集群高可用
- Spring Cloud Eureka 增加权限认证
- Spring Cloud Eureka 初探
- 房价网是怎么使用分布式作业框架elastic-job
- Spring Cloud Sleuth Zipkin 展示追踪数据
- Spring cloud Zuul Filter 使用小经验
- Spring Cloud Eureka REST 接口
- Spring Cloud Eureka 控制台快速查看Swagger API文档
- Spring Cloud Feign 启动UnsatisfiedDependencyException
- Spring Cloud Zuul结合Smconf配置中心动态进行IP黑名单限制
- 高性能NIO框架Netty入门篇
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- CentOS 7.4下安装Oracle 11.2.0.4数据库的方法
- CentOS桌面环境中网卡启动失败的解决方法
- 浅谈Linux vfork与fork简单对比分析
- Linux定时任务Crontab的使用方法
- linux虚拟网络设备之vlan配置详解
- Centos7安装完后无法联网的解决方法
- Linux静态链接库与模板类的处理方式
- 深入研究RocketMQ消费者是如何获取消息的
- CentOS7下 Apache的安装配置方法
- expect命令在linux下实现批量ssh免密
- 学习Vim合并行的方法和技巧
- 九种查找算法
- 代码防御性编程的十条技巧
- Ubuntu终端多窗口分屏Terminator
- linux 编译安装python3.6的教程详解