g++ -Wall -fPIC -shared -o net_ip_hook.so main.cpp -ldl
sudo gedit /etc/environment

#LD_LIBRARY_PATH
#LD_PRELOAD
LD_PRELOAD="/home/dongl/code/safe_test/hook.so"
#LD_PRELOAD="/home/dongl/code/safe_test/net_ip_hook.so"
This commit is contained in:
dongl 2023-07-10 13:22:50 +08:00
commit 64452a7aa7
6 changed files with 820 additions and 0 deletions

7
CMakeLists.txt Normal file
View File

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.25)
project(ko_open)
set(CMAKE_CXX_STANDARD 17)
#add_executable(ko_open main.cpp)
add_executable(ko_open hook.bin.cpp)

273
hook.bin.cpp Normal file
View File

@ -0,0 +1,273 @@
//
// Created by dongl on 23-7-10.
//
#include <dlfcn.h>
#include <fcntl.h>
#include <cstring>
#include <string>
#include <set>
#include <unistd.h>
#include <algorithm>
#include <arpa/inet.h>
#define ACCEPT 9999
#define CONNECT 19999
// 定义指向原始open函数的函数指针
typedef int (*file_open_func_t)(const char *pathname, int flags, ...);
static file_open_func_t original_file_open = nullptr;
static file_open_func_t file_open = nullptr;
//read
typedef ssize_t (*file_read_func_t)(int fd, void *buf, size_t nbytes);
static file_read_func_t original_file_read = nullptr;
static file_read_func_t file_read = nullptr;
// connect
typedef int (*ip_connect_fun_t)(int, const struct sockaddr *, socklen_t);
static ip_connect_fun_t original_file_connect = nullptr;
static ip_connect_fun_t file_connect = nullptr;
// accept
typedef int (*ip_accept_fun_t)(int, struct sockaddr *, socklen_t *);
static ip_accept_fun_t original_file_accept = nullptr;
static ip_accept_fun_t file_accept = nullptr;
// 定义原始的do_sys_open()函数指针
//static long (*real_do_sys_open)(int dfd, const char __user *filename, int flags, umode_t mode) = nullptr;
// 定义日志文件路径和配置文件路径的环境变量
const char *LOG_FILE_PATH = "/home/dongl/code/safe_test/log";
const char *CONFIG_FILE_PATH = "/home/dongl/code/safe_test/config.txt";
const char *LOG_NET_IP_PATH = "/home/dongl/code/safe_test/net-log";
const char *CONFIG_NET_IP_PATH = "/home/dongl/code/safe_test/net-config.txt";
// 将时间戳转换为字符串
std::string Time_t2String(time_t t) {
char tmp[64] = {0};
strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&t));
return tmp;
}
// 获取当前进程的可执行文件路径和名称
size_t get_executable_path(char *processdir, char *processname, size_t len) {
char *path_end;
if (readlink("/proc/self/exe", processdir, len) <= 0)
return -1;
path_end = strrchr(processdir, '/');
if (path_end == nullptr)
return -1;
++path_end;
strcpy(processname, path_end);
*path_end = '\0';
return (size_t) (path_end - processdir);
}
// 读取配置文件并填充文件和进程集合
void read_config_file(std::set<std::string>& file_set, std::set<std::string>& process_set, const char* config_name) {
// 打开配置文件
int config_fd = original_file_open(config_name, O_RDONLY);
if (config_fd < 0)
return;
// 读取配置文件
char buff[4096];
std::string data;
bool state = true;
while (original_file_read(config_fd, buff, sizeof(buff)) > 0) {
for (const auto &item: buff) {
if (item != '\n') {
data.push_back(item);
} else if (item == '\n') {
// 检查行是文件部分还是进程部分
std::string temp = config_name == CONFIG_FILE_PATH ? "[safe_file]" : "[black_ip]";
if (data == temp) {
state = true;
data.clear();
continue;
} else if (data == "[safe_process]") {
state = false;
data.clear();
continue;
}
// 将文件或进程添加到相应的集合中
if (state) {
file_set.insert(data);
data.clear();
} else {
process_set.insert(data);
data.clear();
}
}
}
}
// 关闭配置文件
close(config_fd);
}
// 将文件访问日志写入日志文件
void write_log(const std::string &pathname, int mode, const std::string &result, const char* log_name) {
char run_path[40960] = {0};
char process_name[10240] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
std::string access_mode;
if (mode == O_RDONLY)
access_mode = "读取";
else if (mode == ACCEPT)
access_mode = "ACCEPT";
else if (mode == CONNECT)
access_mode = "CONNECT";
else if (mode == O_WRONLY)
access_mode = "写入";
else if (mode == O_RDWR)
access_mode = "读写";
else if (mode == (O_WRONLY | O_APPEND))
access_mode = "追加";
std::string log = "[" + Time_t2String(time(nullptr)) + "] " +
"<" + pathname + "> " + access_mode + " {" + process_name + ":" + run_path + "} " + result + "\n";
int log_fd = original_file_open(log_name, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (log_fd > 0) {
write(log_fd, log.c_str(), log.size());
close(log_fd);
}
}
//
ssize_t read(int fd, void *buf, size_t nbytes) {
std::set<std::string> file_set;
std::set<std::string> process_set;
read_config_file(file_set, process_set, CONFIG_FILE_PATH);
// 查进程名 及 运行路径
char run_path[4096] = {0};
char process_name[1024] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
// 根据fd取文件名
char file_name[4096] = {'\0'};
char file_path[4096] = {'\0'};
snprintf(file_name, sizeof(file_name), "/proc/%d/fd/%d", getpid(), fd);
ssize_t ret = readlink(file_name, file_path, sizeof(file_path) - 1);
if (ret == -1) {
return original_file_read(fd, buf, nbytes);
}
// 检查
auto safe_file = file_set.find(file_path);
auto safe_process = process_set.find(process_name);
// 校验
if (safe_file != file_set.end()) {
if (safe_process != process_set.end()) {
write_log(file_path, O_RDONLY, "正常访问", LOG_FILE_PATH);
} else {
write_log(file_path, O_RDONLY, "拒绝访问", LOG_FILE_PATH);
errno = EACCES;
return original_file_read(fd, buf, 0);
}
}
return original_file_read(fd, buf, nbytes);
}
// 判断接入的网络是否为过滤IP如果是则提前返回
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
// 获取链接ip
char ip[128];
memset(ip, 0, sizeof(ip)); // ip地址
int port = -1; // 端口号
if (AF_INET == addr->sa_family) {
auto *sa4 = (struct sockaddr_in *) addr;
inet_ntop(AF_INET, (void *) (struct sockaddr *) &sa4->sin_addr, ip, sizeof(ip));
port = ntohs(sa4->sin_port);
printf("\nAF_INET IP===%s:%d\n", ip, port);
}
// 查进程名 及 运行路径
char run_path[4096] = {0};
char process_name[1024] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
// 获取黑名单ip
std::set<std::string> ip_set;
std::set<std::string> process_set;
read_config_file(ip_set, process_set, CONFIG_NET_IP_PATH);
auto black_ip = ip_set.find(ip);
auto safe_process = process_set.find(process_name);
// 比较IP 是黑名单ip
if (black_ip != ip_set.end()) {
// log ip
std::string temp;
temp.append(ip);
temp.append(":"+std::to_string(port)+"<"+std::to_string(sockfd)+">");
if (safe_process != process_set.end()) {
write_log(temp, CONNECT, "允许访问", LOG_NET_IP_PATH);
return original_file_connect(sockfd, addr, addrlen);
} else {
write_log(temp, CONNECT, "拒绝访问", LOG_NET_IP_PATH);
return -1;
}
}
return original_file_connect(sockfd, addr, addrlen);
}
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
// 获取链接ip
char ip[128];
memset(ip, 0, sizeof(ip)); // ip地址
int port = -1; // 端口号
if (AF_INET == addr->sa_family) {
auto *sa4 = (struct sockaddr_in *) addr;
inet_ntop(AF_INET, (void *) (struct sockaddr *) &sa4->sin_addr, ip, sizeof(ip));
port = ntohs(sa4->sin_port);
printf("\nAF_INET IP===%s:%d\n", ip, port);
}
// 查进程名 及 运行路径
char run_path[4096] = {0};
char process_name[1024] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
// 获取黑名单ip
std::set<std::string> ip_set;
std::set<std::string> process_set;
read_config_file(ip_set, process_set, CONFIG_NET_IP_PATH);
auto black_ip = ip_set.find(ip);
auto safe_process = process_set.find(process_name);
// log ip
std::string temp;
temp.append(ip);
temp.append(":"+std::to_string(port)+"<"+std::to_string(sockfd)+">");
// 比较IP 是黑名单ip
if (black_ip != ip_set.end()) {
if (safe_process != process_set.end()) {
write_log(temp, ACCEPT, "允许访问",LOG_NET_IP_PATH);
return original_file_accept(sockfd, addr, addrlen);
} else {
write_log(temp, ACCEPT, "拒绝访问", LOG_NET_IP_PATH);
return -1;
}
}
// 放行
return original_file_accept(sockfd, addr, addrlen);
}
// 初始化函数,获取原始文件访问函数的地址并替换为拦截函数
int main() {
original_file_open = (file_open_func_t) dlsym(RTLD_NEXT, "open");
original_file_read = (file_read_func_t) dlsym(RTLD_NEXT, "read");
original_file_connect = (ip_connect_fun_t) dlsym(RTLD_NEXT, "connect");
original_file_accept = (ip_accept_fun_t) dlsym(RTLD_NEXT, "accept");
}

BIN
hook.so Executable file

Binary file not shown.

270
main.cpp Normal file
View File

@ -0,0 +1,270 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <cstring>
#include <string>
#include <set>
#include <unistd.h>
#include <algorithm>
#include <arpa/inet.h>
#define ACCEPT 9999
#define CONNECT 19999
// 定义指向原始文件访问函数的函数指针
typedef int (*file_access_func_t)(const char *pathname, int mode, ...);
static file_access_func_t original_file_access = nullptr;
// 定义指向原始open函数的函数指针
typedef int (*file_open_func_t)(const char *pathname, int flags, ...);
static file_open_func_t original_file_open = nullptr;
// 定义指向原始creat函数的函数指针
typedef int (*file_creat_func_t)(const char *pathname, mode_t mode);
static file_creat_func_t original_file_creat = nullptr;
//read
typedef ssize_t (*file_read_func_t)(int fd, void *buf, size_t nbytes);
static file_read_func_t original_file_read = nullptr;
// connect
typedef int (*ip_connect_fun_t)(int, const struct sockaddr *, socklen_t);
static ip_connect_fun_t original_file_connect = nullptr;
// accept
typedef int (*ip_accept_fun_t)(int, struct sockaddr *, socklen_t *);
static ip_accept_fun_t original_file_accept = nullptr;
// 定义原始的do_sys_open()函数指针
//static long (*real_do_sys_open)(int dfd, const char __user *filename, int flags, umode_t mode) = nullptr;
// 定义日志文件路径和配置文件路径的环境变量
const char *LOG_FILE_PATH = "/home/dongl/code/safe_test/log";
const char *CONFIG_FILE_PATH = "/home/dongl/code/safe_test/config.txt";
const char *LOG_NET_IP_PATH = "/home/dongl/code/safe_test/net-log";
const char *CONFIG_NET_IP_PATH = "/home/dongl/code/safe_test/net-config.txt";
// 将时间戳转换为字符串
std::string Time_t2String(time_t t) {
char tmp[64] = {0};
strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&t));
return tmp;
}
// 获取当前进程的可执行文件路径和名称
size_t get_executable_path(char *processdir, char *processname, size_t len) {
char *path_end;
if (readlink("/proc/self/exe", processdir, len) <= 0)
return -1;
path_end = strrchr(processdir, '/');
if (path_end == nullptr)
return -1;
++path_end;
strcpy(processname, path_end);
*path_end = '\0';
return (size_t) (path_end - processdir);
}
// 读取配置文件并填充文件和进程集合
void read_config_file(std::set<std::string>& file_set, std::set<std::string>& process_set, const char* config_name) {
// 打开配置文件
int config_fd = original_file_open(config_name, O_RDONLY);
if (config_fd < 0)
return;
// 读取配置文件
char buff[4096];
std::string data;
bool state = true;
while (original_file_read(config_fd, buff, sizeof(buff)) > 0) {
for (const auto &item: buff) {
if (item != '\n') {
data.push_back(item);
} else if (item == '\n') {
// 检查行是文件部分还是进程部分
std::string temp = config_name == CONFIG_FILE_PATH ? "[safe_file]" : "[black_ip]";
if (data == temp) {
state = true;
data.clear();
continue;
} else if (data == "[safe_process]") {
state = false;
data.clear();
continue;
}
// 将文件或进程添加到相应的集合中
if (state) {
file_set.insert(data);
data.clear();
} else {
process_set.insert(data);
data.clear();
}
}
}
}
// 关闭配置文件
close(config_fd);
}
// 将文件访问日志写入日志文件
void write_log(const std::string &pathname, int mode, const std::string &result, const char* log_name) {
char run_path[40960] = {0};
char process_name[10240] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
std::string access_mode;
if (mode == O_RDONLY)
access_mode = "读取";
else if (mode == ACCEPT)
access_mode = "ACCEPT";
else if (mode == CONNECT)
access_mode = "CONNECT";
else if (mode == O_WRONLY)
access_mode = "写入";
else if (mode == O_RDWR)
access_mode = "读写";
else if (mode == (O_WRONLY | O_APPEND))
access_mode = "追加";
std::string log = "[" + Time_t2String(time(nullptr)) + "] " +
"<" + pathname + "> " + access_mode + " {" + process_name + ":" + run_path + "} " + result + "\n";
int log_fd = original_file_open(log_name, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (log_fd > 0) {
write(log_fd, log.c_str(), log.size());
close(log_fd);
}
}
//
ssize_t read(int fd, void *buf, size_t nbytes) {
std::set<std::string> file_set;
std::set<std::string> process_set;
read_config_file(file_set, process_set, CONFIG_FILE_PATH);
// 查进程名 及 运行路径
char run_path[4096] = {0};
char process_name[1024] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
// 根据fd取文件名
char file_name[4096] = {'\0'};
char file_path[4096] = {'\0'};
snprintf(file_name, sizeof(file_name), "/proc/%d/fd/%d", getpid(), fd);
ssize_t ret = readlink(file_name, file_path, sizeof(file_path) - 1);
if (ret == -1) {
return original_file_read(fd, buf, nbytes);
}
// 检查
auto safe_file = file_set.find(file_path);
auto safe_process = process_set.find(process_name);
// 校验
if (safe_file != file_set.end()) {
if (safe_process != process_set.end()) {
write_log(file_path, O_RDONLY, "正常访问", LOG_FILE_PATH);
} else {
write_log(file_path, O_RDONLY, "拒绝访问", LOG_FILE_PATH);
errno = EACCES;
return original_file_read(fd, buf, 0);
}
}
return original_file_read(fd, buf, nbytes);
}
// 判断接入的网络是否为过滤IP如果是则提前返回
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
// 获取链接ip
char ip[128];
memset(ip, 0, sizeof(ip)); // ip地址
int port = -1; // 端口号
if (AF_INET == addr->sa_family) {
auto *sa4 = (struct sockaddr_in *) addr;
inet_ntop(AF_INET, (void *) (struct sockaddr *) &sa4->sin_addr, ip, sizeof(ip));
port = ntohs(sa4->sin_port);
printf("\nAF_INET IP===%s:%d\n", ip, port);
}
// 查进程名 及 运行路径
char run_path[4096] = {0};
char process_name[1024] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
// 获取黑名单ip
std::set<std::string> ip_set;
std::set<std::string> process_set;
read_config_file(ip_set, process_set, CONFIG_NET_IP_PATH);
auto black_ip = ip_set.find(ip);
auto safe_process = process_set.find(process_name);
// 比较IP 是黑名单ip
if (black_ip != ip_set.end()) {
// log ip
std::string temp;
temp.append(ip);
temp.append(":"+std::to_string(port)+"<"+std::to_string(sockfd)+">");
if (safe_process != process_set.end()) {
write_log(temp, CONNECT, "允许访问", LOG_NET_IP_PATH);
return original_file_connect(sockfd, addr, addrlen);
} else {
write_log(temp, CONNECT, "拒绝访问", LOG_NET_IP_PATH);
return -1;
}
}
return original_file_connect(sockfd, addr, addrlen);
}
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
// 获取链接ip
char ip[128];
memset(ip, 0, sizeof(ip)); // ip地址
int port = -1; // 端口号
if (AF_INET == addr->sa_family) {
auto *sa4 = (struct sockaddr_in *) addr;
inet_ntop(AF_INET, (void *) (struct sockaddr *) &sa4->sin_addr, ip, sizeof(ip));
port = ntohs(sa4->sin_port);
printf("\nAF_INET IP===%s:%d\n", ip, port);
}
// 查进程名 及 运行路径
char run_path[4096] = {0};
char process_name[1024] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
// 获取黑名单ip
std::set<std::string> ip_set;
std::set<std::string> process_set;
read_config_file(ip_set, process_set, CONFIG_NET_IP_PATH);
auto black_ip = ip_set.find(ip);
auto safe_process = process_set.find(process_name);
// log ip
std::string temp;
temp.append(ip);
temp.append(":"+std::to_string(port)+"<"+std::to_string(sockfd)+">");
// 比较IP 是黑名单ip
if (black_ip != ip_set.end()) {
if (safe_process != process_set.end()) {
write_log(temp, ACCEPT, "允许访问",LOG_NET_IP_PATH);
return original_file_accept(sockfd, addr, addrlen);
} else {
write_log(temp, ACCEPT, "拒绝访问", LOG_NET_IP_PATH);
return -1;
}
}
// 放行
return original_file_accept(sockfd, addr, addrlen);
}
// 初始化函数,获取原始文件访问函数的地址并替换为拦截函数
__attribute__((constructor)) void init() {
original_file_access = (file_access_func_t) dlsym(RTLD_NEXT, "access");
original_file_open = (file_open_func_t) dlsym(RTLD_NEXT, "open");
original_file_creat = (file_creat_func_t) dlsym(RTLD_NEXT, "creat");
original_file_read = (file_read_func_t) dlsym(RTLD_NEXT, "read");
original_file_connect = (ip_connect_fun_t) dlsym(RTLD_NEXT, "connect");
original_file_accept = (ip_accept_fun_t) dlsym(RTLD_NEXT, "accept");
}

270
old.cpp Normal file
View File

@ -0,0 +1,270 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <cstring>
#include <string>
#include <set>
#include <unistd.h>
#include <algorithm>
#include <arpa/inet.h>
#define ACCEPT 9999
#define CONNECT 19999
// 定义指向原始文件访问函数的函数指针
typedef int (*file_access_func_t)(const char *pathname, int mode, ...);
static file_access_func_t original_file_access = nullptr;
// 定义指向原始open函数的函数指针
typedef int (*file_open_func_t)(const char *pathname, int flags, ...);
static file_open_func_t original_file_open = nullptr;
// 定义指向原始creat函数的函数指针
typedef int (*file_creat_func_t)(const char *pathname, mode_t mode);
static file_creat_func_t original_file_creat = nullptr;
//read
typedef ssize_t (*file_read_func_t)(int fd, void *buf, size_t nbytes);
static file_read_func_t original_file_read = nullptr;
// connect
typedef int (*ip_connect_fun_t)(int, const struct sockaddr *, socklen_t);
static ip_connect_fun_t original_file_connect = nullptr;
// accept
typedef int (*ip_accept_fun_t)(int, struct sockaddr *, socklen_t *);
static ip_accept_fun_t original_file_accept = nullptr;
// 定义原始的do_sys_open()函数指针
//static long (*real_do_sys_open)(int dfd, const char __user *filename, int flags, umode_t mode) = nullptr;
// 定义日志文件路径和配置文件路径的环境变量
const char *LOG_FILE_PATH = "/home/dongl/code/safe_test/log";
const char *CONFIG_FILE_PATH = "/home/dongl/code/safe_test/config.txt";
const char *LOG_NET_IP_PATH = "/home/dongl/code/safe_test/net-log";
const char *CONFIG_NET_IP_PATH = "/home/dongl/code/safe_test/net-config.txt";
// 将时间戳转换为字符串
std::string Time_t2String(time_t t) {
char tmp[64] = {0};
strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&t));
return tmp;
}
// 获取当前进程的可执行文件路径和名称
size_t get_executable_path(char *processdir, char *processname, size_t len) {
char *path_end;
if (readlink("/proc/self/exe", processdir, len) <= 0)
return -1;
path_end = strrchr(processdir, '/');
if (path_end == nullptr)
return -1;
++path_end;
strcpy(processname, path_end);
*path_end = '\0';
return (size_t) (path_end - processdir);
}
// 读取配置文件并填充文件和进程集合
void read_config_file(std::set<std::string>& file_set, std::set<std::string>& process_set, const char* config_name) {
// 打开配置文件
int config_fd = original_file_open(config_name, O_RDONLY);
if (config_fd < 0)
return;
// 读取配置文件
char buff[4096];
std::string data;
bool state = true;
while (original_file_read(config_fd, buff, sizeof(buff)) > 0) {
for (const auto &item: buff) {
if (item != '\n') {
data.push_back(item);
} else if (item == '\n') {
// 检查行是文件部分还是进程部分
std::string temp = config_name == CONFIG_FILE_PATH ? "[safe_file]" : "[black_ip]";
if (data == temp) {
state = true;
data.clear();
continue;
} else if (data == "[safe_process]") {
state = false;
data.clear();
continue;
}
// 将文件或进程添加到相应的集合中
if (state) {
file_set.insert(data);
data.clear();
} else {
process_set.insert(data);
data.clear();
}
}
}
}
// 关闭配置文件
close(config_fd);
}
// 将文件访问日志写入日志文件
void write_log(const std::string &pathname, int mode, const std::string &result, const char* log_name) {
char run_path[40960] = {0};
char process_name[10240] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
std::string access_mode;
if (mode == O_RDONLY)
access_mode = "读取";
else if (mode == ACCEPT)
access_mode = "ACCEPT";
else if (mode == CONNECT)
access_mode = "CONNECT";
else if (mode == O_WRONLY)
access_mode = "写入";
else if (mode == O_RDWR)
access_mode = "读写";
else if (mode == (O_WRONLY | O_APPEND))
access_mode = "追加";
std::string log = "[" + Time_t2String(time(nullptr)) + "] " +
"<" + pathname + "> " + access_mode + " {" + process_name + ":" + run_path + "} " + result + "\n";
int log_fd = original_file_open(log_name, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (log_fd > 0) {
write(log_fd, log.c_str(), log.size());
close(log_fd);
}
}
//
ssize_t read(int fd, void *buf, size_t nbytes) {
std::set<std::string> file_set;
std::set<std::string> process_set;
read_config_file(file_set, process_set, CONFIG_FILE_PATH);
// 查进程名 及 运行路径
char run_path[4096] = {0};
char process_name[1024] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
// 根据fd取文件名
char file_name[4096] = {'\0'};
char file_path[4096] = {'\0'};
snprintf(file_name, sizeof(file_name), "/proc/%d/fd/%d", getpid(), fd);
ssize_t ret = readlink(file_name, file_path, sizeof(file_path) - 1);
if (ret == -1) {
return original_file_read(fd, buf, nbytes);
}
// 检查
auto safe_file = file_set.find(file_path);
auto safe_process = process_set.find(process_name);
// 校验
if (safe_file != file_set.end()) {
if (safe_process != process_set.end()) {
write_log(file_path, O_RDONLY, "正常访问", LOG_FILE_PATH);
} else {
write_log(file_path, O_RDONLY, "拒绝访问", LOG_FILE_PATH);
errno = EACCES;
return original_file_read(fd, buf, 0);
}
}
return original_file_read(fd, buf, nbytes);
}
// 判断接入的网络是否为过滤IP如果是则提前返回
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
// 获取链接ip
char ip[128];
memset(ip, 0, sizeof(ip)); // ip地址
int port = -1; // 端口号
if (AF_INET == addr->sa_family) {
auto *sa4 = (struct sockaddr_in *) addr;
inet_ntop(AF_INET, (void *) (struct sockaddr *) &sa4->sin_addr, ip, sizeof(ip));
port = ntohs(sa4->sin_port);
printf("\nAF_INET IP===%s:%d\n", ip, port);
}
// 查进程名 及 运行路径
char run_path[4096] = {0};
char process_name[1024] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
// 获取黑名单ip
std::set<std::string> ip_set;
std::set<std::string> process_set;
read_config_file(ip_set, process_set, CONFIG_NET_IP_PATH);
auto black_ip = ip_set.find(ip);
auto safe_process = process_set.find(process_name);
// 比较IP 是黑名单ip
if (black_ip != ip_set.end()) {
// log ip
std::string temp;
temp.append(ip);
temp.append(":"+std::to_string(port)+"<"+std::to_string(sockfd)+">");
if (safe_process != process_set.end()) {
write_log(temp, CONNECT, "允许访问", LOG_NET_IP_PATH);
return original_file_connect(sockfd, addr, addrlen);
} else {
write_log(temp, CONNECT, "拒绝访问", LOG_NET_IP_PATH);
return -1;
}
}
return original_file_connect(sockfd, addr, addrlen);
}
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
// 获取链接ip
char ip[128];
memset(ip, 0, sizeof(ip)); // ip地址
int port = -1; // 端口号
if (AF_INET == addr->sa_family) {
auto *sa4 = (struct sockaddr_in *) addr;
inet_ntop(AF_INET, (void *) (struct sockaddr *) &sa4->sin_addr, ip, sizeof(ip));
port = ntohs(sa4->sin_port);
printf("\nAF_INET IP===%s:%d\n", ip, port);
}
// 查进程名 及 运行路径
char run_path[4096] = {0};
char process_name[1024] = {0};
get_executable_path(run_path, process_name, sizeof(run_path));
// 获取黑名单ip
std::set<std::string> ip_set;
std::set<std::string> process_set;
read_config_file(ip_set, process_set, CONFIG_NET_IP_PATH);
auto black_ip = ip_set.find(ip);
auto safe_process = process_set.find(process_name);
// log ip
std::string temp;
temp.append(ip);
temp.append(":"+std::to_string(port)+"<"+std::to_string(sockfd)+">");
// 比较IP 是黑名单ip
if (black_ip != ip_set.end()) {
if (safe_process != process_set.end()) {
write_log(temp, ACCEPT, "允许访问",LOG_NET_IP_PATH);
return original_file_accept(sockfd, addr, addrlen);
} else {
write_log(temp, ACCEPT, "拒绝访问", LOG_NET_IP_PATH);
return -1;
}
}
// 放行
return original_file_accept(sockfd, addr, addrlen);
}
// 初始化函数,获取原始文件访问函数的地址并替换为拦截函数
__attribute__((constructor)) void init() {
original_file_access = (file_access_func_t) dlsym(RTLD_NEXT, "access");
original_file_open = (file_open_func_t) dlsym(RTLD_NEXT, "open");
original_file_creat = (file_creat_func_t) dlsym(RTLD_NEXT, "creat");
original_file_read = (file_read_func_t) dlsym(RTLD_NEXT, "read");
original_file_connect = (ip_connect_fun_t) dlsym(RTLD_NEXT, "connect");
original_file_accept = (ip_accept_fun_t) dlsym(RTLD_NEXT, "accept");
}

0
temp.cpp Normal file
View File