程序的功能是一个4*4的“rubik's square”游戏,有一个0x10大小的叫做__m128i的结构体。
程序的功能如下
其中有专门存放指令记录的地方,位于stack上,并且有记录code_num的变量,相对位置关系如下
漏洞点在如下位置
正常情况是将指令历史存入code_buffer位置,但是没有对code_num大小限制,导致可以溢出到code_num变量位置,更改code_num的信息,导致可以泄露更改stack上的信息。
思路:
exp如下:
程序给了,但是跑不起来,本地不能测试。
程序逻辑比较简单,是两次任意地址读和一次任意地址写,可以通过修改got表来获得更多次数的任意地址写权限。
通过这道题目可以学习一下怎么获得shell
这里我直接贴一下已经放出来blog的解答思路
首先是这篇博客https://ptr-yudai.hatenablog.com/entry/2020/02/06/130551#pwn-491pts-Think-twice-before-speaking-once
然后是这一篇博客http://blog.redrocket.club/2020/02/04/hacktm20-thinktwice/
参考链接
http://blog.redrocket.club/2020/02/04/hacktm20-thinktwice/
https://ptr-yudai.hatenablog.com/entry/2020/02/06/130551#pwn-491pts-Think-twice-before-speaking-once
这道题目给了两处任意地址写的机会,并且提供了libc的地址,libc环境是2.29,2.29的vtable是具有写权限的。
https://teamrocketist.github.io/2020/02/05/Pwn-HackTM-2020-Trip-To-Trick/这个博客记录了详细的解题过程,看了之后受益很多,考查点主要是fclose()函数触发的程序流劫持。
本题目是可以修改vtable的值,利用fclose()控制程序流主要是如下源码
当调用setbuf关闭缓冲区之后,再次输入的时候将不会在heap区域分配空间当做缓冲区,其中IO_buf_base指向的是缓冲区起点,IO_buf_end指向的是缓冲区终点,关闭缓冲区之后,IO_buf_base 指向_IO_2_1stdin->shortbuf,位于stdin内部,保存\n或者\0,IO_buf_end=IO_buf_base+1。
我们修改_IO_2_1stdin->IO_buf_end,使其增大之后,便可以控制此缓冲区内部的内容,即输入时的内容都会先存储在当前的缓冲区内(libc空间)。
我最初还有一个疑问是,scanf("%llx %llx",&v4,&v5)正常来说是输入两个64位十六进制整数,在第二次输入时输入了长度很长的payload,不按照正常输入可以输入进去么? 经过程序测试的结果是,他会将输入的所有字符串先缓存在缓冲区内,然后按照格式解析给v4,v5,所以我们的payload是可以正常覆盖到libc上的。
解题思路:
之所以介绍这道题目,是因为这道题目最后的get shell方式也是通过fclose函数,本题目不可以在libc段写,但是可以再bss段写,我们可以在bss段伪造stderr,然后利用fclose(stderr)获得shell。
由于是伪造stderr,所以不同于上题目中利用_IO_FINISH (fp);来控制程序流,我们控制程序流的位置要稍微靠前一下,否则还要保证之前的功能可以正常,劫持程序流位置如下:
贴一下exp,感兴趣的可以自己去调试一下
题目进行了seccomp限制,但是rules未知,需要首先编写shellcode进行探测
得知seccomp限制条件如下
只允许read open 并且open的fd=3时,对于buffer值进行了规定,因此需要两次open,使得fd值为4
解题思路是第一步利用shellcode进一步扩大shellcode空间,可以输入更多的shellcode;然后利用侧信道攻击,将flag内容读取到内存中,然后利用汇编指令进行遍历比对,最终得到flag。
详见博客:https://r3billions.com/writeup-obey-the-rules/
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)