声明
仅供学习,禁止用于违法行为。请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与文章作者和本公众号无关。
前言
我们从事计算机专业的师傅们在日常工作的时候,很多时候都需要我们看端口开放的情况,最近学习了一下下易语言,就编写端口扫描器练练手。
端口扫描原理
端口扫描,顾名思义,就是逐个对一段端口或指定的端口进行扫描。通过扫描结果可以知道一台计算机上都提供了哪些服务。其原理是当一个主机向远端一个服务器的某一个端口提出建立一个连接的请求,如果对方有此项服务,就会应答,如果对方未安装此项服务时,即使你向相应的端口发出请求,对方仍无应答。
常见端口号
HTTP协议代理服务器常用端口号:80/8080/3128/8081/9080
SOCKS代理协议服务器常用端口号:1080
FTP(文件传输)协议代理服务器常用端口号:21
Telnet(远程登录)协议代理服务器常用端口:23
HTTP服务器,默认的端口号为80/tcp(木马Executor开放此端口)
HTTPS(securely transferring web pages)服务器,默认的端口号为443/tcp 443/udp
Telnet(不安全的文本传送),默认端口号为23/tcp(木马Tiny Telnet Server所开放的端口)
FTP,默认的端口号为21/tcp(木马Doly Trojan、Fore、Invisible FTP、WebEx、WinCrash和Blade Runner所开放的端口)
TFTP(Trivial File Transfer Protocol),默认的端口号为69/udp
SSH(安全登录)、SCP(文件传输)、端口重定向,默认的端口号为22/tcp;
SMTP Simple Mail Transfer Protocol (E-mail),默认的端口号为25/tcp(木马Antigen、Email Password Sender、Haebu Coceda、Shtrilitz Stealth、WinPC、WinSpy都开放这个端口)
POP3 Post Office Protocol (E-mail) ,默认的端口号为110/tcp
WebLogic,默认的端口号为7001
Webshpere应用程序,默认的端口号为9080
webshpere管理工具,默认的端口号为9090
JBOSS,默认的端口号为8080
TOMCAT,默认的端口号为8080
WIN2003远程登陆,默认的端口号为3389
Symantec AV/Filter for MSE,默认端口号为 8081
Oracle 数据库,默认的端口号为1521
ORACLE EMCTL,默认的端口号为1158
Oracle XDB(XML 数据库),默认的端口号为8080
Oracle XDB FTP服务,默认的端口号为2100
MS SQL*SERVER数据库server,默认的端口号为1433/tcp 1433/udp
MS SQL*SERVER数据库monitor,默认的端口号为1434/tcp 1434/udp
QQ,默认的端口号为1080/udp
TCP三次握手
动态过程
所谓的三次握手即TCP连接的建立。这个连接必须是一方主动打开,另一方被动打开的。以下为客户端主动发起连接的图解:
握手之前主动打开连接的客户端结束CLOSED阶段,被动打开的服务器端也结束CLOSED阶段,并进入LISTEN阶段。随后开始“三次握手”:
(1)首先客户端向服务器端发送一段TCP报文,其中:
-
标记位为SYN,表示“请求建立新连接”;序号为Seq=X(X一般为1);
-
随后客户端进入SYN-SENT阶段。
(2)服务器端接收到来自客户端的TCP报文之后,结束LISTEN阶段。并返回一段TCP报文,其中:
-
标志位为SYN和ACK,表示“确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接”(即告诉客户端,服务器收到了你的数据);序号为Seq=y;
-
确认号为Ack=x+1,表示收到客户端的序号Seq并将其值加1作为自己确认号Ack的值;随后服务器端进入SYN-RCVD阶段。
(3)客户端接收到来自服务器端的确认收到数据的TCP报文之后,明确了从客户端到服务器的数据传输是正常的,结束SYN-SENT阶段。并返回最后一段TCP报文。其中:
-
标志位为ACK,表示“确认收到服务器端同意连接的信号”(即告诉服务器,我知道你收到我发的数据了);序号为Seq=x+1,表示收到服务器端的确认号Ack,并将其值作为自己的序号值;确认号为Ack=y+1,表示收到服务器端序号Seq,并将其值加1作为自己的确认号Ack的值;
-
随后客户端进入ESTABLISHED阶段。
服务器收到来自客户端的“确认收到服务器数据”的TCP报文之后,明确了从服务器到客户端的数据传输是正常的。结束SYN-SENT阶段,进入ESTABLISHED阶段。
在客户端与服务器端传输的TCP报文中,双方的确认号Ack和序号Seq的值,都是在彼此Ack和Seq值的基础上进行计算的,这样做保证了TCP报文传输的连贯性。一旦出现某一方发出的TCP报文丢失,便无法继续"握手",以此确保了"三次握手"的顺利完成。
此后客户端和服务器端进行正常的数据传输。这就是“三次握手”的过程。
为什么要进行三次握手
为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器),在传输的过程中,比如客户端发起了SYN=1创建连接的请求(第一次握手)。
如果服务器端就直接创建了这个连接并返回包含SYN、ACK和Seq等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直没有接收到服务器返回的数据包。
客户端可能设置了一个超时时间,时间到了就关闭了连接创建的请求。再重新发出创建连接的请求,而服务器端是不知道的,如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话,服务器端是不知道客户端有没有接收到服务器端返回的信息的。
也可以这样理解:
“第三次握手”是客户端向服务器端发送数据,这个数据就是要告诉服务器,客户端有没有收到服务器“第二次握手”时传过去的数据。若发送的这个数据是“收到了”的信息,接收后服务器就正常建立TCP连接,否则建立TCP连接失败,服务器关闭连接端口。由此减少服务器开销和接收到失效请求发生的错误。
TCP四次挥手
所谓的四次挥手即TCP连接的释放(解除)。连接的释放必须是一方主动释放,另一方被动释放。以下为客户端主动发起释放连接的图解:
挥手之前主动释放连接的客户端结束ESTABLISHED阶段。随后开始“四次挥手”:
(1)首先客户端想要释放连接,向服务器端发送一段TCP报文,其中:
-
标记位为FIN,表示“请求释放连接“;序号为Seq=U;
-
随后客户端进入FIN-WAIT-1阶段,即半关闭阶段。并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。
注意:这里不发送的是正常连接时传输的数据(非确认报文),而不是一切数据,所以客户端仍然能发送ACK确认报文。
(2)服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段TCP报文,其中:
-
标记位为ACK,表示“接收到客户端发送的释放连接的请求”;序号为Seq=V;
-
确认号为Ack=U+1,表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值;
-
随后服务器端开始准备释放服务器端到客户端方向上的连接。
客户端收到从服务器端发出的TCP报文之后,确认了服务器收到了客户端发出的释放连接请求,随后客户端结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段
前"两次挥手"既让服务器端知道了客户端想要释放连接,也让客户端知道了服务器端了解了自己想要释放连接的请求。于是,可以确认关闭客户端到服务器端方向上的连接了
(3)服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文,其中:
-
标记位为FIN,ACK,表示“已经准备好释放连接了”。注意:这里的ACK并不是确认收到服务器端报文的确认报文。序号为Seq=W;
-
确认号为Ack=U+1;表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值。
随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。
(4)客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务器端发送一段报文,其中:
-
标记位为ACK,表示“接收到服务器准备好释放连接的信号”。序号为Seq=U+1;表示是在收到了服务器端报文的基础上,将其确认号Ack值作为本段报文序号的值。
-
确认号为Ack=W+1;表示是在收到了服务器端报文的基础上,将其序号Seq值作为本段报文确认号的值。
随后客户端开始在TIME-WAIT阶段等待2MSL
服务器端收到从客户端发出的TCP报文之后结束LAST-ACK阶段,进入CLOSED阶段。由此正式确认关闭服务器端到客户端方向上的连接。
客户端等待完2MSL之后,结束TIME-WAIT阶段,进入CLOSED阶段,由此完成“四次挥手”。
后“两次挥手”既让客户端知道了服务器端准备好释放连接了,也让服务器端知道了客户端了解了自己准备好释放连接了。于是,可以确认关闭服务器端到客户端方向上的连接了,由此完成“四次挥手”。
为什么客户端在TIME-WAIT阶段要等2MSL
为的是确认服务器端是否收到客户端发出的ACK确认报文
服务器端在1MSL内没有收到客户端发出的ACK确认报文,就会再次向客户端发出FIN报文;
为什么“握手”是三次,“挥手”却要四次?
TCP建立连接时之所以只需要"三次握手",是因为在第二次"握手"过程中,服务器端发送给客户端的TCP报文是以SYN与ACK作为标志位的。SYN是请求连接标志,表示服务器端同意建立连接;ACK是确认报文,表示告诉客户端,服务器端收到了它的请求报文。
即SYN建立连接报文与ACK确认接收报文是在同一次"握手"当中传输的,所以"三次握手"不多也不少,正好让双方明确彼此信息互通。
TCP释放连接时之所以需要“四次挥手”,是因为FIN释放连接报文与ACK确认接收报文是分别由第二次和第三次"握手"传输的。
为何建立连接时一起传输,释放连接时却要分开传输?
建立连接时,被动方服务器端结束CLOSED阶段进入“握手”阶段并不需要任何准备,可以直接返回SYN和ACK报文,开始建立连接。释放连接时,被动方服务器,突然收到主动方客户端释放连接的请求时并不能立即释放连接,因为还有必要的数据需要处理,所以服务器先返回ACK确认收到报文,经过CLOSE-WAIT阶段准备好释放连接之后,才能返回FIN释放连接报文。
扫描分类
TCP connect() 扫描
这是最基本的TCP扫描。操作系统提供的connect()系统调用,用来与每一个目标计算机的端口进行连接。如果端口处于侦听状态,那么connect()就能成功。否则,这个端口是不能用的,即没有提供服务。这个技术的一个最大的优点是,你不需要任何权限。系统中的任何用户都有权利使用这个调用。另一个好处就是速度。如果对每个目标端口以线性的方式,使用单独的connect()调用,那么将会花费相当长的时间,你可以通过同时打开多个套接字,从而加速扫描。使用非阻塞I/O允许你设置一个低的时间用尽周期,同时观察多个套接字。但这种方法的缺点是很容易被发觉,并且被过滤掉。目标计算机的logs文件会显示一连串的连接和连接是出错的服务消息,并且能很快的使它关闭。
TCP SYN扫描
这种技术通常认为是“半开放”扫描,这是因为扫描程序不必要打开一个完全的TCP连接。扫描程序发送的是一个SYN数据包,好象准备打开一个实际的连接并等待反应一样(参考TCP的三次握手建立一个TCP连接的过程)。一个SYN|ACK的返回信息表示端口处于侦听状态。一个RST返回,表示端口没有处于侦听态。如果收到一个SYN|ACK,则扫描程序必须再发送一个RST信号,来关闭这个连接过程。这种扫描技术的优点在于一般不会在目标计算机上留下记录。但这种方法的一个缺点是,必须要有root权限才能建立自己的SYN数据包。
TCP FIN 扫描
有的时候有可能SYN扫描都不够秘密。一些防火墙和包过滤器会对一些指定的端口进行监视,有的程序能检测到这些扫描。相反,FIN数据包可以通过。这种扫描方法的思想是关闭的端口会用适当的RST来回复FIN数据包。另一方面,打开的端口会忽略对FIN数据包的回复。这种方法和系统的实现有一定的关系。有的系统不管端口是否打开,都回复RST,这样,这种扫描方法就不适用了。并且这种方法在区分Unix和NT时,是十分有用的。
IP段扫描
这种不能算是新方法,只是其它技术的变化。它并不是直接发送TCP探测数据包,是将数据包分成两个较小的IP段。这样就将一个TCP头分成好几个数据包,从而过滤器就很难探测到。但必须小心。一些程序在处理这些小数据包时会有些麻烦。
TCP 反向 ident扫描
ident 协议允许(rfc1413)看到通过TCP连接的任何进程的拥有者的用户名,即使这个连接不是由这个进程开始的。因此你能,举个例子,连接到http端口,然后用identd来发现服务器是否正在以root权限运行。这种方法只能在和目标端口建立了一个完整的TCP连接后才能看到。
FTP 返回攻击
FTP协议的一个有趣的特点是它支持代理(proxy)FTP连接。即入侵者可以从自己的计算机和目标主机的FTP server-PI(协议解释器)连接,建立一个控制通信连接。然后,请求这个server-PI激活一个有效的server-DTP(数据传输进程)来给Internet上任何地方发送文件。对于一个User-DTP,这是个推测,尽管RFC明确地定义请求一个服务器发送文件到另一个服务器是可以的。给许多服务器造成打击,用尽磁盘,企图越过防火墙”。
我们利用这个的目的是从一个代理的FTP服务器来扫描TCP端口。这样,你能在一个防火墙后面连接到一个FTP服务器,然后扫描端口(这些原来有可能被阻塞)。如果FTP服务器允许从一个目录读写数据,你就能发送任意的数据到发现的打开的端口。
易语言版的端口扫描器
核心代码如下:(以下代码仅供学习交流使用)
.版本 2
.支持库 iext2
.支持库 EThread
.支持库 eAPI
.程序集 窗口程序集1
.子程序 __启动窗口_创建完毕
.子程序 _按钮1_被单击
.局部变量 末地址, 文本型
.局部变量 始地址, 文本型
.局部变量 循环地址, 整数型, , , 用IP地址作循环用
.局部变量 循环端口, 整数型, , , 用作端口循环用
.局部变量 I, 整数型
已扫描数量 = 0
进程数 = 0
按下停止 = 假
.如果真 (按钮1.标题 = “停止”)
按下停止 = 真
返回 ()
.如果真结束
.如果真 (IP开始.地址 = “”)
信息框 (“你必须填写开始IP地址”, 0, )
返回 ()
.如果真结束
.如果 (IP结束.地址 = “”)
末地址 = IP开始.地址
末地址 = 取文本左边 (末地址, 倒找文本 (末地址, “.”, , 假))
末地址 = 末地址 + “254”
IP结束.地址 = 末地址
.否则
.如果结束
.如果真 (IP结束.地址 = “”)
信息框 (“IP格式不对”, 0, )
.如果真结束
始地址 = IP开始.地址
末地址 = IP结束.地址
.如果 (比较IP大小 (始地址, 末地址) = 假)
信息框 (“开始地址不能大于结束地址”, 0, )
返回 ()
.否则
.如果结束
得到IP范围 (始地址, 末地址) ' 调用过程给IP地址赋值
.如果真 (得到端口号 () = 假)
信息框 (“你的端口设置有误,请检查”, 0, )
编辑框1.起始选择位置 = 1
编辑框1.被选择字符数 = 取文本长度 (编辑框1.内容)
.如果真结束
扫描端口 ()
.子程序 得到端口号, 逻辑型, , 将端口号存入数组,输入有错就返回假
.局部变量 临时文本, 文本型, , "0"
.局部变量 开始端口, 文本型
.局部变量 结束端口, 文本型
.局部变量 临时数值, 整数型
.局部变量 I, 整数型
.局部变量 临时端口, 文本型
重定义数组 (端口号, 假, 0)
.如果真 (删首尾空 (编辑框1.内容) = “”)
信息框 (“没有填端口号”, 0, )
返回 (假)
.如果真结束
.如果真 (寻找文本 (编辑框1.内容, “-”, , 假) > 0)
开始端口 = 取文本左边 (编辑框1.内容, 寻找文本 (编辑框1.内容, “-”, , 假) - 1)
结束端口 = 取文本右边 (编辑框1.内容, 取文本长度 (编辑框1.内容) - 寻找文本 (编辑框1.内容, “-”, , 假))
.如果真 (到数值 (开始端口) > 到数值 (结束端口))
返回 (假)
.如果真结束
临时数值 = 到数值 (结束端口) - 到数值 (开始端口)
临时端口 = 开始端口
.计次循环首 (临时数值, I)
加入成员 (端口号, 临时端口)
临时端口 = 到文本 (到数值 (临时端口) + 1)
.计次循环尾 ()
加入成员 (端口号, 结束端口)
返回 (真)
.如果真结束
端口号 = 分割文本 (编辑框1.内容, “,”, )
返回 (真)
.子程序 扫描端口, , 公开, 开始扫描
.局部变量 I, 整数型
.局部变量 J, 整数型
进度条1.最大位置 = 取数组成员数 (IP地址) × 取数组成员数 (端口号)
进度条1.最小位置 = 1
进度条1.位置 = 1
按钮1.标题 = “停止”
列表框1.清空 ()
.计次循环首 (取数组成员数 (IP地址), I)
.如果真 (按下停止 = 真)
编辑框1.禁止 = 假
按钮1.标题 = “开始(&S)”
返回 ()
.如果真结束
启动线程 (&扫描, I) ' 启动进程进行扫描
.计次循环尾 ()
.子程序 扫描
.参数 IP, 整数型
.局部变量 J, 整数型
.计次循环首 (取数组成员数 (端口号), J)
扫描子程序 (到整数 (端口号 [J]), IP地址 [IP])
.如果真 (按下停止 = 真)
编辑框1.禁止 = 假
按钮1.标题 = “开始(&S)”
返回 ()
.如果真结束
.计次循环尾 ()
.子程序 扫描子程序
.参数 端口, 整数型, , 要检测的端口
.参数 IP, 文本型, , 要检测的IP地址
信息.标题 = “当前IP地址:” + IP + “ 检测端口:” + 到文本 (端口)
.如果真 (端口检测 (端口, IP))
列表框1.加入项目 (IP + “:” + 格式化文本 (“%-5ld”, 端口) + “开放”, )
.如果真结束
' 输出调试文本 (当前IP + “:” + 到文本 (端口) + “ 已扫描了:” + 到文本 (已扫描数量))
进度条1.位置 = 进度条1.位置 + 1
.如果真 (按下停止 = 真)
编辑框1.禁止 = 假
按钮1.标题 = “开始(&S)”
返回 ()
.如果真结束
.如果真 (进度条1.位置 ≥ 进度条1.最大位置)
进度条1.位置 = 0
编辑框1.禁止 = 假
按钮1.标题 = “开始(&S)”
.如果真结束
进程数 = 进程数 - 1
退出许可区 (许可证号)
.子程序 得到IP范围
.参数 开始地址, 文本型
.参数 结束地址, 文本型
.局部变量 临时变量1, 文本型
.局部变量 临时变量2, 文本型
.局部变量 尾数, 文本型, , , 保存循环时的IP地址最尾那个数
临时变量1 = 开始地址
重定义数组 (IP地址, 假, 0)
IP数量 = 0
.判断循环首 (比较IP大小 (临时变量1, 结束地址))
加入成员 (IP地址, 临时变量1)
临时变量1 = IP加1 (临时变量1)
IP数量 = IP数量 + 1
' 列表框1.加入项目 (IP地址 [IP数量], )
.判断循环尾 ()
.子程序 IP加1, 文本型, , 将一个IP 地址的值加1
.参数 开始地址, 文本型
.局部变量 J, 整数型
.局部变量 分隔点位置1, 整数型, , "3"
.局部变量 临时变量1, 文本型, , "4"
.局部变量 临时位置, 整数型
.局部变量 临时变量, 文本型
J = 1
.计次循环首 (取文本长度 (开始地址), 临时位置)
.如果真 (取文本中间 (开始地址, 临时位置, 1) = “.”)
分隔点位置1 [J] = 临时位置
.如果真 (J = 1)
临时变量1 [J] = 取文本中间 (开始地址, 1, 分隔点位置1 [J] - 1)
.如果真结束
.如果真 (J = 2)
临时变量1 [J] = 取文本中间 (开始地址, 分隔点位置1 [J - 1] + 1, 分隔点位置1 [J] - 分隔点位置1 [J - 1] - 1)
.如果真结束
.如果真 (J = 3)
临时变量1 [J] = 取文本中间 (开始地址, 分隔点位置1 [J - 1] + 1, 分隔点位置1 [J] - 分隔点位置1 [J - 1] - 1)
临时变量1 [J + 1] = 取文本右边 (开始地址, 取文本长度 (开始地址) - 分隔点位置1 [J])
跳出循环 ()
.如果真结束
J = J + 1
.如果真结束
.计次循环尾 ()
J = 4
.判断循环首 (J > 0)
.如果真 (到数值 (临时变量1 [J]) ≤ 254)
.如果真 (J = 1)
临时变量 = 到文本 (到数值 (临时变量1 [J]) + 1) + “.1.1.1”
跳出循环 ()
.如果真结束
.如果真 (J = 4)
临时变量 = 临时变量1 [1] + “.” + 临时变量1 [2] + “.” + 临时变量1 [3] + “.” + 到文本 (到数值 (临时变量1 [J]) + 1)
跳出循环 ()
.如果真结束
.如果真 (J = 2)
临时变量 = 临时变量1 [1] + “.” + 到文本 (到数值 (临时变量1 [J]) + 1) + “.1.1”
跳出循环 ()
.如果真结束
.如果真 (J = 3)
临时变量 = 临时变量1 [1] + “.” + 临时变量1 [2] + “.” + 到文本 (到数值 (临时变量1 [J]) + 1) + “.1”
跳出循环 ()
.如果真结束
.如果真结束
J = J - 1
.判断循环尾 ()
' 结果:
返回 (临时变量)
.子程序 比较IP大小, 逻辑型, , 如果开始IP大于结束IP则返回真,否则返回假
.参数 开始地址, 文本型
.参数 结束地址, 文本型
.局部变量 临时位置, 整数型
.局部变量 临时变量1, 文本型, , "4"
.局部变量 临时变量2, 文本型, , "4"
.局部变量 J, 整数型
.局部变量 分隔点位置1, 整数型, , "3"
.局部变量 分隔点位置2, 整数型, , "3"
.如果真 (开始地址 = 结束地址)
返回 (真)
.如果真结束
J = 1
.计次循环首 (取文本长度 (开始地址), 临时位置)
.如果真 (取文本中间 (开始地址, 临时位置, 1) = “.”)
分隔点位置1 [J] = 临时位置
.如果真 (J = 1)
临时变量1 [J] = 取文本中间 (开始地址, 1, 分隔点位置1 [J] - 1)
.如果真结束
.如果真 (J = 2)
临时变量1 [J] = 取文本中间 (开始地址, 分隔点位置1 [J - 1] + 1, 分隔点位置1 [J] - 分隔点位置1 [J - 1] - 1)
.如果真结束
.如果真 (J = 3)
临时变量1 [J] = 取文本中间 (开始地址, 分隔点位置1 [J - 1] + 1, 分隔点位置1 [J] - 分隔点位置1 [J - 1] - 1)
临时变量1 [J + 1] = 取文本右边 (开始地址, 取文本长度 (开始地址) - 分隔点位置1 [J])
跳出循环 ()
.如果真结束
J = J + 1
.如果真结束
.计次循环尾 ()
J = 1
.计次循环首 (取文本长度 (结束地址), 临时位置)
.如果真 (取文本中间 (结束地址, 临时位置, 1) = “.”)
分隔点位置2 [J] = 临时位置
.如果真 (J = 1)
临时变量2 [J] = 取文本中间 (结束地址, 1, 分隔点位置2 [J] - 1)
.如果真结束
.如果真 (J = 2)
临时变量2 [J] = 取文本中间 (结束地址, 分隔点位置2 [J - 1] + 1, 分隔点位置2 [J] - 分隔点位置2 [J - 1] - 1)
.如果真结束
.如果真 (J = 3)
临时变量2 [J] = 取文本中间 (结束地址, 分隔点位置2 [J - 1] + 1, 分隔点位置2 [J] - 分隔点位置2 [J - 1] - 1)
临时变量2 [J + 1] = 取文本右边 (结束地址, 取文本长度 (结束地址) - 分隔点位置2 [J])
跳出循环 ()
.如果真结束
J = J + 1
.如果真结束
.计次循环尾 ()
.计次循环首 (4, J)
.如果真 (到数值 (临时变量1 [J]) < 到数值 (临时变量2 [J]))
' 输出调试文本 (开始地址 + “<” + 结束地址)
返回 (真)
.如果真结束
.计次循环尾 ()
返回 (假)
.子程序 _IP开始_字符输入, 整数型
.参数 字符代码, 整数型
输出调试文本 (IP开始.地址)
.子程序 _保存_被选择
.局部变量 文件号, 整数型
.局部变量 I, 整数型
.如果真 (列表框1.取项目数 () < 1)
信息框 (“没有扫描到可用内容”, 0, )
返回 ()
.如果真结束
通用对话框1.文件名 = IP开始.地址 + “-” + IP结束.地址
通用对话框1.过滤器 = “文本文件(*.txt)|*.txt|所有文件(*.*)|*.*”
通用对话框1.默认文件后缀 = “.txt”
.如果真 (通用对话框1.打开 ())
.如果真 (通用对话框1.文件名 ≠ “”)
文件号 = 打开文件 (通用对话框1.文件名 + 通用对话框1.默认文件后缀, #重写, )
.如果真 (文件号 = 0)
返回 ()
.如果真结束
.计次循环首 (列表框1.取项目数 (), I)
写文本行 (文件号, 列表框1.取项目文本 (I))
.计次循环尾 ()
关闭文件 (文件号)
信息框 (“保存成功:” + 通用对话框1.文件名 + 通用对话框1.默认文件后缀, 0, )
.如果真结束
.如果真结束
.子程序 _退出_被选择
结束 ()
.子程序 _浏览器打开_被选择
.局部变量 HTTP地址, 文本型
HTTP地址 = “http://” + 到IP地址 ()
' 系统执行 (取窗口句柄 (), “Open”, HTTP地址, “ ”, “ ”, 1)
运行 (#引号 + “C:Program FilesInternet ExplorerIEXPLORE.EXE” + #引号 + “ ” + HTTP地址 + “:” + 列表端口 (), 假, )
.子程序 到IP地址, 文本型, , 返回列表框中的经过格式化后的IP 地址
返回 (取文本左边 (列表框1.取项目文本 (列表框1.现行选中项), 寻找文本 (列表框1.取项目文本 (列表框1.现行选中项), “:”, , 假) - 1))
.子程序 _FTP打开_被选择
运行 (#引号 + “C:Program FilesInternet ExplorerIEXPLORE.EXE” + #引号 + “ ” + “FTP://” + 到IP地址 () + “:” + 列表端口 (), 假, )
.子程序 _SQL打开_被选择
.如果真 (到IP地址 () = “”)
返回 ()
.如果真结束
.如果 (信息框 (“你想用图形方式吗?”, #确认取消钮, ) = #确认钮)
运行 (“isqlw -S ” + 到IP地址 (), 假, )
.否则
运行 (“cmd.exe /c isql -S ” + 到IP地址 () + “:” + 列表端口 (), 假, )
.如果结束
.子程序 _超级终端打开_被选择
.如果 (到IP地址 () = “”)
返回 ()
.否则
运行 (“mstsc -V ” + 到IP地址 () + “:” + 列表端口 (), 假, )
.如果结束
.子程序 列表端口, 文本型, , 列表项选中项的端口
' 临时文本=取文本中间(列表框1.取项目文本(,
返回 (删首尾空 (取文本中间 (列表框1.取项目文本 (列表框1.现行选中项), 寻找文本 (列表框1.取项目文本 (列表框1.现行选中项), “:”, , 假) + 1, 5)))
.子程序 _删除此项_被选择
.如果真 (列表框1.取项目数 () = 0)
返回 ()
.如果真结束
列表框1.删除项目 (列表框1.现行选中项)
.子程序 _关于端口扫描器_被选择
信息框 (“lmonlove7端口扫描器V1.0” + #换行符 + “程序设计:lemonlove7” + #换行符 + “ QQ:2103950795”, 0, , )
.子程序 _按钮2_被单击
编辑框1.内容 = “21,25,80,135,138,139,445,1433,3389,4889,5631”
.子程序 _列表框1_鼠标右键被按下, 逻辑型
.参数 横向位置, 整数型
.参数 纵向位置, 整数型
.参数 功能键状态, 整数型
.如果真 (列表框1.取项目数 () > 0)
弹出菜单 (IP操作, 取鼠标水平位置 () - 10, 取鼠标垂直位置 () - 15)
.如果真结束
.子程序 __启动窗口_可否被关闭, 逻辑型
.子程序 _按钮3_被单击
IP结束.地址 = IP开始.地址
置剪辑板文本 (IP开始.地址)
.子程序 _按钮4_被单击
载入 (域名转IP, , 真)
使用效果
如下图
结尾
扫描器并不是一个直接的攻击网络漏洞的程序,它仅仅能帮助我们发现目标机的某些内在的弱点。以后会持续输出文章,师傅们轻喷
防止链接失效,完整代码以及便携版
公众号后台回复【易语言端口扫描器】 就可以拿到下载链接啦
原文始发于微信公众号(鹏组安全):端口扫描详解以及端口扫描器(万字小结)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论