0x00 sqlmap
sqlmap是一个自动化的SQL注入工具,其主要功能是扫描、发现并利用给定URL的SQL注入漏洞,内置了很多绕过插件,支持的数据库是MySQL、Oracle、PostgreSQL、Microsoft SQL Server、Microsoft Access、IBM DB2、SQLite、Firebird、Sybase和SAP MaxDB。
sqlmap采用了以下5种SQL注入技术:
1.基于布尔类型的盲注,即可以根据返回页面判断条件真假的注入。
2.基于时间的盲注,即不能根据页面返回的内容判断任何信息,要用条件语句查看时间延迟语句是否已执行(即页面返回时间是否增加)来判断。
3.基于报错注入,即页面会返回错误信息,或者把注入的语句的结果直接返回到页面中。
4.联合查询注入,在可以使用Union的情况下注入。
5.堆查询注入,可以同时执行多条语句时的注入。
sqlmap的功能包括数据库指纹识别、数据库枚举、数据提取、访问目标文件系统,并在获取完全的操作权限时实行任意命令。
0x01 sqlmap入门
sqlmap的安装,到官网http://www.sqlmap.org下载即可,另外需要python2的环境。
1.判断是否存在注入点
sqlmap.py -u http://127.0.0.1/?id=1
当注入点后面的参数大于等于两个时,需要用双引号将url括起来。
sqlmap.py -u "http://127.0.0.1/?id=1&uid=2"
2.判断文本中的请求是否存在注入
sqlmap.py -r desktop/1.txt
-r一般在存在cookie注入时使用。
txt文件中的内容为web数据包,用burp拦截即可。
3.查询当前用户下的所有数据库
sqlmap.py -u url --dbs
继续下一步的话,也就是爆表,需要将--dbs改为-D xxx,这里的xxx是你选中的数据库名。
4.获取数据库中的表名
sqlmap.py -u url -D xxx --tables
在进行下一步爆字段,需要将--tables改为-T xxx。
5.获取表中的字段名
sqlmap.py -u url -D xxx -T xxx --columns
同样的,需要将--columns改为-C xxx。
6.获取字段内容
sqlmap.py -u url -D xxx -T xxx --C xxx --dump
7.获取数据库的所有用户
sqlmap.py -u url --users
改命令的作用是列出数据库的所有用户,前提是当前用户有足够的权限读取包含所有用户的表的权限。
8.获取数据库用户的密码
sqlmap.py -u url --passwords
该命令是列出数据库用户的密码,当然权限很重要。
sqlmap会先列举出用户,然后列出hash,并尝试破解。密码可以自行进行MD5解密。
9.获取当前网站数据库的名称
sqlmap.py -u url --current-db
该命令是列出当前网站使用的数据库。
10.获取当前网站数据库的用户名称
sqlmap.py -u url --current-user
该命令是列出当前网站使用的数据库用户。
0x02 sqlmap进阶
1.--level 5:探测等级
总共有5个等级,不加--level的话,默认是1。等级越高,那么payload就越多。
cookie在等级2就会进行测试,user-Agent/Referer头在等级3会进行测试。
2.--is-dba:当前用户是否为管理权限
该命令用于查询当前账户是否为数据库管理员用户,是就会返回true,反之则是false。
3.--roles:列出数据库管理员角色
该命令仅使用于Oracle数据库,是用于查询当前数据库用户的角色,前期是有权限。
4.--referer:HTTP Referer头。(当--level参数设定为3或以上时,会尝试对referer注入)
可以使用referer命令来进行欺骗,如--referer http://www.baidu.com。
5.--sql-shell:运行自定义SQL语句
该命令用于执行指定的SQL语句。
6.--os-cmd,--os-shell:运行任意操作系统命令
7.--file-read:从数据库服务器中读取文件
该命令用于读取执行文件,读取的文件可以是文本,也可以是二进制文件,前提是有权限使用特定的函数且数据库为MySQL、PostgreSQL或Microsoft SQL Server。
8.--file-write--file-dest:上传文件到数据库服务器中
该命令用于写入本地文件到服务器中。前提条件和--file-read一样。
0x03 sqlmap自带绕过脚本tamper
sqlmap在默认情况下除了使用CHAR()函数防止出现单引号,没有对注入的数据进行修改。--tamper参数对数据做修改来绕过WAF等设备,其中大部分脚本主要用正则模块替换攻击载荷字符编码的方式尝试绕过WAF的检测规则。命令如下所示:
sqlmap.py XXX --tamper "模块名"
目前官方提供53个绕过脚本。另外可以使用参数--identify-waf进行检测是否有安全防护(WAF/IDS/IPS)。
0x04 Nmap
Nmap(Network Mapper,网络映射器)是一款开放源代码的网络探测和安全审核工具。它被设计用来快速扫描大型网络,包括主机探测与发现、开放的端口情况、操作系统与应用服务指纹识别、WAF识别及常见安全漏洞,它的图形化界面是Zenmap,分布式框架为DNmap。
其特点如下:
主机探测:探测网络上的主机。
端口扫描:探测目标主机所开放的端口。
版本检测:探测目标主机的网络服务,判断其服务名称及版本号。
系统检测:探测目标主机的操作系统及网络设备的硬件特性。
支持探测脚本的编写:使用Nmap的脚本引擎(NSE)和Lua编程语言。
0x05 Nmap入门
安装地址:https://nmap.org/download.html
当然kali上面是自带nmap的。
1.扫描目标
-iR:随机选择目标主机。
-exclude:后面跟的主机或网段将不在扫描范围内。
-excludefile:导入文件中的主机或网段将不在扫描范围中。
-iL :从文件中导入目标主机或目标网段。
2.主机发现
-sL:列表扫描,仅列举指定目标的IP,不进行主机发现。
-sn:ping scan,只进行主机发现,不进行端口扫描。
-Pn:将所有指定的主机视作已开启,跳过主机发现的过程。
-PS/PA/PU/PY[portlist]:使用TCP SYN/ACK或SCTP INIT/ECHO方式来发现。
-PE/PP/PM:使用ICMP echo、timestamp、netmask请求包发现主机。
-PO[protocollist]:使用IP协议包探测对方主机是否开启。
-n/-R:-n表示不进行DNS解析;-R表示总是进行DNS解析。
--dns-servers<serv1[,serv2],......>:指定DNS服务器。
--system-dns:指定使用系统的DNS服务器。
--traceroute:追踪每个路由节点。
3.端口扫描
-sS/sT/sA/sW/sM:指定使用TCP SYN/Connect()/ACK/Window/Maimon scans的方式对目标主机进行扫描。
-sU:指定使用UDP扫描的方式确定目标主机的UDP端口状况。
-sN/sF/sX:指定使用TCP Null/FIN/Xmas scans秘密扫描的方式协助探测对方的TCP端口状态。
--sccanflags<flags>:定制TCP包的flags。
-sY/sZ:使用SCTP INIT/COOKIE-ECHO扫描SCTP协议端口的开放情况。
-sO:使用IP protocol扫描确定目标机支持的协议类型。
-b<FTP relay host>:使用FTP bounce scan扫描方式。
-p:扫描指定的端口。
-F:快速模式,仅扫描TOP100的端口。
-r:不进行端口随机打乱的操作。
--top-ports<number>:扫描开放概率最高的number个端口。
--port-ratio<ratio>:扫描指定概率以上的端口。
4.版本侦测
-sV:指定让Nmap进行版本侦测。
--version-intensity<level>:指定版本侦测的强度(0~9),默认为7.数值越高,探测出的服务越准确,但是运行时间比较长。
--version-light:指定使用轻量级侦测方式(intensity2)。
--version-all:尝试使用所有的probes进行侦测(intensity9)。
--version-trace:显示出详细的版本侦测过程信息。
5.常用方法(此处只记录自己可能会忘的)
扫描主机列表targets.txt中的所有目标地址:nmap -iL C:\Users\Desktop\targets.txt
扫描除某一个目标地址之外的所有目标地址:nmap ip/24 -exclude ip
扫描除某一个文件中的目标地址之外的目标地址:nmap ip/24 -excludefile 文件的绝对路径
对目标地址进行路由跟踪:nmap --traceroute IP
扫描目标地址所在C段的在线情况:nmap -sP ip/24
目标地址的操作系统指纹识别:nmap -O ip
目标地址提供的服务版本检测:nmap -sV ip
探测防火墙状态:nmap -sF -T4 ip (实战中可以利用FIN扫描来探测防火墙的状态。FIN扫描用于识别端口是否关闭,收到RST回复则说明该端口关闭,反之则是open或filtered状态)
6.状态识别
Nmap输出的是扫描列表,包括端口号、端口状态、服务名称、服务版本及协议 。
open:开放的。表示应用程序正在监听该端口的连接,外部可以访问。
filtered:被过滤的,表示端口被防火墙或其他网络设备阻止,不能访问。
closed:关闭的,表示目标主机未开启该端口。
unfiltered:未被过滤的,表示Nmap无法确定端口所处状态,需进一步探测。
open/filtered:开放的或被过滤的,Nmap不能识别。
closed/filtered:关闭的或被过滤的,Nmap不能识别。
0x06 Nmap进阶
1.脚本介绍
存放位置:默认存在/xx/nmap/scripts文件夹。
脚本类型如下:
Auth:负责处理鉴权证书(绕过鉴权)的脚本。
Broadcast:在局域网内探查更多服务的开启情况,如DHCP/DNS/SQLServer等。
Brute:针对常见的应用提供暴力破解方式,如HTTP/SMTP等。
Default:使用-sC或-A选项扫描时默认的脚本,提供基本的脚本扫描能力。
Discovery:对网络进行更多信息的搜集,如SMB枚举、SNMP查询等。
Dos:用于进行拒绝服务攻击。
Exploit:利用已知的漏洞入侵系统。
External:利用第三方的数据库或资源。
Fuzzer:模糊测试脚本,发送异常的包到目标机,探测出潜在漏洞。
Intrusive:入侵性的脚本,此类脚本可能引发对方的IDS/IPS的记录或屏蔽。
Malware:探测目标机是否感染了病毒、开启后门等信息。
Safe:此类与Intrusive相反,属于安全性脚本。
Version:负责增强服务与版本扫描功能的脚本。
Vuln:负责检查目标机是否有常见漏洞。
2.常用脚本
--script=default:使用默认的脚本进行扫描。
--script=<Lua scripts>:使用某个脚本进行扫描。
--script-args=key1=value1,key2=value2....:该参数用于传递脚本里的参数,key1是参数名,该参数对应value1这个值。
-script-args-file=filename:使用文件为脚本提供参数。
--script-trace:如果设置该参数,则显示脚本执行过程中发送与接受的数据。
--script-updatedb:在Nmap的scripts目录里有一个script.db文件,该文件保存了当前Nmap可用的脚本,类似于一个小型数据库,如果我们开启Nmap并调用了此参数,则Nmap会自行扫描scripts目录中的扩展脚本,进行数据库更新。
--script-help:调用该参数后,Nmap会输出该脚本对应的脚本使用参数,以及详细的介绍信息。
3.实例
nmap --script=auth ip:该命令可以对目标主机或目标主机所在的网段进行应用弱口令检测。
nmap --script=brute ip:可对数据库、SMB、SNMP等进行简单密码的暴力破解。
nmap --script=vuln ip:检查目标主机或网段是否存在常见的漏洞。
nmap --script=realvnc-auth-bypass ip:扫描VNC服务。
nmap -n -p 445 --script=broadcast ip:探测局域网内更多服务开启的情况。
nmap -script external baidu.com:利用第三方的数据库或资源查询目标地址的信息。
注:因为burp自己用的很多,就不做记载了。
------------------------------------------------------------------------------
【转载】Nmap源码分析(基本框架)
AspirationFlow 2012-07-28 21:32:50 11401 收藏 2
展开
Nmap源码分析(基本框架)
2012年7月18日
Nmap是一款非常强大的开源扫描工具。自己在使用过程中忍不住想仔细阅读一下它的源码。源码里面汇集了众多安全专家的精巧设计与优雅写法,读起来令人心旷神怡而又受益匪浅。
这里我们以阅读nmap6.0的代码作为主线来分析Nmap源码的实现框架。
源码下载地址:http://nmap.org/dist/nmap-6.01.tar.bz2
SVN检出:svn co https://svn.nmap.org/nmap
1 文件组织
我们先从总体上了解Nmap的文件组织方式及分析源码需要关注的重点。
1.1 目录结构
解压Nmap的源码包后,可以看到根目录下有许多的子目录和文件。
文件分析
放在Nmap/根目录下包括几种类型文件:
1) Nmap核心功能的源码(如nmap.cc/ scan_engine.cc/ service_scan.cc/osscan2.cc/ nse_main.lua等)。
2) Nmap的核心数据库文件(nmap-os-db/ nmap-service-probes/ nmap-rpc/nmap-protocols等)。
3) 编译链接相关的Makefile或CONFIG文件。
4) 其他杂项文件(如安装提示:README-WIN32)
目录分析
使用Windows的tree命令列举出Nmap的目录结构.
为了避免目录树过长,这里只显示了3个级别的目录,目录的主要作用在名字后面简略说明。
可以看到Nmap工具也使用到很多其他开源项目的成果,例如libdnet/ liblinear/ liblua/libpcap/ libpcre等;另外Nmap自身也实现很多有用的程序库,如nsock/ libnetutil/;Nmap项目包括附带几个小工具:1)ncat,这是根据TCPIP协议栈瑞士军刀netcat(该工具已停止维护更新)开发扩展出来的工具。2)nping,类似于Hping的工具,用于进行主机探测和发包收包。3)ndiff,用于比较两次nmap扫描结果之间差异。
Nmap/
├─docs(Nmap相关文档,包括License、usage说明及XMLschema文件等)
│ ├─licenses
│ └─man-xlate
├─libdnet-stripped(libdnet:简单的网络接口开源库)
│ ├─config
│ ├─include
│ └─src
├─liblinear(LIBLINEAR:负责大型线性分类的开源库)
│ └─blas
├─liblua(Lua脚本语言源码库)
├─libnetutil(Nmap实现的基本的网络实用函数)
├─libpcap(开源的抓包代码库libpcap)
│ ├─bpf
│ ├─ChmodBPF
│ ├─lbl
│ ├─missing
│ ├─msdos
│ ├─NMAP_MODIFICATIONS
│ ├─packaging
│ ├─pcap
│ ├─SUNOS4
│ ├─tests
│ └─Win32
├─libpcre(Perl兼容的正则表达式开源库libpcre)
├─macosx(该目录负责支持苹果的操作系统MACOS X)
│ └─nmap.pmdoc
├─mswin32(该目录负责支持Windows操作系统)
│ ├─lib
│ ├─license-format
│ ├─NET
│ ├─NETINET
│ ├─nsis
│ ├─OpenSSL
│ ├─pcap-include
│ ├─RPC
│ └─winpcap
├─nbase(Nmap封装的基础使用程序库,包括string/path/random等)
├─ncat(Ncat是Nmap项目组实现的新版的netcat:强大的网络工具)
│ ├─certs
│ ├─docs
│ └─test
├─ndiff(Ndiff是用于比较Nmap扫描结果的实用命令)
│ ├─docs
│ └─test-scans
├─nmap-update(负责Nmap更新相关操作)
├─nping(Nping是Nmap项目组实现的新版的Hping:网络探测与构建packet)
│ └─docs
├─nselib(Nmap使用Lua语言编写的常用的脚本库)
│ └─data
├─nsock(Nmap实现的并行的SocketEvent处理库)
│ ├─include
│ └─src
├─scripts(Nmap提供常用的扫描检查的lua脚本)
├─todo(介绍Nmap项目将来开发的具体任务)
└─zenmap(Nmap的官方的图形界面程序,由python语言编写)
├─install_scripts
├─radialnet
├─share
├─test
├─zenmapCore
└─zenmapGUI
1.2 文件类型
下面从源码类型的角度上浏览一下Nmap项目的特点:
Nmap6.0工程内总共包括1300多个文件。
1) C和C++文件有600多个,主要实现Nmap最核心的功能:主机发现、端口扫描、服务侦测、OS侦测及搭建脚本引擎框架;也包括其他开源项目如libpcap的源码。
2) Python文件有100多个,主要实现Zenmap图形界面,Zenmap会调用到Nmap基本命令,也实现一些新的功能:例如确定网络拓扑结构、Profile的管理(常用的命令保存为Profile)等。
3) Lua与NSE文件400多个,负责构建Nmap脚本引擎及提供常用的扫描脚本。其中NSE格式为Nmap定制的Lua文件,方便用户自行编写脚本进行功能扩展。
4) XML文件数十个,用于辅助描述Nmap的内容或Zenmap的测试等工作。
5) 其他文件,其他辅助工具操作的文件。
2 源码分析
2.1 执行流程框架
Nmap的执行流程简单清晰,主要的工作在nmap.cc文件中完成,而main.cc负责简单地包装nmap_main()函数。
nmap_main()函数是执行流程的核心。
准备阶段:在其中会执行参数解析、资源分配、基本扫描信息的输出、端口与地址列表的初始化、NSE环境准备及pre-scripts的运行等基本的准备操作。
工作阶段:然后进入主循环,每次循环对一组目标地址进行主机发现、端口扫描、服务与版本侦测、OS侦测及脚本扫描等操作,直到所有的目标地址都被扫描完毕才推出主循环。
善后阶段:在完成所有的扫描操作后,调用post-script完成相应处理,然后打印出扫描的最终结果,并释放掉分配的资源。
2.2 nmap_main()函数
以下代码是对nmap_main()函数基本的分析。
其中以///开头是新添加的注释。而以类似于///<Start------创建主机组状态,进入主循环--------Start>的形式出现的注释用于标注一个比较大的功能代码段。
Nmap的所有的功能都在此nmap_main()设有入口,以此为基础可以更深入地分析Nmap的其他模块。
int nmap_main(int argc, char *argv[]) {
int i;
vector<Target *> Targets;
time_t now;
struct hostent *target = NULL;
time_t timep;
char mytime[128];
addrset exclude_group;
#ifndef NOLUA
/* Only NSE scripts can add targets */
NewTargets *new_targets = NULL;///NewTargets为Singleton模式,产生单个实例
/* Pre-Scan and Post-Scan script results datastructure */
ScriptResults *script_scan_results = NULL;
#endif
char **host_exp_group;
int num_host_exp_groups;
HostGroupState *hstate = NULL;
unsigned int ideal_scan_group_sz = 0;
Target *currenths;
char *host_spec = NULL;
char myname[MAXHOSTNAMELEN + 1];
int sourceaddrwarning = 0; /* Have we warned them yet about unguessable
source addresses? */
unsigned int targetno;
char hostname[MAXHOSTNAMELEN + 1] = "";
struct sockaddr_storage ss;
size_t sslen;
char **fakeargv = NULL;
now = time(NULL);
local_time = localtime(&now);
///设置错误log输出函数
if(o.debugging)
nbase_set_log(fatal,error);
else
nbase_set_log(fatal,NULL);
if (argc < 2 ) printusage(-1);
/* argv faking silliness */
fakeargv = (char **) safe_malloc(sizeof(char *) * (argc + 1));
for(i=0; i < argc; i++) {
fakeargv[i] = strdup(argv[i]);
}
fakeargv[argc] = NULL;
Targets.reserve(100);
#ifdef WIN32
win_pre_init();
#endif
///调用parse_options进行命令参数的解析
parse_options(argc, fakeargv);
///在Linux下设置终端为只读非阻塞方式,在Windows平台为空函数。
tty_init(); // Put the keyboard in raw mode
///将解析命令时需要延迟执行的操作在此处处理
apply_delayed_options();
#ifdef WIN32
///调用WSAStartup启动Winsock DLL,后续网络解析等需要用到。
win_init();
#endif
///如果用户使用了参数--iflist,那么会在此处打印网卡和路由表信息,然后退出。
///该选项对于显示指定发送网卡非常有帮助,可以提供基本的网络设备信息。
if (delayed_options.iflist) {
print_iflist();
exit(0);
}
///quashargv部分用于修改命令行参数,将程序名字更改为FAKE_ARGV(默认为“pine”),
///并将剩余的各个参数都清空。
///在命令中加入-q可实现quashargv功能。这最初是为了逃避ps等程序名称显示,便于隐蔽Nmap。
///不过在Windows系统上并无实效。
/* more fakeargv junk, BTW malloc\'ing extra space in argv[0] doesn\'t work */
if (o.quashargv) {
size_t fakeargvlen = strlen(FAKE_ARGV), argvlen = strlen(argv[0]);
if (argvlen < fakeargvlen)
fatal("If you want me to fake your argv, you need to call the program with a longer name. Try the full pathname, or rename it fyodorssuperdedouperportscanner");
strncpy(argv[0], FAKE_ARGV, fakeargvlen);
memset(&argv[0][fakeargvlen], \'\0\', strlen(&argv[0][fakeargvlen]));
for(i=1; i < argc; i++)
memset(argv[i], \'\0\', strlen(argv[i]));
}
///如果使用FTP bounce scan的扫描方式,那么需要首先保证该FTP网站是可以访问到的。
///关于FTP bounce scan更多介绍,请参考:http://nmap.org/nmap_doc.html#bounce
/* If he wants to bounce off of an FTP site, that site better damn well be reachable! */
if (o.bouncescan) {
if (!inet_pton(AF_INET, ftp.server_name, &ftp.server)) {
if ((target = gethostbyname(ftp.server_name)))
memcpy(&ftp.server, target->h_addr_list[0], 4);
else {
fatal("Failed to resolve FTP bounce proxy hostname/IP: %s",
ftp.server_name);
}
} else if (o.verbose) {
log_write(LOG_STDOUT, "Resolved FTP bounce attack proxy to %s (%s).\n",
ftp.server_name, inet_ntoa(ftp.server));
}
}
///<Start--------------扫描信息输出-----------------Start>
fflush(stdout);
fflush(stderr);
timep = time(NULL);
///准备将基本的扫描输出到文件与控制台中
/* Brief info in case they forget what was scanned */
Strncpy(mytime, ctime(&timep), sizeof(mytime));
chomp(mytime); ///去掉字符串末尾换行符
char *xslfname = o.XSLStyleSheet();///XML样式表
xml_start_document();
if (xslfname) {
xml_open_pi("xml-stylesheet");
xml_attribute("href", "%s", xslfname);
xml_attribute("type", "text/xsl");
xml_close_pi();
xml_newline();
}
std::string command;
if (argc > 0)
command += fakeargv[0];
for (i = 1; i < argc; i++) {
command += " ";
command += fakeargv[i];
}
xml_start_comment();
xml_write_escaped(" %s %s scan initiated %s as: %s ", NMAP_NAME, NMAP_VERSION, mytime, join_quoted(fakeargv, argc).c_str());
xml_end_comment();
xml_newline();
log_write(LOG_NORMAL|LOG_MACHINE, "# ");
log_write(LOG_NORMAL|LOG_MACHINE, "%s %s scan initiated %s as: ", NMAP_NAME, NMAP_VERSION, mytime);
log_write(LOG_NORMAL|LOG_MACHINE, "%s", command.c_str());
log_write(LOG_NORMAL|LOG_MACHINE, "\n");
xml_open_start_tag("nmaprun");
xml_attribute("scanner", "nmap");
xml_attribute("args", "%s", join_quoted(fakeargv, argc).c_str());
xml_attribute("start", "%lu", (unsigned long) timep);
xml_attribute("startstr", "%s", mytime);
xml_attribute("version", "%s", NMAP_VERSION);
xml_attribute("xmloutputversion", NMAP_XMLOUTPUTVERSION);
xml_close_start_tag();
xml_newline();
output_xml_scaninfo_records(&ports);
xml_open_start_tag("verbose");
xml_attribute("level", "%d", o.verbose);
xml_close_empty_tag();
xml_newline();
xml_open_start_tag("debugging");
xml_attribute("level", "%d", o.debugging);
xml_close_empty_tag();
xml_newline();
/* Before we randomize the ports scanned, lets output them to machine
parseable output */
if (o.verbose) ///输出机器可以解析端口信息(grepable格式)
output_ports_to_machine_parseable_output(&ports);
#if defined(HAVE_SIGNAL) && defined(SIGPIPE)
///注册信号处理函数,这里只是直接忽略SIGPIPE信号。其具体实现为#define SIG_IGN (void (*)(int))1
signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE so our program doesn\'t crash because
of it, but we really shouldn\'t get an unexpected
SIGPIPE */
#endif
///检查配置的最大并发度是否在系统最大的套接字数量范围之内
if (o.max_parallelism && (i = max_sd()) && i < o.max_parallelism) {
error("WARNING: Your specified max_parallel_sockets of %d, but your system says it might only give us %d. Trying anyway", o.max_parallelism, i);
}
if (o.debugging > 1) log_write(LOG_STDOUT, "The max # of sockets we are using is: %d\n", o.max_parallelism);
// At this point we should fully know our timing parameters
if (o.debugging) {
log_write(LOG_PLAIN, "--------------- Timing report ---------------\n");
log_write(LOG_PLAIN, " hostgroups: min %d, max %d\n", o.minHostGroupSz(), o.maxHostGroupSz());
log_write(LOG_PLAIN, " rtt-timeouts: init %d, min %d, max %d\n", o.initialRttTimeout(), o.minRttTimeout(), o.maxRttTimeout());
log_write(LOG_PLAIN, " max-scan-delay: TCP %d, UDP %d, SCTP %d\n", o.maxTCPScanDelay(), o.maxUDPScanDelay(), o.maxSCTPScanDelay());
log_write(LOG_PLAIN, " parallelism: min %d, max %d\n", o.min_parallelism, o.max_parallelism);
log_write(LOG_PLAIN, " max-retries: %d, host-timeout: %ld\n", o.getMaxRetransmissions(), o.host_timeout);
log_write(LOG_PLAIN, " min-rate: %g, max-rate: %g\n", o.min_packet_send_rate, o.max_packet_send_rate);
log_write(LOG_PLAIN, "---------------------------------------------\n");
}
///<End--------------扫描信息输出-----------------End>
///<Start-------------端口与地址初始化-------------Start>
/* Before we randomize the ports scanned, we must initialize PortList class. */
if (o.ipprotscan)
PortList::initializePortMap(IPPROTO_IP, ports.prots, ports.prot_count);
if (o.TCPScan())
PortList::initializePortMap(IPPROTO_TCP, ports.tcp_ports, ports.tcp_count);
if (o.UDPScan())
PortList::initializePortMap(IPPROTO_UDP, ports.udp_ports, ports.udp_count);
if (o.SCTPScan())
PortList::initializePortMap(IPPROTO_SCTP, ports.sctp_ports, ports.sctp_count);
if (o.randomize_ports) {
if (ports.tcp_count) {
///将端口进行随机打乱操作
shortfry(ports.tcp_ports, ports.tcp_count);
// move a few more common ports closer to the beginning to speed scan
///将常见的端口移动到前面,以便最快地发现有效的端口
random_port_cheat(ports.tcp_ports, ports.tcp_count);
}
if (ports.udp_count)
shortfry(ports.udp_ports, ports.udp_count);
if (ports.sctp_count)
shortfry(ports.sctp_ports, ports.sctp_count);
if (ports.prot_count)
shortfry(ports.prots, ports.prot_count);
}
///exclude_group记录的是排除地址,如命令行nmap 192.168.1.1/24 --exclude 192.168.1.0-10
///扫描C类地址192.168.1.x,并排除其中192.168.1.0-192.168.1.10地址。
///addrset_init()将初始化排除地址组的链表头指针为NULL。
addrset_init(&exclude_group);
/* lets load our exclude list */
if (o.excludefd != NULL) {///文件指定的排除地址
load_exclude_file(&exclude_group, o.excludefd);
fclose(o.excludefd);
}
if (o.exclude_spec != NULL) {///命令行直接指定的排除地址
load_exclude_string(&exclude_group, o.exclude_spec);
}
if (o.debugging > 3) ///若调试级别大于3,打印出排除地址信息
dumpExclude(&exclude_group);
///<End-------------端口与地址初始化-------------End>
///<Start------NSE环境准备并执行pre-scripts--------Start>
#ifndef NOLUA
if (o.scriptupdatedb) {
o.max_ips_to_scan = o.numhosts_scanned; // disable warnings?
}
if (o.servicescan) ///当配置了版本扫描时,会默认启动版本扫描脚本,位于NSE中version类别中
o.scriptversion = 1;
if (o.scriptversion || o.script || o.scriptupdatedb)
open_nse(); ///开启NSE环境
/* Run the script pre-scanning phase */
if (o.script) {
new_targets = NewTargets::get(); ///分配实例或返回已有实例(Singleton模式)
script_scan_results = get_script_scan_results_obj();
script_scan(Targets, SCRIPT_PRE_SCAN);
printscriptresults(script_scan_results, SCRIPT_PRE_SCAN);
script_scan_results->clear();
}
#endif
///<End------NSE环境准备并执行pre-scripts--------End>
///<Start------创建主机组状态,进入主循环--------Start>
/* Time to create a hostgroup state object filled with all the requested
machines. The list is initially empty. It is refilled inside the loop
whenever it is empty. */
///分配字符串数组,用以保存各个主机表达式字符串的地址
host_exp_group = (char **) safe_malloc(o.ping_group_sz * sizeof(char *));
num_host_exp_groups = 0;
hstate = new HostGroupState(o.ping_group_sz, o.randomize_hosts,
host_exp_group, num_host_exp_groups);
do {
///确定最佳的host group的大小,该大小取决于扫描方式与网络速度。
ideal_scan_group_sz = determineScanGroupSize(o.numhosts_scanned, &ports);
///<Start---------对host group进行主机发现----------Start>
///以下的while()将依次进行主机发现,确定主机是否在线。
///若该主机在线加入该host group,用于后续的操作。当数量达到最佳大小时,退出循环。
while(Targets.size() < ideal_scan_group_sz) {
o.current_scantype = HOST_DISCOVERY; ///设置扫描状态:HOST_DICOVERY
currenths = nexthost(hstate, &exclude_group, &ports, o.pingtype); ///主机发现的核心函数
///如果当前主机发现无法找到有效主机,那么会做以下尝试:
///1)更换主机表达式(host expressions)
///例如:nmap 192.168.1.1/24 10.10.30.55-100,192.168.1.x不能再发现主机时候,切换为10.30.55-100
///2)将执行脚本扫描时发现的主机,加入主机表达式组host_exp_group
///3) 建立新的主机组状态,并做最后的主机发现尝试
if (!currenths) {
/* Try to refill with any remaining expressions */
/* First free the old ones */
for(i=0; i < num_host_exp_groups; i++)
free(host_exp_group[i]);
num_host_exp_groups = 0;
/* Now grab any new expressions */
while(num_host_exp_groups < o.ping_group_sz &&
(!o.max_ips_to_scan || o.max_ips_to_scan > o.numhosts_scanned + (int) Targets.size() + num_host_exp_groups) &&
(host_spec = grab_next_host_spec(o.inputfd, o.generate_random_ips, argc, fakeargv))) {
// For purposes of random scan
host_exp_group[num_host_exp_groups++] = strdup(host_spec);
}
#ifndef NOLUA
/* Add the new NSE discovered targets to the scan queue */
if (o.script) {
if (new_targets != NULL) {
while (new_targets->get_queued() > 0 && num_host_exp_groups < o.ping_group_sz) {
std::string target_spec = new_targets->read();
if (target_spec.length())
host_exp_group[num_host_exp_groups++] = strdup(target_spec.c_str());
}
if (o.debugging > 3)
log_write(LOG_PLAIN,
"New targets in the scanned cache: %ld, pending ones: %ld.\n",
new_targets->get_scanned(), new_targets->get_queued());
}
}
#endif
if (num_host_exp_groups == 0) ///当没有其他的主机表达式时,退出整个主机发现循环
break;
delete hstate;
hstate = new HostGroupState(o.ping_group_sz, o.randomize_hosts,host_exp_group,
num_host_exp_groups);
/* Try one last time -- with new expressions */
currenths = nexthost(hstate, &exclude_group, &ports, o.pingtype);
if (!currenths)
break;
}
if (currenths->flags & HOST_UP && !o.listscan)
o.numhosts_up++;
if ((o.noportscan && !o.traceroute
#ifndef NOLUA
&& !o.script
#endif
) || o.listscan) {
///当不进行端口扫描(-sn)并且没有指定traceroute和脚本的话,那么扫描就到此处就结束。
///或当进行列表扫描(-sL,只列举出主机IP,并不真正扫描)时,扫描也到此结束。
/* We\'re done with the hosts */
if (currenths->flags & HOST_UP || o.verbose) {
xml_start_tag("host");
write_host_header(currenths);
printmacinfo(currenths);
// if (currenths->flags & HOST_UP)
// log_write(LOG_PLAIN,"\n");
printtimes(currenths);
xml_end_tag();
xml_newline();
log_flush_all();
}
delete currenths;
o.numhosts_scanned++;
continue;
}
///若配置要伪造源IP地址(-S ip),将命令行中传入的地址写入当前主机源地址
if (o.spoofsource) {
o.SourceSockAddr(&ss, &sslen);
currenths->setSourceSockAddr(&ss, sslen);
}
///如果主机状态为HOST_DOWN,那么需要根据配置考虑是否输出其状态
///输出条件:verbose级别大于0,并且没有指定openonly或已确定有开放端口。
///疑问:如果有open Ports,为什么此主机状态会是HOST_DOWN呢?
/* I used to check that !currenths->weird_responses, but in some
rare cases, such IPs CAN be port successfully scanned and even
connected to */
if (!(currenths->flags & HOST_UP)) {
if (o.verbose && (!o.openOnly() || currenths->ports.hasOpenPorts())) {
xml_start_tag("host");
write_host_header(currenths);
xml_end_tag();
xml_newline();
}
delete currenths;
o.numhosts_scanned++;
continue;
}
///如果是RawScan(即涉及到构建原始的packet的扫描方式,如SYN/FIN/ARP等等),
///需要设置套接字源IP地址
if (o.RawScan()) {
if (currenths->SourceSockAddr(NULL, NULL) != 0) {
if (o.SourceSockAddr(&ss, &sslen) == 0) {
///若全局变量o中已有源IP地址,直接赋值给当前目标机
currenths->setSourceSockAddr(&ss, sslen);
} else {
///否则,需要重新查询、解析主机来获取源地址
if (gethostname(myname, MAXHOSTNAMELEN) ||
resolve(myname, 0, 0, &ss, &sslen, o.af()) == 0)
fatal("Cannot get hostname! Try using -S <my_IP_address> or -e <interface to scan through>\n");
o.setSourceSockAddr(&ss, sslen);
currenths->setSourceSockAddr(&ss, sslen);
if (! sourceaddrwarning) {
error("WARNING: We could not determine for sure which interface to use, so we are guessing %s . If this is wrong, use -S <my_IP_address>.",
inet_socktop(&ss));
sourceaddrwarning = 1;
}
}
}
if (!currenths->deviceName())///网卡名字,在主机发现函数nexthost()中设置
fatal("Do not have appropriate device name for target");
///如果新发现的主机与该主机组类型不大相同,那么考虑将此主机放入新的主机组内。
///因为对主机分组是为了加快扫描速度,所以尽可能特征相似的主机组合在一起。
///流水线工作模式的扫描思想。
/* Hosts in a group need to be somewhat homogeneous. Put this host in
the next group if necessary. See target_needs_new_hostgroup for the
details of when we need to split. */
if (target_needs_new_hostgroup(Targets, currenths)) {
returnhost(hstate);
o.numhosts_up--;
break;
}
///设置IP诱骗时,将当前主机真实IP放入decoyturn位置。
///其他的诱骗IP地址在parse options时已经确定。
o.decoys[o.decoyturn] = currenths->v4source();
}
///将新发现的主机加入Targets向量
Targets.push_back(currenths);
}///一次分组的主机发现在此处结束,接下来执行端口扫描、服务侦测、OS侦测、脚本扫描等。
///<End---------对host group进行主机发现----------End>
if (Targets.size() == 0)///主机发现没有找到任何目标机时,退出主循环
break; /* Couldn\'t find any more targets */
// Set the variable for status printing
o.numhosts_scanning = Targets.size();
// Our source must be set in decoy list because nexthost() call can
// change it (that issue really should be fixed when possible)
if (o.af() == AF_INET && o.RawScan())
o.decoys[o.decoyturn] = Targets[0]->v4source();
/* I now have the group for scanning in the Targets vector */
if (!o.noportscan) {
///<Start---------端口扫描----------Start>
///针对用户指定的不同扫描方式,分别使用不同参数调用ultra_scan()
///ultra_scan()设计精巧,用统一的接口处理大多数的端口扫描
// Ultra_scan sets o.scantype for us so we don\'t have to worry
if (o.synscan)
ultra_scan(Targets, &ports, SYN_SCAN);
if (o.ackscan)
ultra_scan(Targets, &ports, ACK_SCAN);
if (o.windowscan)
ultra_scan(Targets, &ports, WINDOW_SCAN);
if (o.finscan)
ultra_scan(Targets, &ports, FIN_SCAN);
if (o.xmasscan)
ultra_scan(Targets, &ports, XMAS_SCAN);
if (o.nullscan)
ultra_scan(Targets, &ports, NULL_SCAN);
if (o.maimonscan)
ultra_scan(Targets, &ports, MAIMON_SCAN);
if (o.udpscan)
ultra_scan(Targets, &ports, UDP_SCAN);
if (o.connectscan)
ultra_scan(Targets, &ports, CONNECT_SCAN);
if (o.sctpinitscan)
ultra_scan(Targets, &ports, SCTP_INIT_SCAN);
if (o.sctpcookieechoscan)
ultra_scan(Targets, &ports, SCTP_COOKIE_ECHO_SCAN);
if (o.ipprotscan)
ultra_scan(Targets, &ports, IPPROT_SCAN);
/* These lame functions can only handle one target at a time */
if (o.idlescan) {
for(targetno = 0; targetno < Targets.size(); targetno++) {
o.current_scantype = IDLE_SCAN;
keyWasPressed(); // Check if a status message should be printed
idle_scan(Targets[targetno], ports.tcp_ports,
ports.tcp_count, o.idleProxy, &ports);
}
}
if (o.bouncescan) {
for(targetno = 0; targetno < Targets.size(); targetno++) {
o.current_scantype = BOUNCE_SCAN;
keyWasPressed(); // Check if a status message should be printed
if (ftp.sd <= 0) ftp_anon_connect(&ftp);
if (ftp.sd > 0) bounce_scan(Targets[targetno], ports.tcp_ports,
ports.tcp_count, &ftp);
}
}
///<End---------端口扫描----------End>
///<Start------服务与版本扫描--------Start>
if (o.servicescan) {
o.current_scantype = SERVICE_SCAN;
service_scan(Targets);
}
if (o.servicescan) {
/* This scantype must be after any TCP or UDP scans since it
* get\'s it\'s port scan list from the open port list of the current
* host rather than port list the user specified.
*/
for(targetno = 0; targetno < Targets.size(); targetno++)
pos_scan(Targets[targetno], NULL, 0, RPC_SCAN);
}
///<End------服务与版本扫描--------End>
}
///操作系统扫描
if (o.osscan){
OSScan os_engine;
os_engine.os_scan(Targets);
}
///若需要路径追踪,在此处调用traceroute获取路径
if (o.traceroute)
traceroute(Targets);
///脚本扫描
#ifndef NOLUA
if(o.script || o.scriptversion) {
script_scan(Targets, SCRIPT_SCAN);
}
#endif
///<Start------输出扫描结果--------Start>
for(targetno = 0; targetno < Targets.size(); targetno++) {
currenths = Targets[targetno];
/* Now I can do the output and such for each host */
if (currenths->timedOut(NULL)) {
xml_open_start_tag("host");
xml_attribute("starttime", "%lu", (unsigned long) currenths->StartTime());
xml_attribute("endtime", "%lu", (unsigned long) currenths->EndTime());
xml_close_start_tag();
write_host_header(currenths);
xml_end_tag(); /* host */
xml_newline();
log_write(LOG_PLAIN,"Skipping host %s due to host timeout\n",
currenths->NameIP(hostname, sizeof(hostname)));
log_write(LOG_MACHINE,"Host: %s (%s)\tStatus: Timeout",
currenths->targetipstr(), currenths->HostName());
} else {
/* --open means don\'t show any hosts without open ports. */
if (o.openOnly() && !currenths->ports.hasOpenPorts())
continue;
xml_open_start_tag("host");
xml_attribute("starttime", "%lu", (unsigned long) currenths->StartTime());
xml_attribute("endtime", "%lu", (unsigned long) currenths->EndTime());
xml_close_start_tag();
write_host_header(currenths);
printportoutput(currenths, ¤ths->ports);
printmacinfo(currenths);
printosscanoutput(currenths);
printserviceinfooutput(currenths);
#ifndef NOLUA
printhostscriptresults(currenths);
#endif
if (o.traceroute)
printtraceroute(currenths);
printtimes(currenths);
log_write(LOG_PLAIN|LOG_MACHINE,"\n");
xml_end_tag(); /* host */
xml_newline();
}
}
log_flush_all();
///<End------输出扫描结果--------End>
o.numhosts_scanned += Targets.size();
/* Free all of the Targets */
while(!Targets.empty()) {
currenths = Targets.back();
delete currenths;
Targets.pop_back();
}
o.numhosts_scanning = 0;
} while(!o.max_ips_to_scan || o.max_ips_to_scan > o.numhosts_scanned);
///当指定的扫描数量没有达到已经扫描数量,继续循环
///<End------创建主机组状态,进入主循环--------End>
///执行post-script,释放分配的资源
#ifndef NOLUA
if (o.script) {
script_scan(Targets, SCRIPT_POST_SCAN);
printscriptresults(script_scan_results, SCRIPT_POST_SCAN);
script_scan_results->clear();
delete new_targets;
new_targets = NULL;
}
#endif
delete hstate;
addrset_free(&exclude_group);
hstate = NULL;
/* Free host expressions */
for(i=0; i < num_host_exp_groups; i++)
free(host_exp_group[i]);
num_host_exp_groups = 0;
free(host_exp_group);
if (o.inputfd != NULL)
fclose(o.inputfd);
printdatafilepaths();
printfinaloutput();
free_scan_lists(&ports);
eth_close_cached();
if (o.release_memory) {
/* Free fake argv */
for(i=0; i < argc; i++)
free(fakeargv[i]);
free(fakeargv);
nmap_free_mem();
}
return 0;
}
————————————————
版权声明:本文为CSDN博主「AspirationFlow」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/aspirationflow/article/details/7797708
网络攻击测试方法和工具简介
目录
网络攻击测试方法和工具简介 1
说明 1
漏洞检测 1
扫描系统漏洞 2
网络攻击检测和防护 3
攻击模拟 3
攻击防护 5
说明
本文档内容根据网络上关于网络攻击测试方法和工具进行了分类整理,归纳出最适用于漏洞检测和 DDOS 攻防测试工具。本文中出现的工具大部分属于开源和可以免费获取到的网络工具。
漏洞检测
目前针对漏洞检测的工具分为两大类:
- 网络安全公司开发的收费软件
- 开源爱好者和组织开发的免费软件
一般收费软件更新速度快,能够根据漏洞数据库扫描出最新的漏洞;而免费工具基本很少更新,基本上只能扫描到一些基本的漏洞。
著名收费漏洞扫描软件,国内有:绿盟,知道创宇,360,软件均无法免费获得,需购买。
著名收费漏洞扫描软件,国外:Nessus,OpenVAS, Core Impact。
免费漏洞扫描软件:国内无,国外有 nmap, Retina, Nipper。
经测试使用,nmap 数据库比较新,能够实用。
扫描系统漏洞
以普通 Linux 系统为例:
-
从官网下载最新 nmap 7 源代码,https://nmap.org/download.html.
-
解压源代码到本机
bzip2 -cd nmap-.tar.bz2 | tar xvf – -
进入源码目录
cd nmap- -
配置源码
./configure
配置完成成功后,会有 ASCII 界面 -
编译并安装
make
su root
make install -
下载漏洞扫描脚本
git clone https://github.com/scipag/vulscan.git -
将脚本拷贝到 nmap script 目录
cp vulscan /usr/share/nmap/scripts/ -r -
执行目标机扫描
本例,以局域网内 Linux 机器扫描:
nmap --script vulscan --script-args vulscandb=cve.csv -sV 10.56.56.236
扫描到的结果和 CVE 漏洞编号将打印在终端:
网络攻击检测和防护
目前针对网络设备的攻击主要是拒绝服务攻击(DoS)。针对 DoS 的工具测试工具主要有:
- 网络测试仪
- 网络爱好者开发的免费工具
- 专业网络安全工作人员的专用工具
其中 网络测试仪是一种能够产生任何需要的测试数据包的网络硬件,能够根据需要定制测试项目,但是价格昂贵。
专业工具一般都是收费软件,网络上较难获取到。
攻击模拟
本文使用免费的工具 HYENAE,该工具最后更新时间是 2010-12-04
该工具可以自定义模拟执行所有的 DoS 攻击:
Features
• ARP-Request flooding
• ARP-Cache poisoning
• PPPoE session initiation flooding
• Blind PPPoE session termination
• ICMP-Echo flooding
• ICMP-Smurf attack
• ICMP based TCP-Connection reset
• TCP-SYN flooding
• TCP-Land attack
• Blind TCP-Connection reset
• UDP flooding
• DNS-Query flooding
• DHCP-Discover flooding
• DHCP starvation attack
• DHCP-Release forcing
• Cisco HSRP active router hijacking
• Pattern based packet address configuration
• Intelligent address and address protocol detection
• Smart wildcard-based randomization
• Daemon for setting up remote attack networks
• HyenaeFE QT-Frontend support
经测试,在 Windows 10 系统正常运行,并成功发出自定义攻击数据包。
以 ARP 请求风暴为例:
WireShark 显示系统发出大量 ARP 请求数据包请求地址 10.56.56.236:
攻击防护
Dos 攻击主要靠流量取胜,流量决定攻击和防护的输赢。所以为了保证正常业务的运行,保证正常通信流量是唯一途径。针对攻击的类型,可以采用一些基本的防护措施:
- 针对 TCP SYNC 攻击
优化sysctl内核 tcp 参数,并提高 tcp 连接能力 - 主动丢弃异常数据包
- 使用脚本和专用 DoS 防火墙阻击工具数据包
其中针对 CentOS 的防火墙配置防 DoS 功能:
CentOS7 默认是用 Firewall 配置防火墙,但是 Firewall 功能有限,建议使用 DoS Deflate 防御 DoS 攻击:
停用 Firewall:
systemctl stop firewalld
安装命令:
wget http://www.inetbase.com/scripts/ddos/install.sh
chmod 700 install.sh
./install.sh
卸载命令:
wget http://www.inetbase.com/scripts/ddos/uninstall.ddos
chmod 700 uninstall.ddos
./uninstall.ddos
2、配置DDoS deflate
下面是DDoS deflate的默认配置位于/usr/local/ddos/ddos.conf ,内容如下:
Paths of the script and other files
PROGDIR="/usr/local/ddos"
PROG="/usr/local/ddos/ddos.sh"
IGNORE_IP_LIST="/usr/local/ddos/ignore.ip.list" //IP地址白名单
CRON="/etc/cron.d/ddos.cron" //定时执行程序
APF="/etc/apf/apf"
IPT="/sbin/iptables"
frequency in minutes for running the script
Caution: Every time this setting is changed, run the script with --cron
option so that the new frequency takes effect
FREQ=1 //检查时间间隔,默认1分钟
How many connections define a bad IP? Indicate that below.
NO_OF_CONNECTIONS=150 //最大连接数,超过这个数IP就会被屏蔽,一般默认即可
APF_BAN=1 (Make sure your APF version is atleast 0.96)
APF_BAN=0 (Uses iptables for banning ips instead of APF)
APF_BAN=1 //使用APF还是iptables。推荐使用iptables,将APF_BAN的值改为0即可。
KILL=0 (Bad IPs are\'nt banned, good for interactive execution of script)
KILL=1 (Recommended setting)
KILL=1 //是否屏蔽IP,默认即可
An email is sent to the following address when an IP is banned.
Blank would suppress sending of mails
EMAIL_TO="root" //当IP被屏蔽时给指定邮箱发送邮件,推荐使用,换成自己的邮箱即可
Number of seconds the banned ip should remain in blacklist.
BAN_PERIOD=600 //禁用IP时间,默认600秒,可根据情况调整
用户可根据给默认配置文件加上的注释提示内容,修改配置文件。
查看/usr/local/ddos/ddos.sh文件的第117行
netstat -ntu | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -nr > $BAD_IP_LIST
修改为以下代码即可!
netstat -ntu | awk ‘{print $5}’ | cut -d: -f1 | sed -n ‘/[0-9]/p’ | sort | uniq -c | sort -nr > $BAD_IP_LIST
【转载】渗透测试工具Nmap的攻防战
JackxinXu2100 2014-03-02 10:51:04 2772 收藏 2
展开
Nmap的下载地址:http://nmap.org/download.html
Nmap的基本功能介绍
Nmap是一款网络扫描和主机检测的非常有用的工具。 Nmap是不局限于仅仅收集信息和枚举,同时可以用来作为一个漏洞探测器或安全扫描器。它可以适用于winodws,linux,mac等操作系统。Nmap是一款非常强大的实用工具,可用于:
检测活在网络上的主机(主机发现)
检测主机上开放的端口(端口发现或枚举)
检测到相应的端口(服务发现)的软件和版本
检测操作系统,硬件地址,以及软件版本
检测脆弱性的漏洞(Nmap的脚本)
Nmap是一个非常普遍的工具,它有命令行界面和图形用户界面。本人包括以下方面的内容:
介绍Nmap
扫描中的重要参数
操作系统检测
Nmap使用教程
Nmap使用不同的技术来执行扫描,包括:TCP的connect()扫描,TCP反向的ident扫描,FTP反弹扫描等。所有这些扫描的类型有自己的优点和缺点,我们接下来将讨论这些问题。
Nmap的使用取决于目标主机,因为有一个简单的(基本)扫描和预先扫描之间的差异。我们需要使用一些先进的技术来绕过防火墙和入侵检测/防御系统,以获得正确的结果。下面是一些基本的命令和它们的用法的例子:
扫描单一的一个主机,命令如下:
#nmap nxadmin.com
#nmap 192.168.1.2
扫描整个子网,命令如下:
#nmap 192.168.1.1/24
扫描多个目标,命令如下:
#nmap 192.168.1.2 192.168.1.5
扫描一个范围内的目标,如下:
#nmap 192.168.1.1-100 (扫描IP地址为192.168.1.1-192.168.1.100内的所有主机)
如果你有一个ip地址列表,将这个保存为一个txt文件,和namp在同一目录下,扫描这个txt内的所有主机,命令如下:
#nmap -iL target.txt
如果你想看到你扫描的所有主机的列表,用以下命令:
#nmap -sL 192.168.1.1/24
扫描除过某一个ip外的所有子网主机,命令:
#nmap 192.168.1.1/24 -exclude 192.168.1.1
扫描除过某一个文件中的ip外的子网主机命令
#nmap 192.168.1.1/24 -exclude file xxx.txt (xxx.txt中的文件将会从扫描的主机中排除)
扫描特定主机上的80,21,23端口,命令如下
#nmap -p80,21,23 192.168.1.123 192.168.1.1
从上面我们已经了解了Nmap的基础知识,下面我们深入的探讨一下Nmap的扫描技术.
Tcp SYN Scan (sS)
这是一个基本的扫描方式,它被称为半开放扫描,因为这种技术使得Nmap不需要通过完整的握手,就能获得远程主机的信息。Nmap发送SYN包到远程主机,但是它不会产生任何会话.因此不会在目标主机上产生任何日志记录,因为没有形成会话。这个就是SYN扫描的优势.
如果Nmap命令中没有指出扫描类型,默认的就是Tcp SYN.但是它需要root/administrator权限.
#nmap -sS 192.168.1.1
Tcp connect() scan(sT)
如果不选择SYN扫描,TCP connect()扫描就是默认的扫描模式.不同于Tcp SYN扫描,Tcp connect()扫描需要完成三次握手,并且要求调用系统的connect().Tcp connect()扫描技术只适用于找出TCP和UDP端口.
#nmap -sT 192.168.1.1
Udp scan(sU)
顾名思义,这种扫描技术用来寻找目标主机打开的UDP端口.它不需要发送任何的SYN包,因为这种技术是针对UDP端口的。UDP扫描发送UDP数 据包到目标主机,并等待响应,如果返回ICMP不可达的错误消息,说明端口是关闭的,如果得到正确的适当的回应,说明端口是开放的.
#nmap -sU 192.168.1.1
FIN scan (sF)
有时候Tcp SYN扫描不是最佳的扫描模式,因为有防火墙的存在.目标主机有时候可能有IDS和IPS系统的存在,防火墙会阻止掉SYN数据包。发送一个设置了FIN标志的数据包并不需要完成TCP的握手.
root@bt:~# nmap -sF 192.168.1.8
Starting Nmap 5.51 at 2012-07-08 19:21 PKT
Nmap scan report for 192.168.1.8
Host is up (0.000026s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
111/tcp open|filtered rpcbind
FIN扫描也不会在目标主机上创建日志(FIN扫描的优势之一).个类型的扫描都是具有差异性的,FIN扫描发送的包只包含FIN标识,NULL扫描不发送数据包上的任何字节,XMAS扫描发送FIN、PSH和URG标识的数据包.
PING Scan (sP)
PING扫描不同于其它的扫描方式,因为它只用于找出主机是否是存在在网络中的.它不是用来发现是否开放端口的.PING扫描需要ROOT权限,如果用户没有ROOT权限,PING扫描将会使用connect()调用.
#nmap -sP 192.168.1.1
版本检测(sV)
版本检测是用来扫描目标主机和端口上运行的软件的版本.它不同于其它的扫描技术,它不是用来扫描目标主机上开放的端口,不过它需要从开放的端口获取信息来判断软件的版本.使用版本检测扫描之前需要先用TCP SYN扫描开放了哪些端口.
#nmap -sV 192.168.1.1
Idle scan (sL)
Idle scan是一种先进的扫描技术,它不是用你真实的主机Ip发送数据包,而是使用另外一个目标网络的主机发送数据包.
#nmap -sI 192.168.1.6 192.168.1.1
Idle scan是一种理想的匿名扫描技术,通过目标网络中的192.168.1.6向主机192.168.1.1发送数据,来获取192.168.1.1开放的端口
有需要其它的扫描技术,如 FTP bounce(FTP反弹), fragmentation scan(碎片扫描), IP protocol scan(IP协议扫描),以上讨论的是几种最主要的扫描方式.
Nmap的OS检测(O)
Nmap最重要的特点之一是能够远程检测操作系统和软件,Nmap的OS检测技术在渗透测试中用来了解远程主机的操作系统和软件是非常有用的,通过 获取的信息你可以知道已知的漏洞。Nmap有一个名为的nmap-OS-DB数据库,该数据库包含超过2600操作系统的信息。 Nmap把TCP和UDP数据包发送到目标机器上,然后检查结果和数据库对照。
Initiating SYN Stealth Scan at 10:21
Scanning localhost (127.0.0.1) [1000 ports]
Discovered open port 111/tcp on 127.0.0.1
Completed SYN Stealth Scan at 10:21, 0.08s elapsed (1000 total ports)
Initiating OS detection (try #1) against localhost (127.0.0.1)
Retrying OS detection (try #2) against localhost (127.0.0.1)
上面的例子清楚地表明,Nmap的首次发现开放的端口,然后发送数据包发现远程操作系统。操作系统检测参数是O(大写O)
Nmap的操作系统指纹识别技术:
设备类型(路由器,工作组等)
运行(运行的操作系统)
操作系统的详细信息(操作系统的名称和版本)
网络距离(目标和攻击者之间的距离跳)
如果远程主机有防火墙,IDS和IPS系统,你可以使用-PN命令来确保不ping远程主机,因为有时候防火墙会组织掉ping请求.-PN命令告诉Nmap不用ping远程主机。
# nmap -O -PN 192.168.1.1/24
以上命令告诉发信主机远程主机是存活在网络上的,所以没有必要发送ping请求,使用-PN参数可以绕过PING命令,但是不影响主机的系统的发现.
Nmap的操作系统检测的基础是有开放和关闭的端口,如果OS scan无法检测到至少一个开放或者关闭的端口,会返回以下错误:
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
OS Scan的结果是不可靠的,因为没有发现至少一个开放或者关闭的端口.
这种情况是非常不理想的,应该是远程主机做了针对操作系统检测的防范。如果Nmap不能检测到远程操作系统类型,那么就没有必要使用-osscan_limit检测。
想好通过Nmap准确的检测到远程操作系统是比较困难的,需要使用到Nmap的猜测功能选项, –osscan-guess 猜测认为最接近目标的匹配操作系统类型。
# nmap -O –osscan-guess 192.168.1.1
总结
Nmap是一个非常强大的工具,它具有覆盖渗透测试的第一方面的能力,其中包括信息的收集和统计。本文从初级到高级的讲解了Nmap入侵扫描工具的使用.希望对大家有所帮助.
阻止Nmap的黑手
一般黑客都会用nmap扫描我们的网站,这是我们所不希望看到的,一下我提供几个过滤机制,nmap是无法扫描到你的:
在Linux下面预防Nmap的黑手:
1 #iptables -F
2 #iptables -A INPUT -p tcp –tcp-flags ALL FIN,URG,PSH -j Drop
3 #iptables -A INPUT -p tcp –tcp-flags SYN,RST SYN,RST -j Drop
4 #iptables -A INPUT -p tcp –tcp-flags SYN,FIN SYN,FIN -j Drop
5 #iptables -A INPUT -p tcp –tcp-flags SyN SYN –dport 80 -j Drop
有了这样的设置,nmap就扫不到你的tcp端口和操作系统的版本号了,而你的80还可以提供好的http服务。
Nmap更详细介绍请参见如下链接: http://blog.csdn.net/aspirationflow/article/details/7797708
————————————————
版权声明:本文为CSDN博主「JackxinXu2100」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jackxinxu2100/article/details/20283279