分类 二进制 下的文章

Ubuntu下测试格式化字符串漏洞

基础内容可以参考

http://120.78.88.5/WooyunDrops/#!/drops/823.漏洞挖掘基础之格式化字符串

 

首先确保系统禁用了ASLR

执行以下命令禁用ASLR,防止地址动态分配造成实验失败

实验源码

gcc编译.关闭ld链接器不可执行机制,关闭gcc编译器gs验证码机制

gcc编译器gs验证码机制

gcc编译器专门为防止缓冲区溢出而采取的保护措施,具体方法是gcc首先在缓冲区被写入之前在buf的结束地址之后返回地址之前放入随机的gs验证码,并在缓冲区写入操作结束时检验该值。通常缓冲区溢出会从低地址到高地址覆写内存,所以如果要覆写返回地址,则需要覆写该gs验证码。这样就可以通过比较写入前和写入后gs验证码的数据,判断是否产生溢出。

关闭gcc编译器gs验证码机制的方法是:

在gcc编译时采用-fno-stack-protector选项。

ld链接器堆栈段不可执行机制

ld链接器在链接程序的时候,如果所有的.o文件的堆栈段都标记为不可执行,那么整个库的堆栈段才会被标记为不可执行;相反,即使只有一个.0文件的堆栈段被标记为可执行,那么整个库的堆栈段将被标记为可执行。检查堆栈段可执行性的方法是:

如果是检查ELF库:readelf -lW $BIN | grep GNU_STACK查看是否有E标记

如果是检查生成的.o文件:scanelf -e $BIN查看是否有X标记

ld链接器如果将堆栈段标记为不可执行,即使控制了eip产生了跳转,依然会产生段错误。

关闭ld链接器不可执行机制的方法是:

在gcc编译时采用-z execstack选项。

开始调试

首先分析一下汇编代码,下面这一段代码就是将p指向flag,并且将局部变量flag、p压栈,我们只需要利用格式化字符串漏洞覆盖掉*p指向的内存地址的内容为2000就可以了。

*p地址即位ebp-0x10 从上图我们可以看到为0xffffcfb8

所以,我们现在要将0xffffcfb8这个地址的内容修改为2000。

注: gdb调试环境里面的栈地址跟直接运行程序是不一样的,也就是说我们在直接运行程序时修改这个地址是没用的,所以我们需要结合格式化字符串漏洞读内存的功能,先泄露一个地址出来,然后我们根据泄露出来的地址计算出ebp-0x10的地址。

执行get()函数后随便输入AAAAAAA可以观察到栈区如下图

如果输入%x的话就可以读出esp+4地址上的数据 即0xffffcf54

所以说b8-54=64 计算出偏移量后我们可以去获取泄漏的地址然后再去覆盖

0xffffcfa4+0x64=0xffffd008

所以我们要修改的地址为0xffffd008

生成payload

成功

pwnable入门题笔记

fd

ssh连上

找到fd的源码

首先,程序接收一个参数argv[1],转换为整数型之后减0x1234 ,读入buf ,比较是否与LETMEWIN相同,如果相同则get flag

 

read函数

read()会把参数fd所指的文件传送nbyte个字节到buf指针所指的内存中。若参数nbyte为0,则read()不会有作用并返回0。返回值为实际读取到的字节数,如果返回0,表示已到达文件尾或无可读取的数据。错误返回-1,并将根据不同的错误原因适当的设置错误码。

linux文件描述符

Integer value <stdio.h> file stream
0 stdin
1 stdout
2 stderr

也就是我们可以令fd=0 使得标准输入,buf的值就可以键入了

又因为

所以我们令fd=0x1234的10进制4660然后键入LETMEWIN

 

collision

先看代码

分析源码,首先输入长度为20的字符然后与关键函数check_password比较

p强制转化为指针,32位下指针一般与char的大小相同,所以相当于分成5组(char1个字节,int4个字节

然后把每四个字符看成一共int型的数字,进行5次循环相加,结果放入res中

最后符合hashcode = 0x21DD09EC; 拆分一下符合20长度限制,如下

注意下是小端模式

 

bof

给的源码:

key == 0xcafebabe 即可拿到shell但实际传的key为0xdeadbeef

又看到gets 可以溢出

IDA打开编译好的c

发现char s //[sp + 1Ch] [bp – 2Ch]说明,这个字符串s 是从[bp – 2Ch]处开始进入栈缓冲区的,所以我们只要覆盖2C字节,再加上EBP和EIP的8个字节,总共52个字节就可以成功覆盖第一个变量,也就是func里面的参数覆盖为0xcafebabe

这里盗个图方便理解

所以EXP为

拿到flag

PE文件小记

PE文件的全称是Portable Executable,意为可移植的可执行的文件,常见的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微软Windows操作系统上的程序文件(可能是间接被执行,如DLL)


一个可执行文件不光包括二进制的机器代码,还有许多其他信息如字串符,字体,图标等。PE文件格式规定了所有这些信息在可执行文件中如何组织。

PE文件格式把可执行文件分成若干个数据节,不同资源放在不同节中。

一个典型的pe文件中包含的节如下:

.text 由编译器产生,存放二进制的机器代码,也是我们反汇编和调试的对象

.data 初始化的数据块,如宏定义、全局变量、静态变量等

.idata 可执行文件所使用的动态链接库等外来函数与文件的信息

.rsrc 存放程序的资源,如图标、菜单等

(参考:《0day:软件漏洞分析技术》)

PE文件的结构一般如下图

  • DOS头是用来兼容MS-DOS操作系统的,目的是当这个文件在MS-DOS上运行时提示一段文字,大部分情况下是:This program cannot be run in DOS mode.还有一个目的,就是指明NT头在文件中的位置。
  • NT头包含windows PE文件的主要信息,其中包括一个‘PE’字样的签名,PE文件头(IMAGE_FILE_HEADER)和PE可选头(IMAGE_OPTIONAL_HEADER32),头部的详细结构以及其具体意义在PE文件头文章中详细描述。
  • 节表:是PE文件后续节的描述,windows根据节表的描述加载每个节。
  • 节:每个节实际上是一个容器,可以包含代码、数据等等,每个节可以有独立的内存权限,比如代码节默认有读/执行权限,节的名字和数量可以自己定义,未必是上图中的三个。

(来源:http://blog.csdn.net/evileagle/article/details/11693499)