此问题与Exploitable PHP Functions类似。
受污染的数据来自用户,或者更具体地来说是攻击者。当受污染的变量达到接收器功能时,您就会有漏洞。例如,执行sql查询的函数是接收器,而GET / POST变量是污点源。
C#中的所有接收器功能是什么?我正在寻找引入漏洞或software weakness的功能。我对远程执行代码漏洞特别感兴趣。是否存在整个类/库,其中包含黑客想要影响的功能恶劣?人们如何不小心制作危险的C#代码?
答案 0 :(得分:55)
任何使用正则表达式的东西(特别是RegularExpressionValidator)。要查看此内容,请使用正则表达式^(\d+)+$
运行RegularExpressionValidator,并为其提供30位数字和字母字符以进行验证。
一些帖子:
这称为正则表达式拒绝服务攻击,它可以使网站瘫痪。
答案 1 :(得分:27)
在基于Web的方面,C#(更一般地说,ASP.NET)通常容易受到以下攻击(OWASP Top 10 2013列出的项目)。我意识到你主要对接收器功能很感兴趣,其中我介绍了一些,但是你确实问过人们如何不小心制作了危险的C#代码,所以希望我能在这里提供一些见解。
通过字符串连接生成查询。
var sql = "SELECT * FROM UserAccount WHERE Username = '" + username "'";
SqlCommand command = new SqlCommand(sql , connection);
SqlDataReader reader = command.ExecuteReader();
这通常可以通过parameterised queries来解决,但是如果你使用IN
条件currently isn't possible没有字符串连接。
代码如
searcher.Filter = string.Format("(sAMAccountName={1})", loginName);
可以使应用程序容易受到攻击。更多信息here。
此代码容易受到命令注入的影响,因为Process.Start
的第二个参数可以使用&
字符传递给它的额外命令来批处理多个命令
string strCmdText= @"/C dir c:\files\" + Request.QueryString["dir"];
ProcessStartInfo info = new ProcessStartInfo("CMD.exe", strCmdText);
Process.Start(info);
e.g。 foldername && ipconfig
默认的Forms Authentication SignOut方法不会更新服务器端的任何内容,从而允许继续使用捕获的身份验证令牌。
调用SignOut方法只会删除表单身份验证Cookie。 Web服务器不存储有效和过期的身份验证票证以供以后进行比较。如果恶意用户获得有效的表单身份验证cookie,这会使您的站点容易受到重播攻击。
如果用户使用session fixation,则可能存在session state for authentication个漏洞。
Response.Write
(以及快捷方式<%= =>
)容易受到攻击,除非开发人员记得对输出进行HTML编码。最近的快捷方式<%:
HTML默认编码,尽管一些开发人员可能会使用此方法将值插入JavaScript中,攻击者仍然可以将其转义。即使使用现代Razor engine,也很难做到这一点:
var name = '@Html.Raw(HttpUtility.JavaScriptStringEncode(Model.Name))';
ASP.NET默认启用Request Validation,它将阻止来自cookie的任何输入,查询字符串以及可能是恶意的POST数据(例如HTML标记)。这似乎可以很好地应对来自特定应用程序的输入,但如果数据库中的内容是从其他来源(例如使用其他技术编写的应用程序)插入的,则可能仍然可以输出恶意脚本代码。另一个缺点是数据是在属性值中插入的。 e.g。
<%
alt = Request.QueryString["alt"];
%>
<img src="http://example.com/foo.jpg" alt="<%=alt %>" />
这可以在不触发请求验证的情况下被利用:
如果alt
是
" onload="alert('xss')
然后这呈现
<img src="http://example.com/foo.jpg" alt="" onload="alert('xss')" />
在旧版本的.NET中,对于开发人员来说,确保使用某些默认Web控件正确编码其输出是mine-field。
不幸的是,数据绑定语法还没有包含内置的编码语法;它将出现在ASP.NET的下一个版本中
e.g。不容易受伤:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:TextBox ID="txtYourField" Text='<%# Bind("YourField") %>'
runat="server"></asp:TextBox>
</ItemTemplate>
</asp:Repeater>
脆弱:
<asp:Repeater ID="Repeater2" runat="server">
<ItemTemplate>
<%# Eval("YourField") %>
</ItemTemplate>
</asp:Repeater>
MVC模型绑定可以允许parameters added to POST data映射到数据模型。这可能是无意中发生的,因为开发人员还没有意识到恶意用户可能以这种方式修改参数。 Bind
属性可用于prevent this。
有许多配置选项可能会削弱应用程序的安全性。例如,将customErrors
设置为On
或启用跟踪。
ASafaWeb等扫描程序可以检查此常见错误配置。
ASP.NET中的默认密码哈希方法有时不是最好的。
在集成管道模式下,.NET可以看到每个请求和句柄都可以授权每个请求,甚至是非.NET资源(例如.js
和图像)。但是,如果应用程序在经典模式下运行,.NET只会看到.aspx
等文件的请求,因此其他文件可能会意外取消保护。有关差异的详细信息,请参阅this answer。
e.g。 www.example.com/images/private_photograph_user1.jpg
更有可能在以经典模式运行的应用程序中容易受到攻击,尽管有workarounds。
虽然遗留Web表单应用程序通常对CSRF更安全,因为要求攻击者伪造View State和Event Validation值,但除非开发人员已手动实现anti forgery tokens,否则较新的MVC应用程序可能容易受到攻击。注意我并不是说Web表单不容易受到攻击,只是传递一些基本参数更加困难 - 虽然有一些修复,例如integrating the user key进入View State值。
当EnableEventValidation属性设置为true时,ASP.NET将验证控件事件是否源自该控件呈现的用户界面。控件在呈现期间注册其事件,然后在回发或回调处理期间验证事件。例如,如果列表控件包括呈现页面时编号为1,2或3的选项,并且如果收到指定选项编号4的回发请求,则ASP.NET会引发异常。 ASP.NET中的所有事件驱动控件都默认使用此功能。
[EnableEventValidation]功能可降低未经授权或恶意回发请求和回调的风险。强烈建议您不要禁用事件验证。
添加
等代码Response.Redirect(Request.QueryString["Url"]);
会使您的网站容易受到攻击。可以通过向包含链接的用户发送网络钓鱼电子邮件来启动攻击。如果用户保持警惕,他们可能会在点击之前仔细检查URL的域名。但是,由于域名将与您信任的域名相匹配,因此他们会点击该链接,而不会发现该页面会将用户重定向到攻击者的域名。
应在Url
上进行验证,以确保它是相对的,允许的网址或您自己允许的域和网页之一的绝对网址。例如,您可能希望检查某人是否未将用户重定向到/Logout.aspx
。虽然可能没有什么能阻止攻击者直接链接到http://www.example.com/Logout.aspx
,但是他们可以使用重定向来隐藏URL,这样用户就更难理解正在访问哪个页面(http://www.example.com/Redirect.aspx?Url=%2f%4c%6f%67%6f%75%74%2e%61%73%70%78
)。 / p>
其他OWASP类别是:
我无法想到任何特定于C#/ ASP.NET的内容。如果我有任何想法(如果您认为它们与您的问题相关),我会更新我的答案。
答案 2 :(得分:18)
Process.Start
是第一个浮现在脑海中的人。
我确信WindowsIdentity
和System.Security
的大部分内容也可以用于邪恶。
当然,有SQL注入攻击,但我不认为这是你的意思(尽管可以通过SQL Server进行远程执行)。
答案 3 :(得分:17)
除了已经提到的显而易见的Process.Start()
之外,我还可以看到几种潜在的间接剥削方式。
CreateProcess()
以及诸如此类。Assembly.Load()
和其他此类重载的任何类型的动态程序集加载机制。如果受损组件进入系统并加载。现在就想到了这一切。
答案 4 :(得分:12)
IMO:nr 1可利用的功能,看起来是无辜的,但在没有考虑的情况下使用时非常危险。
在ASP.Net Response.Write
或快捷方式中:
<%= searchTermFromUser %>
在ADO.Net中:
string
+
运营商:var sql = "SELECT * FROM table WHERE name = '" + searchTermFromUser + "'"
答案 5 :(得分:11)
您从用户(或任何其他外部来源)获得并传递给其他系统或其他用户的任何数据都是潜在的利用。
如果您从用户那里获得一个字符串并将其显示给另一个用户而不使用HtmlEncode,那么这是一个潜在的漏洞。
如果你从用户那里得到一个字符串并用它来构造SQL,那么这是一个潜在的SQL注入。
如果您从用户那里获得一个字符串并使用它来收集Process.Start或Assembly.Load的文件名,那么它就是一个远程执行漏洞
您明白了,危险来自于使用未经过清理的数据,如果您从未将用户输入传递给外部系统而未对其进行清理(例如:HtmlEncode)或使用注入安全接口(例如:SQL参数),则相对安全 - 当你忘记清理某些东西时,最无辜的方法可能会成为一个安全漏洞。
注意:cookie,html标头和通过网络传递的任何其他内容也是来自用户的数据,在大多数情况下,即使数据库中的数据也是来自用户的数据。
答案 6 :(得分:8)
System.Net,System.XML,System.IO中的大量内容(任何采用URI和/或文件路径并实际处理它们识别的资源的东西)System.Reflection,System.Security,System。 Web,System.Data和System.Threading命名空间可能很危险,因为它们可以用来做坏事,而不仅仅是弄乱当前的执行。这么多,以至于尝试识别每个都是耗时的。
当然,除非另有说明,否则所有第三方程序集中的每种方法都必须被认为是危险的。再次耗费时间。
我认为这不是一种特别富有成效的方法。制作功能清单只适用于有限的库,或者使用大型语言,其中C#语言库中的许多内容都在语言本身中。
有一些经典危险的例子,例如Process.Start()
或任何直接执行另一个过程的例子,但它们通过明显危险来平衡。即使是一个相对愚蠢和无能的编码人员在使用它时也可能会小心,同时将未经过其他方法的数据留下来。
数据卫生比任何功能列表都要富有成效。数据是否经过验证可以删除明显不正确的输入(可能是由于攻击造成的,或者可能只是一个错误),并且是否以适当的方式对给定层进行编码和转义(关于“危险”字符序列的讨论太多了,'
从不伤害任何人,'
没有正确地转义SQL,当它确实在SQL层时会受到伤害 - 确保数据正确进入那里所需的工作与那是为了避免漏洞利用)。与代码之外的东西进行通信的层是否牢固。例如,使用未经检查的输入构造URI - 如果不是,您可以将一些更常用的System.Net和System.XML方法转换为漏洞。
答案 7 :(得分:7)
使用任何类型的不安全代码都可能导致指针等问题。 Microsoft在这里提供了一篇关于不安全代码的好文章:http://msdn.microsoft.com/en-us/library/aa288474(VS.71).aspx
答案 8 :(得分:7)
Reflection.Emit和CodeDom
修改:
允许使用线程的插件或第三方库可以将整个应用程序关闭,除非您将这些库/插件加载到单独的应用程序域中。
答案 9 :(得分:7)
可能一半的框架包含非常可怕的功能。我自己认为File.WriteAllText()
非常可怕,因为它可以覆盖当前用户有权访问的任何文件。
这个问题的另一种方法是如何管理安全性。 http://ondotnet.com/pub/a/dotnet/2003/02/18/permissions.html上的文章包含有关.NET安全系统的基本描述,System.Security.Permissions命名空间包含.NET提供的所有权限。您还可以查看http://msdn.microsoft.com/en-us/library/5ba4k1c5.aspx以获取更多信息。
简而言之,.NET允许您限制进程可以拥有的权限,例如,拒绝更改磁盘上数据的方法。然后,您可以检查这些权限,并根据流程是否包含这些权限进行操作。
答案 10 :(得分:7)
即使是简单的字符串比较也可能是一个问题。
如果应用程序信任 决定基于此结果 String.Compare操作,结果 该决定可能会被颠覆 改变CurrentCulture
看看example。相当容易错过
答案 11 :(得分:3)
我见过用户可以在数据库中设置函数调用的名称和参数的代码。然后,系统将通过Reflection执行指定的函数,而不检查任何内容......