发表于 2020-3-30 10:07

申请会员ID:NuclearEngine【申请通过】

1. 申请会员ID:NuclearEngine
2个人邮箱:wxydwxyd@foxmail.com


对某电子教室软件远控的简单分析与编程模拟


功能挺多,今天主要来分析远程cmd命令执行与消息发送

消息模块 先来试试看

发送后果然在学生机上显示一个消息

命令模块

发送个ping 百度试试

打开一个cmd开始ping

怎么分析呢,由于软件为了防止被破解授权,做了许多混淆,连功能模块也有各种无用代码,搞起来挺麻烦,
算了,从网络包分析吧,俗话说:抓包抓得好,牢饭吃到饱,可见抓包的威力。

控制变量法我们已经无法再熟悉了,用同一内容发送两次指令,抓包看看
第一次

第二次


把数据作为16进制流保存下来

```
444d4f43000001009e030000b29c383c32b3034eb79984ee9f093dab204e0000c0a801049103000091030000000800000000000005000000604f7d59405400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
444d4f43000001009e030000008ce4300eb5c94ca9a255f3df5e3c20204e0000c0a801049103000091030000000800000000000005000000604f7d594a5500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

```
两次数据包如上 ,手动分析有点难,vb宏也不太熟悉,用c++做个处理器吧
```
#include<iostream>
#include<cstring>
using namespace std;
char text1;
char text2;
int main()
{
      freopen("out.txt","w",stdout);
      freopen("in.txt","r",stdin);
      char a;int i=0;
      while(cin>>a)
      {
                text1=a;
                if(a=='#') break;
      }
      i=0;
      while(cin>>a)
      {
                text2=a;
                if(a=='#') break;
      }
      
      for(int i=0;i<=strlen(text1)-1;i++)//不同数位处理为0
      {
                if(text1!=text2)
               text1='0';
      }
      for(int i=0;i<=strlen(text1)-1;i+=2)//加上前缀0x好放到数组中去
      {
                cout<<"0x"<<text1<<text1<<',';      
      }
}
```

跑一下做好的数据```
char datmsg={0x44,0x4D,0x4F,0x43,0x00,0x00,0x01,0x00,0x9E,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x00,0x00,0xC0,0xA8,0x8E,0x01,0x91,0x03,0x00,0x00,0x91,0x03,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00};

```


数据规则
0x44,0x4D,0x4F,0x43,0x00,0x00,0x01,0x00,0x9E,0x03,0x00,0x00 ------------固定的数据包命令头
。。。。。。。。。。。。。。。。。。---------------乱码,经观察发现,同样的数据包内容28s内只会识别一边,多了丢弃,搞个随机数即可
第65位往后0x60,0x4f,0x7d,0x59,0x4a,0x55--------------------”你好“的编码


unicode分析
你好的正规编码应该是这样的 你好
但它的编码却为0x60,0x4f,0x7d,0x59,0x4a,0x55
不难发现 每两位之间发生了颠倒
处理代码
```
      int topt=56;
      for(int i=0;i<wcslen(comin);i++)//数据数组位comin
      {

                unsigned int byte = comin;
                unsigned int high;
                unsigned int low ;
                high = (byte>>8)&0xff;//通过移位实现两位两位分离
                low = byte & 0xff;
                datmsg=low;//理论上这里是high,但因为要颠倒所以这里是low
                datmsg=high;
      }
```

连接上原来不变的数位
发送实现
udpsend函数
```
int udpsend(char *adre,char *dat,int bagdx,int port)
{
      //加载套接字库
      WORD wVersionRequested;
      WSADATA wsaData;
      int err;

      wVersionRequested = MAKEWORD( 2, 2 );

      err = WSAStartup( wVersionRequested, &wsaData );
      if ( err != 0 ) {
                return -1;
      }

      if ( LOBYTE( wsaData.wVersion ) != 2 ||
                HIBYTE( wsaData.wVersion ) != 2 ) {                                 
                        WSACleanup( );
                        return -1;   
      }

      //创建套接字
      SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0);
      if (INVALID_SOCKET == sockClient)
                return -1;


      SOCKADDR_IN addrServer;
      addrServer.sin_addr.S_un.S_addr = inet_addr(adre);
      addrServer.sin_family = AF_INET;
      addrServer.sin_port = htons(port);

      //发送数据
      err = sendto(sockClient, dat, bagdx, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
      if (SOCKET_ERROR == err)
                return -1;

      //关闭套接字
      closesocket(sockClient);

      //终止套接字库的使用
      WSACleanup();

      return 0;
}
```
发送细节实现
```
datmsg=char(randnum2(56,70));
                datmsg=char(randnum2(56,70));
                datmsg=char(randnum2(56,70));
                datmsg=char(randnum2(56,70));
                datmsg=char(randnum2(56,70));
                //经观察打5个随机数就够了
                udpsend(adree,datmsg,1038,4705);//adree为对方的ip地址,1038为包大小,4705是端口,用winsock实现即可
```
这里要说一下,这个软件对包大小极为敏感,之前没注意包大小导致一直失败
发送试试看,成功



发送命令的实现也大同小异
几个关键点(随机数,包大小,unicode反一下)关键代码同上
这里就不在赘述了

附上之前拍的视频
https://www.bilibili.com/video/BV1SE411V7rB/

本人中学生一枚,想看看某大佬的文章,迫于囊中羞涩,无法实现,望h大能实现我的愿望。,

Hmily 发表于 2020-3-30 19:14

I D:NuclearEngine
邮箱:wxydwxyd@foxmail.com

申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。

ps:文章有些简单了,另外逆向协议还是从软件本身下手比较好,从代码分析这个东西怎么来的比猜靠谱,最后学生还是要以学业为重。

NuclearEngine 发表于 2020-3-30 22:40

报道报道

发表于 2020-3-31 09:15

中学生啊加油啊~ 但学生还是要以学业为重,中学学习压力还是挺大的,祝你考上理想的大学,到时候再深入研究,磨刀不误砍柴工
页: [1]
查看完整版本: 申请会员ID:NuclearEngine【申请通过】