LACTF2026-pwn 个人题解
tic-tac-no
IDA
main

井字棋
playerMove

数组越界写
checkWin

相同字符就胜利
bss

越界写把电脑的棋子变成自己的就行了,脚本都不用写
ScrabASM
IDA
main

swap_tile

play

其实就是执行随机生成的 shellcode ,但可以更换任意字节为随机字节
攻击思路
由于 srand 以时间作种子,可以考虑在同时运行本地随机数生成程序和攻击脚本以预测随机数,进而控制 shellcode
且由于只有 15 字节的空间,我们可以先执行 read shellcode 再自行写入提权 shellcode

(这张图片用了队友 ItsFlicker 的,懒得自己再截了)
1 | add al, 0xd |
exp
c
1 |
|
python
1 | from pwn import * |
tcademy
checksec

保护全开
IDA
main

菜单题
menu

create_note

只有两个槽位
delete_note

print_note

puts 可以通过溢出泄露一些内容
get_note_index

read_data_into_note

此处有由整数溢出造成的堆溢出漏洞
攻击思路
glibc 版本为 2.35 ,是高版本,有 PIE 保护,没有 hook 函数可以劫持
所以考虑劫持某个 _IO_FILE 结构体用来 getshell ,在此之前应先 leak libc
可以通过 tcache poisoning 去把一个 chunk 放入 unsortedbin 中来实现 libc leak
在高版本 libc 中, tcache 劫持的要求会更加严格
首先是 safe-linking 机制,这需要还原泄露出的 next 指针,并且 key 的生成不再与堆地址相关,改为和 canary 类似的随机 8 字节数据
然后是分配 tcache 时的判断,决定 tcache 是否分配的标准由 entry 是否为空变为 counts 是否为 0 ,不能再简单粗暴地劫持 tcache_pthread_struct 就完事了
对于这道题目而言,更加棘手的是同时持有的 chunk 槽位只有两个,而想要通过 tcache poisoning 把目标地址写的权限拿到手至少需要持有两个该 tcache 的 chunk ,这需要我们修改 counts ,而在能够修改 counts 之前的 tcache_pthread_struct 劫持步骤,我们必须预先申请两个相同大小的 chunk 再放入 tcache
而且还要注意不要破坏掉 size ,破坏了也要修复,不然 delete 的时候有你好受
在进行 unsortedbin 布置时我们采用了堆溢出修改 size 结合 counts 篡改的方式,这样可以在持有该 chunk 的情形下将其定位到 unsortedbin ,事后直接 free 即可,非常方便
还要注意一个小细节: tcache_pthread_struct 会被劫持也会被释放,这样的话前面的一些 counts 会变得比较奇怪,而且用于劫持 tcache_pthread_struct 的那个 tcache 会废掉,需要更换 size 做接下来的步骤
最后劫持 IO_2_1_stdout 打 house_of_apple2 即可
exp
1 | from pwn import * |