PWN 是一个黑客语法的俚语词 ,是指攻破设备或者系统 。发音类似”砰”,对黑客而言,这就是成功实施黑客攻击的声音–砰的一声,被”黑”的电脑或手机就被你操纵了 。
简单点说就是利用简单逆向工程后得到代码(源码、字节码、汇编等),分析与研究代码最终发现漏洞,再通过二进制或系统调用等方式获得目标主机的shell 。(取自link)
环境准备:link
PWN入门:link
PWN入门到放弃:link
缓冲区溢出初讲:link
PWNTOOLS使用简介:link
第一步:通过file判断附件文件类型,判断是ELF文件,然后利用checksec命令查看开启了哪些保护机制,运行一下,查看程序功能(参考checksec工具使用-pwn )
- Arch
程序架构信息。判断是拖进64位IDA还是32位,exp编写时p64还是p32函数。
- RELRO
是Relocation Read-Only的缩写,主要针对 GOT 改写的攻击方式。它分为两种,Partial RELRO 和 Full RELRO。如果开启FULL RELRO,意味着我们无法修改got表
- Stack
如果栈中开启Canary found,那么就不能用直接用溢出的方法覆盖栈中返回地址,而且要通过改写指针与局部变量、leak canary、overwrite canary的方法来绕过
- NX
NX enabled如果这个保护开启就是意味着栈中数据没有执行权限,如此一来, 当攻击者在堆栈上部署自己的 shellcode 并触发时, 只会直接造成程序的崩溃,但是可以利用rop这种方法绕过 - PIE
PIE enabled如果程序开启这个地址随机化选项就意味着程序每次运行的时候地址都会变化,而如果没有开PIE的话那么No PIE (0x400000),括号内的数据就是程序的基地址
运行后,就一行helloworld,没什么特殊的:
第二步:拖入IDA,观察结构
汇编代码:
F5反汇编后的代码:
函数:
IDA的快捷键 Link
a:将数据转换为字符串
f5:一键反汇编
esc:回退键,能够倒回上一部操作的视图(只有在反汇编窗口才是这个作用,如果是在其他窗口按下esc,会关闭该窗口)
shift+f12:可以打开string窗口,一键找出所有的字符串,右击setup,还能对窗口的属性进行设置
ctrl+w:保存ida数据库
ctrl+s:选择某个数据段,直接进行跳转
ctrl+鼠标滚轮:能够调节流程视图的大小
x:对着某个函数、变量按该快捷键,可以查看它的交叉引用
g:直接跳转到某个地址
n:更改变量的名称
y:更改变量的类型
/ :在反编译后伪代码的界面中写下注释
:在反编译后伪代码的界面中隐藏/显示变量和函数的类型描述,有时候变量特别多的时候隐藏掉类型描述看起来会轻松很多
;:在反汇编后的界面中写下注释
ctrl+shift+w:拍摄IDA快照
u:undefine,取消定义函数、代码、数据的定义
第三步:查看有哪些字符串
shift + F12 打开String窗口
看到了/bin/sh,点进去发现在command中
按X查找引用,然后进入,得到:
(这里其实已经告诉你函数从400596开始)
反汇编后:
程序中的system("/bin/sh");是关键所在,system拥有系统的最高权限,啥都能干,而它和**“/bin/sh”**连在一起则可以给我们提供一个类 似 cmd 的东西,我们可以用它来进行查看/修改/操作等动作。
现在我们已经找到了一个可以获取系统权限的函数,可以自己去查询flag,我们要做的就是调用这个函数
这个时候我们就想到了刚才看着好像有点奇怪的函数:
插入一个科普:ULL代表是unsigned long long
由上图可知:buf这个数组只有0x80 的空间 ,却可以输入长度 0x200 的东西,明显会造成栈溢出
溢出后会覆盖数组后面的内容,我们只要疯狂填充,直到我们要用到的语句(该题就是把数据填充到跳转语句,然后将跳转语句中的返回地址改为system函数所在的地址即可)
那我们就看一下buf后面有什么我们可以用到的语句:
当属于数组的空间结束后(到 0x0000000000000000 时),首先,有一个 s,8 个字节长度, 其次是一个 r,重点就在这,r 中存放着的就是返回地址。即当 read 函数结束后,程序下一 步要到的地方。
那我们只要知道函数的地址就可以了
设置一下可以看到地址偏移:菜单栏:Options->General,勾选此项
可以看到函数的开始地址是400596,那么我们只要把跳转的地址改为此地址就可以执行system("/bin/sh"),进而获得shell了。
编写EXP:
1 from pwn import * #导入 pwntools 中 pwn 包的所有内容 2 r = remote("220.249.52.133","43726") # 链接服务器远程交互 3 callsystem = 0x400596 4 exp = 0x80 * "A" 5 exp += 'x00x00x00x00x00x00x00x00' 6 exp += 'x96x05@x00x00x00x00x00' 7 r.sendline(exp) # 将shellcode (这里是exp) 发送到远程连接 8 r.interactive() # 将控制权交给用户,这样就可以使用打开的shell了
@ 是 x40
成功了!!!泪目