[天堂之门+模拟执行]2021羊城杯oddcode

news/2024/12/23 14:58:24/文章来源:https://www.cnblogs.com/Un1corn/p/18296638

天堂之门

学习文章 https://taardisaa.github.io/2021/09/25/Heaven'sGate/

前言

Windows判别位的方式,是根据cs段寄存器的。

在32位程序中,cs的值是0x23;

在64位程序中,cs的值是0x33。

所以只要修改cs的值,就能实现切换。而实现这个切换,使用的是ljmp长跳转指令(在Intel语法中也可以叫做jmp far ptr),或者retf长返回指令.

32位转64位

以jmp far ptr xxxx对应jmp xx:xxxx
img
读硬编码:
EA 10 53 C7 00 33 00
jmp 0033:00C75310(cs:ip)
以这个长跳转便改变了cs的值位0x33.之后便会以64位执行下面call的函数

64位转32位

用retf实现
img
call到下一条指令,并将这条指令的地址压栈.
call $+5
将栈顶esp的上一个数赋值为0x23
mov dword ptr [esp+4], 23h
将栈顶esp进行修正.将返回地址设置到retf后一共0x874331-0x87431A=0x17(从mov到retf)
sub dword ptr [esp], 87431Ah
add dword ptr [esp], 874331h
最好retf依次从栈顶弹出ip的值与cs的值,cs:ip共同作用实现返回

模拟执行(Unicorn)

先贴一下exp
import capstone
from unicorn import *
from unicorn.x86_const import *

ADDRESS = 0xC71000  # 初始地址
INPUT_ADDR = 0xc7701d
KEY_ADDR = 0xc7705c
with open(r"D:\ctf\ctf_game\OddCode.exe", 'rb') as fp:fp.seek(0x400)x64_code = fp.read(0x5000)class UniVM:def __init__(self, flag, except_hit):# 创建虚拟机(x86架构,64位)mu = Uc(UC_ARCH_X86, UC_MODE_64)# 分配内存mu.mem_map(ADDRESS, 0x1000000)# 填充内存mu.mem_write(ADDRESS, x64_code)# 填充寄存器mu.mem_write(INPUT_ADDR, flag)mu.mem_write(KEY_ADDR, b'\x90\xF0\x70\x7C\x52\x05\x91\x90\xAA\xDA\x8F\xFA\x7B\xBC\x79\x4D')mu.reg_write(UC_X86_REG_RAX, 1)mu.reg_write(UC_X86_REG_RBX, 0xf1b02d)mu.reg_write(UC_X86_REG_RCX, 0x5779887a)mu.reg_write(UC_X86_REG_RDX, 1)mu.reg_write(UC_X86_REG_RSI, INPUT_ADDR)mu.reg_write(UC_X86_REG_RDI, KEY_ADDR)mu.reg_write(UC_X86_REG_RBP, 0x118fe44)mu.reg_write(UC_X86_REG_RSP, 0x118fe34)mu.reg_write(UC_X86_REG_RIP, 0xC75309)mu.reg_write(UC_X86_REG_RFLAGS, 0x202)# mu.hook_add(UC_HOOK_MEM_READ, self.hook_mem_read)mu.hook_add(UC_HOOK_CODE, self.trace)self.md = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_64)self.mu = muself.except_addr = 0self.except_hit = except_hitself.traces = []self.hit = 0self.success = False'''#capstone查看cmp与test位置def trace(self, mu, address,size, data):disasm = self.md.disasm(mu.mem_read(address, size), address)for i in disasm:mnemonic = i.mnemonicif mnemonic == 'cmp' or mnemonic == 'test':print(f'Instruction{mnemonic} at {hex(address)}')if address != self.except_addr:self.traces.append(address)self.except_addr = address+size'''def trace(self, mu, address, size, data):if address != self.except_addr:self.traces.append(address)self.except_addr = address + size  # 更新 self.except_addr 为当前指令结束后的地址(address + size)if address == 0xc738EF:self.hit += 1if self.hit == self.except_hit:self.success = Truemu.emu_stop()def hook_mem_read(self, mu, access, address, size, value, data):if address >= INPUT_ADDR and address <= INPUT_ADDR + 41:print(f'Read input[{address - INPUT_ADDR}] at {hex(mu.reg_read(UC_X86_REG_RIP))}')if address >= KEY_ADDR and address <= KEY_ADDR + 16:print(f'Read key[{address - KEY_ADDR}] at {hex(mu.reg_read(UC_X86_REG_RIP))}')def solve(self):try:self.mu.emu_start(ADDRESS + 0x10, -1)except:passreturn self.successdef get_flag(flag, except_hit):for i in b'1234567890abcdefABCDEF':for j in b'1234567890abcdefABCDEF':flag[8 + (except_hit - 1) * 2] = iflag[8 + (except_hit - 1) * 2 + 1] = jif UniVM(bytes(flag), except_hit).solve():returnflag = bytearray(b'SangFor{00000000000000000000000000000000}')
for i in range(1, 17):get_flag(flag, i)print(flag.decode())

基本使用方法: https://www.cnblogs.com/Only-xiaoxiao/p/17316343.html

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全面对比:天工大模型 vs 紫东太初大模型

在当今信息时代,人工智能(AI)技术的飞速发展正以前所未有的速度和深度改变着我们的生活和工作方式。随着大数据、计算能力和算法的不断提升,各类大模型的涌现使得AI的应用领域日益广泛,从自然语言处理到图像识别,从推荐系统到自动驾驶,AI正逐渐渗透到各行各业,成为推动…

读人工智能全传15意向立场

读人工智能全传15意向立场1. 物理立场 1.1. 可以解释一个实体行为 1.2. 在物理立场中,我们使用自然法则(物理、化学等)来预测系统的行为结果 1.3. 虽然物理立场在解释这种行为的时候非常有效,但无法应用于理解或者预测人类行为 1.3.1. …

Microsoft宣布将在开发人员会议上专注于.NET Aspire

2024年7月15日微软宣布,其开发执行团队将在下个月的开发者大会上聚焦于使用 .NET Aspire 的云原生开发,以及结合人工智能的“现代 SQL”在 Microsoft Fabric 中的应用。微软的 Visual Studio LIVE! 2024 大会不仅是一个会议,而是创新、学习和社区庆祝的盛会。大会将于 8 月 …

PDF 分割拆分 API 数据接口

PDF 分割拆分 API 数据接口 文件处理,PDF 高效的 PDF 分割工具,高效处理,可永久存储。1. 产品功能高效处理大文件; 支持多语言字符识别; 支持 formdata 格式 PDF 文件流传参; 支持设置每个 PDF 文件的页数; 输出文件永久 CDN 存储; 全接口支持 HTTPS(TLS v1.0 / v1.1 …

拯救SQL Server数据库事务日志文件损坏的终极大招

拯救SQL Server数据库事务日志文件损坏的终极大招在数据库的日常管理中,我们不可避免的会遇到服务器突然断电(没有进行电源冗余),服务器故障或者 SQL Server 服务突然停掉, 头大的是ldf事务日志文件也损毁了,SQL Server服务器起来之后,发现数据库处于"Recovery Pen…

On July

STAYING IN HOME 7月3日放假回家,这段时间大致是起床挖洞、晚上打球、外卖度日。完全的"宅",计划去练车,不巧的是打球崴脚了,只能闭关一下了。刚回家的那几天全是凌晨四五点睡,这几天好转一些,有意控制早点,不然窗帘一拉,起床就是下午三四点。每次起床就是吃完…

openEuler arm 环境源码编译mysql 8.0.37

部分参考博客 https://blog.csdn.net/ghpanxt/article/details/119387253 1、安装依赖:yum install -y openssl-devel ncurses-devel libaio libaio-devel libtirpc-devel openldap-devel openldap git bison 【注意】:对于openEuler操作系统,还需要安装rpcsvc-proto依赖,具…

Windows安装MySQL8

Windows安装MySQL8 0.下载 社区版最新版:https://dev.mysql.com/downloads/installer/ 各版本:https://downloads.mysql.com/archives/installer/Windows (x86, 32-bit), MSI Installer,迅雷下载 企业版 ... 1. 安装 1). 双击官方下来的安装包文件2). 根据安装提示进行安装安…

全网最适合入门的面向对象编程教程:18 类和对象的 Python 实现-多重继承与 PyQtGraph 串口数据绘制曲线图

本文主要介绍了Python中创建自定义类时如何使用多重继承、菱形继承的概念和易错点,同时讲解了如何使用PyQtGraph库对串口接收的数据进行绘图。全网最适合入门的面向对象编程教程:18 类和对象的 Python 实现-多重继承与 PyQtGraph 串口数据绘制曲线图 摘要: 本文主要介绍了 P…

【笔记】圆方树

【笔记】圆方树 1 定义 仙人掌: 所有边都至多被包含在一个环中。2 构建 给一个点和它所在的所在的所有点双连边,同时,我们定义方点为虚点(即表示点双的点),圆点为原图上的点。 注意,是所有点双,所以一个割点会连向多个点双。同时,由定义得,该图有且仅有圆方边,因为圆…

缓存穿透、缓存击穿、缓存雪崩的场景以及解决方法

缓存穿透、缓存击穿、缓存雪崩的场景以及解决方法都是缓存惹的祸 在项目开发中,我们的数据都是要持久化到磁盘中去,比如使用 MySQL进行持久化存储,但是呢由于流量越来越大,查询速度也逐渐变慢了起来,于是我们决定!使用缓存!然而使用缓存导致会经常面临三座大山!缓存穿透!!…

CSS Case Insensitive Attribute Selector All In One

CSS Case Insensitive Attribute Selector All In One CSS 大小写敏感的属性选择器CSS Case Insensitive Attribute Selector All In OneCSS 大小写敏感的属性选择器/* case sensitive, only matches "case_sensitive" */ [class=case_sensitive] {background: pink;…