我的 ASP.NET 网站受到SQL注入攻击

My ASP.NET Website is Attacked With SQL Injection

提问人:codeblock 提问时间:12/17/2019 最后编辑:marc_scodeblock 更新时间:12/21/2019 访问量:978

问:

黑客访问了我的数据库用户列表和其他表。

首先,我在所有事务中使用参数化命令

command.Parameters.Add("@Parameter1", SqlDbType.NVarChar).Value

所有事务都是存储过程。

我正在将每个站点导航插入数据库。具体数据库表如下;

ID int (PK)
UserID int (null)
URL nvarchar(500)
IPAddress nvarchar(25)
CreatedAt datetime

项目从代码中获取信息,无论会话是否打开。UserID

CreatedAt是。DateTime.UtcNow

IPAddress代码如下:

public static string GetIPAddress(HttpContext context)
{
    string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

    if (!string.IsNullOrEmpty(ipAddress))
    {
        string[] addresses = ipAddress.Split(',');
        if (addresses.Length != 0)
            return addresses[0];
    }

    return context.Request.ServerVariables["HTTP_CLIENT_IP"] ?? context.Request.ServerVariables["REMOTE_ADDR"];
}

但是,使用所有查询字符串从网站当前 URL 填充。(URLRequest.RawUrl)

通常,当用户访问该站点时,日志会插入到数据库中,如上所述。以下记录正常插入。示例数据如下所示:

ID      UserID    URL                        IPAddress      CreatedAt
1        NULL     /User                      1.22.33.444    2019-12-12 16:22:33.441
2        NULL     /User/MyOrders             1.22.33.444    2019-12-12 16:24:33.441
3        NULL     /User?utm_source=email     1.22.33.444    2019-12-12 16:29:33.441

黑客以某种方式将一条记录插入数据库,如下所示:

ID      UserID    URL                        IPAddress                     CreatedAt
4        NULL     /User                      (select(0)from(select(sle     2019-12-12 17:22:33.441
5        NULL     /User/MyOrders             -1; waitfor delay '0:0:9'     2019-12-12 17:24:33.441
6        NULL     /User?utm_source=email     prvNA0R6'; waitfor delay      2019-12-12 17:29:33.441
7        NULL     /User?utm_source=email     -1' OR 2+198-198-1=0+0+0+     2019-12-12 17:29:33.441

如您所见,列是 SQL 查询攻击。 字段长度限制为 25 个字符。以下 SQL 查询文本被 SQL 截断。IPAddressIPAddress

在我看来,黑客通过使用 SQL 注入通过更改 or 作为 SQL 脚本来获取数据库记录。URLIPAddress

知道黑客如何进入我的数据库以及如何从现在开始避免攻击吗?

编辑

存储过程如下:

create procedure SP_InsertLogNavigation
    @URL nvarchar(150),
    @UserID int,
    @IPAddress nvarchar(25),
    @CreatedAt datetime
as
    insert into LogNavigation (URL, UserID, IPAddress, CreatedAt)
    values (@URL, @UserID, @IPAddress, @CreatedAt)

存储过程的用法如下:

public bool Save(LogNavigation logNavigation)
{
    int affectedRows = 0;

    InitializeSqlFields("SP_InsertLogNavigation");

    command.Parameters.Add("@URL", SqlDbType.NVarChar).Value = logNavigation.URL;
    command.Parameters.Add("@UserID", SqlDbType.Int).Value = Validation.IsNull(logNavigation.UserID);
    command.Parameters.Add("@IPAddress", SqlDbType.NVarChar).Value = logNavigation.IPAddress;
    command.Parameters.Add("@CreatedAt", SqlDbType.DateTime).Value = logNavigation.CreatedAt;

    try
    {
        Connect();

        affectedRows = command.ExecuteNonQuery();
    }
    catch (SqlException)
    {
    }
    finally
    {
        Disconnect();
    }

    return affectedRows != 0;
}
asp.net SQL-Server SQL 注入 客户端攻击

评论

0赞 jishan siddique 12/17/2019
您正在使用存储过程或计划查询?
0赞 codeblock 12/17/2019
我正在使用 StoredProcedure
0赞 Steve 12/17/2019
你告诉我们你使用参数,那么这些尝试做sql注入有什么效果呢?
1赞 Ravi Kant Singh 12/17/2019
他只是想获取访问权限,但是您正在使用的东西不能轻易被黑客入侵。从我的角度来看,尝试在 n 层中编写代码。这样东西就不能轻易地注入到代码中。
2赞 GarethD 12/17/2019
@codeblock 您的代码和过程是 100% 好的(好吧,有一种情况反对为您的存储过程使用 sp_ 前缀,但就 SQL 注入和与问题相关的事情而言,它们很好)。正如马丁在他的回答中指出的那样,这次尝试似乎没有成功。您发布的任何代码中都没有任何内容可以执行注入的 SQL。

答:

8赞 Martin 12/17/2019 #1

所以我敢断言,你实际上并没有屈服于SQL注入攻击。如果仅使用参数化查询,则攻击者已尝试获取访问权限,但失败了。

但是,您的表进行攻击尝试的原因与以下代码行有关:

string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

return context.Request.ServerVariables["HTTP_CLIENT_IP"] ?? context.Request.ServerVariables["REMOTE_ADDR"];

您必须了解,客户几乎可以完全控制提交给您网站的标题。攻击者可以将标头修改为他们想要的任何值。

这些参数由客户端在其请求中提供:

HTTP_X_FORWARDED_FOR
REMOTE_ADDR
HTTP_CLIENT_IP

在您的案例中,攻击者提供了包含 SQL 注入代码的欺骗性标头,您已将其忠实地放置在数据库的 IP 地址列中。

在注释中编辑以下 OP 查询

OP问道:

太好了,但我只有一个问题。她/他如何通过超过 25 个字符到我的服务器端

请求标头没有指定的大小限制,尽管各种实现(即 Apache 中的 8Kb)应用了实际限制。客户端可以发送任何长度的请求标头,最高可达您的网站主机软件允许的长度

但是,由于 SP 配置了最大长度为 25 个字符的参数,因此在保存到数据库时,溢出的文本将被截断。

评论

0赞 codeblock 12/17/2019
太好了,但我只有一个问题。她/他如何将超过 25 个字符传递给我的服务器端。
0赞 Martin 12/17/2019
@codeblock 我已经对我的问题进行了编辑,以解释其原因
0赞 codeblock 12/17/2019
我了解 RequestHeader 的局限性。用户可以为标题设置任何内容。我唯一不明白的;除了 IPAddress 之外,我没有在代码中执行 Request Header。IPAddress 由函数返回。如何向她/他传递长度超过 25 的 SQL 查询并执行它。GetIPAddress()
1赞 Martin 12/17/2019
@codeblock 如果攻击者破坏了您的 SQL Server,则不是通过您向我们展示的代码。通过 IP 地址标头提供的 SQL 不会针对服务器执行(除非您尚未向我们显示更多代码)
0赞 codeblock 12/17/2019
你是对的。是否可以使用,因为如果用户可以使用任何项目处理的 URL 数据并插入它。URLURL