前言

本来想拿这个思路出题的,结果发现去年N1CTF已经用过这个思路了,所以就把这个思路分享一下

这是一篇篇幅不长的水文

Keep-Alive

在http早期,每个http请求都要求打开一个tpc socket连接,并且使用一次之后就断开这个tcp连接。

使用keep-alive可以改善这种状态,即在一次TCP连接中可以持续发送多份数据而不会断开连接。通过使用keep-alive机制,可以减少tcp连接建立次数,也意味着可以减少TIME_WAIT状态连接,以此提高性能和提高httpd服务器的吞吐率(更少的tcp连接意味着更少的系统内核调用,socket的accept()和close()调用)。

简而言之,HTTP协议是建立在TCP协议上的,在HTTP1.0协议中,一次TCP连接只能携带一次HTTP请求

这就是一个很正常的一个TCP带一个HTTP请求的样子

1551447040386.png

这是一个HTTP长连接Keep-Alive的样子,一次TCP请求可以带上两次HTTP请求,设置Connection: Keep-Alive即可实现HTTP长连接,Connection: close则表示关闭
5.png

复现的时候记得设置Repeater Update Content-Length为关闭

1551447759445.png

CRLF漏洞

CRLF是”回车 + 换行”(rn)的简称。在HTTP协议中,HTTP Header与HTTP Body是用两个CRLF分隔的,浏览器就是根据这两个CRLF来取出HTTP 内容并显示出来。所以,一旦我们能够控制HTTP 消息头中的字符,注入一些恶意的换行,这样我们就能注入一些会话Cookie或者HTML代码,所以CRLF Injection又叫HTTP Response Splitting,简称HRS。

CRLF就不细讲了,随便扔个简介,不懂得了解下这篇文章CRLF Injection漏洞的利用与实例分析

TRICK

对于一般的CTF来说,考查CRLF,无非是通过CRLF改写HTTP请求或返回头,比如改cookie,User-Agent,或者挤掉一些不需要的HTTP头,因为在HTTP协议中,当请求头中有相同的键值的时候,是一第个为准的。比如CSP,CORS,由于返回HTML内容在请求头下,所以CRLF理论上可以控制整个HTTP返回内容。

但是如果我们需要改写的内容在我们可控CRLF以上,该怎么办。以PHP内置类SoapClient为例,在18年的N1CTF hard PHP这道题中,我们控制的注入点在请求头第一行以下

POST /index.php HTTP/1.1
xxxxxxx
注入点
xxxxxxx

但是我们必须发送GET请求,但是http协议规定相同内容以先出现为准,这个时候无法改写请求方法

于是,我们可以结合HTTP长连接,在第一次的HTTP头注入一个Connection: Keep-Alive,然后往下注入第二个HTTP请求,即可达到目的

参考

http://wonderkun.cc/index.html/?paged=10