diff --git a/nfq2/darkmagic.c b/nfq2/darkmagic.c index 03f4de8..ca93329 100644 --- a/nfq2/darkmagic.c +++ b/nfq2/darkmagic.c @@ -557,6 +557,8 @@ uint8_t ttl46(const struct ip *ip, const struct ip6_hdr *ip6) } + + #ifdef __CYGWIN__ uint32_t w_win32_error=0; @@ -644,7 +646,6 @@ BOOL SetMandatoryLabelFile(LPCSTR lpFileName, DWORD dwMandatoryLabelRID, DWORD d dwFileAttributes = GetFileAttributesW(lpFileNameW); if (dwFileAttributes == INVALID_FILE_ATTRIBUTES) goto err; } - InitializeSid(label, &label_authority, 1); *GetSidSubAuthority(label, 0) = dwMandatoryLabelRID; if (InitializeAcl(pacl, sizeof(buf_pacl), ACL_REVISION) && AddMandatoryAce(pacl, (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? ACL_REVISION_DS : ACL_REVISION, dwAceFlags, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, label)) @@ -692,7 +693,12 @@ bool ensure_file_access(const char *filename) { return SetMandatoryLabelFile(filename, SECURITY_MANDATORY_LOW_RID, 0); } -static bool prepare_low_appdata() +bool ensure_dir_access(const char *dir) +{ + return SetMandatoryLabelFile(dir, SECURITY_MANDATORY_LOW_RID, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE); +} + +bool prepare_low_appdata() { bool b = false; PWSTR pszPath = NULL; @@ -707,20 +713,6 @@ static bool prepare_low_appdata() { b = true; setenv("APPDATALOW", buf, 1); - memcpy(buf+l-1,"/zapret2",9); - setenv("WRITEABLE", buf, 1); - mkdir(buf,0755); - - l = wcslen(pszPath); - PWSTR pszPath2 = malloc((l+9)*sizeof(WCHAR)); - if (pszPath2) - { - memcpy(pszPath2,pszPath,l*sizeof(WCHAR)); - memcpy(pszPath2+l,L"\\zapret2",9*sizeof(WCHAR)); - // ensure it's low and everything created inside is also low - SetMandatoryLabelFileW(pszPath2, SECURITY_MANDATORY_LOW_RID, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE); - free(pszPath2); - } } free(buf); } @@ -729,6 +721,7 @@ static bool prepare_low_appdata() return b; } + #define WINDIVERT_DEVICE_NAME "WinDivert" static bool b_isandbox_set = false; bool win_sandbox(void) @@ -742,7 +735,6 @@ bool win_sandbox(void) // set low mandatory label on windivert device to allow administrators with low label access the driver if (logical_net_filter_present() && !SetMandatoryLabelFile("\\\\.\\" WINDIVERT_DEVICE_NAME, SECURITY_MANDATORY_LOW_RID, 0)) return FALSE; - prepare_low_appdata(); if (!LowMandatoryLevel()) return false; // for LUA code to find where to store files @@ -1896,3 +1888,54 @@ bool set_socket_buffers(int fd, int rcvbuf, int sndbuf) dbgprint_socket_buffers(fd); return true; } + +bool make_writeable_dir() +{ + char wdir[PATH_MAX], *wrdir; + if (*params.writeable_dir) + wrdir = params.writeable_dir; + else + { +#ifdef __CYGWIN__ + char *env = getenv("APPDATALOW"); + if (!env) return false; +#else + char *env = getenv("TMPDIR"); + if (!env) env = "/tmp"; +#endif + snprintf(wdir,sizeof(wdir),"%s/zapret2",env); + wrdir = wdir; + } + if (mkdir(wrdir,0755) && errno!=EEXIST) + return false; + + bool b = false; +#ifdef __CYGWIN__ + size_t l = cygwin_conv_path(CCP_POSIX_TO_WIN_W | CCP_ABSOLUTE, wrdir, NULL, 0); + WCHAR *wwrdir = (WCHAR*)malloc(l); + if (wwrdir) + { + if (!cygwin_conv_path(CCP_POSIX_TO_WIN_W | CCP_ABSOLUTE, wrdir, wwrdir, l)) + b = SetMandatoryLabelFileW(wwrdir, SECURITY_MANDATORY_LOW_RID, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE); + free(wwrdir); + } +#else + if (ensure_dir_access(wrdir)) + b = true; + else + { + // could not chown. may be still accessible ? + char testfile[PATH_MAX]; + snprintf(testfile,sizeof(testfile),"%s/test_XXXXXX",wrdir); + int fd = mkstemp(testfile); + if (fd>0) + { + close(fd); + unlink(testfile); + b = true; + } + } +#endif + if (b) setenv("WRITEABLE",wrdir,1); + return b; +} diff --git a/nfq2/darkmagic.h b/nfq2/darkmagic.h index d9c62b4..f713ba1 100644 --- a/nfq2/darkmagic.h +++ b/nfq2/darkmagic.h @@ -89,11 +89,13 @@ bool tcp_syn_segment(const struct tcphdr *tcphdr); bool ip_has_df(const struct ip *ip); +bool make_writeable_dir(); bool ensure_file_access(const char *filename); - #ifdef __CYGWIN__ extern uint32_t w_win32_error; +bool ensure_dir_access(const char *filename); +bool prepare_low_appdata(); bool win_sandbox(void); bool win_dark_init(const struct str_list_head *ssid_filter, const struct str_list_head *nlm_filter); bool win_dark_deinit(void); @@ -104,6 +106,7 @@ bool windivert_init(const char *filter); bool windivert_recv(uint8_t *packet, size_t *len, WINDIVERT_ADDRESS *wa); bool windivert_send(const uint8_t *packet, size_t len, const WINDIVERT_ADDRESS *wa); #else +#define ensure_dir_access(dir) ensure_file_access(dir) // should pre-do it if dropping privileges. otherwise its not necessary bool rawsend_preinit(bool bind_fix4, bool bind_fix6); #endif diff --git a/nfq2/nfqws.c b/nfq2/nfqws.c index 29557e7..269712c 100644 --- a/nfq2/nfqws.c +++ b/nfq2/nfqws.c @@ -1402,6 +1402,7 @@ static void exithelp(void) " --nlm-list[=all]\t\t\t\t\t; list Network List Manager (NLM) networks. connected only or all.\n" #endif "\nDESYNC ENGINE INIT:\n" + " --writeable[=]\t\t\t\t; create writeable dir for LUA engine and pass it in WRITEABLE env variable (only one dir possible)\n" " --blob=:[+ofs]@|0xHEX\t\t; load blob to LUA var \n" " --lua-init=@|\t\t\t; load LUA program from a file or string. if multiple parameters present order of execution is preserved.\n" " --lua-gc=\t\t\t\t\t\t; forced garbage collection every N sec. default %u sec. triggers only when a packet arrives. 0 = disable.\n" @@ -1540,6 +1541,8 @@ enum opt_indices { IDX_SOCKARG, #endif + IDX_WRITEABLE, + IDX_BLOB, IDX_LUA_INIT, IDX_LUA_GC, @@ -1620,6 +1623,7 @@ static const struct option long_options[] = { #elif defined(SO_USER_COOKIE) [IDX_SOCKARG] = {"sockarg", required_argument, 0, 0}, #endif + [IDX_WRITEABLE] = {"writeable", optional_argument, 0, 0}, [IDX_BLOB] = {"blob", required_argument, 0, 0}, [IDX_LUA_INIT] = {"lua-init", required_argument, 0, 0}, [IDX_LUA_GC] = {"lua-gc", required_argument, 0, 0}, @@ -1678,6 +1682,7 @@ int main(int argc, char **argv) set_env_exedir(argv[0]); #ifdef __CYGWIN__ + prepare_low_appdata(); if (service_run(argc, argv)) { // we were running as service. now exit. @@ -1692,11 +1697,10 @@ int main(int argc, char **argv) uint64_t payload_type=0; struct packet_range range_in = PACKET_RANGE_NEVER, range_out = PACKET_RANGE_ALWAYS; #ifdef __CYGWIN__ - char wf_save_file[256]; + char wf_save_file[256]=""; bool wf_ipv4 = true, wf_ipv6 = true, wf_filter_lan = true, wf_tcp_empty = false; unsigned int IfIdx = 0, SubIfIdx = 0; unsigned int hash_wf_tcp_in = 0, hash_wf_udp_in = 0, hash_wf_tcp_out = 0, hash_wf_udp_out = 0, hash_wf_raw = 0, hash_wf_raw_part = 0, hash_ssid_filter = 0, hash_nlm_filter = 0; - *wf_save_file = 0; #endif srandom(time(NULL)); @@ -1966,6 +1970,17 @@ int main(int argc, char **argv) } break; #endif + case IDX_WRITEABLE: + params.writeable_dir_enable = true; + if (optarg) + { + strncpy(params.writeable_dir, optarg, sizeof(params.writeable_dir)); + params.writeable_dir[sizeof(params.writeable_dir) - 1] = 0; + } + else + *params.writeable_dir = 0; + break; + case IDX_BLOB: load_blob_to_collection(optarg, ¶ms.blobs, MAX_BLOB_SIZE, BLOB_EXTRA_BYTES); break; @@ -2410,6 +2425,15 @@ int main(int argc, char **argv) DLOG_CONDUP("we have %d user defined desync profile(s) and default low priority profile 0\n", desync_profile_count); + if (params.writeable_dir_enable) + { + if (!make_writeable_dir()) + { + DLOG_ERR("could not make writeable dir for LUA\n"); + exit_clean(1); + } + DLOG("LUA writeable dir : %s\n", getenv("WRITEABLE")); + } #ifndef __CYGWIN__ if (params.droproot) #endif @@ -2434,7 +2458,7 @@ int main(int argc, char **argv) #endif { if (dp->hostlist_auto && ensure_file_access(dp->hostlist_auto->filename)) - DLOG_ERR("could not chown %s. auto hostlist file may not be writable after privilege drop\n", dp->hostlist_auto->filename); + DLOG_ERR("could not make '%s' accessible. auto hostlist file may not be writable after privilege drop\n", dp->hostlist_auto->filename); } LuaDesyncDebug(dp); diff --git a/nfq2/params.h b/nfq2/params.h index 35cc109..b8b261a 100644 --- a/nfq2/params.h +++ b/nfq2/params.h @@ -161,6 +161,8 @@ struct params_s uint64_t reasm_payload_disable; struct str_list_head lua_init_scripts; + bool writeable_dir_enable; + char writeable_dir[PATH_MAX]; int lua_gc; lua_State *L; diff --git a/nfq2/sec.c b/nfq2/sec.c index bf2f04f..25e67f1 100644 --- a/nfq2/sec.c +++ b/nfq2/sec.c @@ -37,9 +37,6 @@ SYS_exec_with_loader, #ifdef SYS_osf_execve SYS_osf_execve, #endif -#ifdef SYS_uselib -SYS_uselib, -#endif #ifdef SYS_chmod SYS_chmod, #endif