检查
1 | $ file death_note |
32位程序,没去符号表,只开了canary
分析
add_note()
index不能大于10,会检查name是否为可打印字符,同时会malloc一块地址用于存储字符串内容,将地址保存在note[index]数组中,但是index可以为负数,会造成数组越界
show_note()
读取地址指向的内容,同样存在数组越界的问题
del_note()
会free掉那块内存并清零指针
漏洞点
read_int()函数中没有检查index是否为负数,使得数组越界造成任意地址写
利用
我们可以构造出全是可见字符的shellcode,然后将got表地址改为我们需要执行的指令入口即可
shellcode
常见的shellcode思路是利用int 80h陷入软中断,
并使得eax内容为0x0b,ebx指向一个字符串”/bin/sh”,ecx、edx置0。如shellcraft.sh()
1 | /* execve(path='/bin///sh', argv=['sh'], envp=0) */ |
但是由于本题的限制,并不能直接使用
根据某师傅博客中写到,此题可用的汇编指令如下:
1 | 1.数据传送: |
我们可以先看看执行shellcode时的寄存器状况(断在了地址0x080487ef,即 call puts
可以发现,edx寄存器地址是shellcode的起始地址,而ebx、ecx的值是0,可以用来置0
我们可以修改shellcode如下
1 | /* execve(path='/bin///sh', argv=0, envp=0) */ |
修改got表
我们可以直接修改puts的got表,可以看到note的地址是0x0804A060,而我们只需要获得puts的got表地址,将它们相减并除以4即可
exp
我们需要获得的是32位汇编,所以不要把arch置为amd64
1 | #!/usr/bin/env python3 |
参考:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 0bs3rver的小屋!