目录
1 逆向及Bof基础实践说明
1.1 实践目标
实践对象:一个名为pwn1的linux可执行文件(已改名为pwn2127)。
程序正常执行流程:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。
正常情况下getShell是不会被运行的。实践目标就是想办法运行getShell。
实践内容:
- 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
- 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
- 注入一个自己制作的shellcode并运行这段shellcode。
1.2 基础知识
汇编知识
- call:调用子程序。先将返回地址(EIP)压入栈顶,再将程序跳转到当前调用方法的起始地址。
call=push eip + jump - leave:关闭栈帧。栈指针指向帧指针,然后POP备份的原帧指针到%EBP。
leave=mov %ebp %esp + pop %ebp - ret:子程序的返回指令。栈顶的返回地址弹出到EIP,按照EIP此时指示的指令地址继续执行程序。
ret=pop eip - NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)
- EIP:寄存器,存放CPU下一条要执行指令的内存地址。例如:主函数调用子函数,EIP指明子函数执行完后回到主函数中要执行的指令是哪一条。
- ESP:寄存器,存放栈顶指针,并且始终指向栈顶。
- EBP:寄存器,存放栈底指针。当调用子函数前,ESP将值传递给EBP,作为栈底;当子函数调用结束后,EBP将值传递给ESP,ESP再次指向栈顶。
Linux知识
- objdump -d:从objfile中反汇编那些特定指令机器码的section。
- “|”:管道,将前者的输出作为后者的输入。
- “>”:输入输出重定向符,将前者输出的内容输入到后者中。
- more:分页显示文件内容。
- perl:后面紧跟单引号括起来的字符串,表示在命令行要执行的命令。Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。“perl -e”后面紧跟单引号括起来的字符串,表示在命令行要执行的命令;使用输出重定向“>”可将perl生成的字符串存储到文件中。
- xxd:为给定的标准输入或者文件做一次十六进制的输出,它也可以将十六进制输出转换为原来的二进制格式。
- ps -ef:显示所有进程,并显示每个进程的UID,PPIP,C与STIME栏位。
- 小端模式:数据高字节保存在内存高地址,数据低字节保存在内存低地址。
- 大端模式:数据高字节保存在内存低地址,数据低字节保存在内存高地址,和阅读习惯一致。
- 栈:LIFO,栈顶低栈底高,增长方向由高地址向低地址,指令执行方向从低地址到高地址。
- shellcode:一段机器指令(code)。通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。
- ASLR:Address Space Layout Randomization,地址空间布局随机化。这是一种针对缓冲区溢出的安全保护技术。借助ASLR,文件每次加载到内存的起始地址都会随机变化。
2 直接修改程序机器指令,改变程序执行流程
下载目标文件pwn1,将文件名改为与自己学号相关的名字(我在实验中改为pwn2127&