在C#/ VB.NET中解码T-SQL CAST

在C#/ VB.NET中解码T-SQL CAST

Decoding T-SQL CAST in C#/VB.NET

最近,我们的网站因Asprox僵尸网络SQL注入攻击的兴起而沉迷。无需详细说明,攻击尝试通过将T-SQL命令编码为ASCII编码的BINARY字符串来执行SQL代码。看起来像这样:

1
DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x44004500...06F007200%20AS%20NVARCHAR(4000));EXEC(@S);--

我能够在SQL中对其进行解码,但是由于对此我一无所知,所以我对此有所警惕。

我试图编写一个简单的解码工具,因此即使不接触SQL Server也可以解码这种类型的文本。我需要解码的主要部分是:

1
2
CAST(0x44004500...06F007200 AS
NVARCHAR(4000))

我已经尝试了以下所有命令,但没有运气:

1
2
3
4
5
6
7
8
9
10
txtDecodedText.Text =
    System.Web.HttpUtility.UrlDecode(txtURLText.Text);
txtDecodedText.Text =
    Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(txtURLText.Text));
txtDecodedText.Text =
    Encoding.Unicode.GetString(Encoding.Unicode.GetBytes(txtURLText.Text));
txtDecodedText.Text =
    Encoding.ASCII.GetString(Encoding.Unicode.GetBytes(txtURLText.Text));
txtDecodedText.Text =
    Encoding.Unicode.GetString(Convert.FromBase64String(txtURLText.Text));

翻译此编码的正确方法是什么?不使用SQL Server?可能吗?我也会用VB.NET代码,因为我也很熟悉。

好吧,我确定我在这里遗漏了一些东西,所以这就是我的位置。

由于我的输入是基本字符串,因此我只从编码部分的一个片段开始-4445434C41(转换为DECLA),并且第一次尝试是这样做的...

1
txtDecodedText.Text = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(txtURL.Text));

...它所做的只是返回与我输入的完全相同的东西,因为它将每个字符转换为一个字节。

我意识到我需要手动将每两个字符解析为一个字节,因为我不知道的任何方法都可以做到这一点,所以现在我的小解码器看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
while (!boolIsDone)
{
    bytURLChar = byte.Parse(txtURLText.Text.Substring(intParseIndex, 2));
    bytURL[intURLIndex] = bytURLChar;
    intParseIndex += 2;
    intURLIndex++;

    if (txtURLText.Text.Length - intParseIndex < 2)
    {
        boolIsDone = true;
    }
}

txtDecodedText.Text = Encoding.UTF8.GetString(bytURL);

前两对看起来不错,但是当循环到达\\时,循环就不起作用了。"" 4C "对,并指出该字符串的格式不正确。

足够有趣的是,当我逐步执行调试程序并到达能够解析到该字节数组上的GetString方法时,我得到",-"作为结果。

如何弄清楚我所缺少的是-我需要为每个字节做一个"直接转换",而不是尝试对其进行解析吗?


我回到Michael的职位,做了一些戳记,意识到我确实需要进行两次转换,并最终得出了这个小块:

1
Convert.ToString(Convert.ToChar(Int32.Parse(EncodedString.Substring(intParseIndex, 2), System.Globalization.NumberStyles.HexNumber)));

从那里我简单地做了一个循环依次将所有字符都乘2乘2,然后将其" hexified \\"转换为字符串。

对Nick和其他感兴趣的人,我继续将我的小应用程序发布到CodePlex上。随时根据需要使用/修改。


尝试先删除0x,然后调用Encoding.UTF8.GetString。我认为这可能有效。

本质上:0x44004500

删除0x,然后总是两个字节是一个字符:

1
2
3
4
5
6
7
44 00 = D

45 00 = E

6F 00 = o

72 00 = r

Unicode / UTF格式,两个字节/字符。


推荐阅读