搜索
有爱,有技术,有你^_^)y
╱人◕‿‿◕人╲订下契约(注册新用户)

合作站点账号登陆

QQ登录

只需一步,快速开始

快捷导航
查看: 371|回复: 0
收起左侧

[黑客技术研究] Binary(pwn)学习笔记之一:基础知识

[复制链接]

签到天数: 1 天

连续签到: 1 天

[LV.1]初来乍到

15

主题

15

好友

3464

积分

序章

积分
3464
发表于 2016-6-18 13:25:48 | 显示全部楼层 |阅读模式

╱人◕‿‿◕人╲定下契约

您需要 登录 才可以下载或查看,没有账号?╱人◕‿‿◕人╲订下契约(注册新用户)

x
pwn是二进制安全的一个分方向,其主要目的是挖掘软件中的缓冲区溢出;格式化字符串等漏洞,来达到控制程序流程,甚至任意命令执行的结果
作为开始的一篇,首先还是复习一下binary的一些基础知识,以下是需要用到的资料。
[灰帽攻击安全手册].(美)哈里斯&哈珀
《汇编语言》王爽
Exploit编写系列教程1-10篇
Linux_Interactive_Exploit_Development_with_GDB_and_PEDA_Slides
http://shell-storm.org/shellcode/  在线的shellcode库
这里首先以简单的栈溢出作为开始吧。
栈溢出的形式多种多样,其中最主要的方式是通过覆盖函数的返回地址,来使程序执行任意地址的指令的方法。
同时,由于现代计算机不区分代码和数据,于是我们还可以构造一段shellcode,直接跳转执行,来实现在程序中植入代码的效果。
由于笔者之前有一定的基础,所以这里比较简略,由于程序运行时每次初始化后的地址都有所不同,覆盖的返回地址不能是某段代码的一个静态的地址(硬编码)。

而最好是一条程序中地址相对固定的,类似于jmp rsp的指令。
这里如果是为了方便快速的寻找,大可不用gdb,直接使用objdump命令

objdump -d test 反汇编test中的需要执行指令的那些section
objdump -D test 与-d类似,但反汇编test中的所有section

对于objdump指令,可以使用|grep xxx管道符来过滤出我们想要的的指令。

对于python来说,我们要方便的生成填充用的buffer和之后的payload,可以直接用python -c "print '$\backslash$x11'*1" 之类的指令来实现

在python中要集成在pwning中的网络通信功能,需要用到zio库,这个库可以在Linux下通过pip来进行pip install zio,如果没有pip,则需要sudo apt-get install pip

参考网页:https://pypi.python.org/pypi/zio
在这其中,zio主要起到的是简化socket编程的作用。

大概的使用方法如下
from zio import * 来导入zio库。

如果你需要在本地进行调试
    io = zio('./buggy-server')            \# used for local pwning development

如果需要连接到远程服务器
    io = zio(('1.2.3.4', 1337))           \# used to exploit remote service

Bigtang给出了更详细的用法
io = zio(target,timeout=5,print_read=COLORED(REPR,’yellow’),print_write=COLORED(REPR,’red’))

这里target就是ip,port. 也就是说后面还可以指定超时的时间和读写的字体颜色。

io.read_until(“input name:\x00″) 可以指定读取的终止部分。

io.write()方法,用于向服务器端传输指定的数据(字符串)

另外,zio内部带有很方便的转换函数l32,l64.可以把你的给的形似0x01020202的内存地址转化为hex编码,并且反序后的地址,这样就可以直接用write()方法了。

如果你通过write方法获取了一个交互shell,使用io.interact()来进入这个shell。

GDB:在linux下,唯一真正可靠的动态调试工具,大概就是gdb了,自带了disassemble的功能,可以查看到汇编源码,美中不足是没有GUI,而且指令较为复杂。

BT命令,可以查看当前使用的栈和其地址。另外,如果需要下断点,使用break 函数名,如break main,来对main()函数下断

如果要对某个内存地址下断点,使用break *内存地址来下断点,同时,后面还可以跟上条件语句,如 break *01010101 if x==1,这里如果有一个局部变量x,就可以进行判断

gdb查看指定地址的内存地址的值:examine 简写 x 用法:x/(n,f,u为可选参数) 内存地址(或者\$寄存器名称)

其中n是整数,表示从x开始到后面取几个内存单元的内容加以显示,每个内存单元的大小由u决定,u=b:1 byte     h:2 bytes     w:4 bytes g:8 bytes (均以字节为单位,1byte=2bits

f是显示的字符格式,x是16进制,c是字符串(char),d是10进制,i可以显示出反编译的汇编代码。

查看寄存器的指令,使用i r \$寄存器名称,或者是i r a来查看所有寄存器。

用r运行该程序 同时后面可以跟上参数python -c ' '来把输出的内容应用到程序的输入流上。

使用set disassembly-flavor intel可以把反汇编的结构显示为intel风格

set variable 变量名= 或者*(地址)= 可以修改内存的数值

使用metasploit的pattern_create.rb来精确计算缓冲区的大小,其原理是生成一个有序字符串,根据最终EIP被冲刷后的结果,来确定缓冲区的大小。

该工具位于framework\tools目录下,使用方法是 ./pattern_create.rb 字符串大小(例如5000)

最终通过./pattern_offset.rb (EIP地址)0x356b4234 5000 来计算出最终的buffer大小。

如果buffer过大,其实可以先大致的确定其大体部分,再把这个模型附加在后面,会更省时间和计算量。

//在gdb下,由于无法像od那样每步跟踪,所以对于rip来说无法直接观测到被覆盖后的结果。因此我们需要直接对rbp进行观察,计算出了rbp之前的buffer后,就可以加上rbp的长度,然后继续溢出

peda可以方便的让你查看寄存器的信息和其他数据,它也是用python编写的,而且直接附加到gdb。
可以用jmpcall来搜寻一些跳板指令,如jmpcall rsp

评分

参与人数 1宅币 +20 收起 理由
蛋挞妹。 + 20 o(* ̄▽ ̄*)ブ 发糖

查看全部评分

签名被小宅喵吞掉了~~~~(>_<)~~~~
回复

使用道具 举报

本版积分规则

小黑屋|手机版|技术宅(Z站|基宅) ( 粤ICP备18082987号-1 )

GMT+8, 2025-6-16 18:36 , Processed in 0.081425 second(s), 16 queries , Redis On.

Copyright © 2018 技术宅社区

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表