HanDs
管理员

[Visual Studio文章] 真正的VB木马,不用WINSOCK控件(1) 





学习中请遵循国家相关法律法规,黑客不作恶。没有网络安全就没有国家安全

本站需要登陆后才能查看

这篇文章不是我写的,我也正在研究,里面很多代码都有错误,希望高手把代码调试完了发给我,谢了`~~~(奉劝各位学VB的朋友,不要以为用WINSOCK控件连接的两个窗口就是木马,VB木马真正的核心还是API)
一、开篇废话一箩筐
VB写的BackDoor/Trojan似乎是与尴尬同在的,不信?你去各大技术论坛发帖问问“小弟想做个木马,用什么开发好啊?”,大多数Expert级的建议都是“VC++、C++ Builder、Delphi”,唯独把VC++的同门兄弟VB拒之门外。难道VB真的就这么烂?进一步问问吧,高手们会给你列举VB的以下“好处”:
1.必须有MSVBVM60.DLL(VB6.0)、MSVBVM50.DLL(VB5.0)存在,否则VB木马就只能当花瓶了。
2.看看你用了多少个ActiveX吧——“Can't create Object,refused to run”
3.运行时例外错误,突然蹦出个窗口来告诉马场主:“嘿,我是VB写的木马,我崩溃了,啦啦啦:P”
4.超级不稳定,不知道什么时候就挂了。
5.体积庞大……
以上的确是在说实话……由于VB编写的程序有很多致命弱点,所以“聪明人”的首选当然是VC++、Delphi,但这并不能说VB就是穷途末路,记住,程序写得怎么样,看的是编写者的水平,而不是看他用什么语言!
开动你的脑筋,做最周到的考虑,尽最精细的分析,就让VB木马也疯狂一回!

二、忍住ActiveX的诱惑——纯API编程
最基本的重点!别把后门技术与一般编程混为一谈,平时写程序喜欢挂多少个ActiveX随便你,但是在这里不可以!要想VB木马能四处撒欢,就必须先把VB程序无形的束缚——ActiveX技术抛掉,否则它就如一条缰绳,把你费尽苦心“拼装”出来的木马给牢牢的拴在你家里——难道你还想为你的马驹做个InstallShield?
抛掉了ActiveX,还有什么?Windows给我们提供了强大的API(Application Programming Interface,应用程序编程接口)支持,为什么C代码这么简洁?就因为Windows环境的大部分C代码实际上是与系统API紧紧结合的,微软和第三方开发商已经提前把大量的API调用声明写入头文件(C++ Header File)了,VC程序员不必自己再写一大堆函数声明,直接用#include把相关的API声明的头文件拉进代码就可以!大家可以找个简单的C写的Exploit代码来看看头文件声明,例如:
====================================================
#include <winsock.h>
WSAStartup(MAKEWORD(1,1),&wsaData);
SockRaw=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
====================================================

而在VB里要写一大堆:
====================================================
Declare Function WSAStartup Lib "Winsock.dll" (ByVal wVR As Integer, lpWSAD As WSADataType) As Integer
Declare Function socket Lib "Winsock.dll" (ByVal af As Integer, ByVal s_type As Integer, ByVal protocol As Integer) As Integer
Const AF_INET = 2
Const SOCK_RAW = 3
Const IPPROTO_ICMP = 1
ret = WSAStartup(&H101, wsadStartupData)
SockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
====================================================

对比两段代码,看出什么没有?VC程序员可以用一句#include <winsock.h>就把WSAStartup、socket、AF_INET等API声明和常数定义给省略了,而VB程序员就有得苦了。难怪ActiveX可以在VB的天下横行无忌——偷懒谁不会啊?
但是我们是在做木马,要偷懒你就睡觉去吧,要想你的马驹在别人的马场里撒欢,就要对ActiveX说“NO”!我们只剩下API,好好发挥吧!

三、沟通的窗户——WinSock
首先介绍一下什么是WinSock。
WinSock是在90年代初,为了方便网络编程而由Microsoft联合几家公司共同制定的一套WINDOWS下的网络编程接口,即Windows Sockets规范,它不是一种网络协议,而是一套开放的、支持多种协议的Windows下的网络编程接口。Socket实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有Socket接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个Socket接口来实现。Socket也称为“套接字”。Windows下的大部分语言都支持WinSock,VB也不例外。
只不过,用VB+API写WinSock是件很不爽的事,太多的API调用和常数定义,一个套一个,写得头昏眼花,如果你懒得(或者没办法)写出一个完整的WinSock架构,那么我建议你去www.allapi.net下载KPD-Team做好的WinSock API Function Calls For VB再看下文。(文章附源代码)
以前看到一些介绍“VB木马制作”的文章,大言不惭的使用了Microsoft WinSock Control 6.0(MSWINSCK.OCX)来做WinSock核心部件,这样做当然可以省去许多功夫,但是别忘了这是ActiveX!那些文章唬唬菜鸟可以,要想实际应用,做梦!既然已经把代码限制在API领域里,就要自己动手。
如果你以前习惯了使用Microsoft WinSock Control 6.0来拼装网络应用程序,就要把那种简洁忘掉,否则你会很痛苦的,因为WinSock API不同于WinSock ActiveX,它们之间有很多差别:

1.WinSock ActiveX(WSAX)给程序员提供了一个很方便的接收事件DataArrival,在里面用GetData方法就能获取数据,在WinSock API(WSAP)里,这个想法只能是美好的。
2.WSAX想什么时候收发数据都可以,WSAP要求你老老实实先WSAStartup,填充sockaddr结构(sin_family、sin_port、sin_addr、sin_zero),connect后再send或者直接sendto出去,然后下面的recv马上进入戒备状态接收返回的数据,最后别忘了closesocket还有WSACleanup。
3.WSAX把WinSock架构理想化了,每个事件都能做到看似分离实际整合(DataArrival、SendProgress、Error、Close等),而在WSAP编程里,你只能无奈的看着几个对应WSAX不同事件的API挤作一团,而且只能在一个过程里做完所有工作——WSAP只给你在一个过程里处理接收、回应和操作事件。如果你习惯在WSAX里几个不同的事件里写不同作用的代码,那么在WSAP里,你会发现完成相同作用的代码基本上都被挤在一个WinSock的recv/send处理过程里,也许你会说,建立一个异步模式的接收过程,但是这样的效率仍然比WSAX低。
4.WSAP比WSAX容易崩溃,举个例子,如果你在没有对套接字进行特殊处理(例如select设置异步模式)的情况下直接让WSAP试图connect一个无法连接的服务器,你的整个程序都会被挂起,直到connect返回INVALID_SOCKET——弄不好就是永久的挂起,崩溃了;而WSAX则轻松的返回一个INVALID_SOCKET。
5.最大一个问题:WSAP的声明和调用都太复杂了!如果你对WinSock API很了解,你可以写一个和WinSock设置有关的全局类模块,配合API使用,但这些并不能很好的解决WSAP繁琐复杂的问题。有兴趣的可以研究一下我在一个外国专业编程网站搜集到的VB代码WinsockTestBench。(随文章附上)

在VB里用API写WinSock虽然很令人头痛,但是我们不得不忍受,为了制造马驹。而且,编写WinSock API会让你学到很多。
木马程序里,WinSock部分占有很重要的地位,程序操作基本上都处于WinSock传输的数据控制下,所以写木马的第一步最好先完成一个能正常进行通讯的WinSock框架,这不是坏习惯。

四、协议,端口
接下来,就要思考清楚后门的报文协议,是TCP、UDP还是ICMP?开什么端口?这些都要想清楚,否则代码写复杂的时候要改就是一项很大的工程了。大多数木马是基于TCP协议+高位端口的,UDP协议不能很好的保证传输质量而且容易被伪造,一般不推荐使用。TCP和UDP都要开端口,并不代表UDP就能更好隐蔽端口的。新型的木马采用ICMP/IP头部信息来实现传输,做到了更高的隐蔽性,因为ICMP是由系统核心处理的,而且比TCP/UDP协议的层次更低些,不需要开端口,除非对方禁止了ICMP,否则这种后门可以在防火墙眼皮底下穿行;基于IP头部的传输模式在Win9x/Me系统上应该无法实现了,这些非NT架构的系统不支持IP_HDRINCL,用户不能自己填充IP头部数据。很少人会留意这些零碎的IP数据包是否正在传递信息,不过就是不如直接TCP传输得舒服就是了,因为IP报文的头部空域很有限,并不是你想添加多少就添加多少的。用IP报文尾部发送数据?你不如直接用TCP/UDP发送好了……

五、当错误发生的时候
VB程序其实很脆弱,当一些不可预料的错误(例如溢出、文件读写失败等)发生时,它们会很委屈的弹出提示信息,设想一下你的木马在读取文件时突然遇到磁盘坏道,它就会弹出信息暴露自己了。所以,VB木马作者们必须认真对待VB的错误处理机制,为程序设置错误陷阱,做到最大的安全性。
错误陷阱必须设置在每个过程的第一行里,记住这两个常用的错误处理语句:On Error Resume Next、On Error GoTo [Flag]。

1.On Error Resume Next
它让VB程序遇到例外错误时直接执行下一句代码,例如这句代码存在风险:
Open "c:\scandisk.log" For Input As #1
这句代码本身并没有什么错误,但是它带来了产生致命错误的风险:C盘根目录下的scandisk.log文件不存在时,程序就崩溃了。如果我们给这个语句加入错误陷阱,告诉它无论遇到什么情况都别出声,就可以把风险降到最低:)
On Error Resume Next
Open "c:\scandisk." For Input As #1
'经过这样的处理,这个语句永远不会弹出错误信息:)

2.On Error GoTo [Flag]
虽然On Error Resume Next能降低风险,但是它并不是万能的,一些严重错误如溢出、死循环用On Error Resume Next只会让程序越陷越深。考虑周全一些,在一些危险代码里使用On Error GoTo [Flag],它至少能让程序跳出挣扎的泥潭:
=========================================================
On Error GoTo ErrProcess
Set vDoc = webMain.Document
For j = 0 To vDoc.All.length - 1
Set vTag = vDoc.All(j)
If UCase(vTag.tagName) = "A" Then
tmpUser = vTag.innertext
tmpUser = Replace(tmpUser, "[所有人]", "所有人")
If InStr(tmpUser, "在线列表") <> 0 Then tmpUser = ""
If InStr(tmpUser, "本室") <> 0 Then tmpUser = ""
If tmpUser = "所有人" Then tmpUser = ""
If tmpUser <> "" Then
ConnectedUser(i) = tmpUser
i = i + 1
UserCount = UserCount + 1
Else
End If
Else
End If
Next j
Exit Sub

ErrProcess:
Exit Sub
=========================================================
在上面的代码里,由于Resume Next会让程序忽略错误,用变量的初始值去进行计算处理,因此当vDoc=Null时,vDoc.All=0,程序会在下面的Next循环里死掉,因为我们强制了程序的错误处理为“忽略错误并执行下一个语句”,要让程序跳出这个死循环,唯有设置一个Flag,让程序跳过一大堆可能会造成致命错误的语句,直接Exit Sub。
但是也不要大量的使用On Error GoTo错误陷阱,它不仅繁琐,而且让你的代码跳来跳去,非常不结构。
综上所述,On Error Resume Next和On Error GoTo [Flag]任何一方都不是万能钥匙,不要一统天下都是On Error Resume Next或On Error GoTo [Flag],唯有根据不同情况配合使用不同错误处理语句,才能最大限度确保程序安全。

六、整齐的,才是最好的
没有人喜欢零散,写程序也一样,零散的代码让程序变得难读难修改,时间久了连你自己都不知道某个语句为什么在那里,起什么作用了;而且代码零散还会降低程序运行效率,增加不必要的重复代码,增大了程序的体积。
例如一个用于判断文件是否存在的代码:
=========================================================
Dim FileExists As Boolean
Open FileName For Input As #1
If Err = 0 Then
FileExist = True
Else
FileExist = False
End If
=========================================================


学习中请遵守法律法规,本网站内容均来自于互联网,本网站不负担法律责任
真正 V B 木马
#1楼
发帖时间:2016-7-9   |   查看数:0   |   回复数:0
游客组
快速回复