Hi, Here is one of the more technical articles covering NASL writing within the customer portal. This was written by a Tenable Customer Support (TCS) engineer with the assistance of the Tenable's Research team. TCS borrowed information from the Nessus Network Auditing book, ISBN: 1-931836-08-6, various articles of information in house at Tenable, team discussions, etc. It's one of several that TCS compiles to assist customers with specific subjects that are covered in many online and printed documentations like the book above (shameless plug here for Renaud's book) but the information may be in more than one place.
I am pasting it below, as is in html, I hope everyone can see it properly. Warning, another shameless plug. Currently there are about 217 KB online articles on Tenable products available to Tenable customers, 81 of which deal with Nessus. We add to them when ever we see recurrent configuration questions, articles we believe are helpful to trouble shooting various issues, technical articles that may not exist or are found in several sources of documentation. Shameless plugs for Tenable complete. Please see the NASL doc below. Regards, -- Dan Daniel Bowman Director of Support & ITS Tenable Network Security <mailto:[EMAIL PROTECTED]> mailto:[EMAIL PROTECTED] <http://www.tenablesecurity.com/> http://www.tenablesecurity.com/ Knowledgebase ARTICLE SUMMARY: What is NASL? SYMPTOMS: NASL (Nessus Attack Scripting Language) is a language designed after having written ~ 100 (or 200?) Nessus plugins in C. Its initial aim was to "factorize" all the network operations done by the plugins to have a single point where to tune scripts (if every plugin was written in C, then they could each decide to enforce some timeout or not, etc...), and to speed up the development of new scripts. In particular, NASL has no concept of memory management (not even pointers), and lets you manipulate strings in the same way you would manipulate integers. While initially a script would mainly do something like build buffer / send / recv / process result, the initial NASL functionality allowed to do more. NASL has support for() and while() loops since day one, as well as user-defined functions. As time went by, NASL scripts have become more complex. NASL2 (16 times faster than NASL1) solved a lot of the problems we had met between 1999 and 2002. It also extended the language significantly, by adding the support for arrays, a real parser, etc.... NASL3 is a rewrite of the NASL2 engine, but the parser is mostly the same. As a result, NASL3 extends the language capabilities a little, but less than NASL2 extended NASL1. RESOLUTION: The NASL syntax The NASL syntax is mostly inspired from the C language. It also looks similar to PHP without the useless '$' character in front of variables. Just as in C/PHP/BASH/PERL, a control block starts with a { and ends with a } ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Variables Variables do not need to be pre-declared in NASL, except when you want them to be a function local variable. The following is legal : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ a = 42; ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ By default, every variable is global unless if explicitly stated otherwise. Therefore : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ function some_function() { a = 42; } ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ In the code above, the function some_function() declares and modifies the value of the global variable 'a'. This often leads to fun and late-night debugging exercises such as in the code below : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ function myFunc() { for ( i = 0 ; i < 10 ; i ++ ) display("i = ", i, "\n"); } for ( i = 0 ; i < 5 ; i ++ ) myFunc(); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ In the example above, one would naively expect myFunc() to be called 5 times. This does not happen because myFunc() modifies the variable i, so it ends up being called only once. The solution to this problem is to use the local_var keyword : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ function myFunc() { local_var i; for ( i = 0 ; i < 10 ; i ++ ) display("i = ", i, "\n"); } for ( i = 0 ; i < 5 ; i ++ ) myFunc(); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ In the case above, the code works as expected. By convention, every NASL function should declare all its local variables, so avoid the problem above. The command nasl -W script.nasl will warn the user about global variables defined in a local function, but won't notice the re-use of a global variable inside of a local function. Some historical notes : * NASL1 did not have any support for local variables. As a result, it was not uncommon to have scripts which used variable names such as ____i to make sure they were not stepping on any other i variable out there. * NASL2 had some kind of variables inheritance. That is, if you call the function foo() which declares the variable 'x' and then calls the function bar() which uses the variable x without declaring it, then bar() would modify foo's x. This behavior has been removed in NASL3. NASL is very lax'ist when it comes to variable types (in the same way PHP is). The following three types exist : * integers * strings * arrays/hash tables In some cases you may want to explicitly convert one type to the other using the string(), int() or make_list() functions. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ String manipulation Since most NASL scripts end up sending and receiving data, handling strings is fairly easy. Strings can be manipulated the same way as integers -- they can be added or subtracted : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ x = "hello"; y = "world"; z = x + y; ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ See the chapter on string functions for more information about string handling. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Named/Anonymous arguments One big difference is the concept of anonymous and named variables for some functions. For instance, imagine the following C function : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ int make_smb_request(int soc, char * pipe, int fid, int pid, int mid, char * message) ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ This function is a bit complex. Some arguments may not be necessary (and would therefore set to NULL when used), while some others are important. As the function is complex, one has to remember the order of the arguments. That is, if I want to call make_smb_request() in my C program, I would probably have to look it up to see what is the order of the arguments and so forth. So your function call would be : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ e = make_smb_request(soc, "\\PIPE", -1, 42, 4096, NULL); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ I solved this problem by introducing named arguments in NASL. Basically, you'd prefix each argument of the function by its name. So if we had the following NASL function (equivalent to the C function above) : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ function make_smb_request(socket, pipe, fid, pid, mid, message) ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Then you would call it by prefixing each argument with its name : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ e = make_smb_request(socket:soc, pipe:"\\PIPE", fid:-1, pid:42, mid:4096, message:NULL); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ The good thing is that you can skip the arguments you don't use. If in the function above message and fid are optional, you could very well call : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ e = make_smb_request(socket:soc, pipe:"\\PIPE", pid:42, mid:4096); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ And that would work just as perfectly (fid and message would then be set to NULL in the function itself). The order of the arguments does not matter either -- the following call is equivalent to the previous one : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ e = make_smb_request(pid:42, mid:4096, socket:soc, pipe:"\\PIPE"); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ A lot of functions have such a prototype. We call them named functions. At the opposite, a function which does prefix the arguments by their name is called an anonymous function. For instance : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ display(1,2,3); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ In anonymous functions, the order of the arguments does matter. Finally, some functions are mixed (open_sock_tcp() is a good example) -- that is, they take named AND anonymous arguments. In general, functions with anonymous arguments either only take one argument, or an infinite number of arguments of the same kind. Some functions are an exception to confirm that rule. I thought I was the first one to come up with this concept, but it turns out that Objective C (http://en.wikipedia.org/wiki/Objective_C) did it before (however all the variables are mandatory and their order must be respected). Perl also supports the same kind of notation when passing a hash table as arguments to a function. So I did not invent anything at all in the end. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ User-defined functions One can easily define his own functions using the function keyword. One can define named functions or anonymous functions : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ function my_named_function(fist_name, last_name) { display("Hello ", first_name, " ", last_name, "\n"); return 0; } ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ The arguments passed to a function are copied. Therefore modifying them within the function does not affect the caller : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ function func(i) { i++; } j = 42; func(i:j); display(j, "\n"); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ An anonymous function is defined as below : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ function myFunc() { display(_FCT_ANON_ARGS[0]); } myFunc(1); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ That is, by using the local array _FCT_ANON_ARGS, which is a reserved variable name, one can access the anonymous arguments passed to the function. _FCT_ANON_ARGS[0] returns the first argument passed to the function, _FCT_ANON_ARGS[1] returns the second one, etc... ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ includes One can include scripts by calling the include() function. Note that this is not really a function but a pre-processor macro, which means that it will ALWAYS be evaluated. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ include("foobar.inc"); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ If the included file does not exist, then a warning is displayed but the script is executed anyways. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Control structures ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NASL supports several control structures : if() ... else ... NASL supports C-style if/else statements, which do not require braces (at the opposite of perl which forces the user to write unreadable code) : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ if ( a != b ) display("OK"); else display("Not OK"); if ( a < 42 ) { display("OK\n"); } else display("Not OK\n"); if ( a ) a = 42; ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ for() C style for() loops are supported, however a condition MUST be defined as a second argument. Once again, braces are not mandatory : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ for ( i = 0 ; i < 42 ; i ++ ) display("OK\n"); i = 0; for ( ; i < 42 ; ) i ++; ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ The following is not valid, as no condition is defined : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ for ( ;; ) ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ while() C style while() loops are supported, and once again the braces are not mandatory : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ i = 0; while ( i < 42 ) i ++; while ( j < 1000 ) { j ++; } ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ repeat...until The syntax is repeat BLOCK until CONDITION. 'BLOCK' must start and end with braces : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ i = 0; repeat { display("Hello World\n"); i ++; } until i > 42; ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ foreach() foreach() iterates through an array an copies each of its element into a variable : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ array = make_list("This", "is", "a", "wonderful", "world"); foreach word (array) { display(word, " "); } display("\n"); ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ x The 'x' operator repeats the function call before it N times : ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ display("Hello World\n") x 10; ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Note that this operator is considered deprecated and may therefore be removed in the future. -----Original Message----- From: [EMAIL PROTECTED] [ <mailto:[EMAIL PROTECTED]> mailto:[EMAIL PROTECTED] On Behalf Of Jason Chambers Sent: Friday, May 18, 2007 03:45 To: George A. Theall Cc: [email protected] Subject: Re: NASL DOCS George A. Theall wrote: > As far as I know, those are the most up-to-date versions, at least > that are generally available. > > > I expected to find some >> documentation on the web site, but nada... > > If others are interested in this, please let me know and I'll see what > can be done. I'm interested as well. Regards, -- Jason Chambers UCLA [EMAIL PROTECTED] 310-206-5603
_______________________________________________ Nessus mailing list [email protected] http://mail.nessus.org/mailman/listinfo/nessus
