CISCN 2023 华南赛区 记录贴
桂林之旅(虽然还没玩就回学校了
比赛
easynote
scanf函数中格式化 "%ld"
对应的参数没有做取址操作,相当于以size的值为地址写八个字节,并且这里size未进行初始化
利用这个函数可以很容易地提前控制好scanf函数中未初始化的size的值,于是就构成了可控的任意地址写
比赛时我是先利用任意地址写劫持atoi函数的got表为printf函数的plt表,由于atoi的参数是由我们输入控制的,所以就有了可控的格式化字符串,利用这个可以泄露出包括libc地址在内的很多栈上数据。泄露完后再利用任意地址写往bss段上布置好伪造的 IO_FILE
结构体最后劫持stdout指针即可
1 | #!/usr/bin/python2 |
hnlogin
比赛时师兄CSOME打的,注意最后rop要用 execve("/bin/sh", 0, 0)
,system
函数可能会因为环境问题不能完整执行
1 | from pwn import * |
oldheap
add函数中会先申请一个 0x20
大小 ( malloc(0x10
) 的chunk,其后8个字节储存content的chunk指针,前8个字节储存content的size,content的chunk大小是由我们控制的,并且后续的edit和show的大小都是以这前8个字节表示的size为依据
delete中存在UAF
先申请一个content大小为0x20 ( malloc(0x10)
) 的chunk,得到两个chunk(A1和A2),再申请一个content大小为0x30 ( malloc(0x20)
) 的chunk,得到两个chunk(B1和B2)。将它们按顺序释放,此时tcache(0x20)链表的结构为 B1->A1->A2
,这时申请出content大小为0x10的chunk,其用于储存content的指针刚好就是之前的A1,于是就可以控制A1的size和content指针,达成了任意地址任意长度的写入和泄露。由于存在UAF,所以这个洞可以反复利用,第一次将content指针改为got表泄露libc地址,第二次改为bss段地址布置 IO_FILE
结构体,第三次改为储存stdout指针的地址劫持stdout指针即可
1 | #!/usr/bin/python2 |
Virtual_World
break阶段结束两分钟打通的,心态炸裂(导致后面的fix阶段第一轮直接开摆)。主要是最后几分钟太急了,新放到exp里的gadget都忘记加libc基址的偏移了(要背大锅力),导致 rop_chain
断了(其实早就该通的了(悲)
vm的pop指令里可以泄露堆上的数据
由于成员r0初始为0,所以连续执行pop指令可以造成数组下溢泄露上一个chunk的数据。比赛时是CSOME帮忙泄露的libc地址,大概就是先把 unsortedbin chunk
扩大,然后先申请一个chunk,把 main_arena
的地址留在这个chunk中,之后的calloc会在这个chunk的下方申请,再利用负数溢出就可以通过负下标溢出读取到上面的chunk上的数据
edit函数里没有检查idx,可以利用负idx使其下溢到stdout指针的位置修改 _IO_2_1_stdout_
结构体上的内容
exp不太稳定,可能需要多打几次(
1 | #!/usr/bin/python2 |
others
留坑(虽然比完赛当天就急着赶回学校了好像也没太多好写的