nse_init.cc
来自「Ubuntu packages of security software。 相」· CC 代码 · 共 816 行 · 第 1/2 页
CC
816 行
return SCRIPT_ENGINE_SUCCESS;}int init_loadcategories(lua_State* l, std::vector<std::string> categories, std::vector<std::string> &unusedTags) { std::vector<std::string>::iterator iter; std::vector<std::string> files; std::string dbpath = std::string(SCRIPT_ENGINE_LUA_DIR) + std::string(SCRIPT_ENGINE_DATABASE); char* c_dbpath_buf; char c_dbpath[MAX_FILENAME_LEN]; const char* stub = "\files = {}\n\Entry = function(e)\n\ if (categories[e.category] ~= nil) then\n\ categories[e.category] = categories[e.category] + 1\n\ files[e.filename] = true\n\ end\n\ if (categories[\"all\"] ~= nil and e.category ~= \"version\") then\n\ categories[\"all\"] = categories[\"all\"] + 1\n\ files[e.filename] = true\n\ end\n\end\n"; int categories_usage; char* c_iter; char script_path[MAX_FILENAME_LEN]; int type; // closure lua_newtable(l); // categories table lua_newtable(l); for(iter = categories.begin(); iter != categories.end(); iter++) { lua_pushinteger(l, 0); lua_setfield(l, -2, (*iter).c_str()); } lua_setfield(l, -2, "categories"); // we load the stub // the strlen is safe in this case because the stub is a constant string SCRIPT_ENGINE_LUA_TRY(luaL_loadbuffer(l, stub, strlen(stub), "Database Stub")); lua_pushvalue(l, -2); lua_setfenv(l, -2); SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0)); // if we can't find the database we try to create it c_dbpath_buf = strdup(dbpath.c_str()); if(nmap_fetchfile(c_dbpath, sizeof(c_dbpath), c_dbpath_buf) == 0) { SCRIPT_ENGINE_TRY(init_updatedb(l)); } free(c_dbpath_buf); SCRIPT_ENGINE_LUA_TRY(luaL_loadfile(l, c_dbpath)); lua_pushvalue(l, -2); lua_setfenv(l, -2); SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0)); // retrieve the filenames produced by the stub lua_getfield(l, -1, "files"); lua_pushnil(l); while(lua_next(l, -2) != 0) { if(lua_isstring(l, -2)) files.push_back(std::string(lua_tostring(l, -2))); else { error("%s: One of the filenames in '%s' is not a string?!", SCRIPT_ENGINE, SCRIPT_ENGINE_DATABASE); return SCRIPT_ENGINE_ERROR; } lua_pop(l, 1); } lua_pop(l, 1); // find out which categories didn't produce any filenames lua_getfield(l, -1, "categories"); lua_pushnil(l); while(lua_next(l, -2) != 0) { categories_usage = lua_tointeger(l, -1); if(categories_usage == 0) { unusedTags.push_back(std::string(lua_tostring(l, -2))); } lua_pop(l, 1); } lua_pop(l, 2); // load all the files we have found for the given categories for(iter = files.begin(); iter != files.end(); iter++) { c_iter = strdup((*iter).c_str()); type = init_fetchfile(script_path, sizeof(script_path), c_iter); if(type != 1) { error("%s: %s is not a file.", SCRIPT_ENGINE, c_iter); return SCRIPT_ENGINE_ERROR; } free(c_iter); SCRIPT_ENGINE_TRY(init_loadfile(l, script_path)); } return SCRIPT_ENGINE_SUCCESS;}int init_fetchfile(char *path, size_t path_len, char* file) { int type; type = nmap_fetchfile(path, path_len, file); // lets look in <nmap>/scripts too if(type == 0) { char* alt_path = strdup((std::string(SCRIPT_ENGINE_LUA_DIR) + std::string(file)).c_str()); type = nmap_fetchfile(path, path_len, alt_path); free(alt_path); } return type;}static bool filename_is_absolute(const char *file) { if (file[0] == '/') return true;#ifdef WIN32 if ((file[0] != '\0' && file[1] == ':') || file[0] == '\\') return true;#endif return false;}/* This is a modification of init_fetchfile that first looks for an * absolute file name. */int init_fetchfile_absolute(char *path, size_t path_len, char *file) { if (filename_is_absolute(file)) { if (o.debugging > 1) log_write(LOG_STDOUT, "%s: Trying absolute path %s\n", SCRIPT_ENGINE, file); Strncpy(path, file, path_len); return nmap_fileexistsandisreadable(file); } return init_fetchfile(path, path_len, file);}/* This is simply the most portable way to check * if a file has a given extension. * The portability comes at the price of reduced * flexibility. */int check_extension(const char* ext, const char* path) { int pathlen = strlen(path); int extlen = strlen(ext); const char* offset; if( extlen > pathlen || pathlen > MAX_FILENAME_LEN) return -1; offset = path + pathlen - extlen; if(strcmp(offset, ext) != MATCH) return 1; else return MATCH;}int init_loaddir(lua_State* l, char* dirname) { std::vector<std::string> files; char* c_iter; SCRIPT_ENGINE_TRY(init_scandir(dirname, files, FILES)); std::vector<std::string>::iterator iter; for(iter = files.begin(); iter != files.end(); iter++) { c_iter = strdup((*iter).c_str()); SCRIPT_ENGINE_TRY(init_loadfile(l, c_iter)); free(c_iter); } return SCRIPT_ENGINE_SUCCESS;}#ifdef WIN32int init_scandir(char* dirname, std::vector<std::string>& result, int files_or_dirs) { HANDLE dir; WIN32_FIND_DATA entry; std::string path; BOOL morefiles = FALSE; dir = FindFirstFile((std::string(dirname) + "\\*").c_str(), &entry); if (dir == INVALID_HANDLE_VALUE) { error("%s: No files in '%s\\*'", SCRIPT_ENGINE, dirname); return SCRIPT_ENGINE_ERROR; } while(!(morefiles == FALSE && GetLastError() == ERROR_NO_MORE_FILES)) { // if we are looking for files and this file doesn't end with .nse or // is a directory, then we don't look further at it if(files_or_dirs == FILES) { if(!( (check_extension(SCRIPT_ENGINE_EXTENSION, entry.cFileName) == MATCH) && !(entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )) { morefiles = FindNextFile(dir, &entry); continue; } // if we are looking for dirs and this dir // isn't a directory, then we don't look further at it } else if(files_or_dirs == DIRS) { if(!( (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )) { morefiles = FindNextFile(dir, &entry); continue; } // they have passed an invalid value for files_or_dirs } else { fatal("%s: In: %s:%i This should never happen.", SCRIPT_ENGINE, __FILE__, __LINE__); } // otherwise we add it to the results // we assume that dirname ends with a directory separator of some kind path = std::string(dirname) + "\\" + std::string(entry.cFileName); result.push_back(path); morefiles = FindNextFile(dir, &entry); } return SCRIPT_ENGINE_SUCCESS;}#elseint init_scandir(char* dirname, std::vector<std::string>& result, int files_or_dirs) { DIR* dir; struct dirent* entry; std::string path; struct stat stat_entry; dir = opendir(dirname); if(dir == NULL) { error("%s: Could not open directory '%s'.", SCRIPT_ENGINE, dirname); return SCRIPT_ENGINE_ERROR; } // note that if there is a symlink in the dir, we have to rely on // the .nse extension // if they provide a symlink to a dir which ends with .nse, things // break :/ while((entry = readdir(dir)) != NULL) { path = std::string(dirname) + "/" + std::string(entry->d_name); if(stat(path.c_str(), &stat_entry) != 0) fatal("%s: In: %s:%i This should never happen.", SCRIPT_ENGINE, __FILE__, __LINE__); // if we are looking for files and this file doesn't end with .nse and // isn't a file or a link, then we don't look further at it if(files_or_dirs == FILES) { if(!( (check_extension(SCRIPT_ENGINE_EXTENSION, entry->d_name) == MATCH) && (S_ISREG(stat_entry.st_mode) || S_ISLNK(stat_entry.st_mode)) )) { continue; } // if we are looking for dirs and this dir // isn't a dir or a link, then we don't look further at it } else if(files_or_dirs == DIRS) { if(!( (S_ISDIR(stat_entry.st_mode) || S_ISLNK(stat_entry.st_mode)) )) { continue; } // they have passed an invalid value for files_or_dirs } else { fatal("%s: In: %s:%i This should never happen.", SCRIPT_ENGINE, __FILE__, __LINE__); } // otherwise we add it to the results result.push_back(path); } closedir(dir); return SCRIPT_ENGINE_SUCCESS;}#endif/* load an nmap-lua script * create a new closure to store the script * tell the closure where to find the standard * lua libs and the nmap bindings * we do some error checking to make sure that * the script is well formed * the script is then added to either the hostrules * or the portrules * */int init_loadfile(lua_State* l, char* filename) { int rule_count; /* create a closure for encapsuled execution * give the closure access to the global enviroment */ lua_newtable(l); /* tell the script about its filename */ lua_pushstring(l, filename); lua_setfield(l, -2, "filename"); /* we give the script access to the global name space * */ lua_newtable(l); lua_getglobal(l, "_G"); lua_setfield(l, -2, "__index"); lua_setmetatable(l, -2); /* load the *.nse file, set the closure and execute (init) the test * */ SCRIPT_ENGINE_LUA_TRY(luaL_loadfile(l, filename)); lua_pushvalue(l, -2); lua_setfenv(l, -2); SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0)); /* look at the runlevel, if it is not set, we set it to 1.0 * */ lua_getfield(l, -1, RUNLEVEL); if(lua_isnil(l, -1)) { lua_pushnumber(l, 1.0); lua_setfield(l, -3, RUNLEVEL); } lua_pop(l, 1); /* finally we make sure nobody tampers with the global name space any more * and prepare for runlevel sorting * */ lua_getmetatable(l, -1); std::string buf = (std::string("err = \"Attempted to change the global '\" .. select(2, ...) .. \"' in ") + std::string(filename) + std::string(" - use nmap.registry if you really want to share data between scripts.\"") + std::string("error(err)")); SCRIPT_ENGINE_LUA_TRY(luaL_loadbuffer(l, buf.c_str(), buf.length(), "Global Access")); lua_setfield(l, -2, "__newindex"); lua_setmetatable(l, -2); /* store the initialized test in either * the hosttests or the porttests * */ lua_getfield(l, -1, PORTRULE); lua_getfield(l, -2, HOSTRULE); /* if we are looking at a portrule then store it in the porttestsets table * if it is a hostrule, then it goes into the hosttestsets table * otherwise we fail * if there is no action in the script we also fail * */ if(lua_isnil(l, -2) == 0) { lua_pop(l, 2); lua_getglobal(l, PORTTESTS); rule_count = lua_objlen(l, -1); lua_pushvalue(l, -2); lua_rawseti(l, -2, (rule_count + 1)); lua_pop(l, 1); // pop the porttests table } else if(lua_isnil(l, -1) == 0) { lua_pop(l, 2); lua_getglobal(l, HOSTTESTS); rule_count = lua_objlen(l, -1); lua_pushvalue(l, -2); lua_rawseti(l, -2, (rule_count + 1)); lua_pop(l, 1); // pop the hosttests table } else { error("%s: No rules in script '%s'.", SCRIPT_ENGINE, filename); return SCRIPT_ENGINE_ERROR; } std::vector<std::string> required_fields; required_fields.push_back(std::string(ACTION)); required_fields.push_back(std::string(DESCRIPTION)); std::vector<std::string>::iterator iter; for(iter = required_fields.begin(); iter != required_fields.end(); iter++) { lua_getfield(l, -1, (*iter).c_str()); if(lua_isnil(l, -1) == 1) { error("%s: No '%s' field in script '%s'.", SCRIPT_ENGINE, (*iter).c_str(), filename); return SCRIPT_ENGINE_ERROR; } lua_pop(l, 1); // pop the action } lua_pop(l, 1); // pop the closure return SCRIPT_ENGINE_SUCCESS;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?