nse_nsock.cc
来自「Ubuntu packages of security software。 相」· CC 代码 · 共 1,410 行 · 第 1/3 页
CC
1,410 行
inet_ntop_both(af, &local, ipstring_local), inet_port_both(af, &local), (direction == TO)? ">" : "<", inet_ntop_both(af, &remote, ipstring_remote), inet_port_both(af, &remote), message); free(ipstring_local); free(ipstring_remote); }else{ // is pcap device log_write(LOG_STDOUT, "SCRIPT ENGINE: %s | %s\n", (direction == TO)? ">" : "<", message); }}char* inet_ntop_both(int af, const void* v_addr, char* ipstring) {// char* ipstring = (char*) safe_malloc(sizeof(char) * INET6_ADDRSTRLEN); if(af == AF_INET) { inet_ntop(AF_INET, &((struct sockaddr_in*) v_addr)->sin_addr, ipstring, INET6_ADDRSTRLEN); return ipstring; } #ifdef HAVE_IPV6 else if(af == AF_INET6) { inet_ntop(AF_INET6, &((struct sockaddr_in6*) v_addr)->sin6_addr, ipstring, INET6_ADDRSTRLEN); return ipstring; } #endif else { return "unknown protocol"; }}unsigned short inet_port_both(int af, const void* v_addr) { int port; if(af == AF_INET) { port = ((struct sockaddr_in*) v_addr)->sin_port; }#ifdef HAVE_IPV6 else if(af == AF_INET6) { port = ((struct sockaddr_in6*) v_addr)->sin6_port; }#endif else { port = 0; } return ntohs(port);}static int l_nsock_get_info(lua_State* l) { l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1); int status; int protocol; // tcp or udp int af; // address family struct sockaddr local; struct sockaddr remote; char* ipstring_local = (char*) safe_malloc(sizeof(char) * INET6_ADDRSTRLEN); char* ipstring_remote = (char*) safe_malloc(sizeof(char) * INET6_ADDRSTRLEN); if(udata->nsiod == NULL) { lua_pushboolean(l, false); lua_pushstring(l, "Trying to get info from a closed socket\n"); return 2; } status = nsi_getlastcommunicationinfo(udata->nsiod, &protocol, &af, &local, &remote, sizeof(sockaddr)); lua_pushboolean(l, true); lua_pushstring(l, inet_ntop_both(af, &local, ipstring_local)); lua_pushnumber(l, inet_port_both(af, &local)); lua_pushstring(l, inet_ntop_both(af, &remote, ipstring_remote)); lua_pushnumber(l, inet_port_both(af, &remote)); free(ipstring_local); free(ipstring_remote); return 5;}static int l_nsock_gc(lua_State* l){ l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1); if(udata->nsiod == NULL) { //socket obviously got closed already - so no finalization needed return 0; }else{ //FIXME - check wheter close returned true!! l_nsock_close(l); } return 0;}static int l_nsock_close(lua_State* l) { l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1); /* Never ever collect nse-pcap connections. */ if(udata->ncap_socket){ return 0; } l_nsock_clear_buf(l, udata); if(udata->nsiod == NULL) { lua_pushboolean(l, false); lua_pushstring(l, "Trying to close a closed socket\n"); return 2; } if(o.scriptTrace()) { l_nsock_trace(udata->nsiod, "CLOSE", TO); }#ifdef HAVE_OPENSSL if (udata->ssl_session) SSL_SESSION_free((SSL_SESSION*)udata->ssl_session); udata->ssl_session=NULL;#endif nsi_delete(udata->nsiod, NSOCK_PENDING_NOTIFY); nsock_descriptors_used--; /* handle threads that are waiting for free sockets*/ if(nsock_connect_queue.size()){ lua_State *nl = nsock_connect_queue.front(); nsock_connect_queue.pop_front(); /* we can't restore lua thread here. instead create timer event with * short timeout 0, and restore thread there*/ nsock_timer_create(nsp, l_nsock_connect_queued_handler, 0, (void*) nl); } udata->nsiod = NULL; lua_pushboolean(l, true); return 1;}static int l_nsock_set_timeout(lua_State* l) { l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1); int timeout = (unsigned short) luaL_checkint(l, 2); udata->timeout = timeout; return 0;}/* buffered I/O */static int l_nsock_receive_buf(lua_State* l) { l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1); if(lua_gettop(l)==2){ /*we were called with 2 arguments only - push the default third one*/ lua_pushboolean(l,true); } if(udata->nsiod == NULL) { lua_pushboolean(l, false); lua_pushstring(l, "Trying to receive through a closed socket\n"); return 2; } if(udata->bufused==0){ lua_pushstring(l,""); udata->bufidx = luaL_ref(l, LUA_REGISTRYINDEX); udata->bufused=1; nsock_read(nsp, udata->nsiod, l_nsock_receive_buf_handler, udata->timeout, l); }else if(udata->bufused==-1){ /*error message is inside the buffer*/ lua_pushboolean(l,false); lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); return 2; }else{ /*buffer contains already some data */ /*we keep track here of how many calls to receive_buf are made */ udata->bufused++; if(l_nsock_check_buf(l)==NSOCK_WRAPPER_BUFFER_MOREREAD){ /*if we didn't have enough data in the buffer another nsock_read() * was scheduled - its callback will put us in running state again */ return lua_yield(l,3); } return 2; } /*yielding with 3 arguments since we need them when the callback arrives */ return lua_yield(l, 3);}void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_state) { lua_State* l = (lua_State*) lua_state; char* rcvd_string; int rcvd_len = 0; char* hexified; int tmpidx; l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1); if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) { //l_nsock_checkstatus pushes true on the stack in case of success // we do this on our own here lua_pop(l,1); rcvd_string = nse_readbuf(nse, &rcvd_len); if(o.scriptTrace()) { hexified = nse_hexify((const void*) rcvd_string, (size_t) rcvd_len); l_nsock_trace(nse_iod(nse), hexified, FROM); free(hexified); } /* push the buffer and what we received from nsock on the stack and * concatenate both*/ lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); lua_pushlstring(l, rcvd_string, rcvd_len); lua_concat (l, 2); luaL_unref(l, LUA_REGISTRYINDEX, udata->bufidx); udata->bufidx = luaL_ref(l, LUA_REGISTRYINDEX); if(l_nsock_check_buf(l)==NSOCK_WRAPPER_BUFFER_MOREREAD){ /*if there wasn't enough data in the buffer and we've issued another * nsock_read() the next callback will schedule the script for running */ return; } process_waiting2running((lua_State*) lua_state, 2); } else { if(udata->bufused>1){ /*error occured after we read into some data into the buffer * behave as if there was no error and push the rest of the buffer * and clean the buffer afterwards */ /*save the error message inside the buffer*/ tmpidx=luaL_ref(l, LUA_REGISTRYINDEX); /*pop the status (==false) of the stack*/ lua_pop(l,1); lua_pushboolean(l, true); lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); l_nsock_clear_buf(l, udata); udata->bufidx=tmpidx; udata->bufused=-1; process_waiting2running((lua_State*) lua_state, 2); }else{ /*buffer should be empty */ process_waiting2running((lua_State*) lua_state, 2); } }}int l_nsock_check_buf(lua_State* l ){ l_nsock_udata* udata; size_t startpos, endpos, bufsize; const char *tmpbuf; int tmpidx; int keeppattern; /*should we return the string including the pattern or without it */ keeppattern= lua_toboolean(l,-1); lua_pop(l,1); udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1); if(lua_isfunction(l,2)){ lua_pushvalue(l,2); lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); /* the buffer is the only argument to the function */ if(lua_pcall(l,1,2,0)!=0){ lua_pushboolean(l,false); lua_pushfstring(l,"Error inside splitting-function: %s\n", lua_tostring(l,-1)); return NSOCK_WRAPPER_BUFFER_OK; //luaL_error(l,"Error inside splitting-function, given as argument to nsockobj:receive_buf: %s\n", lua_tostring(l,-1)); } }else if(lua_isstring(l,2)){ lua_getglobal(l,"string"); lua_getfield(l,-1,"find"); lua_remove(l, -2); /*drop the string-table, since we don't need it! */ lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); lua_pushvalue(l,2); /*the pattern we are searching for */ if(lua_pcall(l,2,2,0)!=0){ lua_pushboolean(l,false); lua_pushstring(l,"Error in string.find (nsockobj:receive_buf)!"); return NSOCK_WRAPPER_BUFFER_OK; } }else{ lua_pushboolean(l,false); lua_pushstring(l,"Expected either a function or a string!"); return NSOCK_WRAPPER_BUFFER_OK; //luaL_argerror(l,2,"expected either a function or a string!"); } /*the stack contains on top the indices where we want to seperate */ if(lua_isnil(l,-1)){ /*not found anything try to read more data*/ lua_pop(l,2); nsock_read(nsp, udata->nsiod, l_nsock_receive_buf_handler, udata->timeout, l); lua_pushboolean(l,keeppattern); return NSOCK_WRAPPER_BUFFER_MOREREAD; }else{ startpos = (size_t) lua_tointeger(l, -2); endpos = (size_t) lua_tointeger(l, -1); lua_settop(l,0); /* clear the stack for returning */ if(startpos>endpos){ lua_pushboolean(l,false); lua_pushstring(l,"Delimiter has negative size!"); return NSOCK_WRAPPER_BUFFER_OK; }else if(startpos==endpos){ /* if the delimter has a size of zero we keep it, since otherwise * retured string would be trucated */ keeppattern=1; } lua_settop(l,0); /* clear the stack for returning */ lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); tmpbuf = lua_tolstring(l, -1, &bufsize); lua_pop(l,1); /* pop the buffer off the stack, should be safe since it it is still in the registry */ if(tmpbuf==NULL){ fatal("%s: In: %s:%i The buffer is not a string?! - please report this to nmap-dev@insecure.org.", SCRIPT_ENGINE, __FILE__, __LINE__); } /*first push the remains of the buffer */ lua_pushlstring(l,tmpbuf+endpos,(bufsize-endpos)); tmpidx = luaL_ref(l,LUA_REGISTRYINDEX); lua_pushboolean(l,true); if(keeppattern){ lua_pushlstring(l,tmpbuf,endpos); }else{ lua_pushlstring(l,tmpbuf,startpos-1); } luaL_unref(l,LUA_REGISTRYINDEX,udata->bufidx); udata->bufidx=tmpidx; //l_dumpStack(l); return NSOCK_WRAPPER_BUFFER_OK; } assert(0); return 1;//unreachable}void l_nsock_clear_buf(lua_State* l, l_nsock_udata* udata){ luaL_unref (l, LUA_REGISTRYINDEX, udata->bufidx); udata->bufidx=LUA_NOREF; udata->bufused=0;}/****************** NCAP_SOCKET ***********************************************/ #ifdef WIN32/* From tcpip.cc. Gets pcap device name from dnet name. */bool DnetName2PcapName(const char *dnetdev, char *pcapdev, int pcapdevlen);#endif/* fuckin' C++ maps stuff *//* here we store ncap_sockets */std::map<std::string, struct ncap_socket*> ncap_socket_map;/* receive sthing from socket_map */struct ncap_socket *ncap_socket_map_get(char *key){ std::string skey = key; return ncap_socket_map[skey];}/* set sthing on socket_map */void ncap_socket_map_set(char *key, struct ncap_socket *ns){ std::string skey = key; ncap_socket_map[skey] = ns; return;}/* receive sthing from socket_map */void ncap_socket_map_del(char *key){ std::string skey = key; ncap_socket_map.erase(skey); return;}/* (static) Dnet-like device name to Pcap-like name */char *dnet_to_pcap_device_name(const char *device){ static char pcapdev[128]; if( strcmp(device, "any") == 0 ) return strncpy(pcapdev, "any", sizeof(pcapdev)); #ifdef WIN32 /* Nmap normally uses device names obtained through dnet for interfaces, * but Pcap has its own naming system. So the conversion is done here */ if (!DnetName2PcapName(device, pcapdev, sizeof(pcapdev))) { /* Oh crap -- couldn't find the corresponding dev apparently. * Let's just go with what we have then ... */ strncpy(pcapdev, device, sizeof(pcapdev)); } #else strncpy(pcapdev, device, sizeof(pcapdev)); #endif return pcapdev;}/* (LUA) Open nsock-pcap socket. * 1) device - dnet-style network interface name, or "any" * 2) snaplen - maximum number of bytes to be captured for packet * 3) promisc - should we set network car in promiscuous mode (0/1) * 4) callback- callback function, that will create hash string from packet * 5) bpf - berkeley packet filter, see tcpdump(8) * */ static int l_nsock_ncap_open(lua_State* l){ l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1); const char* device = luaL_checkstring(l, 2); int snaplen = luaL_checkint(l, 3); int promisc = luaL_checkint(l, 4); luaL_checktype(l, 5, LUA_TFUNCTION); /* callback function that creates hash */ const char* bpf = luaL_checkstring(l, 6); if(udata->nsiod || udata->ncap_request || udata->ncap_socket) { luaL_argerror(l, 1, "Trying to open nsock-pcap, but this connection is already opened"); return 0; } char *pcapdev = dnet_to_pcap_device_name(device); if(!strlen(device) || !strlen(pcapdev)) { luaL_argerror(l, 1, "Trying to open nsock-pcap, but you're passing empty or wrong device name."); return 0; } lua_pop(l, 1); // pop bpf /* take func from top of stack and store it in the Registry */ int hash_func_ref = luaL_ref(l, LUA_REGISTRYINDEX); /* push function on the registry-stack */ lua_rawgeti(l, LUA_REGISTRYINDEX, hash_func_ref); struct ncap_socket *ns; /* create key */ char key[8192]; Snprintf(key, sizeof(key), "%s|%i|%i|%u|%s", pcapdev, snaplen, promisc, (unsigned int)strlen(bpf), bpf); ns = ncap_socket_map_get(key); if(ns == NULL){ ns = (struct ncap_socket*)safe_zalloc(sizeof(struct ncap_socket)); ns->nsiod = nsi_new(nsp, ns); ns->key = strdup(key); /* error messages are passed here */ char *emsg = nsock_pcap_open(nsp, ns->nsiod, pcapdev, snaplen, promisc, bpf); if(emsg){ luaL_argerror(l, 1, emsg); return 0; } ncap_socket_map_set(key, ns); } ns->references++; udata->nsiod = ns->nsiod; udata->ncap_socket = ns; udata->ncap_cback_ref = hash_func_ref; return 0;}/* (LUA) Close nsock-pcap socket. * */ static int l_nsock_ncap_close(lua_State* l){ l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1); struct ncap_socket *ns = udata->ncap_socket; if(!udata->nsiod || !udata->ncap_socket) { luaL_argerror(l, 1, "Trying to close nsock-pcap, but it was never opened."); return 0; } if(udata->ncap_request) { luaL_argerror(l, 1, "Trying to close nsock-pcap, but it has active event."); return 0; } assert(ns->references > 0); ns->references--; if(ns->references == 0){ ncap_socket_map_del(ns->key); if(ns->key) free(ns->key); nsi_delete(ns->nsiod, NSOCK_PENDING_NOTIFY); free(ns); } udata->nsiod = NULL; udata->ncap_socket = NULL; lua_unref(l, udata->ncap_cback_ref);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?