Detecting HTTP Compression With nMap Script
With all the recent talk of the BREACH attack, a really sweet (compression based) oracle attack, I whipped up a quick NSE script to check if a server supports HTTP compression. Granted, this script is far from complete, however it is short, optimized, and to the point. Also keep in mind, that there are several other requirements that make a server susceptible to a BREACH attack, so this is simply a compression check, not a BREACH vulnerability check. Some of the additional requirements on the the server side involve supporting a reflected parameter in the body and a static parameters to attack in the body. Other requirements are placed on the attacker, such as being required to know the parameters to attack, the ability to see the traffic both ways, and to getting the victim to a page they control code on. With all of these conditions hanging in the balance, it's tough for an automated scanner to say with certainty that a site is vulnerable to this attack. I used this resource to aid me in writing my nmap script, and this resource to better understand HTTP compression. The following is Lua code for the compression.nse script (and there is still a lot of room for improvement here):
description = [[
http compression detector
]]
--breachattack.com--
author = "Dan Borges"
license = "Same as Nmap-See http://nmap.org/book/man-legal.html"
categories = {"discovery", "safe"}
local http = require("http")
local shortport = require("shortport")
local stdnse = require("stdnse")
local options = {header={}}
options['header']['Accept-Encoding'] = "gzip, deflate"
portrule = shortport.http
action = function(host, port)
local response = http.get(host, port, "/", options)
return response.header["content-encoding"]
end
description = [[
http compression detector
]]
--breachattack.com--
author = "Dan Borges"
license = "Same as Nmap-See http://nmap.org/book/man-legal.html"
categories = {"discovery", "safe"}
local http = require("http")
local shortport = require("shortport")
local stdnse = require("stdnse")
local options = {header={}}
options['header']['Accept-Encoding'] = "gzip, deflate"
portrule = shortport.http
action = function(host, port)
local response = http.get(host, port, "/", options)
return response.header["content-encoding"]
end