精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>电脑技术>>● 计算机安全>>◆破解技巧◆>>用Perl实现高级远程操作系统探测(转贴)

主题:用Perl实现高级远程操作系统探测(转贴)
发信人: coobear(ZEPHYR)
整理人: williamlong(2001-11-27 15:31:35), 站内信件
摘要  

这个文档从PERL编程的角度讨论操作系统探测的理论和实践。深入的讨论了  
远程操作系统探测的方法和概念,并用PERL实现。  



I. 介绍  

几年来,许多关于如何确定一个远程主机上运行的操作系统的方法和技术被  
公布出来。因为这些操作系统探测方法依赖于特定的因素,而这些因素并不  
总是存在的,所以这些操作系统的探测并不能保证100%的准确性。  



II. 基本的操作系统探测方法  

在涉及到高级的操作系统探测概念之前,我要简要介绍一下几种其他几种探  
测远程主机操作系统的方法。这些方法可能是很老,但它们可以使我们完成  
探测。  


   (1) 抓取telnet标识  

我想这很容易理解。比如说你连接到远程主机的上telnetd ,就可以看到登  
录的时候telnet打出了什么标识。 :)  

   (2) 抓取FTP标识  

和telnet的概念一样,只要针对ftpd而不是telnetd。  

   (3) http的head方法  

你可以通过检查web服务器(httpd)的方法来确定目标上运行的操作系统。比  
如Web是Microsoft-IIS,那么操作系统基本上就是WindowsNT/2k了。  


好了,我想已经基本上总结了现今的几种基本的操作系统的探测方法了。  



III. 远程操作系统探测和方式路径追踪概念  

有许多种技术用来探测一个主机的操作系统。这个文档讨论了以下四种:  

    * telnetd 指纹:  
   依靠telnet会话协商和选项。  

    * identd 指纹:  
     依靠identd/auth (113)是否打开。  
      
    * TCP 协议堆指纹:  
     依靠数据包中的Window,TTL,ToS和DF等参数。  
      
    * Queso 指纹:  
      依靠数据包中的Window,Seq,Ack_seq等参数。  
      依靠各种 IP/TCP 头标记。  

    * 被动指纹:  
      与TCP 协议堆指纹很接近。  
      依靠Window,TTL,ToS和DF等参数。  
      依靠网络流量。  
        
在以下的几节中我将深入的讨论上面提到的几种方法。  


一些术语:  

  * Window:TCP包中的窗口值,在未收到确认的情况下包中所能发送的最大  
    数据量。  
      
  * TTL:存活时间,一个包在被丢弃之前所能通过的最大节点数。  
    
  * ToS:服务的类型  

  * DF:不分片标记位  
      
  * MSS:最大的段大小  
    
    
这些因素可以被用来决定一个远程机器上运行了什么操作系统。依靠所有以  
上这些标记的组合,与一个标记数据库进行比对就可以猜测出操作系统。下  
面是一个入站连接的tcpdump片断:  

00:44:09.194998 eth0 < 203.9.66.52.www > my.ip.com.domain:  
S 2006693595:2006693595(0) ack 1 win 9112 <mss 536> (DF)  
(ttl 232, id 25119)  

我们忽略包中的一些其他信息,可以得到下面的东西:  

+-> 设备                    +-> 目的地址          +-> 不分片位  
|                             |                      |  
eth0 < 203.9.66.52.www > my.ip.com.domain: win 9112 (DF) (ttl 232)  
               |                                 |        |  
               +-> 源地址                      |        +-> 存活时间值  
                                                 |  
                                                 +-> TCP 窗口值  
    


Tcpdump 收集了包中的以下信息:  

+++++++++++++++++++++++++++++++++++++++++++++  
+ 目的地址   : my.ip.com                    +  
+ 目的端口   : domain (53)                  +  
+ 源地址     : 203.9.66.52 (www.sun.com.au) +  
+ 源端口     : www (80)                     +  
+ 窗口值     : 9112 (0x2398)                +  
+ 存活时间值 : 232                          +  
+ 服务类型值 : 0                            +  
+ 不分片位   : ON                           +  
+ 最大片断值 : 536                          +  
+++++++++++++++++++++++++++++++++++++++++++++  


从窗口值看可能是一个Solaris机器。存活时间值和服务类型值看也符合Solaris  
系统的特征。Solaris系统的默认存活时间值是255,在数据包沿它的路径到达  
目标地址的过程中,经过一定数量的节点,存活时间值可能会减到232。  


一点有关窗口值的小说明:  

一般来说,一个高的窗口值意味着是一个UNIX机器,而一个低的窗口值  
则很可能是一个windows机器,路由器,交换机等....  


下面的traceroute证实了我们存活时间值接近255的猜测:  


1  my.ip.com (127.0.0.1)  148.010 ms  138.609 ms  118.812 ms  
2  ??.kpnbelgium.be (194.119.225.185)  129.111 ms  138.566 ms  118.877 ms  
3  ??.kpnbelgium.be (194.119.228.161)  119.008 ms  119.300 ms  128.546 ms    
...  
...  
20  fddi0-0.chw1.sydney.telstra.net (139.130.36.227)  509.930 ms  519.879 ms    
509.941 ms  
21  sunmi1.lnk.telstra.net (139.130.37.142)  538.911 ms !X  509.879 ms !X    
549.903 ms !X  


节点21是我们进出internet的最后节点,那个 !X 信号意思是通讯出于管理  
目的被禁止的意思。  


我们的存活时间值 : 232  
节点数          :  21  
               + ---  
总存活时间值     : 253  

到达Solaris系统默认的存活时间值255,少了两个节点,所以我们知道了  
在节点21后还有两个节点。第一个为位于内网的网际互联设备,第二个就是  
目标主机(203.9.66.52),它有Solaris系统的存活时间值255。现在我们  
可以说(以相当的肯定程序上)说203.9.66.52是一个Solaris机器。  

远程主机的路径追踪对操作系统的指纹来说是一个很重要的问题。一个数据  
包所走过的路径可明显地决定操作系统指纹的匹配。所以,对这些存活时间  
上区别做些缓冲有很大用处。  



IV. 用Perl实现远程系统的探测的方法  



1. Telnetd 会话协商(TSN)和Telnet选项。  

这项技术涉及到远程系统上运行的telnetd,允许你去连接。当与telnetd的  
socket连接初始化完成后,我们执行sysread()操作来收集telnet会话的协商  
指纹信息。这个指纹看起来会是这样的:  


Linux <= 2.2.16 : �齘X�?�?�?


为了使用telnet守护进程来确定操作系统,我们需要知道在telnet.h中定义
的TELOPT(Telnet选项)的顺序。除了个别例处,每个操作系统有它自己的
顺序。

一旦我们得到我们的指纹信息,我们必须首先把它转换为十进制的数(1-
255),然后各自地把十进制值和它相应的TELOPT值想匹配。


Ascii 值 : �齘X�?�?�?
十进制值 : 255 253 24 255 253 32 255 253 35 255 253 39
Telopts 值 : IAC DO TELOPT_TTYPE IAC DO TELOPT_LINEMODE IAC DO TELOPT_XDISPLOC IAC DO

TELOPT_NEW_ENVIRON


虽然这些TELOPT值可以在 /usr/include/arpa/telnet.h 中找到,但我也把
它们放到了下面,这样如果你想做一些 telnetd指纹检查的时候可以用到:


/* telnet protocol definitions */

255 IAC /* interpret as command: */
254 DONT /* you are not to use option */
253 DO /* please, you use option */
252 WONT /* I won't use option */
251 WILL /* I will use option */
250 SB /* interpret as subnegotiation */
249 GA /* you may reverse the line */
248 EL /* erase the current line */
247 EC /* erase the current character */
246 AYT /* are you there */
245 AO /* abort output--but let prog finish */
244 IP /* interrupt process--permanently */
243 BREAK /* break */
242 DM /* data mark--for connect. cleaning */
241 NOP /* nop */
240 SE /* end sub negotiation */
239 EOR /* end of record (transparent mode) */
238 ABORT /* Abort process */
237 SUSP /* Suspend process */
236 xEOF /* End of file: EOF is already used... */


/* telnet options */

0 TELOPT_BINARY /* 8-bit data path */
1 TELOPT_ECHO /* echo */
2 TELOPT_RCP /* prepare to reconnect */
3 TELOPT_SGA /* suppress go ahead */
4 TELOPT_NAMS /* approximate message size */
5 TELOPT_STATUS /* give status */
6 TELOPT_TM /* timing mark */
7 TELOPT_RCTE /* remote controlled transmission and echo */
8 TELOPT_NAOL /* negotiate about output line width */
9 TELOPT_NAOP /* negotiate about output page size */
10 TELOPT_NAOCRD /* negotiate about CR disposition */
11 TELOPT_NAOHTS /* negotiate about horizontal tabstops */
12 TELOPT_NAOHTD /* negotiate about horizontal tab disposition */
13 TELOPT_NAOFFD /* negotiate about formfeed disposition */
14 TELOPT_NAOVTS /* negotiate about vertical tab stops */
15 TELOPT_NAOVTD /* negotiate about vertical tab disposition */
16 TELOPT_NAOLFD /* negotiate about output LF disposition */
17 TELOPT_XASCII /* extended ascii character set */
18 TELOPT_LOGOUT /* force logout */
19 TELOPT_BM /* byte macro */
20 TELOPT_DET /* data entry terminal */
21 TELOPT_SUPDUP /* supdup protocol */
22 TELOPT_SUPDUPOUTPUT /* supdup output */
23 TELOPT_SNDLOC /* send location */
24 TELOPT_TTYPE /* terminal type */
25 TELOPT_EOR /* end of record */
26 TELOPT_TUID /* TACACS user identification */
27 TELOPT_OUTMRK /* output marking */
28 TELOPT_TTYLOC /* terminal location number */
29 TELOPT_3270REGIME /* 3270 regime */
30 TELOPT_X3PAD /* X.3 PAD */
31 TELOPT_NAWS /* window size */
32 TELOPT_TSPEED /* terminal speed */
33 TELOPT_LFLOW /* remote flow control */
34 TELOPT_LINEMODE /* Linemode option */
35 TELOPT_XDISPLOC /* X Display location */
36 TELOPT_OLD_ENVIRON /* Old - Environmental variables */
37 TELOPT_AUTHENTICATION /* Authenticate */
38 TELOPT_ENCRYPT /* Encryption option */
39 TELOPT_NEW_ENVIRON /* New - Environmental variables */
255 TELOPT_EXOPL /* extended options list */


当对telnetd 进行指纹探测的时候,应该记住这些检测非常依赖于在主机上
默认的telnetd安装方式。如果你不是在Linux机器上运行in.telnetd,那么
这种方法可能会使你觉得运行了别的操作系统而不是实际的运行的。

这是我telnetd指纹文件的一部份:


# daemon, daemon version, os, os version, architecture, fingerprint

# 3Com SuperStack_II Switch
,,3Com,,SuperStack_II Switch,�齘C,

# HP-UX B.10.20
,,HP-UX,B.10.20,HP 9000,�?,

# Linux 2.2.9
,,Linux,2.2.9,x86,�齘X�?�?�?,

# Cobalt Linux 3.0
,,Cobalt Linux,3.0,mips,�齘X�?�?�?,


在有些时候,用这种指纹探测方法我们可能碰上问题,几个操作系统可以有
相同类型的指纹,会使操作系统的区分变得困难。当然,有问题就会有解决
的方法。

除了只是对telnetd用sysread()收集信息,我们可以发送telnet选项给目标
主机,收集它的回应,与一个指纹数据库进行比对。通过发送诸如:
IAC/DO/DONT/WILL/WONT 的命令,我们就会对每个操作系统如何对命令作出
反应有一个清楚的认识,因而对可能的操作系统有一个比较准确的猜测。


进行TSN指纹探测的一个示例代码:

--cut--


#!/usr/bin/perl
#
# TSN fingerprint example (by f0bic)
# usage: ./tsn <host> (telnetd-port)  
        # It is also possible to check for the DONT's  
        # instead of for the DO's.  
          
        use Socket;  
        $h=$ARGV[0];  
        $p="23" unless $ARGV[1];  
        socket(S, PF_INET, SOCK_STREAM, 6);  
        $iaddr=inet_aton($h);$paddr=sockaddr_in($p,$iaddr);  
        if(connect(S, $paddr)) {  
          sysread(S, $fprint, 200); # gathering telnetd fingerprint  
          print "\n[$h - connected]\n\nfingerprint: $fprint\n";  
          @ords = split(//, $fprint);print "ordinal: ";  
      foreach $tval (@ords){print ord($tval);print " ";} # ordinal  
      print "\n\n";  
        } else {  
        print "$host: cant connect!\n\n";  
        }  
      

--cut--  

一旦你用tsn.pl得到了指纹信息,你就可以与一个数据库进行比对看看是不  
是有成功的匹配。  


---  
优点:快,不需要超级用户权限  
缺点:不太可靠,容易被记录  
---  





----
喔,你是智慧之石,你是投石器之石,你是击碎星辰之人,你将自己高高地投出
  

[关闭][返回]