68

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

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

我能够在 SQL 中对此进行解码,但我对此有点谨慎,因为我不知道当时究竟发生了什么。

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

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 方法时,我得到“,-+”作为结果。

我如何弄清楚我缺少什么 - 我是否需要对每个字节进行“直接转换”而不是尝试解析它?

4

2 回答 2

24

I went back to Michael's post, did some more poking and realized that I did need to do a double conversion, and eventually worked out this little nugget:

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

From there I simply made a loop to go through all the characters 2 by 2 and get them "hexified" and then translated to a string.

To Nick, and anybody else interested, I went ahead and posted my little application over in CodePlex. Feel free to use/modify as you need.

于 2008-08-05T17:02:30.870 回答
8

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

本质上:0x44004500

去掉 0x,然后总是两个字节是一个字符:

44 00 = D

45 00 = E

6F 00 = o

72 00 = r

所以它绝对是一个带有两个字节/字符的 Unicode/UTF 格式。

于 2008-08-02T01:38:14.077 回答