Nmap Development mailing list archives
Re: [NSE] new features: script arguments and buffered reading
From: "Eddie Bell" <ejlbell () gmail com>
Date: Thu, 9 Aug 2007 11:49:21 +0100
hi Stoiko, nice work ;) Passing arguments to scripts was always going to be hard. I think maybe we should enforce (as a coding standard) that all script arguments should be in their own namespace to avoid confusion. I.E. anonFtp={user='x',pass='y'},SSHv1_Support={algo='blah'} Otherwise we are going to end up with a lot of values for user, pass, host etc. It could cause subtle behavioural errors such as one script having a mandatory argument and another having an optional argument with the same name. The user may wish to set the mandatory argument without realising an optional argument will be also set for a different script. Another problem, which may be out of the scope of this patch, is how to know what options are available. If a script has a mandatory argument how does the user know this without running a scan in verbose mode and seeing the error? If a script has optional arguments how can the user know these exist with out reading and understanding the script? Perhaps the best place to tell the user about arguments would be umit. It could eventually have a nse interface where script options can be viewed and set graphically. Anyway these are not issues with your patch, just things to bare in mind thanks - eddie On 07/08/07, Stoiko Ivanov <stoiko () xover htu tuwien ac at> wrote:
1) arguments to nse-scripts can be passed via the --script-args option it takes a string as argument, which is interpreted as a lua-tableconstructor (with a slightly different syntax): i.e. --script-args foo=bar,user=baz,ftp={srv=192.168.1.1,pass=droz} results in a table containing the following entries: t={foo="bar",user="baz", ftp={srv="192.168.1.1",pass="droz"}} (note that the keys (e.g. user) are strings (i.e. you can access "baz" either as t.user or as t["user"]) ). I've allowed for subtables to be part of the script-arguments, since this gives the opportunity to override arguments for certain scripts (e.g. if script foo.nse should be provided with another user-name than the others it simply gets its own subtable). script-arguments (both key and values) may contain any characters, apart from '{', '}', '=' and ',' (should those be needed - I'll find a workaround). However since the arguments are processed by the shell, they have to be put inside '"' (or escaped), if they contain spaces (or other special characters, including the brackets for sub-tables). The argument-string is checked wheter it contains exactly as many '{' as '}' as a sort of simple tampering prevention (should be enough since only a '}' closes the table-constructor, which would make it possible to do damage) - until now I haven't found a way to bypass it, but I guess there may be some possibilities - maybe anyone of you has an idea? The argument-table is then saved inside the nmap.registry with the name "args". Thus l = nmap.registry.args.ftp.pass (with the above --script-args string) would assign "droz" to l.
2) buffered network I/O a new function inside NSE's nsock buffer allows to parse data incoming through a socket: sd:receive_buf() (I actually don't think the name fits - so suggestions about alternatives would be appreciated) it takes two arguments. The first one is either a string or a function. If it is a string it is passed to lua's string.find() function for parsing the data and the prefix until the match is returned with the remains being saved inside a buffer for later calls to receive_buf(). If the argument is a function it is called instead of string.find(). The provided function has to take one argument (the buffer) and its return values have to be as those of string.find(). The second parameter is a boolean indicating wheter the delimiter should be returned along with the prefix (defaulting to true). For example with a buffer of: "some data ab some more data" the first call to sd:receive_buf("ab",false) would return: "some data " and the second call would return " some more data" whereas a call to sd:receive_buf("ab") would return: "some data ab" the first time. If no match is found receive_buf() tries to fetch more data. From the script-developers point of view receive_buf() behaves exactly like the other receive_*() functions: It returns two values (status and val). I've also added a new nselib-module (match.lua) which contains functions to be used as first parameter to receive_buf(). Currently there are two functions: regex("pcre-pattern") - uses the provided pcre-lua-module to match for a delimiter and numbytes(number) which works similarily to the unbuffered receive_bytes(), it returns however exactly the requested number of bytes leaving the rest inside the buffer for later processing. I took most inspiration for receive_buf() from doug's make_buffer, which is inside the stdnse nselib module. I would be grateful for testing and reviewing (especially wheter someone finds a way to tamper with the --script-args). cheers stoiko
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://SecLists.Org
Current thread:
- [NSE] new features: script arguments and buffered reading Stoiko Ivanov (Aug 07)
- Re: [NSE] new features: script arguments and buffered reading Eddie Bell (Aug 09)