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 + -
显示快捷键?