Декодирование T-SQL CAST в C# / VB.NET


недавно наш сайт был затоплен с возрождением ботнет AsproxSQL-инъекций атака. Не вдаваясь в подробности, атака пытается выполнить SQL-код, кодируя T-SQL команды в кодированной двоичной строке ASCII. Это выглядит примерно так:

DECLARE%[email protected]%20NVARCHAR(4000);SET%[email protected]=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 в массиве байтов, который я смог разобрать до этого момента, я получаю", - + " в результате.

как я могу выяснить, что мне не хватает - нужно ли мне делать "прямое приведение" для каждого байта вместо того, чтобы пытаться его разобрать?

2   51  

2 ответа:

Hazzah!!!!

Я вернулся к сообщению Майкла, сделал еще несколько тычков и понял, что мне нужно сделать двойное преобразование, и в конечном итоге разработал этот маленький самородок:

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

оттуда я просто сделал цикл, чтобы пройти через все символы 2 на 2 и получить их "hexified", а затем перевести в строку.

к Нику, и кто-нибудь еще заинтересован, я пошел вперед и разместил мое маленькое приложение в CodePlex. Не стесняйтесь использовать / изменять, как вам нужно.

Попробуйте удалить 0x сначала позвоните Encoding.UTF8.GetString. Я думаю, что это может работать.

по существу: 0x44004500

удалить 0x, а затем всегда два байта один символ:

44 00 = D

45 00 = E

6F 00 = o

72 00 = r

Так что это определенно формат Unicode / UTF с двумя байтами / символами.