使用 raw socket 来躲开 netstat 的连接监控

先来看一个非常普通的收发

服务端

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <assert.h>

int main() {
    int listen_fd = socket(AF_INET, SOCK_DGRAM, 0);
    assert(listen_fd > 0);
    struct sockaddr_in listen_addr;
    memset(&listen_addr, 0, sizeof(listen_addr));
    listen_addr.sin_family = AF_INET;
    listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    listen_addr.sin_port = htons(9999);
    assert(bind(listen_fd, (struct sockaddr*)&listen_addr, sizeof(listen_addr)) != -1);
    while (1) {
        struct sockaddr_in cli_addr;
        memset(&cli_addr, 0, sizeof(cli_addr));
        socklen_t cli_addr_len = sizeof(cli_addr);
        int msg, msg_len;
        recvfrom(listen_fd, &msg, sizeof(msg), 0, (struct sockaddr*)&cli_addr, &cli_addr_len);
        printf("%d\n", msg);
        sleep(1);
        msg++;
        sendto(listen_fd, &msg, sizeof(msg), 0, (struct sockaddr*)&cli_addr, cli_addr_len);
    }
    return 0;
}

客户端

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <assert.h>

int main() {
    int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
    assert(socket_fd > 0);
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(9999);
    assert(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) >= 0);
    int msg = 1;
    while (1) {
        sendto(socket_fd, &msg, sizeof(msg), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
        socklen_t serv_addr_len = sizeof(serv_addr);
        recvfrom(socket_fd, &msg, sizeof(msg), 0, (struct sockaddr*)&serv_addr, &serv_addr_len);
        printf("%d\n", msg);
        sleep(1);
        msg++;
    }
    return 0;
}

跑起来之后,可以用 netstat -anp|grep 9999 看到下面的链接

(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
udp        0      0 0.0.0.0:9999            0.0.0.0:*                           16144/ser  

问题来了,如果我不想被 netstat 看到,需要怎么搞呢

这个思路其实比较直接,就是使用 raw socket,注意到 netstat 是分析 tcp 或者 udp 包头中的 port 字段来判定这个是个什么样的连接的,所以如果我们使用一个自定义的传输层协议,然后自行填充 ip 包的包头,发送出去,就可以绕过 netstat 的检查了。

说起来容易,但是实际调起来发现 raw socket 确实是不好调,稍后代码如果能调通了会放一份上来。

可以看这里有相关的说明,http://sec.chinabyte.com/429/8…

2 thoughts on “使用 raw socket 来躲开 netstat 的连接监控

  1. 不过楼主的目的是要创建一种属于自己的protocol,这样就不会受到TCP/UDP监控?有种covert channel的感觉…

    • 是的,可以看我原文最后引用的那篇文章,里面有说明,这种技术一般是木马用于躲避简单的监控

Leave a Reply

Your email address will not be published. Required fields are marked *