【问题标题】:How to execute a raw union SQL query on several tables with Entity Framework Core如何使用 Entity Framework Core 对多个表执行原始联合 SQL 查询
【发布时间】:2019-08-27 20:09:29
【问题描述】:

我正在为 CTF 竞赛编写一个带有有意实现的漏洞的 Web 应用程序,并且我正在使用带有 SQLite 数据库的 ASP.NET Core 和 Entity Framework Core。我想让 SQL 注入成为可能,为此,我需要使用联合语句以某种方式查询多个表上的数据库。

不幸的是,我的所有尝试都导致了错误消息。后端控制器通过 ajax 请求获取参数,客户端应滥用UserId 变量并修改 ajax 请求中的参数以获取有关另一个表的更多信息。

我尝试了几种FromSql 方法,但都没有成功。有人知道我该如何解决这个问题吗?

这是后端控制器代码

public JsonResult ListImagePaths(string UserId)
{
    string query = $"SELECT * FROM UserImage WHERE UID == {UserId}";

    var results = mContext.UserImage.FromSql(query);           

    return Json(results);
}

这样我只对UserImage 表进行查询。我没有找到查询两个表的方法。我尝试创建一个包含两个表中的属性的DbSet,但这也不起作用。

这是客户端的ajax请求

$(document).ready(function () {
    $.ajax({
        type: 'GET',
        url: 'ListImagePaths/"27b988e3-77ab-41e4-b945-6ac9315a70ec"',
        success: function (result){
            console.log(result)
        }
    })
})

这是 UserImage 表的示例

Uid = 27b988e3-77ab-41e4-b945-6ac9315a70ec
路径 = CloudImages/picture.jpg
id = e802a368-229f-4ed5-ba84-42ce4da5ed0a

这是 AspNetUsers 表的示例

Id = 81858e0d-e75f-45c5-8054-ef956e843a04
用户名 = SomeGuy43
NormalizedUserName = SOMEGUY43
电子邮件 = myemail@somehere.com
NormalizedEmail = MYEMAIL@SOMEWHERE.COM
已确认电子邮件 = 1
PasswordHash = uRGWeGWq5ZorrzgNvSuz8Q==
SecuritySamp = RBCZDCBA3IEMPET2ZCL4MVCXW3IA3H4C
ConcurrencyStamp = 0b8873cc-ecfe-4280-a6bf-0f354242f4a4
电话号码 = NULL
PhoneNumberConfirmed= 0
TwoFactorEnabled = 0
锁定结束 = 0
LockoutEnabled = 0
AccessFailedCount = 0
AvatarImage = 图片/头像.jpg
盐 = 4r1rtuji0cc
IsAdmin = 0

【问题讨论】:

  • 我相信您可以将.Include放在FromSql之前以包含相关表格?
  • 我现在正在试验.Includevar results = mContext.UserImage.Include( u => u.Users)FromSql(query); 但我只能访问 UserImage 表的属性。 @mason 应用程序应该允许 SQL-Incjections
  • 请提供您想要UNION的表格示例。例如至少两个代表表的示例实体类。
  • 我已经编辑了帖子并添加了两个示例。
  • 但它们没有共同点——它们更像是JOIN 而不是UNION 的候选者。我期待看到您在我尝试创建一个包含两个表中的属性的 DbSet 中使用的类,即两个实体类和具有公共属性的类。

标签: c# ajax sqlite entity-framework-core


【解决方案1】:

试试这个查询:

string query = $"SELECT * FROM UserImage WHERE UID == convert(UNIQUEIDENTIFIER, convert(varchar(max),{UserId}))";

我想强调的是,使用 * 是不实用的,最好使用列。

【讨论】:

  • 我应该为 UNIQUEIDENTIFIER 选择什么?
  • FromSql 方法不允许对特定列进行查询...这就是我使用 * 的原因
【解决方案2】:

我没有找到查询两个表的方法。我尝试创建一个包含两个表中的属性的 DbSet,但这也不起作用。

不确定究竟是什么“不起作用”,但这是要走的路。但不是创建包含公共属性的类的 DbSet,从而告诉 EF 将其视为一个实体,而是创建 DbQuery 或简单地将该类注册为 query type

例如:

public class MyQueryType
{
    public Guid Id { get; set; }
    publc string Text { get; set; }
}

在您的 DbContext 类中,或者:

public DbQuery<MyQueryType> MyQueryType { get; set; }

或(在OnModelCreating 覆盖内):

modelBuilder.Query<MyQueryType>();

两者都允许您使用MyQueryType 作为FromSql 的目标:

string query = $"SELECT Id, Path AS Text FROM UserImage WHERE UID == {UserId}"
    + $" UNION ALL SELECT Id, UserName AS Text FROM AspNetUsers";

var results = mContext.Query<MyQueryType>().FromSql(query);

只需确保 SQL 查询通过使用别名返回预期的列名和类型,如上所示。

【讨论】:

  • 非常感谢!这终于奏效了。我松了一口气。
猜你喜欢
  • 2020-11-27
  • 2018-02-28
  • 2020-11-22
  • 1970-01-01
  • 2017-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多