TCP安全之——实现简单远控(Socket编程)

最近学习SOCKET编程 , 在主机和虚拟机间实验了简单的远控(强制关机、取消关机、截图)。
整体思路 : 很简单,就是建立C/S两端 , 通过TCP连接传输指令和图片信息 , 模拟远程控制的效果 , 此处未涉及过防火墙等知识 , 只是简单的模拟TCP 原理 , 大牛请无视~

实验环境 : 主机 (WIN 10) 虚拟机(WIN7)
步骤一 : 配置局域网 , 虚拟网卡VMnet0

更改IP\子网掩码\网关在同一网段
这里写图片描述
控制机 (虚拟机):192.168.43.249
靶机(主机)   :192.168.43.153

步骤二 : 受控方打开程序LISTEN接收控制方指令,远控方输入关机指令

弹出WIN10的关机窗口(截图不完整,但显然不是WIN7界面)

这里写图片描述

步骤三 : noshutdown命令取消自动关机

这里写图片描述

步骤四 : 截图操作(控制主机截图 , 并通过TCP传送到虚拟机并保存到桌面prt_0.png)

这里写图片描述

最后贴一下两端代码,供大家查看试验 :

控制方代码:

// 远控(控制方).cpp : 定义控制台应用程序的入口点。

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#include <iostream>
#include <fstream>
using namespace std;

#pragma comment(lib,"ws2_32.lib")

//接收图片
void recvfile(SOCKET sock)
{

    //标识截图名称
    static int id = 0;
    //文件名
    char filename[50];
    int err = 0;
    //构建一个文件名,区分文件
    sprintf(filename, "prt_%d.png", id++);
    //创建文件
    ofstream ofile(filename, ios_base::binary);

    while (true)
    {
        char filebuff[1024] = { 0 };
        //接收一次文件
        err = recv(sock, filebuff, 1024, 0);
        //如果接收==0
        if (err == 0)
        {
            printf("recv error\n");
            return;
        }
        //如果小于1024,说明文件传输结束
        else if (err < 1024)
        {
            ofile.write(filebuff, err);
            ofile.close();
            break;
        }
        //如果刚好1024,直接写入文件.
        else
        {
            ofile.write(filebuff, 1024);
        }
    }

}

int main()
{

    //1.初始化环境
    WSADATA wds = { 0 };
    int err;
    //参数1.请求的版本号2.2  参数2.WSADATA结构体
    err = WSAStartup(MAKEWORD(2, 2), &wds);
    if (err != 0)
    {
        printf("WSAStartup error\n");
        return 1;
    }
    //检测是否2.2版本
    if ((HIBYTE(wds.wVersion) != 2)
        || (LOBYTE(wds.wVersion) != 2))
    {
        printf("WSAStartup error\n");
        return 1;
    }
    //2.创建套接字   参数1.IP协议,参数2.流式类型,参数3.TCP协议
    SOCKET Csock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (Csock == INVALID_SOCKET)
    {
        printf("socket error\n ");
        return 1;
    }
    //3.发起链接
    sockaddr_in Saddr = { 0 };

    Saddr.sin_addr.S_un.S_addr = inet_addr("192.168.43.153"); //链接的IP地址
    Saddr.sin_family = AF_INET;                          //使用IP协议
    Saddr.sin_port = htons(1234);                        //端口
    //发起链接  参数1.客户套接字,参数2.服务端地址,参数3.结构体大小
    err = connect(Csock, (sockaddr*)&Saddr, sizeof(Saddr));
    if (err == SOCKET_ERROR)
    {
        printf("connect error\n");
        return 1;
    }
    while (true)
    {
        char buff[1024] = {0};
        gets(buff);
        printf("shutdown        关机\n");
        printf("noshutdown      取消关机\n");
        printf("prtscreen       截图\n");
        //如果输入quit退出程序
        if (strcmp(buff,"quit")==0)
        {
            break;
        }//如果截图消息
        else if (strcmp(buff,"prtscreen")==0)
        {
            //发送截图消息
            err = send(Csock, buff, 1024, 0);
            if (err==SOCKET_ERROR)
            {
                printf("send error\n");
                break;
            }
            Sleep(100);
            //获取文件数据
            recvfile(Csock);
        }
        //其他命令直接发送
        else {
            send(Csock, buff, 1024, 0);
        }
    }
    //5.关闭socket
    closesocket(Csock);

    //6.清理环境
    WSACleanup();

    return 0;
}

受控方代码 :

// 远程控制(受控方).cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#include <atlimage.h>
#include <fstream>
using namespace std;

#pragma comment(lib,"ws2_32.lib")

//截屏保存
bool prtsc()
{
    //模拟键盘点击
    keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
    Sleep(300);
    keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
    Sleep(1000);
    //打开剪切板
    OpenClipboard(NULL);
    //获取剪切板数据
    HBITMAP hbitmap=(HBITMAP)GetClipboardData(CF_BITMAP);

    if (hbitmap != NULL)
    {
        CImage img;
        img.Attach(hbitmap);        //附加图片
        img.Save(L"1.png");         //保存图片
        img.Detach();               //卸下图片
        CloseClipboard();           //关闭剪切板
        return true;
    }
    CloseClipboard();
    return false;
}

//读取png文件
char *readFile(int &len)
{
    ifstream infile("1.png", ios_base::binary);
    //获取文件大小
    infile.seekg(0, ios_base::end);
    len = infile.tellg();
    infile.seekg(0, ios_base::beg);

    //开辟缓冲区
    char *filebuff = new char[len];
    //读取文件
    infile.read(filebuff, len);
    infile.close();
    //返回文件内容
    return filebuff;
}

//执行命令
void  recvcmd(SOCKET sock, char *szcmd)
{
    if (strcmp(szcmd,"shutdown")==0)
    {
        //执行cmd命令关机
        system("shutdown -s -t 300");
        return;
    }
    //取消关机
    else if(strcmp(szcmd,"noshutdown")==0)
    {
        system("shutdown -a");
        return ;
    }
    //屏幕监控
    else if (strcmp(szcmd,"prtscreen")==0)
    {

        //截图
        if (prtsc())
        {
            char *pfile;
            int len;
            //读取文件
            pfile=readFile(len);
            send(sock, pfile, len, 0);
            delete[] pfile;
        }
    }

}

int main()
{
    //1.初始化环境
    WSADATA wds = { 0 };
    int err;
    //参数1.请求的版本号2.2  参数2.WSADATA结构体
    err = WSAStartup(MAKEWORD(2, 2), &wds);
    if (err != 0)
    {
        printf("WSAStartup error\n");
        return 1;
    }
    //检测是否2.2版本
    if (
        (HIBYTE(wds.wVersion) != 2)
        || (LOBYTE(wds.wVersion) != 2)
        )
    {
        printf("WSAStartup error\n");
        return 1;
    }
    //2.创建套接字   参数1.IP协议,参数2.流式类型,参数3.TCP协议
    SOCKET Ssock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (Ssock == INVALID_SOCKET)
    {
        printf("socket error\n ");
        return 1;
    }

    //3.绑定socket
    sockaddr_in Saddr = { 0 };

    Saddr.sin_addr.S_un.S_addr = inet_addr("192.168.43.153"); //链接的IP地址
    Saddr.sin_family = AF_INET;                          //使用IP协议
    Saddr.sin_port = htons(1234);                        //端口

    //参数1.服务端的套接字,参数2.服务端的地址信息,参数3.结构体大小
    err = bind(Ssock, (sockaddr*)&Saddr, sizeof(Saddr));
    if (err == SOCKET_ERROR)
    {
        printf("bind error\n");
        return 1;
    }

    //4.监听socket
    err = listen(Ssock, SOMAXCONN);
    if (err == SOCKET_ERROR)
    {
        printf("listen error\n");
        return 1;
    }

    //5.等待客户端链接
    sockaddr_in Caddr = { 0 };
    int Csize = sizeof(Caddr);
    //返回 客户套接字,     参数1.服务端的套接字,参数2客户端的地址,参数3结构体的大小
    SOCKET ClientSock = accept(Ssock, (sockaddr*)&Caddr, &Csize);

    while (true)
    {
        //接收数据
        char buff[1024] = {0};
        err = recv(ClientSock, buff, 1024, 0);
        if (err==0)
        {
            break;
        }
        //执行quit退出循环
        if (strcmp(buff,"quit")==0)
        {
            break;
        }
        printf(buff);
        //执行控制方发送的命令
        recvcmd(ClientSock, buff);
    }
    //5.关闭socket
    closesocket(Ssock);

    //6.清理环境
    WSACleanup();
    return 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值