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

Reply via email to