首页 > 其他分享 >天堂之门(Heaven's Gate)逆向

天堂之门(Heaven's Gate)逆向

时间:2023-12-02 23:14:21浏览次数:52  
标签:逆向 Heaven 32 代码 mu write 64 Gate self

Heaven's Gate

原理及POC

通过在32位WoW进程中执行64位代码,实现静态反编译以及干扰对Win32Api的检测实现免杀。

详见[原创]天堂之门 (Heaven's Gate) C语言实现-软件逆向-看雪-安全社区|安全招聘|kanxue.com

常见的打开天堂之门的代码块

// convert x86 to x64
6A 33                    push 0x33   ; cs寄存器的新值
E8 00 00 00 00           call $+5     ;push 下一条指令的地址入栈,并继续执行下一条指令
83 04 24 05              add dword [esp], 5  ;栈顶的返回地址加5,指向retf的下一条指令
CB                       retf  ; 通过retf,程序返回到下一条指令继续执行,但cs 寄存器已经被修改为0x33, 执行的代码是64位
// convert x64 to x86
E8 00 00 00 00           call $+5
C7 44 24 04 23 00 00 00  mov dword [rsp + 4], 0x23
83 04 24 0D              add dword [rsp], 0xD
CB                       retf

前置知识

32位程序中调用64位程序的逆向方法

参考CTF中32位程序调用64位代码的逆向方法-安全客 - 安全资讯平台 (anquanke.com)深度好文,解答了在复现OddCode时遇到的种种odd问题的疑惑!

识别

retf是切换32位和64位的关键指令。

retf前有push 0x33(33h)类似的指令。

push    33h 
add     dword ptr [esp], 5 
retf
或者 
mov     dword ptr [eax], 33h 
leave
retf

retf后CS寄存器从0x23变为0x33。

程序中可能有进行支持64位的检查,如GWoC。

当一块可执行的内存,调试时无法识别汇编或者几步一跳时,有可能在是执行64位的代码。

32位代码调用函数的方式和64位代码有差异,32位程序大多通过入栈方式传参,64位程序一般用寄存器传参。

32位和64位的syscall的含义和参数有所不同。

静态

dump出64位代码后拖进ida64分析,在ida64中注意设置基址和源程序中相同便于分析。

动态

用ida64调试时,在进入64位代码所在区域前,在Edit->Segments->Edit segment处设置64位代码所在段为64位模式,可读可写可运行

天堂之门解题trick

根据call far、jmp far定位是天堂之门,找到切换64位模式的代码,然后对64位部分代码进行静态or动态分析。静态的话就是dump出64位部分代码,然后设置基址和段属性。动态就是windows下ida+windbg。

题目

OddCode

本题参考

2021年羊城杯官方Writeup公布(Reverse) (qq.com)

羊城杯_2021 OddCode 天堂之门 + unicorn反混淆 - TLSN - 博客园 (cnblogs.com)

[原创]羊城杯OddCode题解(unicorn模拟调试+求解)-CTF对抗-看雪-安全社区|安全招聘|kanxue.com

这题看起来好炫,跟着wp做做,然后就做了好久好久。用ida打开后发现有很多花指令干扰,但是略向下翻可发现此处远跳转,配合上下面的call指令序列可知此题属于heaven's gate,远跳转和call $+5指令序列分别是32位转64位和64位转32位的代码。ida对远跳转支持不好,可参考汇编中的jmp转移指令:jmp short、jmp near ptr、jmp far ptr-CSDN博客。在这里可看远跳转的机器码,小端序0033:00405313,即设置cs为0x33,地址为0x405310,也就是他下面一行call sub_401010指令。

可以从x32dbg的调试中看出远跳转是在设置cs为0x33

image

可以看出,程序切换到64位模式后跳转下一行,执行的是call sub_401010

image

执行完后经下列指令切换回32位模式。

image

最后根据sub401010的返回值判断flag正误,可知关键函数即sub401010

image

同时观察可知,跳转前将input放入esi,将一个可能是key的数组放入edi

image

image

下面就是要分析64位部分的代码,可以dump后静态分析,也可以动态分析。这个题dump出来后简单观察下就可以发现充满花指令混淆,实在是难以分析,只能动态调试下看看。

思路一:用unicorn来调试代码块,但是我一直搞不懂切换64位前寄存器的状态是怎么获得的,我的EIP指向0x2e1010时寄存器的值和搜到的这个思路的wp都不太一样,不知道是不是因为64/32位切换我没弄好。

from unicorn import *
from unicorn.x86_const import * 
ADDRESS = 0x2E1000          # 程序加载的地址,可通过ida,exeinfoPe,x32dbg调试等获得
INPUT_ADDRESS = 0x2E701D    # 输入的地址
KEY_ADDRESS = 0x2E705C      # 16字节key的地址
with open('OddCode.exe', 'rb') as file:    
	file.seek(0x400)#PE文件结构代码开始部分    
	X64_CODE = file.read(0x4269)    # 读取代码,除去32位程序剩下的所有代码
class Unidbg:     
	def __init__(self, flag):        
		mu = Uc(UC_ARCH_X86, UC_MODE_64)        # 基址为0x2E1000,分配16MB内存        
		mu.mem_map(ADDRESS, 0x1000000)        
		mu.mem_write(ADDRESS, X64_CODE)        
		mu.mem_write(INPUT_ADDRESS, flag)       # 随便写入一个flag        
		mu.mem_write(KEY_ADDRESS, b'\x90\xF0\x70\x7C\x52\x05\x91\x90\xAA\xDA\x8F\xFA\x7B\xBC\x79\x4D') 
        #跳转前存入的key
        # 初始化寄存器,寄存器的状态就是切换到64位模式之前的状态,可以通过动调得到        
		mu.reg_write(UC_X86_REG_RAX, 1)        
		mu.reg_write(UC_X86_REG_RBX, 0x51902D)        
		mu.reg_write(UC_X86_REG_RCX, 0xD86649D8)        
		mu.reg_write(UC_X86_REG_RDX, 0x2E701C)        
		mu.reg_write(UC_X86_REG_RSI, INPUT_ADDRESS)  # input参数        
		mu.reg_write(UC_X86_REG_RDI, KEY_ADDRESS)    # key参数       
		mu.reg_write(UC_X86_REG_RBP, 0x6FFBBC)        
		mu.reg_write(UC_X86_REG_RSP, 0x6FFBAC)       
        mu.reg_write(UC_X86_REG_RIP, 0x2E1010)        
        mu.hook_add(UC_HOOK_CODE, self.trace)        # hook代码执行,保存代码块执行轨迹        
        self.mu = mu        
        self.except_addr = 0        
        self.traces = []        # 用来保存代码块执行轨迹     
	def trace(self, mu, address, size, data):        
		if address != self.except_addr:            
			self.traces.append(address)        
			self.except_addr = address + size     
	def start(self):        
		try:            
			self.mu.emu_start(0x2E1010, -1)        
		except:            
		pass        print([hex(addr)for addr in self.traces]) Unidbg(b'SangFor{00000000000000000000000000000000}').start()

下面就可以用unicorn去hook访问input和key的代码块,同时借助unicorn还可以鉴别花指令和正常执行的指令,详见地球人的博客。后续观察出来了判断的逻辑直接爆破。

另外值得注意,在windows下调试时windbg对32/64位切换的支持较好,其他如ida、x32dbg等调试器在retf语句后都无法调试。

因为这点耽误了很多时间,比如ida虽可以通过断点进入64位部分,但是会一直报错不能调试。稍等研究下ida和windbg结合使用再更下。

思路二:官方wp里把64位部分dump出来重新编译成exe然后运行调试。通过观察寄存器的值发现的变换逻辑。但是这里不太了解dump出来之后那个masm格式怎么写的,再学下之后补上。

西湖论剑2023 Dual personality

挖坑尽快填上。这个题就是直接识别出64位的部分dump出来然后直接分析代码逻辑就好。

标签:逆向,Heaven,32,代码,mu,write,64,Gate,self
From: https://www.cnblogs.com/y0hv2y/p/17872410.html

相关文章

  • 【验证码逆向专栏】百某网数字九宫格验证码逆向分析
    声明本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均......
  • 【Android逆向】一些零碎的笔记
    *在/sdcard/下的文件无法执行,必须将其拷贝到其它位置执行,如/data/目录,/data/目录中是system分组,可以执行程序;*每个应用都会创建一个对应的应用用户,如:cn.abcpiano.pianist包名的应用,创建了一个u0_a147用户;* getpropro.product.cpu.abi ......
  • INFINI Labs 产品更新 | 修复 Easysearch 跨集群复制索引同步问题,Gateway 内存异常增
    INFINILabs产品又更新啦~,本次更新主要对Easysearch、Gateway、Console、Agent等产品功能进行优化和相关Bug修复,解决了内存异常增长等问题,以下是详细说明。INFINIEasysearchv1.6.2INFINIEasysearch是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的ApacheLucene......
  • JS逆向——某道翻译
    文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,如有侵权,请联系作者立即删除!目标网站:aHR0cHM6Ly9mYW55aS55b3VkYW8uY29tL2luZGV4Lmh0bWwjLw==一、定位接口使用Chrome浏览器,打开Network进行抓包输入要翻译的字符串:HelloWorld!页面没有重新加载,初步判断是Ajax......
  • 微信小程序开发的聚合函数排序.aggregate.sort
    //普通查询用.orderBy('add_time','desc'),聚合查询用.sort({ins_time:-1})'usestrict';constdb=uniCloud.database()//对数据库的对象获取;exports.main=async(event,context)=>{ letstart=newDate().getTime(); constcollection=db......
  • ISCTF 逆向题解
    ISCTF逆向题解用一个晚上的时间看了看ISCTF,有的题还蛮难的(毕竟得嘎嘎猜出题人想法)CrackMewinhex打开exe,修改标识头PFX为UPX然后放进UPXshell里面试试脱了,放进ida,直接反编译得到flagEasyReexeinfo看看这个是什么64位,放进ida反编译得到一段很清晰的逻辑反转+异或+单表代换。。。......
  • Mysql - Error 1055: Expression #1 of SELECT list is not in GROUP BY clause and c
    执行SQL时出现错误ERROR1055,SELECT列表不在GROUPBY语句内且存在不函数依赖GROUPBY语句的非聚合字段'edusassvc.u.nickname'这是和sql_mode=only_full_group_by不兼容的(即不支持)。分析问题1)原理层面这个错误会发生在mysql5.7版本及以上版本mysql5.7版本以上默认的sql......
  • pyc逆向以及DASCTF里的ezpython复现
    pyc文件结构分析pyc文件是Python在解释执行源代码时生成的字节码文件,可以直接由Python虚拟机执行。重点了解了下文件头,还不太了解其他部分怎么出题。参考pythonpyc加花指令pyc文件头参考深入理解python虚拟机:pyc文件结构Python代码保护|pyc混淆从入门到工具实现mag......
  • INFINI Gateway 与华为鲲鹏完成产品兼容互认证
    何为华为鲲鹏认证华为鲲鹏认证是华为云围绕鲲鹏云服务(含公有云、私有云、混合云、桌面云)推出的一项合作伙伴计划,旨在为构建持续发展、合作共赢的鲲鹏生态圈,通过整合华为的技术、品牌资源,与合作伙伴共享商机和利益,助力合作伙伴与华为联合打造基于鲲鹏的联合解决方案,改变国产IT长......
  • SpringCloud——网关过滤工厂GatewayFilterFactory
    目录GatewayFilter工厂AddRequestHeaderAddRequestHeadersIfNotPresentAddRequestParameterAddResponseHeaderGatewayFilter工厂网关过滤器工厂GatewayFilterFactory允许以某种方式修改传入的HTTP请求或返回的HTTP响应。其作用域是某些特定路由。SpringCloudGateway包括......