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[1000];
char text2[1000];
int main()
{
freopen("out.txt","w",stdout);
freopen("in.txt","r",stdin);
char a;int i=0;
while(cin>>a)
{
text1[i++]=a;
if(a=='#') break;
}
i=0;
while(cin>>a)
{
text2[i++]=a;
if(a=='#') break;
}
for(int i=0;i<=strlen(text1)-1;i++)//不同数位处理为0
{
if(text1[i]!=text2[i])
text1[i]='0';
}
for(int i=0;i<=strlen(text1)-1;i+=2)//加上前缀0x好放到数组中去
{
cout<<"0x"<<text1[i]<<text1[i+1]<<',';
}
}
跑一下做好的数据char datmsg[200]={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[i];
unsigned int high;
unsigned int low ;
high = (byte>>8)&0xff;//通过移位实现两位两位分离
low = byte & 0xff;
datmsg[topt++]=low;//理论上这里是high,但因为要颠倒所以这里是low
datmsg[topt++]=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[12]=char(randnum2(56,70));
datmsg[13]=char(randnum2(56,70));
datmsg[16]=char(randnum2(56,70));
datmsg[17]=char(randnum2(56,70));
datmsg[18]=char(randnum2(56,70));
//经观察打5个随机数就够了
udpsend(adree,datmsg,1038,4705);//adree为对方的ip地址,1038为包大小,4705是端口,用winsock实现即可
这里要说一下,这个软件对包大小极为敏感,之前没注意包大小导致一直失败
发送试试看,成功
发送命令的实现也大同小异
几个关键点(随机数,包大小,unicode反一下)关键代码同上
这里就不在赘述了
附上之前拍的视频
https://www.bilibili.com/video/BV1SE411V7rB/
本人中学生一枚,想看看某大佬的文章,迫于囊中羞涩,无法实现,望h大能实现我的愿望。,
|