Nmap Development mailing list archives

NSE - raw sockets


From: castorpilot <castorpilot () gmail com>
Date: Thu, 24 Aug 2006 17:58:24 +0200

Hello,

first, this is a good occasion to vote for NSE. I checked out the last
version and I definitely would like to see it included in nmap !
As I already said in a previous post, a lot of the probing/ network
analysing requires low level packet crafting in order to work
(e.g : firewalk, traceroute ...). Unfortunately, Lua does not provide this
facility, so I started to try to add it to the language.
What follows is a ugly hack, since I tried to add raw sockets to Lua even
before having written a single line of Lua ;)
Here is the "modified" Lua tarball :
http://rubyforger.rubyforge.org/liblua.tar.gz .
In fact, I just added a libnet binding (liblibnet.c) for the packet
crafting stuff. The following Lua

functions are available :

libnet.new(type,device), where type is 0 (ethernet) or 1 (ip).
libnet.free()
libnet.ip(len, tos, id, frag, ttl, protocol, chksum, src, dst, payload,
payloadsize)
libnet.tcp(...)
libnet.udp(...)
libnet.icmp (...)
libnet.eth(...)
libnet.arp(...)
libnet.getip()
libnet.getmac()
libnet.getdevice()
libnet.write()

I also added a small sniffer, sniff.open(), sniff.sniff(), sniff.close() ,
which gives a string representation
of any packet it captures.

Using these function, I was able to write the following traceroute script
(very ugly, think of it as a proof of concept :) ) :

------BEGIN-----

traceroute = function(host, port)
libnet.new(1, "eth0")
local localip = libnet.getip() -- get local ip
libnet.free()
local reached = false
local pkt
local timeref
local time
local ttl = 0
MAX = 6
TIMEOUT = 2
sniff.open()
-- pattern matching stuff, deserves a proper function
local shostregex = "shost=%d*.%d*.%d*.%d*"
local protoregex = "proto=%u*"
local flagsregex = "flags=%d*"
local sportregex = "sport=%d*"
local coderegex = "code=%d*"
local ityperegex = "type=%d*"
local shost
local proto
local flags
local sport
local code
local itype
while not(reached) and ttl < MAX do
ttl = ttl + 1
libnet.new(1, "eth0") -- create a handle
libnet.tcp(20,port,0,0,2,8192,0,0,20,"",0) -- SYN packet
libnet.ip(40,0,1,0,ttl,6,0,localip,host,"",0) -- IP packet
libnet.write()
timeref = os.time()
time = timeref
while true and (time - timeref)< TIMEOUT do
pkt = sniff.sniff()
shost=string.sub(string.sub(pkt,string.find(pkt,shostregex)),7,-1)
proto=string.sub(string.sub(pkt,string.find(pkt,protoregex)),7,-1)
if shost == host and proto == "TCP" then
flags=string.sub(string.sub(pkt,string.find(pkt,flagsregex)),7,-1)
sport=string.sub(string.sub(pkt,string.find(pkt,sportregex)),7,-1)
if flags == "18" and sport == (port .. "") then
reached = true
break
end
end
if proto == "ICMP" then
code = string.sub(string.sub(pkt,string.find(pkt,coderegex)),6,-1)
itype = string.sub(string.sub(pkt,string.find(pkt,ityperegex)),6,-1)
if itype == "11" and code == "0" then
print("Time exceeded, gateway ",shost)
break -- time exceeded
end
end
time = os.time()
end
libnet.free()
end
sniff.close()
if reached then
return "Host is at " .. ttl .. " hops"
else
return "Host was not reached"
end
end

print(traceroute(arg[1],arg[2]))
---END-----

I believe it would be nice to be able to write such scripts in NSE. I talked
about it with Diman, and he pointed out
some interesting points : libdnet instead of libnet (since this is the one
nmap uses), pcap instead of my ugly sniffer
(err, for obvious reasons !). The hardest point, I believe, is to make all
this non blocking. As I said, I am new to Lua and
writing bindings for it, so I welcome any ideas / comments you may have .

Cheers !
Fred

_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org


Current thread: