/* Nessus Attack Scripting Language * * Copyright (C) 2002 - 2004 Tenable Network Security * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "includes.h" #include "nasl_raw.h" #include "nasl.h" #include "nasl_tree.h" #include "nasl_global_ctxt.h" #include "nasl_func.h" #include "nasl_var.h" #include "nasl_lex_ctxt.h" #include "exec.h" #include "nasl_packet_forgery.h" #include "nasl_debug.h" #include "nasl_socket.h" #include "nasl_http.h" #include "nasl_host.h" #include "nasl_text_utils.h" #include "nasl_nessusd_glue.h" #include "nasl_misc_funcs.h" #include "nasl_cmd_exec.h" #include "nasl_crypto.h" #include "nasl_crypto2.h" /* **************************************************************** */ typedef struct { const char *name; tree_cell* (*c_code)(lex_ctxt*); int unnamed; /* Nb of unnamed args */ const char *args[16]; /* Must be sorted! Finish list with NULL */ } init_func; static init_func libfuncs[] = { "script_name", script_name, 1, { "deutsch", "english", "francais", "portugues", NULL }, "script_version", script_version, 1, { NULL }, "script_timeout", script_timeout, 1, { NULL }, "script_description", script_description, 999, { "deutsch", "english", "francais", "portugues", NULL }, "script_copyright", script_copyright, 999, { "deutsch", "english", "francais", "portugues", NULL }, "script_summary", script_summary, 999, { "deutsch", "english", "francais", "portugues", NULL }, "script_category", script_category, 1, { NULL }, "script_family", script_family, 999, { "deutsch", "english", "francais", "portugues", NULL }, "script_dependencie", script_dependencie, 999, { NULL }, "script_dependencies",script_dependencie, 999, { NULL }, "script_require_keys",script_require_keys, 999, { NULL }, "script_require_ports", script_require_ports, 999, { NULL }, "script_require_udp_ports", script_require_udp_ports, 999, { NULL }, "script_exclude_keys", script_exclude_keys, 999, { NULL }, "script_add_preference", script_add_preference, 0, { "name", "type", "value", NULL }, "script_get_preference", script_get_preference, 1, { NULL }, "script_get_preference_file_content", script_get_preference_file_content, 1, { NULL }, "script_get_preference_file_location", script_get_preference_file_location, 1, { NULL }, "script_id", script_id, 1, { NULL }, "script_cve_id", script_cve_id, 999, { NULL }, "script_bugtraq_id", script_bugtraq_id, 999, { NULL }, "script_xref", script_xref, 0, {"name", "value", NULL}, "get_preference", nasl_get_preference, 1, { NULL }, "safe_checks", safe_checks, 0, { NULL }, "replace_kb_item", replace_kb_item, 0, {"name", "value", NULL }, "set_kb_item", set_kb_item, 0, {"name", "value", NULL }, "get_kb_item", get_kb_item, 1, { NULL }, "get_kb_fresh_item", get_kb_fresh_item, 1, { NULL }, "get_kb_list", get_kb_list, 1, { NULL }, "security_warning", security_warning, 1, { "data", "port", "proto", "protocol", NULL }, "security_note", security_note, 1, { "data", "port", "proto", "protocol", NULL }, "security_hole", security_hole, 1, { "data", "port", "proto", "protocol", NULL }, "open_sock_tcp", nasl_open_sock_tcp, 1, { "bufsz", "timeout", "transport", NULL }, "open_sock_udp", nasl_open_sock_udp, 1, { NULL }, "open_priv_sock_tcp", nasl_open_priv_sock_tcp, 0, { "dport", "sport", "timeout", NULL }, "open_priv_sock_udp", nasl_open_priv_sock_udp, 0, { "dport", "sport", NULL }, "socket_get_error", nasl_socket_get_error, 1, { NULL }, "recv", nasl_recv, 0, { "length", "min", "socket", "timeout", NULL }, "recv_line", nasl_recv_line, 0, { "length", "socket", "timeout", NULL }, "send", nasl_send, 0, { "data", "length", "option", "socket", NULL }, "close", nasl_close_socket, 1, { NULL }, "join_multicast_group", nasl_join_multicast_group, 1, { NULL }, "leave_multicast_group", nasl_leave_multicast_group, 1, { NULL }, "get_source_port", nasl_get_source_port, 1, { NULL }, /* DOC! */ "cgibin", cgibin, 0, { NULL }, "is_cgi_installed", nasl_is_cgi_installed, 1, {"item", "port", NULL }, "http_open_socket", http_open_socket, 1, { NULL }, "http_head", http_head, 0, {"data", "item", "port", NULL }, "http_get", http_get, 0, {"data", "item", "port", NULL }, "http_post", http_post, 0, {"data", "item", "port", NULL }, "http_delete", http_delete, 0, {"data", "item", "port", NULL }, "http_put", http_put, 0, {"data", "item", "port", NULL }, "http_close_socket", http_close_socket, 0, { "socket", NULL }, "get_host_name", get_hostname, 0, { NULL }, "get_host_ip", get_host_ip, 0, { NULL }, "same_host", nasl_same_host, 2, { "cmp_hostname" }, "get_host_open_port", get_host_open_port, 0, { NULL }, "get_port_state", get_port_state, 1, { NULL }, "get_tcp_port_state", get_port_state, 1, { NULL }, "get_udp_port_state", get_udp_port_state, 1, { NULL }, "scanner_add_port", nasl_scanner_add_port, 0, {"port", "proto", NULL }, "scanner_status", nasl_scanner_status, 0, {"current", "total", NULL }, "scanner_get_port", nasl_scanner_get_port, 1, { NULL }, "islocalhost", nasl_islocalhost, 0, { NULL }, "islocalnet", nasl_islocalnet, 0, { NULL }, "get_port_transport", get_port_transport, 1, { NULL }, "this_host", nasl_this_host, 0, { NULL }, "this_host_name", nasl_this_host_name, 0, { NULL }, "string", nasl_string, 9999, { NULL }, "raw_string", nasl_rawstring, 9999, { NULL }, "strcat", nasl_strcat, 9999, { NULL }, "display", nasl_display, 9999, { NULL }, "ord", nasl_ord, 1, { NULL }, "hex", nasl_hex, 1, { NULL }, "hexstr", nasl_hexstr, 1, { NULL }, "strstr", nasl_strstr, 2, { NULL }, "ereg", nasl_ereg, 0, { "icase", "multiline", "pattern", "string", NULL }, "ereg_replace", nasl_ereg_replace, 0, {"icase", "pattern", "replace", "string", NULL }, "egrep", nasl_egrep, 0, { "icase", "pattern", "string", NULL }, "eregmatch", nasl_eregmatch, 0, { "icase", "pattern", "string", NULL }, "match", nasl_match, 0, { "icase", "pattern", "string", NULL }, "substr", nasl_substr, 3, { NULL }, "insstr", nasl_insstr, 4, { NULL }, "tolower", nasl_tolower, 1, { NULL }, "toupper", nasl_toupper, 1, { NULL }, "crap", nasl_crap, 1, { "data", "length", NULL }, "strlen", nasl_strlen, 1, { NULL }, "split", nasl_split, 1, { "keep", "sep", NULL }, "chomp", nasl_chomp, 1, { NULL }, "int", nasl_int, 1, { NULL }, "stridx", nasl_stridx, 3, { NULL }, "str_replace", nasl_str_replace, 0, { "count", "find", "replace", "string", NULL }, "make_list", nasl_make_list, 9999, { NULL }, "make_array", nasl_make_array, 9999, { NULL }, "keys", nasl_keys, 9999, { NULL }, "max_index", nasl_max_index, 1, { NULL }, "sort", nasl_sort_array, 9999, { NULL }, "unixtime", nasl_unixtime, 0, { NULL }, "gettimeofday", nasl_gettimeofday, 0, { NULL }, "localtime", nasl_localtime, 1, { "utc" }, "mktime", nasl_mktime, 0, { "hour", "isdst", "mday", "min", "mon", "sec", "year" }, "open_sock_kdc", nasl_open_sock_kdc, 0, { NULL }, "telnet_init", nasl_telnet_init, 1, { NULL }, "ftp_log_in", nasl_ftp_log_in, 0, {"pass", "socket", "user", NULL }, "ftp_get_pasv_port", nasl_ftp_get_pasv_address, 0, { "socket", NULL }, "start_denial", nasl_start_denial, 0, { NULL }, "end_denial", nasl_end_denial, 0, { NULL }, "dump_ctxt", nasl_dump_ctxt, 0, { NULL }, "typeof", nasl_typeof, 1, { NULL }, "exit", nasl_do_exit, 1, { NULL }, "rand", nasl_rand, 0, { NULL }, "usleep", nasl_usleep, 1, { NULL }, "sleep", nasl_sleep, 1, { NULL }, "isnull", nasl_isnull, 1, { NULL }, "defined_func", nasl_defined_func, 1, { NULL }, "func_named_args", nasl_func_named_args, 1, { NULL }, "func_unnamed_args", nasl_func_unnamed_args, 1, { NULL }, "func_has_arg", nasl_func_has_arg, 2, { NULL }, "forge_ip_packet", forge_ip_packet, 0, { "data", "ip_dst", "ip_hl", "ip_id", "ip_len", "ip_off", "ip_p", "ip_src", "ip_sum", "ip_tos", "ip_ttl", "ip_v", NULL }, "get_ip_element", get_ip_element, 0, { "element", "ip", NULL }, "set_ip_elements", set_ip_elements, 0, { "ip", "ip_dst", "ip_hl", "ip_id", "ip_len", "ip_off", "ip_p", "ip_src", "ip_sum", "ip_tos", "ip_ttl", "ip_v", NULL }, "insert_ip_options", insert_ip_options, 0, { "code", "ip", "length", "value", NULL}, "dump_ip_packet", dump_ip_packet, 9999, { NULL }, "forge_tcp_packet", forge_tcp_packet, 0, { "data", "ip", "th_ack", "th_dport", "th_flags", "th_off", "th_seq", "th_sport", "th_sum", "th_urp", "th_win", "th_x2", "update_ip_len", NULL }, "get_tcp_element", get_tcp_element, 0, { "element", "tcp", NULL }, "set_tcp_elements", set_tcp_elements, 0, { "data", "tcp", "th_ack", "th_dport", "th_flags", "th_off", "th_seq", "th_sport", "th_sum", "th_urp", "th_win", "th_x2", NULL }, "dump_tcp_packet", dump_tcp_packet, 999, { NULL }, "tcp_ping", nasl_tcp_ping, 0, { "port", NULL }, "forge_udp_packet", forge_udp_packet, 0, { "data", "ip", "uh_dport", "uh_sport", "uh_sum", "uh_ulen", "update_ip_len", NULL }, "get_udp_element", get_udp_element, 0, { "element", "udp", NULL }, "set_udp_elements", set_udp_elements, 0, { "data", "udp", "uh_dport", "uh_sport", "uh_sum", "uh_ulen", NULL }, "dump_udp_packet", dump_udp_packet, 999, { NULL }, "forge_icmp_packet",forge_icmp_packet, 0, { "data", "icmp_cksum", "icmp_code", "icmp_id", "icmp_seq", "icmp_type", "ip", "update_ip_len", NULL }, "get_icmp_element", get_icmp_element, 0, { "element", "icmp", NULL }, "forge_igmp_packet", forge_igmp_packet, 0, { "code", "data", "group", "ip", "type", "update_ip_len", NULL }, "send_packet", nasl_send_packet, 99, { "length", "pcap_active", "pcap_filter", "pcap_timeout", NULL }, "pcap_next", nasl_pcap_next, 1, { "interface", "pcap_filter", "timeout", NULL}, "send_capture", nasl_send_capture, 1, { "data", "interface", "length", "option", "pcap_filter", "socket", "timeout", NULL}, #ifdef HAVE_SSL #ifdef HAVE_OPENSSL_MD2_H "MD2", nasl_md2, 1, { NULL }, #endif #ifdef HAVE_OPENSSL_MD4_H "MD4", nasl_md4, 1, { NULL }, #endif "MD5", nasl_md5, 1, { NULL }, "SHA", nasl_sha, 1, { NULL }, "SHA1", nasl_sha1, 1, { NULL }, "RIPEMD160", nasl_ripemd160, 1, { NULL }, #ifdef HAVE_OPENSSL_MD2_H "HMAC_MD2", nasl_hmac_md2, 0, { "data", "key", NULL }, #endif "HMAC_MD5", nasl_hmac_md5, 0, { "data", "key", NULL }, "HMAC_SHA", nasl_hmac_sha, 0, { "data", "key", NULL }, "HMAC_SHA1", nasl_hmac_sha1, 0, { "data", "key", NULL }, "HMAC_DSS", nasl_hmac_dss, 0, { "data", "key", NULL }, "HMAC_RIPEMD160", nasl_hmac_ripemd160, 0, { "data", "key", NULL }, "dh_generate_key", nasl_dh_generate_key, 0, { "g" , "p", "priv", NULL }, "bn_random", nasl_bn_random, 0, { "need", NULL }, "bn_cmp", nasl_bn_cmp, 0, { "key1", "key2", NULL }, "dh_compute_key", nasl_dh_compute_key, 0, { "dh_server_pub", "g", "p", "priv_key", "pub_key", NULL }, "rsa_public_decrypt", nasl_rsa_public_decrypt, 0, { "e", "n", "sig", NULL }, "bf_cbc_encrypt", nasl_bf_cbc_encrypt, 0, { "data", "iv", "key", NULL}, "bf_cbc_decrypt", nasl_bf_cbc_decrypt, 0, { "data", "iv", "key", NULL}, "dsa_do_verify", nasl_dsa_do_verify, 0, { "data", "g", "p", "pub", "q", "r", "s", NULL }, "pem_to_rsa", nasl_pem_to_rsa, 0, { "passphrase", "priv", NULL }, "pem_to_dsa", nasl_pem_to_dsa, 0, { "passphrase", "priv", NULL }, "rsa_sign", nasl_rsa_sign, 0, { "d", "data", "e", "n", NULL }, "dsa_do_sign", nasl_dsa_do_sign, 0, { "data", "g", "p", "priv", "pub", "q", NULL }, #endif "pread", nasl_pread, 0, { "argv", "cd", "cmd", "nice", NULL }, "find_in_path", nasl_find_in_path, 1, { NULL }, "fread", nasl_fread, 1, { NULL }, "fwrite", nasl_fwrite, 0, { "data", "file", NULL }, "unlink", nasl_unlink, 1, { NULL }, "get_tmp_dir", nasl_get_tmp_dir, 0, { NULL }, "file_stat", nasl_file_stat, 1, { NULL }, "file_open", nasl_file_open, 0, { "mode", "name", NULL }, "file_close", nasl_file_close, 1, { NULL }, "file_read", nasl_file_read, 0, { "fp", "length", NULL }, "file_write", nasl_file_write, 0, { "data", "fp", NULL }, "file_seek", nasl_file_seek, 0, { "fp", "offset", NULL }, "shared_socket_register", nasl_shared_socket_register, 0, { "name", "socket", NULL}, "shared_socket_acquire", nasl_shared_socket_acquire, 1, { NULL }, "shared_socket_release", nasl_shared_socket_release, 1, { NULL }, "shared_socket_destroy", nasl_shared_socket_destroy, 1, { NULL }, NULL, NULL, 0, { NULL } } ; /* String variables */ static struct { const char *name; const char *val; } libsvars[] = { "NESSUS_VERSION", VERSION, NULL, NULL, }; /* Integer variables */ static struct { const char *name; int val; } libivars[] = { "TRUE", 1, "FALSE", 0, "pcap_timeout", 5, "IPPROTO_TCP", IPPROTO_TCP, "IPPROTO_UDP", IPPROTO_UDP, "IPPROTO_ICMP", IPPROTO_ICMP, "IPROTO_IP", IPPROTO_IP, "IPPROTO_IGMP", IPPROTO_IGMP, "ENCAPS_IP", NESSUS_ENCAPS_IP, "ENCAPS_SSLv23", NESSUS_ENCAPS_SSLv23, "ENCAPS_SSLv2", NESSUS_ENCAPS_SSLv2, "ENCAPS_SSLv3", NESSUS_ENCAPS_SSLv3, "ENCAPS_TLSv1", NESSUS_ENCAPS_TLSv1, "NASL_LEVEL", NASL_LEVEL, "TH_FIN", TH_FIN, "TH_SYN", TH_SYN, "TH_RST", TH_RST, "TH_PUSH", TH_PUSH, "TH_ACK", TH_ACK, "TH_URG", TH_URG, "IP_RF", IP_RF, "IP_DF", IP_DF, "IP_MF", IP_MF, "IP_OFFMASK", IP_OFFMASK, "ACT_INIT", ACT_INIT, "ACT_GATHER_INFO", ACT_GATHER_INFO, "ACT_ATTACK", ACT_ATTACK, "ACT_MIXED_ATTACK", ACT_MIXED_ATTACK, "ACT_DESTRUCTIVE_ATTACK", ACT_DESTRUCTIVE_ATTACK, "ACT_DENIAL", ACT_DENIAL, "ACT_SCANNER", ACT_SCANNER, "ACT_SETTINGS", ACT_SETTINGS, "ACT_KILL_HOST", ACT_KILL_HOST, "ACT_FLOOD", ACT_FLOOD, "ACT_END", ACT_END, "MSG_OOB", MSG_OOB, "NOERR", NASL_ERR_NOERR, "ETIMEDOUT", NASL_ERR_ETIMEDOUT, "ECONNRESET", NASL_ERR_ECONNRESET, "EUNREACH", NASL_ERR_EUNREACH, "EUNKNOWN", NASL_ERR_EUNKNOWN, NULL, 0, }; /* See also in exec.c: * COMMAND_LINE * description */ int init_nasl_library(lex_ctxt* lexic) { int i, j, c; nasl_func *pf; named_nasl_var *v; tree_cell tc; const char **p, *q; memset(&tc, 0, sizeof(tc)); for (i = 0, c= 0; i < sizeof(libfuncs) / sizeof(libfuncs[0])-1; i ++) { if ((pf = insert_nasl_func(lexic, libfuncs[i].name, NULL)) == NULL) { nasl_perror(lexic, "init_nasl2_library: could not define fct '%s'\n", libfuncs[i].name); continue; } pf->block = libfuncs[i].c_code; pf->flags |= FUNC_FLAG_INTERNAL; pf->nb_unnamed_args = libfuncs[i].unnamed; for (j = 0, p = libfuncs[i].args, q = NULL; (*p) != NULL; j ++) { if (q != NULL && strcmp(q, *p) > 0) nasl_perror(lexic, "init_nasl2_library: unsorted args for function %s: %s > %s\n", libfuncs[i].name, q, (*p)); q = (*p); p ++; } pf->nb_named_args = j; pf->args_names = (char**)libfuncs[i].args; c++; } tc.type = CONST_INT; for (i = 0; i < sizeof(libivars) / sizeof(libivars[0])-1; i ++) { tc.x.i_val = libivars[i].val; if ((v = add_named_var_to_ctxt(lexic, libivars[i].name, &tc)) == NULL) { nasl_perror(lexic, "init_nasl2_library: could not define var '%s'\n", libivars[i].name); continue; } c ++; } tc.type = CONST_DATA; for (i = 0; i < sizeof(libsvars) / sizeof(libsvars[0])-1; i ++) { tc.x.str_val = libsvars[i].val; tc.size = strlen(libsvars[i].val); if ((v = add_named_var_to_ctxt(lexic, libsvars[i].name, &tc)) == NULL) { nasl_perror(lexic, "init_nasl2_library: could not define var '%s'\n", libsvars[i].name); continue; } c ++; } if (add_named_var_to_ctxt(lexic, "NULL", NULL) == NULL) nasl_perror(lexic, "init_nasl2_library: could not define var 'NULL'\n"); return c; } char * nasl_version() { static char vers[sizeof(VERSION) + 1]; strncpy(vers, VERSION, sizeof(vers) - 1); vers[sizeof(vers) - 1 ] = '\0'; return vers; }