nse_main.cc
来自「Ubuntu packages of security software。 相」· CC 代码 · 共 680 行 · 第 1/2 页
CC
680 行
return SCRIPT_ENGINE_SUCCESS;}// If the target still has scripts in either running_scripts// or waiting_scripts then it is still runningint has_target_finished(Target *target) { std::list<struct thread_record>::iterator iter; for (iter = waiting_scripts.begin(); iter != waiting_scripts.end(); iter++) if (target == iter->rr->host) return 0; for (iter = running_scripts.begin(); iter != running_scripts.end(); iter++) if (target == iter->rr->host) return 0; return 1;}int process_finalize(lua_State* l, unsigned int registry_idx) { luaL_unref(l, LUA_REGISTRYINDEX, registry_idx); struct thread_record thr = running_scripts.front(); running_scripts.pop_front(); if (has_target_finished(thr.rr->host)) thr.rr->host->stopTimeOutClock(NULL); return SCRIPT_ENGINE_SUCCESS;}int process_waiting2running(lua_State* l, int resume_arguments) { std::list<struct thread_record>::iterator iter; // find the lua state which has received i/o for( iter = waiting_scripts.begin(); (*iter).thread != l; iter++) { // It is very unlikely that a thread which // is not in the waiting queue tries to // continue // it does happen when they try to do socket i/o // inside a pcall // This also happens when we timeout a script // In this case, the script is still in the waiting // queue and we will have manually removed it from // the waiting queue so we just return. if(iter == waiting_scripts.end()) return SCRIPT_ENGINE_SUCCESS; } (*iter).resume_arguments = resume_arguments; // put the thread back into the running // queue running_scripts.push_front((*iter)); waiting_scripts.erase(iter); return SCRIPT_ENGINE_SUCCESS;}/* Tries to get the script id and store it in the script scan result structure * if no 'id' field is found, the filename field is used which we set in the * setup phase. If someone changed the filename field to a nonstring we complain * */int process_getScriptId(lua_State* l, struct script_scan_result *ssr) { lua_getfield(l, -2, "id"); lua_getfield(l, -3, "filename"); if(lua_isstring(l, -2)) { ssr->id = strdup(lua_tostring (l, -2)); } else if(lua_isstring(l, -1)) { ssr->id = strdup(lua_tostring (l, -1)); } else { error("%s: The script has no 'id' entry, the 'filename' entry was changed to:", SCRIPT_ENGINE); l_dumpValue(l, -1); return SCRIPT_ENGINE_ERROR; } lua_pop(l, 2); return SCRIPT_ENGINE_SUCCESS;}/* try all host and all port rules against the * state of the current target * make a list with run records for the scripts * which want to run * process all scripts in the list * */int process_preparehost(lua_State* l, Target* target, std::list<struct thread_record>& torun_threads) { PortList* plist = &(target->ports); Port* current = NULL; size_t rules_count; unsigned int i; std::vector<run_record> torun; std::vector<run_record>::iterator iter; struct run_record rr; if (!target->timeOutClockRunning()) target->startTimeOutClock(NULL); /* find the matching hostrules * */ lua_getglobal(l, HOSTTESTS); rules_count = lua_objlen(l, -1); for(i = 1; i <= rules_count; i++) { lua_rawgeti(l, -1, i); lua_getfield(l, -1, "hostrule"); lua_newtable(l); set_hostinfo(l, target); SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 1, 1, 0)); if(lua_isboolean (l, -1) && lua_toboolean(l, -1)) { rr.type = 0; rr.index = i; rr.port = NULL; rr.host = target; torun.push_back(rr); SCRIPT_ENGINE_DEBUGGING( lua_getfield(l, -2, "filename"); log_write(LOG_STDOUT, "%s: Will run %s against %s\n", SCRIPT_ENGINE, lua_tostring(l, -1), target->targetipstr()); lua_pop(l, 1); ) } lua_pop(l, 2); } /* find the matching port rules * */ lua_getglobal(l, PORTTESTS); /* we only publish hostinfo once per portrule */ lua_newtable(l); set_hostinfo(l, target); /* because of the port iteration API we need to awkwardly iterate * over the kinds of ports we're interested in explictely. * */ current = NULL; while((current = plist->nextPort(current, TCPANDUDP, PORT_OPEN)) != NULL) { SCRIPT_ENGINE_TRY(process_pickScriptsForPort(l, target, current, torun)); } while((current = plist->nextPort(current, TCPANDUDP, PORT_OPENFILTERED)) != NULL) { SCRIPT_ENGINE_TRY(process_pickScriptsForPort(l, target, current, torun)); } // pop the hostinfo, we don't need it anymore lua_pop(l, 1); /* ok, let's setup threads for the scripts which said they'd like * to run * Remember: * we have the hosttestset and the porttestset on the stack! * */ struct thread_record tr; for(iter = torun.begin(); iter != torun.end(); iter++) { /* If it is a host rule, execute the action * and append the output to the host output i * If it is a port rule, append the output to * the port and increase the number of scripts * which produced output. We need that number * to generate beautiful output later. * */ switch((*iter).type) { case 0: // this script runs against a host lua_pushvalue(l, -2); SCRIPT_ENGINE_TRY(process_preparethread(l, (*iter), &tr)); lua_pop(l, 1); break; case 1: // this script runs against a port lua_pushvalue(l, -1); SCRIPT_ENGINE_TRY(process_preparethread(l, (*iter), &tr)); lua_pop(l, 1); break; default: fatal("%s: In: %s:%i This should never happen.", SCRIPT_ENGINE, __FILE__, __LINE__); } torun_threads.push_back(tr); } lua_pop(l, 2); torun.clear(); return SCRIPT_ENGINE_SUCCESS;}int process_preparerunlevels(std::list<struct thread_record> torun_threads) { std::list<struct thread_record> current_runlevel; std::list<struct thread_record>::iterator runlevel_iter; double runlevel_idx = 0.0; torun_threads.sort(CompareRunlevels()); for( runlevel_iter = torun_threads.begin(); runlevel_iter != torun_threads.end(); runlevel_iter++) { if(runlevel_idx < (*runlevel_iter).runlevel) { runlevel_idx = (*runlevel_iter).runlevel; current_runlevel.clear(); //push_back an empty list in which we store all scripts of the //current runlevel... torun_scripts.push_back(current_runlevel); } torun_scripts.back().push_back(*runlevel_iter); } return SCRIPT_ENGINE_SUCCESS;}/* Because we can't iterate over all ports of interest in one go * we need to du port matching in a separate function (unlike host * rule matching) * Note that we assume that at -2 on the stack we can find the portrules * and at -1 the hostinfo table * */int process_pickScriptsForPort( lua_State* l, Target* target, Port* port, std::vector<run_record>& torun) { size_t rules_count = lua_objlen(l, -2); struct run_record rr; unsigned int i; for(i = 1; i <= rules_count; i++) { lua_rawgeti(l, -2, i); lua_getfield(l, -1, PORTRULE); lua_pushvalue(l, -3); lua_newtable(l); set_portinfo(l, port); SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 2, 1, 0)); if(lua_isboolean (l, -1) && lua_toboolean(l, -1)) { rr.type = 1; rr.index = i; rr.port = port; rr.host = target; torun.push_back(rr); SCRIPT_ENGINE_DEBUGGING( lua_getfield(l, -2, "filename"); log_write(LOG_STDOUT, "%s: Will run %s against %s:%d\n", SCRIPT_ENGINE, lua_tostring(l, -1), target->targetipstr(), port->portno); lua_pop(l, 1); ) } else if(!lua_isboolean (l, -1)) { lua_getfield(l, -2, "filename"); error("%s: Rule in %s returned %s but boolean was expected.", SCRIPT_ENGINE, lua_tostring(l, -1), lua_typename(l, lua_type(l, -2))); return SCRIPT_ENGINE_LUA_ERROR; } lua_pop(l, 2); } return SCRIPT_ENGINE_SUCCESS;}/* Create a new lua thread and prepare it for execution * we store target info in the thread so that the mainloop * knows where to put the script result * */int process_preparethread(lua_State* l, struct run_record rr, struct thread_record* tr){ lua_State *thread = lua_newthread(l); lua_rawgeti(l, -2, rr.index); // get the script closure // move the script closure into the thread lua_xmove(l, thread, 1); // store the target of this thread in the thread struct run_record *rr_thread = (struct run_record*) safe_malloc(sizeof(struct run_record)); rr_thread->type = rr.type; rr_thread->index = rr.index; rr_thread->host = rr.host; rr_thread->port = rr.port; lua_getfield(thread, -1, RUNLEVEL); tr->runlevel = lua_tonumber(thread, -1); lua_pop(thread, 1); // prepare the thread for a resume by // pushing the action method onto the stack lua_getfield(thread, -1, ACTION); // make the info table lua_newtable(thread); set_hostinfo(thread, rr.host); tr->thread = thread; tr->rr = rr_thread; tr->resume_arguments = 1; // we store the thread in the registry to prevent // garbage collection + tr->registry_idx = luaL_ref(l, LUA_REGISTRYINDEX); /* if this is a host rule we don't have * a port state * */ if(rr.port != NULL) { lua_newtable(thread); set_portinfo(thread, rr.port); tr->resume_arguments = 2; } return SCRIPT_ENGINE_SUCCESS;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?