diff --git a/c/meterpreter/source/extensions/stdapi/server/fs/fs_local.h b/c/meterpreter/source/extensions/stdapi/server/fs/fs_local.h index 79d119654..f13942696 100644 --- a/c/meterpreter/source/extensions/stdapi/server/fs/fs_local.h +++ b/c/meterpreter/source/extensions/stdapi/server/fs/fs_local.h @@ -49,7 +49,7 @@ int fs_ls(const char *directory, fs_ls_cb_t cb, void *arg); int fs_getwd(char **directory); -int fs_mkdir(const char *directory); +int fs_mkdir(char *directory); int fs_move(const char *oldpath, const char *newpath); diff --git a/c/meterpreter/source/extensions/stdapi/server/fs/fs_win.c b/c/meterpreter/source/extensions/stdapi/server/fs/fs_win.c index 98ab4001a..5f02bdfa9 100644 --- a/c/meterpreter/source/extensions/stdapi/server/fs/fs_win.c +++ b/c/meterpreter/source/extensions/stdapi/server/fs/fs_win.c @@ -345,22 +345,69 @@ int fs_copy(const char *oldpath, const char *newpath) return rc; } -int fs_mkdir(const char *directory) +int fs_mkdir(char *directory) { int rc = ERROR_SUCCESS; - wchar_t *dir_w = met_api->string.utf8_to_wchar(directory); + struct meterp_stat s = { 0 }; + wchar_t* dir_w; + size_t directory_length; + char* base_dir; + char* dir; + HANDLE process_heap = NULL; + + if(directory == NULL){ + return ERROR_INVALID_PARAMETER; + } - if (dir_w == NULL) { + process_heap = GetProcessHeap(); + + if(process_heap == NULL){ rc = GetLastError(); - goto out; + return rc; } - if (CreateDirectoryW(dir_w, NULL) == 0) { + // Add 2 because of NULL character and additional backslash + directory_length = lstrlenA(directory)+2; + base_dir = (char *)HeapAlloc(process_heap, 0, directory_length); + + if(base_dir == NULL){ rc = GetLastError(); + return rc; } + dir = strtok(directory, "\\"); + + sprintf_s(base_dir, directory_length, "%s\\", dir); + + while (dir != NULL) + { + if (fs_stat(base_dir, &s) != ERROR_SUCCESS) { + dir_w = met_api->string.utf8_to_wchar(base_dir); + if (dir_w == NULL) { + rc = GetLastError(); + goto out; + } + + if (CreateDirectoryW(dir_w, NULL) == 0) { + rc = GetLastError(); + free(dir_w); + goto out; + } + free(dir_w); + } + + dir = strtok(NULL, "\\"); + + if (dir != NULL){ + sprintf_s((char*)(base_dir+lstrlenA(base_dir)), directory_length, "%s\\",dir); + } + + memset(&s, 0, sizeof(struct meterp_stat)); + } + + out: - free(dir_w); + HeapFree(process_heap,0, base_dir); return rc; }