两种基于HTTP的通用IDS躲避技术
F-8编码允许大于单字节(0-255)的值以字节流的形式表示。HTTP服务器使用UTF-8编码来表示大于ASCII代码范围之外(1-127)的Unicode码。
UTF-8工作的时候,字节的高位有特殊的含义。两字节的UTF-8和三字节的UTF-8序列表示如下:
110xxxxx 10xxxxxx (二字节序列)
1110xxxx 10xxxxxx 10xxxxxx (三字节序列)
UTF-8序列的第一字节是最重要的,通过它你可以知道这个UTF-8序列有多少字节,这是通过检查第一个0之前的1的个数来获得的。例子中,两字节的UTF-8序列,0之前的高位有两个1。第一个UTF-8字节0后边的位可以用来计算最终的值。后边的UTF-8字节格式相同,最高位是1,次高位是0,两位用于鉴别UTF-8,剩下的6位用来计算最终的值。
为了对URL进行UTF-8编码,每个UTF-8字节都是用一个百分号进行转换。一个例子是:%C0%AF = ‘/’.
2)Unicode码点简介
可以使用UTF-8编码来对Unicode码点值进行编码。码点值的范围通常是0-65535,HTTP URL中的任何大于127的码点值都使用UTF-8编码。
值为0-127的Unicode码点,将会映射成单独的ASCII值。这样,就剩下65408个值,可以表示其他语言中的字符(例如匈牙利语或者日语)。通常,这些语言有自己的Unicode代码页,从Unicode代码页中可以得到Unicode的码点值。每种Unicode代码页有自己独特的值,因此如果Unicode代码页变了,Unicode码点值所代表的字符也就不同了。这一概念对于下一节的URL编码是很重要的。
3)把躲避手段综合起来
IDS很难处理UTF-8编码的Unicode码点值,主要有三个原因:
第一个原因是,UTF-8编码可以将一个码点值或者ASCII值用不止一种方式表示,这在最近的Unicode标准中已经修正,但是在Web服务器中仍然很常见(包括Apache)。
例如,大写字母A可以用两字节的UTF-8序列编码:
• %C1%81 (11000001 10000001 = 1000001 = ‘A’)
同样,大写字母A也可以用三字节的UTF-8序列编码:
• %E0%81%81 ( 11100000 10000001 10000001 = 1000001 = ‘A’)
因此,使用UTF-8来对ASCII字符进行编码,会得到很多结果。
第二个原因,某些非ASCII的Unicode码点也可以映射为ASCII字符。例如,Unicode码点12001可以映射为大写字母A。如果想要知道哪一个码点可以映射到ASCII字符,要么阅读整个Unicode码的映射,要么对服务器测试所有不同的Unicode码点。目前,唯一这么做的Web服务器就是微软的IIS服务器。
第三个原因与第二个原因有关。如果Unicode码的映射改变或者未知,翻译后的Unicode码点就有可能是无效的。这一点很重要,这是因为中国、日本、波兰等国的IIS Web服务器使用不同的代码页,因此如果IDS不了解Web服务器使用的代码页,对URL进行UTF-8解码的结果就有可能是错误的。因此如果一个IDS不能对所监视服务器使用的Unicode代码页进行配置,对于IDS没有监测的代码页,任何Web服务器都是不受保护的。
G. UTF-8 空字节编码
UTF-8空字节编码与UTF-8编码类似,区别在于并不适用百分号进行转意,发送的字节就是实际的字节,如果A被编码,结果是:
• 0xC1 0x81 = ‘A’
这种类型的编码只被微软的IIS服务器所支持。
H.微软%U编码
微软的%U编码使用一种独特的方式来对Unicode码点值小与65535(或者两个字节)的对象编码。格式很简单,%U后边是Unicode码点值的4个四位值的十六进制:
• %UXXXX
例如,大写A可以编码成:
• %U0041 = ‘A’
这种编码被微软的IIS所支持。
I.不匹配编码
不匹配编码使用不同的编码方法来表示一个ASCII字符,不过这并不是一种单独的编码。
例如,我们使用微软的%U编码方法来对大写A进行编码。因为IIS要对URL进行双解码,我们可以使用其他的方法来对%U方法进行编码。比如,我们可以对%U方法中的“U”进行十六进制编码。这样,一个简单的%U0041就变成了%%550041。我们也可以对0041进行十六进制编码,或者使用别的编码方法。下边是一个针对IIS服务器的更加复杂的不匹配编码,使着分析这串字符到底代表什么ASCII字符:
• %U0025%550%303%37
IV. 无效协议解析
A.使用请求管道来实现URL躲避
请求管道的躲避方法,是一种无效协议解析的躲避方法。它使用了HTTP协议版本1.1的请求管道来使URI更加模糊。
请求管道标准允许Web客户端在一个数据包中发送多个请求,这个与HTTP的保持连接头有所不同,不要混淆。请求管道把所有的请求放在一个包中,而HTTP保持连接是为了保持TCP流一直开放,接受更多的请求。
我们使用请求管道特性在一个包中嵌入多个URL。大部分的IDS都能正确解析第一个URL,但基本上都不能正确解析其余的URL。这为躲避技术打开了大门,其他的URL虽然
• GET / HTTP/1.1\r\nHost: \r\n\r\nGET /foobar.html \r\nHost: \r\n\r\nGET /cgi%2Dbin%2Fph%66 HTTP/1.1\r\nHost: r\n
B. 使用POST和Content-Encoding参数进行躲避
另一个在攻击中包含恶意数据的HTTP协议字段,就是URL的参数字段。大部分数据库和cgi类型的攻击,都使用了该字段,而大部分的IDS都有相应的规则来检测恶意的参数键和参数值。一种躲避IDS的简单方法,就是使用与编码URL相同的技术来对参数进行编码,但大部分的IDS对参数字段也进行了解码。我们的方法是:使用POST请求将参数字段放到HTTP请求头的末尾。如果参数字段是名文形式,IDS就能很容易的发现恶意内容,因此我们使用了头选项,Content-Encoding,对参数字段进行BASE64编码。除非IDS对POST的内容也进行BASE64解码,攻击就有可能不断进行;即使IDS对POST实现了BASE64编码,这也是一个非常耗时的过程,因此如果发送大量包含巨型参数字段的POST请求,甚至会对IDS造成DOS攻击。
V.结论
HTTP IDS躲避技术有两大类,分别是无效协议解析和无效协议字段编码。如果IDS对HTTP协议字段的编码类型不了解,就不能正确的解码URL,攻击躲避的事件就会发生。这也是经常讨论的编码技术。如果IDS对HTTP缺乏足够的了解,仍有可能发生漏报。请求管道与内容编码躲避技术就是需要注意的。通过对IDS协议解码的研究发现,大部分的漏报都是使用了这两项技术。
本文链接地址:http://www.oyaya.net/fanwen/view/118735.html
UTF-8工作的时候,字节的高位有特殊的含义。两字节的UTF-8和三字节的UTF-8序列表示如下:
110xxxxx 10xxxxxx (二字节序列)
1110xxxx 10xxxxxx 10xxxxxx (三字节序列)
UTF-8序列的第一字节是最重要的,通过它你可以知道这个UTF-8序列有多少字节,这是通过检查第一个0之前的1的个数来获得的。例子中,两字节的UTF-8序列,0之前的高位有两个1。第一个UTF-8字节0后边的位可以用来计算最终的值。后边的UTF-8字节格式相同,最高位是1,次高位是0,两位用于鉴别UTF-8,剩下的6位用来计算最终的值。
为了对URL进行UTF-8编码,每个UTF-8字节都是用一个百分号进行转换。一个例子是:%C0%AF = ‘/’.
2)Unicode码点简介
可以使用UTF-8编码来对Unicode码点值进行编码。码点值的范围通常是0-65535,HTTP URL中的任何大于127的码点值都使用UTF-8编码。
值为0-127的Unicode码点,将会映射成单独的ASCII值。这样,就剩下65408个值,可以表示其他语言中的字符(例如匈牙利语或者日语)。通常,这些语言有自己的Unicode代码页,从Unicode代码页中可以得到Unicode的码点值。每种Unicode代码页有自己独特的值,因此如果Unicode代码页变了,Unicode码点值所代表的字符也就不同了。这一概念对于下一节的URL编码是很重要的。
3)把躲避手段综合起来
IDS很难处理UTF-8编码的Unicode码点值,主要有三个原因:
第一个原因是,UTF-8编码可以将一个码点值或者ASCII值用不止一种方式表示,这在最近的Unicode标准中已经修正,但是在Web服务器中仍然很常见(包括Apache)。
例如,大写字母A可以用两字节的UTF-8序列编码:
• %C1%81 (11000001 10000001 = 1000001 = ‘A’)
同样,大写字母A也可以用三字节的UTF-8序列编码:
• %E0%81%81 ( 11100000 10000001 10000001 = 1000001 = ‘A’)
因此,使用UTF-8来对ASCII字符进行编码,会得到很多结果。
第二个原因,某些非ASCII的Unicode码点也可以映射为ASCII字符。例如,Unicode码点12001可以映射为大写字母A。如果想要知道哪一个码点可以映射到ASCII字符,要么阅读整个Unicode码的映射,要么对服务器测试所有不同的Unicode码点。目前,唯一这么做的Web服务器就是微软的IIS服务器。
第三个原因与第二个原因有关。如果Unicode码的映射改变或者未知,翻译后的Unicode码点就有可能是无效的。这一点很重要,这是因为中国、日本、波兰等国的IIS Web服务器使用不同的代码页,因此如果IDS不了解Web服务器使用的代码页,对URL进行UTF-8解码的结果就有可能是错误的。因此如果一个IDS不能对所监视服务器使用的Unicode代码页进行配置,对于IDS没有监测的代码页,任何Web服务器都是不受保护的。
G. UTF-8 空字节编码
UTF-8空字节编码与UTF-8编码类似,区别在于并不适用百分号进行转意,发送的字节就是实际的字节,如果A被编码,结果是:
• 0xC1 0x81 = ‘A’
这种类型的编码只被微软的IIS服务器所支持。
H.微软%U编码
微软的%U编码使用一种独特的方式来对Unicode码点值小与65535(或者两个字节)的对象编码。格式很简单,%U后边是Unicode码点值的4个四位值的十六进制:
• %UXXXX
例如,大写A可以编码成:
• %U0041 = ‘A’
这种编码被微软的IIS所支持。
I.不匹配编码
不匹配编码使用不同的编码方法来表示一个ASCII字符,不过这并不是一种单独的编码。
例如,我们使用微软的%U编码方法来对大写A进行编码。因为IIS要对URL进行双解码,我们可以使用其他的方法来对%U方法进行编码。比如,我们可以对%U方法中的“U”进行十六进制编码。这样,一个简单的%U0041就变成了%%550041。我们也可以对0041进行十六进制编码,或者使用别的编码方法。下边是一个针对IIS服务器的更加复杂的不匹配编码,使着分析这串字符到底代表什么ASCII字符:
• %U0025%550%303%37
IV. 无效协议解析
A.使用请求管道来实现URL躲避
请求管道的躲避方法,是一种无效协议解析的躲避方法。它使用了HTTP协议版本1.1的请求管道来使URI更加模糊。
请求管道标准允许Web客户端在一个数据包中发送多个请求,这个与HTTP的保持连接头有所不同,不要混淆。请求管道把所有的请求放在一个包中,而HTTP保持连接是为了保持TCP流一直开放,接受更多的请求。
我们使用请求管道特性在一个包中嵌入多个URL。大部分的IDS都能正确解析第一个URL,但基本上都不能正确解析其余的URL。这为躲避技术打开了大门,其他的URL虽然
能被服务器解码,但是却被大多数的IDS忽略。比如,下列的数据负载使用了请求管道的技术来躲避对URL的检测:
• GET / HTTP/1.1\r\nHost: \r\n\r\nGET /foobar.html \r\nHost: \r\n\r\nGET /cgi%2Dbin%2Fph%66 HTTP/1.1\r\nHost: r\n
B. 使用POST和Content-Encoding参数进行躲避
另一个在攻击中包含恶意数据的HTTP协议字段,就是URL的参数字段。大部分数据库和cgi类型的攻击,都使用了该字段,而大部分的IDS都有相应的规则来检测恶意的参数键和参数值。一种躲避IDS的简单方法,就是使用与编码URL相同的技术来对参数进行编码,但大部分的IDS对参数字段也进行了解码。我们的方法是:使用POST请求将参数字段放到HTTP请求头的末尾。如果参数字段是名文形式,IDS就能很容易的发现恶意内容,因此我们使用了头选项,Content-Encoding,对参数字段进行BASE64编码。除非IDS对POST的内容也进行BASE64解码,攻击就有可能不断进行;即使IDS对POST实现了BASE64编码,这也是一个非常耗时的过程,因此如果发送大量包含巨型参数字段的POST请求,甚至会对IDS造成DOS攻击。
V.结论
HTTP IDS躲避技术有两大类,分别是无效协议解析和无效协议字段编码。如果IDS对HTTP协议字段的编码类型不了解,就不能正确的解码URL,攻击躲避的事件就会发生。这也是经常讨论的编码技术。如果IDS对HTTP缺乏足够的了解,仍有可能发生漏报。请求管道与内容编码躲避技术就是需要注意的。通过对IDS协议解码的研究发现,大部分的漏报都是使用了这两项技术。
《两种基于HTTP的通用IDS躲避技术(第2页)》