Pwn
Pwn
环境配置
安装python2.7:
apt install python2.7 python-pip python-dev git libssl-dev libffi-dev build-essential
安装gdb
,gdb-multiarch
,同时安装binfmt
(binfmt*
)识别文件类型;
安装gdb插件pwndbg
(github安装https://github.com/pwndbg/pwndbg.git)
安装pwntools
安装gcc-multilib
可以在64位linux下运行32位程序
Pwn基础理论
在计算机中,当要表示的数据超出计算机所使用的数据的表示范围的时候,则产生数据的溢出.
产生的原因:
- 使用非类型安全的语言比如c/c++
- 以不可靠的方式存取或者复制内存缓冲区
- 编译器设置的内存缓冲区太靠近关键数据结构
gdb的使用:
1 |
|
miniconda安装:如果安装失败,可以通过bash安装而不是zsh
如何查看当前是bash还是sh?echo $0
如何让ubuntu 22.04通过本地root登录?
在/etc/pam.d/gdm-password和/etc/pam.d/gdm-autologin
注释掉auth required pam_succeed_if.so user != root quiet_success
在/root/.profile
中注释mesg n 2> /dev/null || true
,改为tty -s && mesg n || true
如何检查程序保护情况?
checksec --fiel=...
如何在编译时关闭保护?
gcc -no-pie -fno-stack-protector -z execstack -m32 -o read read.c
如何查看程序使用了哪些函数?
objdump -t -j .text read
-j 仅仅显示某一个段
-t 显示符号表入口
基础篇
从汇编角度理解函数调用
在调用一个函数时究竟发生了什么?
- 函数参数压栈
- 取地址
- 压栈
- 返回地址压栈 这个在调用call的同时就执行了
- 执行函数代码
- 保存ebp
- 开启新栈帧
- 保护寄存器
- 执行代码
- 还原寄存器
- 平衡堆栈 找出之前的返回地址
如果一个函数的参数数量大于6,那么参数1到6使用相应的寄存器rdi rsi rdx rcx r8 r9
来传递,超出6的部分使用栈来传递
使用寄存器进行参数传递时,寄存器的使用是有特殊顺序规定的:
此外,寄存器名字的使用取决于传递参数的大小,如果第一个参数大小是4字节,需要用寄存器edi来保存
编译的过程?
- 首先预处理器cpp将main.c翻译成ascii的中间文件main.i(在某些gcc版本中,预处理器被集成到编译器内部)
- 然后c编译器cc1将main.i翻译成ascii的汇编语言main.s
- 然后汇编器as将main.s翻译为可重定位目标文件main.o
- 最后链接器进行链接
接下来我们详细的看一下链接部分
首先感谢好文章7.4 可重定位目标文件 - 深入理解计算机系统(CSAPP) (gitbook.io)
为了链接,链接器必须进行两部分工作
- 符号解析
- 重定位
目标文件有三种
- 可重定位目标文件
- 可执行目标文件
- 共享目标文件
上面的
symtab
是一个符号表,存放程序中定义和引用的函数和全局变量信息
如何理解GOT和PLT?
首先要明确一下链接库的概念,链接库分为两种
动态链接库
在win中后缀为dll,在linux中为.so
动态链接库在编译时并不编译进程序,而是在程序运行时进行调用,性能虽然不高,但是软件的体积较小
静态链接库
在win中后缀为.lib 在linxu中为.a
静态链接库在编译时代码并入程序,造成程序体积庞大 但是性能较高 不依赖任何第三方库
如何理解shellcode?
shellcode对应的C语言代码一般是
system("/bin/sh")
,但是在底层调用的是sysexecve()
接收三个参数:
filename
argv
envp 表示传递给程序的环境变量的字符串数组
如何利用python把字符串和16进制数字相互转换?
1
2print("sh/".encode().hex())
print(bytes.fromhex("73682f").decode())
实战-溢出实例
1 |
|
我们的最终目的是执行exploit函数
首先我们执行checksec --file=read2
查看程序保护情况
然后我们通过objdump -t -j .text read2查看代码段有多少函数
观察到有三个函数,最终我们的目的是执行exploit函数
然后我们进入调试
输入start开始逐步调试程序
注意看此时的ebp和esp是指向同一地址,注意栈帧的变化
单步运行:n
通过disass exploit查看函数得到地址0x08049186
然后运行脚本
1 |
|
Cannary保护
进阶篇
Rop-Ret2Text介绍及插件配置
ret2text就是执行程序中的已有代码
如何使用pwndbg快速定位溢出偏移?
cyclic -l 报错地址
如何使用peda快速定位溢出偏移?
pattern create 200
pattern offset 0x63561
Rop-Ret2Text实例讲解
objdump -t 查看程序中使用的函数 objdump -d 查看函数的汇编代码 objdump -d -j .plt 查看plt表 -j的参数有 .text .data .const .bss objdump -d -M intel查看函数的汇编代码 并且数intel架构的
- gdb attach 你的pid 附加进程调试
Rop-Ret2Shellcode-32位实例
ret2text依赖于程序中存在
system('bin/sh')
的函数ret2shellcode必须不开启nx保护
shellcode就是用于实现特定功能的汇编代码,通常是开启一个shell
-
shellcode获取的两种方式
- 手写
- pwntools生成
nx又称dep,即数据执行保护,可写的不可执行,可执行的不可写
查看要拷贝的那个地址所在的段
- gdb中readelf
- shell中readelf -S
gdb中的vmmap是查看程序的各种段的地址和范围的