前言
本来是学windows网络编程的,结果学着学着,我想着能不能实现一个远控。没想到捣鼓捣鼓了10多天,还真捣鼓出来了。
总结
这是我写的第一个真正意义上的项目,为了祝贺,有必要单独写篇文章来说说。
视频演示,github链接。相关的使用说明已经非常清楚了,这里就不重复了。
本文主要对此项目做个总结。
这里面耗费我最多的时间是在文件传输,我参考别人的代码,单独运行示例代码,没任何的问题。当我把代码移植进项目的时候,会出现发送端数据都发送完了,客户端都还在等待接收数据。于是我在想,是不是发送端发的数据太快了,导致接收端没接收到。然后我将发送端每发个包,就暂停1s。没想到还真的成功了,但传输效率太慢了,差不多1s只能传输2MB。要是传输几百MB,那得等多久啊。继续改进,网上搜索”windows 编程 tcp文件传输不完”之类的关键词,问题是,根本就搜不到我这样的问题。而且我一想tcp本来就是可靠的协议,怎么可能会出现发送太快,对方接收不到的情况。再继续搜索,看到一个csdn的2003年的帖子,标题大致是”大家tcp文件传输完给的文件结束符是什么呀”,看完之后,恍然大悟,终于知道为什么tcp要四次挥手了。按照我这个例子来讲,发送端数据是发送完毕了的,这边发送端的流程是没任何问题。来到接收端,我写了个死循环,一直接收数据,退出的条件是这次收到的大小数据是不是0,因为发送端数据发送完毕,最后会发送一个0,发送0的前提是第三次挥手给了个FIN包。告诉对方我不再发送数据给你了,接收端接收到0退出循环,发送ACK给对方,之后断开连接。这个是示例代码的过程。而我这个不能断开连接,所以也就没发送端发0的过程,当然接收端也永远接收不到0,也就退出不了循环。解决方法是,发送端发送完数据,最后在发送一个自定义的结束字符串,比如再发送一个”send over”过去。接收端,如果收到”send over”表示接收文件完毕,退出循环。这完美的解决了我的问题,也让文件传输效率变高了不少。以后在遇到此类问题,都需要自定义一个结束符,不然会遇到莫名其妙的bug。
第二个是屏幕截图,本来我整个项目都准备使用纯c来写,但在屏幕截图不得不使用c++来完成,因为c++实在太方便了,几行代码就完成了。反观c,网上的示例我没找到能用的,微软官方文档msdn也没看懂,反正就是要自己构建一个bmp的文件结构。将相应的数据一个一个写进对应的bmp,总之是非常的麻烦。我想c语言能不能引用c++中的函数,一搜能实现。经过我不懈的努力,搞了一下午,最后到Stack Overflow一个人评论,说这是官方用例,终于看官方英文文档解决了。其间我都多次想放弃c++来实现,而纯c来实现,终于解决了。
第三个是没实现的功能,内网主机存活探测,我最开始考虑是用icmp,去探测。但这个方法漏扫率太高了。后面用微软官方的arp探测,感觉速度还是不是太快,那部分其实我应该使用多线程来跑,速度应该就起来了。后面又考虑使用netbios协议,笑死使用nbtscan,它直接扫不出我内网的主机,也就放弃netbios协议。最后也是我根本就没敲的代码,只是一个想法,可以使用tcp,挨个挨个探测一个ip开放的端口,如果1-65535它都没探测出来,就说明这个ip未存活。理论是没啥问题的,但速度想了想真的也慢啊,1-65535多线程也救不到,就算是只探测几个固定的端口,速度虽然起来了,但又会出现我前面说的可能漏扫的情况。所以后面实现这个功能,我会考虑使用多线程的arp扫描方式。
最后一个是反弹msf,msf成功连接起来session,就两步,第一步,与msf建立连接(Stagers),通过网络加载Stages。已经有大佬分析的很清楚了。我在github找到了用c语言写的建立msf连接,都已经是10年前创建的了。更厉害的是,放到现在都能过国内的杀软。继续说我项目的问题,我这边加载msf的shellcode是用给本程序分了一块内存空间,然后把shellcode复制进这块内存,创建子进程的方法来运行shellcode。这样就会导致一个问题,msf或者client.exe其中一方退出,整个程序就挂掉,注意是整个包括msf,client.exe,server.exe都挂掉。要想解决此方法,就必须把shellcode注入进其他进程。我目前想法是用傀儡进程来解决。也许还有更优解,现在才疏学浅,待我学到更多的注入、Hook、内存加载等等方式吧。