-
Notifications
You must be signed in to change notification settings - Fork 11
/
targets-ipv6-map4to6.nse
246 lines (208 loc) · 7.3 KB
/
targets-ipv6-map4to6.nse
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
local ipOps = require "ipOps"
local nmap = require "nmap"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local target = require "target"
description = [[
This script runs in the pre-scanning phase to map IPv4 addresses onto IPv6
networks and add them to the scan queue.
The technique is more general than what is technically termed "IPv4-mapped IPv6
addresses." The lower 4 bytes of the IPv6 network address are replaced with the
4 bytes of IPv4 address. When the IPv6 network is ::ffff:0:0/96, then the
script generates IPv4-mapped IPv6 addresses. When the network is ::/96, then it
generates IPv4-compatible IPv6 addresses.
]]
---
-- @usage
-- nmap -6 --script targets-ipv6-map4to6 --script-args newtargets,targets-ipv6-map4to6.IPv4Hosts={192.168.1.0/24},targets-ipv6-subnet={2001:db8:c0ca::/64}
--
-- @output
-- Pre-scan script results:
-- | targets-ipv6-map4to6:
-- | node count: 256
-- | addresses:
-- |_ 2001:db8:c0ca:0:0:0:c0a8:100/120
--
-- @args targets-ipv6-map4to6.IPv4Hosts This must have at least one IPv4
-- Host for the script be able to work
-- (Ex. 192.168.1.1 or
-- { 192.168.1.1, 192.168.2.2 } ) or Subnet
-- Addresses ( 192.168.1.0/24 or
-- { 192.168.1.0/24, 192.168.2.0/24 } )
--
-- @args targets-ipv6-subnet Table/single IPv6 address with prefix
-- (Ex. 2001:db8:c0ca::/48 or
-- { 2001:db8:c0ca::/48, 2001:db8:FEA::/48 })
--
-- @xmloutput
-- <elem key="node count">256</elem>
-- <table key="addresses">
-- <elem>2001:db8:c0ca:0:0:0:c0a8:100/120</elem>
-- </table>
--
-- Version 1.4
-- Update 01/12/2014 - V 1.4 Update for inclusion in Nmap by Daniel Miller
-- Update 05/05/2014 - V 1.3 Eliminate the Host phase.
-- Update 05/05/2014 - V 1.2 Minor corrections and standardization.
-- Update 18/10/2013 - V 1.1 Added SaveMemory option
-- Update 29/03/2013 - V 1.0 Functional script
-- Created 28/03/2013 - v0.1 Created by Raúl Fuentes <[email protected]>
--
author = "Raúl Armando Fuentes Samaniego"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {
"discovery",
}
local function split_prefix (net)
local split = stdnse.strsplit("/", net)
return split[1], tonumber(split[2])
end
---
-- This function will add all the list of IPv4 host to IPv6
--
-- The most normal is returning X:X:X:X::Y.Y.Y.Y/128
-- The conversion is going to be totally IPv6 syntax (we are going to
-- concatenate strings).
-- @param IPv6_Network A IPv6 Address ( X:X:X:X::/YY )
-- @param IPv4SHosts A IPv4 String can be: X.X.X.X or X.X.X.X/YY
-- @param addr_table A table to hold the generated addresses.
-- @return Number Total succesfuly nodes added to the scan.
-- @return Error A warning if something happened. (Nil otherwise)
local From_4_to_6 = function (IPv6_Network, IPv4SHosts, addr_table)
--We check if the PRefix are OK, anything less than 96 is fine
local v6_base, IPv6_Prefix = split_prefix(IPv6_Network)
if IPv6_Prefix > 96 then
return 0, string.format("The IPv6 subnet %s can't support a direct Mapping 4 to 6.", IPv6_Network)
end
local sBin6, sError = ipOps.ip_to_bin(v6_base)
if sBin6 == nil then
return 0, sError
end
-- two options: String or Table, the bes thing to do: make string Table
local tTabla
if type(IPv4SHosts) == "table" then
tTabla = IPv4SHosts
else
tTabla = { IPv4SHosts }
end
stdnse.debug1("Total IPv4 objects to analyze: %d for IPv6 subnet %s",
#tTabla, IPv6_Network)
local iTotal = 0
for _, Host in ipairs(tTabla) do
stdnse.debug2("IPv4 Object: %s", Host)
local v4base, prefix = split_prefix(Host)
local sBin4
sBin4, sError = ipOps.ip_to_bin(v4base)
if sBin4 == nil then
return 0, sError
end
local IPAux
IPAux, sError = ipOps.bin_to_ip(sBin6:sub(1, 96) .. sBin4)
if prefix then
prefix = prefix + (128 - 32) -- adjust for different address lengths
IPAux = string.format("%s/%d", IPAux, prefix)
else
prefix = 128
end
stdnse.debug2("IPv6 address: %s", IPAux)
addr_table[#addr_table+1] = IPAux
if target.ALLOW_NEW_TARGETS then
local bool
bool, sError = target.add(IPAux)
if bool then
iTotal = iTotal + 2^(128 - prefix)
else
stdnse.debug1("Error adding node %s: %s", IPAux, sError)
end
else
iTotal = iTotal + 2^(128 - prefix)
end
end
return iTotal
end
local IPv4Sub = stdnse.get_script_args(SCRIPT_NAME .. ".IPv4Hosts")
local IPv6User = stdnse.get_script_args("targets-ipv6-subnet")
---
-- We populated the host discovery list.
local Prescanning = function ()
local errors = {}
local tSalida = {
Nodos = 0,
addrs = {},
}
local Grantotal = 0
stdnse.debug2("Beginning the work.")
if type(IPv6User) == "string" then
IPv6User = { IPv6User }
end
-- TODO: Gather IPv6 subnets from other sources.
-- This was implemented in the original version of the script, but stripped
-- for now until the other scripts are integrated.
-- http://seclists.org/nmap-dev/2013/q4/285
for _, IPv6_Subnet in ipairs(IPv6User) do
stdnse.debug1("Processing %s", IPv6_Subnet)
local IPv6Host, sError = From_4_to_6(IPv6_Subnet, IPv4Sub, tSalida.addrs)
if sError ~= nil then
stdnse.debug1( "ERROR: One IPv6 subnet wasn't translated")
errors[#errors+1] = sError
end
if IPv6Host then
-- We need to concatenate the new nodes
Grantotal = Grantotal + IPv6Host
end
end
tSalida.Nodos = Grantotal
if #errors > 0 then
tSalida.Error = table.concat(errors, "\n")
end
return true, tSalida
end
---
-- The script need to be working with IPv6
--
--(To bad can't do it with both at same time )
function prerule ()
if not (nmap.address_family() == "inet6") then
stdnse.verbose1("This script is IPv6 only.")
return false
end
-- Because Nmap current limitation of working ONE single IP family we must
-- be sure to have everything for work the Mapped IPv4 to IPv6
if IPv4Sub == nil then
stdnse.verbose1( "There are no IPv4 addresses to map!\z
You must provide it using the %s.IPv4Hosts script-arg.")
return false
end
-- Now we need to have based IPv6 Prefix, the most important is the previous
-- known but we have a last-option too .
if IPv6User == nil then
stdnse.verbose1("There are no IPv6 subnets to scan!\z
You must provide it using the targets-ipv6-subnet script-arg.")
return false
end
return true
end
function action ()
--Vars for created the final report
local tOutput = stdnse.output_table()
local bExito = false
local tSalida
bExito, tSalida = Prescanning()
-- Now we adapt the exit to tOutput and add the hosts to the target!
tOutput.warning = tSalida.Error
if bExito then
--Final report of the Debug Lvl of Prescanning
stdnse.debug1("Successful Mapped IPv4 to IPv6 added to the scan: %d",
tSalida.Nodos)
tOutput["node count"] = tSalida.Nodos
tOutput["addresses"] = tSalida.addrs
if tSalida.Error then
stdnse.debug1("Warnings: %s", tSalida.Error)
end
else
stdnse.debug1("Was unable to add nodes to the scan list due this error: %s",
tSalida.Error)
end
return tOutput
end