SCTF2021——gadget报告
Last Update:
关键点总结:
1.架构切换(retf与retfq与ret)
2.侧信道攻击
首先应该认识到:
retn与retf这两条指令的区别 以及 64位机器是如何执行32位程序的
retn(return near)近跳转,等同于 pop ip
retf(return far)远跳转,等同于 pop ip;pop CS
CS指的是**段寄存器(Code-Segment Register)**,在早期80386时代,它本用于地址拓展,但如今64位的系统下,该寄存器的内容已经和那个时代完全不同了。
现代的CS寄存器中用于存放 **数据段选择子(Code-Segment Descriptors)**,如下为其格式:
本文不再赘述其含义,我们主要关心该选择子的 D 标志位,它用以区分程序应该运行在32位还是64位架构上
因此,如果D标志位被置1,则表示程序应该运行在64位,反之则为32位(请注意,这个说法并不严谨,因为它们的差别不只是一个bit而已,但本文出于便于理解的目的如此称呼,为避免误导,特此提醒)
很多师傅的Writeup中写道:
cs寄存器中0x23表示32位运行模式,0x33表示64位运行模式
实际上,它们只有一个bit的差别而已,0x23:10 0011 ; 0x33:11 0011
高两位是GDT的索引,具体对应到GDT中,其上的D位各不相同,因此导致了运行模式的差异
另外需要提到的一点是,一部分师傅在WP里会这样写:
使用retf切换到32位,retfq再回到64位
但这二者实际上没有区别,不必多此一举,则一即可。但笔者在查阅资料的时候,并没有发现哪份文档写到retfq指令,猜测是由于AT&T语法的关系吧
题目利用思路:
仅有调用号0与5可用。但在32位下,0对于open;在64位下,5对应read。因此我们能够将flag读进内存。
接下来将flag与我们猜测的内容进行比较,如果猜对,那么程序就跳转至死循环处,最终因为超时而down;否则就直接退出。猜测方式很多,较为易懂的是利用sub+jz来实现相等跳转
EXP:
(有时间再补)
参考文章:
https://m-ouse.github.io/post/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3wow64-I/
https://stackoverflow.com/questions/21165678/why-64-bit-mode-long-mode-doesnt-use-segment-registers
Mark:http://liupzmin.com/2021/06/27/theory/stack-insight-01-md/
对我来说算是个冷知识:https://stackoverflow.com/questions/63975447/why-virtual-address-are-48-bits-not-64-bits
插画ID : 93869785