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

时间:2020-03-05 18:37:16  来源:igfitidea点击:

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

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

我可以用SQL对其进行解码,但是由于对此我一无所知,因此我对此有所警惕。

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

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

我尝试了以下所有命令,但都没有碰到运气:

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)的一小段开始,而第一次尝试是这样做的。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

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

...并且所做的只是返回我输入的内容,因为它将每个字符转换为字节。

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

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方法时,得到的结果是",-+"。

我如何找出丢失的内容,我需要对每个字节进行"直接转换",而不是尝试对其进行解析?

解决方案:

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

本质上:0x44004500

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

44 00 = D

45 00 = E

6F 00 = o

72 00 = r

因此,它绝对是具有两个字节/字符的Unicode / UTF格式。

哈扎!

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

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

从那里开始,我简单地进行了一个循环,以2到2的方式遍历所有字符,并将它们"十六进制化",然后转换为字符串。

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