nse_init.cc
来自「Ubuntu packages of security software。 相」· CC 代码 · 共 816 行 · 第 1/2 页
CC
816 行
#include "nse_init.h"#include "nse_nmaplib.h"#include "nse_macros.h"#include "nse_debug.h"// 3rd Party libs#include "nse_pcrelib.h"#include "nbase.h"#include "nmap.h"#include "nmap_error.h"#include "NmapOps.h"#ifndef WIN32 #include "dirent.h"#endif#include "errno.h"#include <algorithm>int init_setlualibpath(lua_State* l);int init_setargs(lua_State *l);int init_parseargs(lua_State* l);int init_loadfile(lua_State* l, char* filename);int init_loaddir(lua_State* l, char* dirname);int init_loadcategories(lua_State* l, std::vector<std::string> categories, std::vector<std::string> &unusedTags);int init_scandir(char* dirname, std::vector<std::string>& result, int files_or_dirs);int init_fetchfile(char *result, size_t result_max_len, char* file);int init_fetchfile_absolute(char *path, size_t path_len, char *file);int init_updatedb(lua_State* l);int init_pick_default_categories(std::vector<std::string>& chosenScripts);int check_extension(const char* ext, const char* path);extern NmapOps o;/* open the standard libs */int init_lua(lua_State* l) { const luaL_Reg lualibs[] = { {"", luaopen_base}, {LUA_LOADLIBNAME, luaopen_package}, {LUA_TABLIBNAME, luaopen_table}, {LUA_IOLIBNAME, luaopen_io}, {LUA_OSLIBNAME, luaopen_os}, {LUA_STRLIBNAME, luaopen_string}, {LUA_MATHLIBNAME, luaopen_math}, {LUA_DBLIBNAME, luaopen_debug}, {NSE_PCRELIBNAME, luaopen_pcrelib}, {NULL, NULL} }; const luaL_Reg* lib; for (lib = lualibs; lib->func; lib++) { lua_pushcfunction(l, lib->func); lua_pushstring(l, lib->name); SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 1, 0, 0)); } /* publish the nmap bindings to the script */ lua_newtable(l); SCRIPT_ENGINE_TRY(set_nmaplib(l)); lua_setglobal(l, "nmap"); SCRIPT_ENGINE_TRY(init_setlualibpath(l)); return SCRIPT_ENGINE_SUCCESS;}/*sets two variables, which control where lua looks for modules (implemented in C or lua */int init_setlualibpath(lua_State* l){ char path[MAX_FILENAME_LEN]; char cpath[MAX_FILENAME_LEN]; const char*oldpath, *oldcpath; std::string luapath, luacpath; /* set the path lua searches for modules*/ if(nmap_fetchfile(path, MAX_FILENAME_LEN, SCRIPT_ENGINE_LIB_DIR)!=2){ /*SCRIPT_ENGINE_LIB_DIR is not a directory - error */ error("%s: %s not a directory", SCRIPT_ENGINE, SCRIPT_ENGINE_LIB_DIR); return SCRIPT_ENGINE_ERROR; } if(nmap_fetchfile(cpath, MAX_FILENAME_LEN, SCRIPT_ENGINE_LIBEXEC_DIR)!=2){ error("%s: %s not a directory", SCRIPT_ENGINE, SCRIPT_ENGINE_LIBEXEC_DIR); return SCRIPT_ENGINE_ERROR; } /* the path lua uses to search for modules is setted to the * SCRIPT_ENGINE_LIBDIR/ *.lua with the default path * (which is read from the package-module) appended - * the path for C-modules is as above but it searches for shared libs (*.so) */ luapath= std::string(path) + "?.lua;"; #ifdef WIN32 luacpath= std::string(cpath) + "?.dll;";#else luacpath= std::string(cpath) + "?.so;";#endif lua_getglobal(l,"package"); if(!lua_istable(l,-1)){ error("%s: the lua global-variable package is not a table?!", SCRIPT_ENGINE); return SCRIPT_ENGINE_ERROR; } lua_getfield(l,-1, "path"); lua_getfield(l,-2, "cpath"); if(!lua_isstring(l,-1)||!lua_isstring(l,-2)){ error("%s: no default paths setted in package table (needed in %s at line %d) -- probably a problem of the lua-configuration?!", SCRIPT_ENGINE, __FILE__, __LINE__); return SCRIPT_ENGINE_ERROR; } oldcpath= lua_tostring(l,-1); oldpath = lua_tostring(l,-2); luacpath= luacpath + oldcpath; luapath= luapath + oldpath; lua_pop(l,2); lua_pushstring(l, luapath.c_str()); lua_setfield(l, -2, "path"); lua_pushstring(l, luacpath.c_str()); lua_setfield(l, -2, "cpath"); lua_getfield(l,-1, "path"); lua_getfield(l,-2, "cpath"); SCRIPT_ENGINE_DEBUGGING(log_write(LOG_STDOUT, "%s: Using %s to search for C-modules and %s for Lua-modules\n", SCRIPT_ENGINE, lua_tostring(l,-1), lua_tostring(l,-2));) /*pop the two strings (luapath and luacpath) and the package table off * the stack */ lua_pop(l,3); return SCRIPT_ENGINE_SUCCESS;}/* parses the argument provided to --script-args and leaves the processed * string on the stack, after this it only has to be prepended with * "<tablename>={" and appended by "}", before it can be called by * luaL_loadbuffer() */int init_parseargs(lua_State* l){ //FIXME - free o.script-args after we're finished!!! if(o.scriptargs==NULL){ //if no arguments are provided we're done return SCRIPT_ENGINE_SUCCESS; } //prepare passed string for loading lua_getglobal(l,"string"); lua_getfield(l,-1,"gsub"); lua_pushvalue(l,-1); lua_pushstring(l,o.scriptargs); lua_pushstring(l,"=([^{},$]+)"); lua_pushstring(l,"=\"%1\""); SCRIPT_ENGINE_TRY(lua_pcall(l,3,1,0)); /* copy the result on the bottom of the stack, since this is the part * we want to return */ lua_pushvalue(l,-1); lua_insert(l,1); lua_pushstring(l,"%b{}"); lua_pushstring(l,""); SCRIPT_ENGINE_TRY(lua_pcall(l,3,1,0)); lua_getfield(l,-2,"find"); lua_pushvalue(l,-2); lua_pushstring(l,"[{}]"); SCRIPT_ENGINE_TRY(lua_pcall(l,2,1,0)); if(!lua_isnil(l,-1)){ error("unbalanced brackets inside script-options!!"); return SCRIPT_ENGINE_ERROR; } lua_settop(l,1); //clear stack //luaL_loadbuffer(l,tmp,strlen(tmp),"Script-Arguments"); //if(lua_pcall(l,0,0,0)!=0){// error("error loading --script-args: %s",lua_tostring(l,-1));// return SCRIPT_ENGINE_ERROR;// } return SCRIPT_ENGINE_SUCCESS;}/* set the arguments inside the nmap.registry, for use by scripts */int init_setargs(lua_State *l){ const char *argbuf; size_t argbuflen; if(o.scriptargs==NULL){ return SCRIPT_ENGINE_SUCCESS; } /* we'll concatenate the stuff we need to prepend and append to the * processed using lua's functionality */ SCRIPT_ENGINE_TRY(init_parseargs(l)); lua_pushstring(l,"nmap.registry.args={"); lua_insert(l,-2); lua_pushstring(l,"}"); lua_concat(l,3); argbuf=lua_tolstring(l,-1,&argbuflen); luaL_loadbuffer(l,argbuf,argbuflen,"Script-Arguments-prerun"); if(lua_pcall(l,0,0,0)!=0){ error("error loading --script-args: %s",lua_tostring(l,-1)); return SCRIPT_ENGINE_ERROR; } return SCRIPT_ENGINE_SUCCESS;}/* if there were no command line arguments specifying * which scripts should be run, a default script set is * chosen * otherwise the script locators given at the command line * (either directories with lua files or lua files) are * loaded * */int init_rules(lua_State* l, std::vector<std::string> chosenScripts) { char path[MAX_FILENAME_LEN]; int type; char* c_iter; std::vector<std::string> unusedTags; lua_newtable(l); lua_setglobal(l, PORTTESTS); lua_newtable(l); lua_setglobal(l, HOSTTESTS); SCRIPT_ENGINE_TRY(init_pick_default_categories(chosenScripts)); // we try to interpret the choices as categories SCRIPT_ENGINE_TRY(init_loadcategories(l, chosenScripts, unusedTags)); // if there's more, we try to interpret as directory or file std::vector<std::string>::iterator iter; bool extension_not_matched = false; for(iter = unusedTags.begin(); iter != unusedTags.end(); iter++) { c_iter = strdup((*iter).c_str()); type = init_fetchfile_absolute(path, sizeof(path), c_iter); free(c_iter); if (type == 0) { c_iter = strdup((*iter + std::string(SCRIPT_ENGINE_EXTENSION)).c_str()); type = init_fetchfile_absolute(path, sizeof(path), c_iter); free(c_iter); } switch(type) { case 0: // no such path error("%s: No such category, file or directory: '%s'", SCRIPT_ENGINE, (*iter).c_str()); return SCRIPT_ENGINE_ERROR; break; case 1: // nmap_fetchfile returned a file if(check_extension(SCRIPT_ENGINE_EXTENSION, path) != MATCH && extension_not_matched == false) { error("%s: Warning: Loading '%s' - the recommended file extension is '.nse'.", SCRIPT_ENGINE, path); extension_not_matched = true; } SCRIPT_ENGINE_TRY(init_loadfile(l, path)); break; case 2: // nmap_fetchfile returned a dir SCRIPT_ENGINE_TRY(init_loaddir(l, path)); break; default: fatal("%s: In: %s:%i This should never happen.", SCRIPT_ENGINE, __FILE__, __LINE__); } } // Compute some stats SCRIPT_ENGINE_DEBUGGING( int rules_count; lua_getglobal(l, HOSTTESTS); rules_count = lua_objlen(l, -1); lua_getglobal(l, PORTTESTS); rules_count += lua_objlen(l, -1); lua_pop(l, 2); log_write(LOG_STDOUT, "%s: Initialized %d rules\n", SCRIPT_ENGINE, rules_count); ) return SCRIPT_ENGINE_SUCCESS;}class ExtensionalCategory {public: std::string category; int option; ExtensionalCategory(std::string _category, int _option) { category = _category; option = _option; }};int init_pick_default_categories(std::vector<std::string>& chosenScripts) { std::vector<ExtensionalCategory> reserved_categories; std::vector<ExtensionalCategory>::iterator rcat_iter; reserved_categories.push_back(ExtensionalCategory(std::string("version"), o.scriptversion)); // if they tried to explicitely select an implicit category, we complain if(o.script) { for( rcat_iter = reserved_categories.begin(); rcat_iter != reserved_categories.end(); rcat_iter++) { if( (*rcat_iter).option == 0 && std::find( chosenScripts.begin(), chosenScripts.end(), (*rcat_iter).category) != chosenScripts.end()) fatal("%s: specifying the \"%s\" category explicitly is not allowed.", SCRIPT_ENGINE, (*rcat_iter).category.c_str()); } } // if no scripts were chosen, we use a default set if( (o.script == 1 && chosenScripts.size() == 0) ) { chosenScripts.push_back(std::string("safe")); chosenScripts.push_back(std::string("intrusive")); // chosenScripts.push_back(std::string("vulnerabilities")); } // we append the implicitely selected categories for( rcat_iter = reserved_categories.begin(); rcat_iter != reserved_categories.end(); rcat_iter++) { if((*rcat_iter).option == 1) chosenScripts.push_back((*rcat_iter).category); } return SCRIPT_ENGINE_SUCCESS;}int init_updatedb(lua_State* l) { char path[MAX_FILENAME_LEN]; FILE* scriptdb; std::vector<std::string> files; std::vector<std::string>::iterator iter; char* c_iter; if(nmap_fetchfile(path, sizeof(path)-sizeof(SCRIPT_ENGINE_DATABASE)-1, SCRIPT_ENGINE_LUA_DIR) == 0) { error("%s: Couldn't find '%s'", SCRIPT_ENGINE, SCRIPT_ENGINE_LUA_DIR); return SCRIPT_ENGINE_ERROR; } SCRIPT_ENGINE_TRY(init_scandir(path, files, FILES)); // we rely on the fact that nmap_fetchfile returned a string which leaves enough room // to append the db filename (see call to nmap_fetchfile above) strncat(path, SCRIPT_ENGINE_DATABASE, MAX_FILENAME_LEN-1); scriptdb = fopen(path, "w"); if(scriptdb == NULL) { error("%s: Could not open '%s' for writing: %s", SCRIPT_ENGINE, path, strerror(errno)); return SCRIPT_ENGINE_ERROR; } SCRIPT_ENGINE_DEBUGGING( log_write(LOG_STDOUT, "%s: Trying to add %d scripts to the database.\n", SCRIPT_ENGINE, (int) files.size()); ) lua_newtable(l); /*give the script global namespace access*/ lua_newtable(l); lua_getglobal(l, "_G"); lua_setfield(l, -2, "__index"); lua_setmetatable(l, -2); std::sort(files.begin(), files.end()); for(iter = files.begin(); iter != files.end(); iter++) { c_iter = strdup((*iter).c_str()); if(check_extension(SCRIPT_ENGINE_EXTENSION, c_iter) == MATCH && strstr(c_iter, SCRIPT_ENGINE_DATABASE) == NULL) { SCRIPT_ENGINE_LUA_TRY(luaL_loadfile(l, c_iter)); lua_pushvalue(l, -2); lua_setfenv(l, -2); SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0)); lua_getfield(l, -1, "categories"); if(lua_isnil(l, -1)) { error("%s: Script '%s' does not contain any category categories.", SCRIPT_ENGINE, c_iter); return SCRIPT_ENGINE_ERROR; } lua_pushnil(l); while(lua_next(l, -2) != 0) { char *filename = path_get_basename(c_iter); if (filename == NULL) { error("%s: Could not allocate temporary memory.", SCRIPT_ENGINE); return SCRIPT_ENGINE_ERROR; } fprintf(scriptdb, "Entry{ category = \"%s\", filename = \"%s\" }\n", lua_tostring(l, -1), filename); free(filename); lua_pop(l, 1); } lua_pop(l, 1); // pop the categories table } free(c_iter); } lua_pop(l, 1); // pop the closure if(fclose(scriptdb) != 0) { error("%s: Could not close %s: %s", SCRIPT_ENGINE, path, strerror(errno)); return SCRIPT_ENGINE_ERROR; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?