菜鸟PWN手进阶之栈溢出基础

一、基础知识

栈的结构概述

编译器使用堆栈传递函数参数、保存返回地址、临时保存寄存器原有值(即函数调用的上下文)以备恢复以及存储本地局部变量
栈的特点:后进先出的数据结构,栈的结构是从进程高地址向进程低地址生长

调用约定:

x32:函数的参数在函数返回地址上方,压栈的方式传参
x64:
.
rdi,rsi,rdx,rcx,r8,r9,(push to stack)
rdi,rsi,rdx,r10,r8,r9,(push to stack)for system call
内存地址小于0x00007FFFFFFFFFFF。6个字节长度

return values is stored in rax
x64函数调用

Stack Frame

function prologue

call 4004e7  //将下一行地址压入栈中
push rbp
mov  rbp,rsp
sub  rsp,0x10

栈结构
function epilogue

leave == mov rsp,rbp
         pop rbp
ret   == pop rip

function epilogue

整个流程执行完,栈的结构不变

Protection
Stack Guard(canary)

做完function prologue的时候会将随机生成的乱数塞入栈中,fuction return前会检查乱数是否有被动过,若发现动过立即结束程序

DEP(NX)

Data execution prevention
可执行的地方不能写,可写的地方不能执行

ASLR

Address Space Layout Randomization
每次程序执行时stack,heap,library的位置不一样

PIE

code和data一起跳来跳去

一句生成无保护程序的gcc
gcc ret2sc.c -m32 -fno-stack-protector -no-pie -z execstack -o ret2sc
ASLR关闭 改kernel文件

二、栈溢出类型

核心:通过控制返回地址控制程序的执行流程

(一)基础缓冲区溢出
条件:

程序必需向栈上写入数据
写入的数据大小没有被控制

栈溢出重要步骤
1.寻找危险函数
  • 输入
    gets,直接读取一行,忽略’\x00’
    scanf
    vscanf
  • 输出
    sprintf
  • 字符串
    strcpy,字符串复制,遇到’\x00’停止
    strcat,字符串拼接,遇到’\x00’停止
    bcopy
2.计算填充

打开IDA,看变量距EBP的值
我们的覆盖需求:

  • 覆盖函数返回地址
  • 覆盖栈上某变量的值
  • 覆盖bss段某变量的内容
  • 根据现实情况,覆盖特定的变量或地址的内容
(二)Basic Rop

ROP攻击的条件
-程序存在栈溢出,并且可以控制返回地址
-可以找到满足条件的gadgets以及相对的gadgets地址
(如果gadgets每次的地址是不固定的,我们就需要想办法获取对应的地址)

1.ret2text

有现成的system(’/bin/sh’),直接覆盖返回地址。

2.ret2shellcode

自己在某段可读可写的地方写shellcode,覆盖返回地址到此处

#自己构造开shell的syscall
sc=asm(
'''
mov  rbx,0x68732f6e69622f
push rbx
mov  rdi,rsp
xor  rsi,rsi
xor  rdx,rdx
mov  rax.0x3b
syscall
''')
#利用pwntools的shellcode
sc=asm(shellcraft.sh())
3.GOT Hijacking

绕过canary

Lazy Binding

因为不一定每个library function都会被执行到,所以采用lazy binding机制,当第一次执行到library function才会去寻找真正的address 并运行 binding

Global Offset Table

GOT为library function的指标阵列,因为lazy binding机制因此一开始不会知道真实位置,取而代之的是plt段的code

Lazy Binding Procedure

第一次加载
1
以后加载
在这里插入图片描述

GOT Hijacking

劫持got地址的值,程序执行常规的库函数时其实执行的是我们的shellcode。

RELRO(Relocation Read-Only)
  • Partial RELRO
    GOT 可写
  • Full RELRO
    load time时会将所有function resolve完毕
    GOT 不可写
    ROP系列
    ret2syscall
    ret2libc
4.ret2syscall

对抗NX
Return Oriented Programming
通过不断去执行包含ret的代码片段来达到想要的操作
这些包含ret的代码片段被称为gadget
execve
利用ROPgadget找到相应gadget按下面排列
叠法

5.ret2plt

程序中有system()函数
22

6.ret2libc

程序里没有execve(),system(),或者后门
开着NX
开着ASLR
把libc当gadget来用,通过实际地址减偏移找到libc_base
在libc里找gadget,这里的gadget都是偏移地址,所以实际地址是偏移地址+libc_base,叠gadget
或者用 one_gadget libc-2.27.so

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值