Недавно наш сайт был наводнен всплеском атаки SQL-инъекций ботнета Asprox. Не вдаваясь в подробности, атака пытается выполнить код SQL путем кодирования команд T-SQL в ASCII-кодированную строку BINARY. Это выглядит примерно так:
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 в байтовом массиве, который мне удалось проанализировать до этого момента, я получаю ", - +" в качестве результата.
Как выяснить, чего мне не хватает - нужно ли выполнять "прямое приведение" для каждого байта вместо попытки его проанализировать?