INTENT2022--一道包含12个反调试反虚拟机操作的ctf题解

news2024/9/30 7:17:47

作者:selph

从一道Re题学习12种反调试反虚拟技术

题目:AntiDebuggingEmporium

来源:INTENT CTF 2022 Re

这个题目很有意思,里面出现了总共12个反调试反虚拟机的操作,本文内容分两部分,前部分是题解,后部分是这12个反调试反虚拟机手法分析

题解

程序逻辑分析

文件信息:是个64位的Windows控制台程序,VS2022编译的

 

主函数:

 

可以看到,逻辑很简单,

1.首先是调用一个函数等待一个对象执行完成

2.然后提示输入flag,

3.对一个数组的值进行判断,如果所有的值都是0,则处理输入字符串输出flag

这里去看看这个数组的值来自哪里:

通过交叉引用,发现这个数组在多个地方被赋值,基本上均在StartAddress这个函数里

 

经分析,这里的这个数组保存的就是检测虚拟机和调试器的情况,检测到了则会有值被赋值为1:

 

这个函数首先从当前文件的资源里读取了二进制数据,保存起来,然后进行了累计12个反虚拟机和反调试的函数,这部分内容我们在后文进行详细分析

随便点开一个:

 

可以看到,这里对一个数组的某个位置进行赋值了,这个赋值后面会用到

现在看一下StartAddress这个函数是在什么时候被调用的:

 

通过交叉引用可以看到,在TLS回调函数中调用,TLS回调函数会在主函数执行前先执行,这里的hHandle就是主函数里等待的对象

也就是说,这个程序会先进行反调试反虚拟机的操作,然后检测完之后,获取用户输入,进行处理

接下来看用户输入是被如何处理的:

 

这里首先是用资源二进制数据和一个数组的对应值进行相加(这个数组的值就是反调试函数里检测成功后赋值的)

然后进行校验,校验是通过异或进行的,这里用到一个哈希值,这个哈希值是对资源数据进行校验得到的,不去修改资源,则这里是固定值,所以可以直接动态调试得到这个值,然后异或用户输入,结果是资源数据计算后的值

逻辑理清楚了,现在要做的事情就是:

1.拿到资源二进制数据

2.拿到反调试数组

3.拿到哈希值

4.计算flag

拿到资源数据

直接从die中就能得到:

 

拿到反调试数组和哈希值

把程序在物理机上跑起来,让程序卡在scanf里,这个时候调试器和虚拟机的检测已经结束了,反调试数组应该也计算好了

这个时候直接调试器附加,查看数组的地址:14000DBE0

 

拿到64字节的数据

哈希值也是保存在全局变量里的,可以直接拿到地址000000014000DB88,去查看即可:

 

计算flag

该有的都有了,写代码生成flag即可:

// antidebuggingemporium.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 
#include 
#include 


unsigned char RescourceData[68] = {
    0x72, 0x6C, 0xCA, 0x03, 0x75, 0x76, 0xE5, 0x00, 0x00, 0x43, 0x00, 0x00, 0x55, 0x16, 0xEA, 0x77,
    0x0B, 0x4C, 0xC1, 0x77, 0x48, 0x7D, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x5B, 0xC1, 0x31,
    0x08, 0x43, 0xEE, 0x76, 0x55, 0x7D, 0xAF, 0x28, 0x64, 0x15, 0xF6, 0x75, 0x64, 0x00, 0x00, 0x00,
    0x64, 0x00, 0x00, 0x00, 0x52, 0x4C, 0xED, 0x71, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x3F,
    0x46, 0x22, 0x3F, 0x46
};


unsigned char antiDbgNum[68] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x56, 0x00, 0xF9, 0x77, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x2E, 0x08, 0x00, 0xAE, 0x28, 0x57, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA, 0x34,
    0x00, 0x16, 0xF9, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xAD, 0x27, 0x57, 0x13, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00
};

unsigned char flag[68] = { 0 };

unsigned int hashsum = 0x469E223B;

int main()
{
    for (int i = 0; i < 68; ++i)
    {
        RescourceData[i] += antiDbgNum[i];
    }

    for (int j = 0; j < 68; j +=4)
    {
        *(DWORD*)&flag[j] = (hashsum ^ *(DWORD*)&RescourceData[j]);// 00000000469E223B
    }
    printf("%s", flag);
}

// INTENT{1mag1n4t10n_1s_7h3_0nly_w3ap0n_1n_7h3_w4r_4gains7_r3al1ty}

反调试反虚拟机手法分析

这里依次分析那12个反调试反虚拟机的函数

0x0-反虚拟机-检测CPU核心数

 

这里通过GetSystemInfo API获取系统信息,这里判断系统的处理器核心数量,现在的用户电脑CPU核心都是4核往上的,一般只有在虚拟机里可能会遇到只分配了1核的情况

0x1-反调试器-检测PEB标志位1

 

看到这个+2偏移就很容易想到PEB里的BeingDebugged标志位

不过这里是使用ZwQueryInformationProcess获取PEB的:

 

0x2-反调试器-检测PEB标志位2

 

这个写的更直接,这个NtCurrentPeb()本质上就是从gs[0x60]处取值,得到的就是peb地址,这里检测的依然是BeingDebugged标志位

0x3-反调试器-检测PEB标志位3

 

这里使用了PEB的另一个标志位NtGlobalFlag,位置是偏移0xBC的地方,这里IDA的F5显示有问题,在反汇编里可以到是:add     rax, 0BCh

0x4-反调试器-检测PEB标志位4

 

通过API的方式检测PEB偏移2位置的BeingDebugged的值

0x5-反虚拟机-cpuid 1

 

cpuid指令,通过rax传递功能号,将返回值保存在eax,ebx,ecx,edx里

当功能号是1的时候,ecx的最高位表示当前是否在虚拟机里

0x6-反虚拟机-cpuid 0x40000000

 

当功能号是0x40000000时,rbx rcx rdx里返回的是一个cpu名称

 

然后接下来检测是否是常见的虚拟机的cpu名称

0x7-反虚拟机-cpuid 0

 

功能号是0时候,是另一种显示cpu相关信息的方法,依然是检测是否出现虚拟机常见字符

0x8-反调试器-rdtsc

 

通过rdtsc指令获取时间,当两次获取时间间隔过大,可以认为有调试器干扰了程序的正常执行

0x9-反调试器-窗口检测

 

检测是否存在调试器的窗口,如果存在,则认为有调试行为

0xA-反调试器-异常处理

 

这里使用SetUnhandledExceptionFilter API设置无法处理的异常的处理函数

通常情况下,当异常无法处理的时候会进入该函数去处理,但是有调试器存在,则会直接由调试器接管,不进入该函数

处理的内容是:

 

效果是跳过某些指令往下执行:

 

这里跳过了这个jmp,以至于下面的0x57能正常赋值到数组里

0xB-反虚拟机-设备检测

 

这里通过API:SetupDiGetClassDevsExW 获取设备集

然后通过API:SetupDiEnumDeviceInfo 枚举设备

使用API:SetupDiGetDeviceRegistryPropertyW 对每一个设备获取其属性

对获取到的信息,去判断是否包含这几个虚拟机相关的特征字符串,来判断是否位于虚拟机内部        ·法人gt03\=[]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/128657.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

六西格玛奠基人之张驰染阳杂记

中招第1天&#xff1a; 上周四从外地出差回来&#xff0c;落地就觉得有点全身乏力&#xff0c;晚上开始发冷&#xff0c;预感可能中招了。大数据预测深圳第一波疫情高峰发生在12月20日&#xff0c;陆续接到深圳同事亲友中招的消息&#xff0c;感慨真是神预测。 因为头晕目眩&…

LeetCode419.甲板上的战舰

LeetCode刷题记录 文章目录&#x1f4dc;题目描述&#x1f4a1;解题思路⌨C代码&#x1f4dc;题目描述 给你一个大小为 m x n 的矩阵 board 表示甲板&#xff0c;其中&#xff0c;每个单元格可以是一艘战舰 X 或者是一个空位 . &#xff0c;返回在甲板board上放置的 战舰 的数量…

Elasticsearch 日志能否把全部请求打印出来?

1、实战问题请问一下球主&#xff0c;es怎么配置可以把请求日志都打印出来。就是不管是调用借口&#xff0c;还是kibana查询数据&#xff0c;es能打印dsl的请求日志吗&#xff1f;&#xff1f;求指导。怎么配置&#xff1f;——问题来源&#xff1a;https://t.zsxq.com/09vv8rq…

现代细胞计数分析平台丨OMIQ简介

单细胞分析&#xff0c;变得简单 OMIQ是一个现代细胞计数分析平台&#xff0c;它将机器学习和分析管道与经典手动分析的世界连接起来。它允许研究人员在一个软件中完成他们的整个工作流程&#xff0c;从原始数据到统计意义&#xff0c;使用他们自己的专业知识和熟悉的工具与数…

java养老系统养老院系统养老院网站源码

简介 本系统是养老院系统&#xff0c;主要是老人入住养老院的业务逻辑&#xff0c;有护工和医生对老人进行护理看病记录等信息管理&#xff0c;缴费入住外出记录管理等。 演示视频 https://www.bilibili.com/video/BV18i4y1Z7je/?share_sourcecopy_web&vd_sourceed0f04fb…

2022(核酸年)结束了

目录2022目标回顾2022生活回顾2023目标祝词现在是北京时间2022-12-30 15:08&#xff0c;再有一天2022就结束了&#xff0c;岁月催人老啊&#xff01;同样又到了一年一度总结的时候了&#xff0c;我清楚记得在 2021年度总结中定下了我的今年目标&#xff0c;即如此那我们一同看看…

strcmp(),strcat(),strcpy()函数复习与模拟实现

tips 1. 与--都是有副作用的&#xff0c;而有关于位的运算都是没有副作用的。 既然是与字符串有关的函数&#xff0c;不得不提一下&#xff1a;\0是字符串结束符&#xff0c;对应到ascll表里面是空字符NULL&#xff0c;对应的ACSLL码为0. 1. 字符串许多函数的操作与\0有些密…

剩余电流继电器在大型游乐场所中的应用探讨

【摘要】游乐场所中大型游乐设备的运转离不开电力系统的支持&#xff0c;例如受到小朋友们欢迎的观光火车&#xff0c;自控飞机&#xff0c;豪华转马等。目前许多游乐经营者在安全用电方面的意识还比较薄弱&#xff0c;存在一定的游乐安全隐患&#xff0c;本文就剩余电流继电器…

机器学习笔记之Sigmoid信念网络(三)KL散度角度观察醒眠算法

机器学习笔记之Sigmoid信念网络——KL散度角度观察醒眠算法引言回顾&#xff1a; 醒眠算法过程KL Divergence\text{KL Divergence}KL Divergence观察醒眠算法引言 上一节介绍了MCMC以及平均场理论变分推断方法的弊端并介绍了醒眠算法(Weak-Sleep Algorithm)。本节将介绍从KL散…

ThinkPHP历史漏洞

文章目录ThinkPHP简介Thinkphp历史漏洞Thinkphp 2.x 任意代码执行漏洞漏洞描述影响版本漏洞复现Thinkphp5.0.23远程代码执行漏洞(CVE-2018-20062)漏洞描述影响版本漏洞复现ThinkPHP 5.0.x 未开启强制路由导致的RCE 漏洞分析(CNVD-2018-24942)漏洞描述影响版本漏洞复现ThinkPHP简…

2023元旦假期值得关注的空投与埋伏任务

不知不觉2023年元旦即将到来&#xff0c;这也是十一国庆之后大家迎来的第一次小假期&#xff0c;相信不少人已经开始“家里蹲”计划&#xff0c;不少项目方也最近搞了一些空投任务&#xff0c;刚好趁此时间也能刷空投&#xff0c;获得意外惊喜&#xff0c;这里我们为大家总结最…

【redis有序集合操作】

【zcount&#xff1a;统计有序集合分数区间内的成员数量】 zadd user_login 1 one zadd user_login 3 two zadd user_login 4 three zadd user_login 5 four ZCOUNT 返回有序集 key 中&#xff0c; score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量…

socket套接字

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 socket套接字1. 什么是socket套接字2. socket编程3. 网络字节序4. IP地址转换函数5. sockaddr数据结构…

【答学员问】服务器上安装好LAMP架构,部署wordpress之后网页端无法访问

文章目录问题反馈问题排查1. 首先是IP&#xff1a; 确认无误&#xff1a;2. 安装一下 php看看是否安装&#xff1a;3. 最后测试PHP是否能够解析再次沟通分析整理列清单排查测试过程1. 上传包解压2. 安装好LAMP架构并测试是否支持php3. 测试是否可以访问wordpress4. 查看日志排查…

Maven是怎么样构建Spring Boot项目的?

准备好项目运行所需的环境后&#xff0c;就可以使用IDEA开发工具搭建一个Spring Boot入门程序了。我们既可以使用Maven方式构建项目&#xff0c;也可以使用Spring Initializr快捷方式构建项目。这里先介绍如何使用Maven方式构建Spring Boot项目&#xff0c;具体步骤如下。 1.初…

SpringBoot+VUE前后端分离项目学习笔记 - 【06 SpringBoot集成Mybatis实现数据查询】

配置文件改成yaml格式&#xff1a; application.yml server:port: 9090spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/joyce?serverTimezoneGMT%2b8username: rootpassword: 123456写基本的功能来验证后台数据查询功能 …

了解初级测试人员从测试自动化开始需要什么?

文章目录 前言 将测试自动化视为软件开发 选择一种编程语言开始 学习干净的代码实践和原则 了解自动化中有用的设计模式 学习干净的代码实践和原则 学习网络工作原理的基础知识 选择一个 UI 自动化工具开始 了解 HTTP 协议以及如何自动化 API 测试 熟悉数据库基础知识…

React 配置文件(三)配置本地IP地址和端口号

1.在环境变量中配置好对应IP地址和端口号,拿UAT来举例 2.在config-overrides.js中配置域名和端口号 3.在package.json中配置好启动脚本 "scripts": { "start": "react-app-rewired start", "uat": "dotenv -e .env.uat react-app…

Android之蚂蚁森林能量水滴效果

最近公司有个需求&#xff0c;需要一个类似于蚂蚁森林能量水滴浮动效果&#xff0c;所以有了这篇文章&#xff0c;目前在项目里&#xff0c;没时间提出来做demo&#xff0c;有代码欠缺的地方欢迎指出&#xff0c;一定补上。 文章目录一&#xff1a;效果图二&#xff1a;具体实现…

HotPDF Delphi PDF VCL完全形成PDF文档

HotPDF Delphi PDF VCL完全形成PDF文档 HotPDF Delphi PDF&#xff0c;用于创建和创建PDF文档的应用程序名称。您的公司已在您之前发布&#xff0c;以便在Delphi和C中使用。事实上&#xff0c;使用这个库&#xff0c;您将能够以不同的方式编辑、执行、构建和管理PDF文档。如果您…