Sito hackerato con sql server express edition

martedì 29 giugno 2010 - 01.28

zseven Profilo | Senior Member

Ciao ragazzi,
ho da poco subito un attacco di un hacker su di un sito realizzato in ASP con supporto di database sql server express edition.
In pratica su ogni riga di tabella, e su ogni campo ho trovato aggiunto al record esistente il seguente indirizzo:
post.webserviceget.ru/js.js
inserito tra i tag script.

Sapete un pò di cosa si tratta? come ho subito l'attacco (credo sql injection) e come posso fare a capire da dove è entrato e soprattutto come rimediare per proteggere meglio il sito?

Grazie mille

Approfondendo l'argomento ho visto nel log del sito che l'attacco è stato fatto sul modello di quanto indicato su questo sito:
http://nsmjunkie.blogspot.com/2010/06/anatomy-of-latest-mass-iisasp-infection.html

La pagina del sito attaccata è dinamica ed è di questo tipo:
http://www.nomedelsito.com/nomepagina.asp?Variabile=valore
Quindi nella pagina l'interrogazione al database viene fatta così:
Variabile = request.querystring("Variabile")
SELECT *FROM tabella WHERE ID = " & Variabile

Ormai con aspx non realizzo più interrogazioni del genere ma le parametrizzo tutte.
Potrei fare una cosa del genere anche con ASP 3.0, o la soluzione da adottare deve essere un'altra?

Grazie ancora tantissimo

alx_81 Profilo | Guru

>Ciao ragazzi,
Ciao

ti consiglio di leggere questo articolo per capire anche come risolvere. Forse la soluzione migliore è utilizzare le stored procedure. Così sei decisamente coperto:
http://www.dotnethell.it/articles/SQL-Injection-Tutorial-Security.aspx

>Grazie ancora tantissimo
di nulla!
--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

Ciao axl!
Purtroppo le stored procedure non le conosco proprio, mentre invece come ti dicevo per le query parametriche è un discorso che faccio quando lavoro su .NET, ma qui in ASP 3.0 non saprei proprio come crearle.

Adesso ho provato a impostare il recupero del parametro attraverso questa funzione di controllo che uso per tutti i campi form:
Function FixSQL(stringa)
stringa = Replace(stringa, "'", "''")
stringa = Replace(stringa, "%", "[%]")
stringa = Replace(stringa, "[", "[[]")
stringa = Replace(stringa, "]", "[]]")
stringa = Replace(stringa, "#", "[#]")
FixSQL = stringa
End function

Pensi che possa andare bene se recupero il valore di querystring attraverso questa funzione e poi dopo lo passo alla query sql?
E soprattutto come posso fare a verificare altre falle nel sito?

Grazie mille
Guido

alx_81 Profilo | Guru

>Pensi che possa andare bene se recupero il valore di querystring
>attraverso questa funzione e poi dopo lo passo alla query sql?
la replace potrebbe essere non sufficiente.
Guarda che per creare stored procedure non ci vuole nulla.
basta che metti la tua query parametrica all'interno del "BEGIN END" della stored. Ad esempio, se la tua query parametrica fosse questa:

INSERT INTO dbo.TuaTabella (campo1, campo2, campo3) VALUES (@campo1, @campo2, @campo3)

la stored procedure potrebbe essere semplicemente questa:

CREATE PROCEDURE dbo.proc_InsertTuaTabella @param1 int ,@param2 varchar(10) ,@param3 datetime AS BEGIN SET NOCOUNT ON; INSERT INTO dbo.TuaTabella (campo1, campo2, campo3) VALUES (@param1, @param2, @param3) END

e per modificarla in seguito basta sostituire CREATE con ALTER
Comunque la reference è:
http://msdn.microsoft.com/it-it/library/ms187926.aspx

>E soprattutto come posso fare a verificare altre falle nel sito?
ci sono strumenti che controllano parte di sql injection:
http://www.databasesecurity.com/sqlinjection-tools.htm
--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

Purtroppo non riesco a capirne proprio il funzionamento della stored, però volevo chiederti se realizzando una query parametriche senza stored di questo tipo riesco a proteggere meglio il sito oppure è uguale:

ID_utente = FixSQL(request.QueryString("ID_utente"))
Set objCommand = Server.CreateObject("ADODB.COMMAND")

sqlUT = "SELECT tab_1.*, tab_2.* FROM tab_1, tab_2 WHERE tab_2.id_utente =? AND tab_1.ID_utenti = tab_2.id_utente"

Set objCommand.ActiveConnection = conn
objCommand.CommandText = sqlUT

Set param1 = objCommand.CreateParameter("id", adInteger, adParamInput)
param1.value = ID_utente
objCommand.Parameters.Append param1

Set rsUT = objCommand.Execute()


Grazie mille
Guido

lbenaglia Profilo | Guru

>La pagina del sito attaccata è dinamica ed è di questo tipo:
>http://www.nomedelsito.com/nomepagina.asp?Variabile=valore
>Quindi nella pagina l'interrogazione al database viene fatta
>così:
>Variabile = request.querystring("Variabile")
>SELECT *FROM tabella WHERE ID = " & Variabile
>
>Ormai con aspx non realizzo più interrogazioni del genere ma
>le parametrizzo tutte.
>Potrei fare una cosa del genere anche con ASP 3.0, o la soluzione
>da adottare deve essere un'altra?

Ciao,

Puoi difenderti efficacemente evitando di costruire query concatenando stringhe, ma piuttosto incapsulandole in stored procedure parametriche che andrai a richiamare via ADODB.Command.

>Grazie ancora tantissimo
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

alx_81 Profilo | Guru

>Purtroppo non riesco a capirne proprio il funzionamento della
>stored, però volevo chiederti se realizzando una query parametriche
>senza stored di questo tipo riesco a proteggere meglio il sito
in teoria le query parametriche ti proteggono, quindi, se proprio non vuoi provare a seguire la strada stored procedure (se vuoi proviamo a superare i tuoi ostacoli insieme) puoi utilizzare quello che proponi.


--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

Ciao Lorenzo,
ho capito che le stored sono fondamentali per essere sicuro al 100% da attacchi.

Quello che però ho scritto sopra come codice, quindi utilizzando le query parametriche, lo reputi attaccabile alla stessa maniera di una query concatenata a stringhe, o ritieni possa essere, almeno per il momento in attesa che mi studio meglio le stored, una soluzione comunque buona?

Grazie mille
Guido

zseven Profilo | Senior Member

magari alx saresti gentilissimo.

Proprio come inizio non ho capito dove e in che maniera andare a realizzare la stored.
La devo creare direttamente sulla tabella del db su sql server?

E successivamente, come la integro nel codice ASP che ho scritto sopra realizzato con i parametri?

Grazie mille

alx_81 Profilo | Guru

>Proprio come inizio non ho capito dove e in che maniera andare a realizzare la stored.
Andiamo per passo (a grandi linee):

Che cosa è una stored procedure?
Una stored procedure può essere vista come un programma, una routine, scritta in un linguaggio tipicamente nativo di un rdbms (come transact-sql per sql server, pl-sql in oracle, ecc.).

Dov'è salvata?
A livello di database, sotto la categoria "PROGRAMMABILITY". Quindi è salvata direttamente a livello di database, non di oggetto. E' compilata e residente sul database.

A cosa serve?
A creare uno strato di software residente su database per raccordare alcune logiche anche complesse in routine e per definire un ulteriore livello di sicurezza nei confronti di chi accede al database.

Detto questo, come la crei?
Tramite la CREATE PROCEDURE:
http://msdn.microsoft.com/it-it/library/ms187926.aspx

Come la modifichi?
Tramite la ALTER PROCEDURE:
http://msdn.microsoft.com/it-it/library/ms189762.aspx

>E successivamente, come la integro nel codice ASP che ho scritto sopra realizzato con i parametri?
nel CommandText metti SOLO il nome della stored procedure.
nel CommandType metti adStoredProcedure (se hai incluso adovbs.inc) o 4.
I parametri sono dichiarati e valorizzati in maniera identica, indicando il nome che definisci nella CREATE (sintassi @nomeparametro).
Se torna record, puoi chiamare la stored per farti tornare un recordset:

set rs = command.Execute

intanto partiamo così..
dimmi se è più chiaro.


--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

sicuramente è molto più chiaro!!

Ok, allora ti spiego cosa ho fatto.
Ho creato la stored, ed ho scritto questo:

SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE Parlo -- Add the parameters for the stored procedure here @id int AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- Insert statements for procedure here SELECT tab_utenti.*, tab_info.* FROM tab_utenti, tab_info WHERE tab_info.id_utente = @id AND tab_utenti.ID_utenti = tab_info.id_utente END GO

successivamente sulla pagina ASP ho modificato il codice di prima funzionante in questa maniera, semplicemente aggiungendo il commandtype in pratica... forse è qui che sbaglio , perchè mi restituisce errore:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Che "orrori" ho fatto? :-)

Grazie mille

alx_81 Profilo | Guru

>Che "orrori" ho fatto? :-)
ci siamo, prova con adCmdStoredProc. e se non va ancora vuol dire che non hai incluso il file .inc delle costanti ado.
In tal caso tutti gli ad* vanno cambiati con costanti numeriche. Qui c'è il file.inc:
http://www.aspcode.it/tutorials/corsoasp/adovbs.zip

--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

il file adovb c'è, e anche la constante è presente come adCmdStoredProc.

Scrivendo questo l'errore cambia e mi restituisce:

Errore di sintassi o violazione di accesso


Ho provato vistando come concedi nelle proprietà del database alla voce "create procedure" ma mi ritorna lo stesso errore...

alx_81 Profilo | Guru

>Ho provato vistando come concedi nelle proprietà del database
>alla voce "create procedure" ma mi ritorna lo stesso errore...
ma nel codice che hai postato hai cambiato l'sql col nome della sp?
poi non devi passare Parlo, o fai:

objCommand.CommandText = "Parlo"

o fai

sqlUT = "Parlo" objCommand.CommandText = sqlUT
--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

Dunque, facendo in questa maniera:

sqlUT = "Parlo"

Set objCommand.ActiveConnection = conn
objCommand.CommandText = sqlUT
objCommand.CommandType = adCmdStoredProc


Mi dice:
impossibile trovare la stored "Parlo".

Ha importanza dove viene salvata la stored?

alx_81 Profilo | Guru

>Ha importanza dove viene salvata la stored?
Eccome! se la connection string punta ad un database dove non è salvata la stored, non la troverai mai
Cerca di capire che le stored procedure, sono viste come oggetti esattamente come Viste o Tabelle.
Cambia solo quello che fanno, ovvero che ci sono logiche al loro interno che altrimenti dovresti fare via codice da qualunque altro software..
Cambia come chiamarle, ovvero la sintassi, ma sono sempre oggetti relativi al database.

--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

Niente da fare...
anche risalvando la stored nella stessa cartella del database continua a dirmi che non trova la stored procedure "Parlo"...

alx_81 Profilo | Guru

>Niente da fare...
>anche risalvando la stored nella stessa cartella del database
>continua a dirmi che non trova la stored procedure "Parlo"...
sicuro che nello statement che crea la sp non ci sia una USE che sposta l'ambito di database?
sicuro che nella tendina del management studio ci sia selezionato il database corretto?
sicuro di averla chiamata così?
fai così per sicurezza:

USE NomeTuoDb; GO CREATE PROCEDURE ....
--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

guarda dovrebbe essere tutto corretto.
Ho provato anche a modificare la SP come mi hai detto, e adesso si presenta così:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


USE NOMEDB;
GO

CREATE PROCEDURE StoredParlo
-- Add the parameters for the stored procedure here
@id int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
SELECT tab_utenti.*, tab_info.*
FROM tab_utenti, tab_info
WHERE tab_info.id_utente = @id AND tab_utenti.ID_utenti = tab_info.id_utente
END
GO

Questa l'ho salvata nella stessa cartella del Db e l'ho chiamata StoredParlo.sql

Quindi l'ho richiamata così:
sqlUT = "StoredParlo"

Set objCommand.ActiveConnection = conn
objCommand.CommandText = sqlUT
objCommand.CommandType = adCmdStoredProc

Ma l'errore è sempre:
Impossibile trovare la stored procedure 'StoredParlo'

lbenaglia Profilo | Guru

>Questa l'ho salvata nella stessa cartella del Db e l'ho chiamata
>StoredParlo.sql
Il comando di CREATE PROCEDURE non va salvato in un file .sql, ma va semplicemente eseguito (ad esempio in una sessione di SSMS) per creare l'oggetto.
Il salvataggio su file può servirti al più per documentare il comando, operazione che puoi eseguire in qualunque momento sempre da SSMS o tramite la stored procedure di sistema sp_helptext, la calalog view sys.sql_modules oppure la funzione OBJECT_DEFINITION().

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

alx_81 Profilo | Guru

>Questa l'ho salvata nella stessa cartella del Db e l'ho chiamata StoredParlo.sql
Ah adesso ho capito cosa hai fatto.. non devi salvare il file, ma eseguire lo statement SQL. Questo "compila" la stored procedure e crea l'oggetto sotto la "cartella" Programmability che vedi dall'ObjectExplorer di SSMS (Sql Server Management Studio). Il comando lo devi eseguire con il tasto F5 o con ESEGUI/Execute su Management Studio.
--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

ah ecco!! perdonatemi ero proprio all'oscuro in questo campo...

Adesso infatti funziona perfettamente!
Con questo sistema tutte le query dinamiche che vado a realizzare con i parametri sulla pagina ASP, o .NET che sia, associate alla SP sono sicure da attacchi di injection!

Ho dovuto dare l'autorizzazione di execute alle proprietà del db per farla funzionare, è corretto e sicuro, o è preferibile fare come ho appena visto su un esempio msdn che fa così:
CREATE PROCEDURE nomesp
WITH EXECUTE

Ho provato a modificare la query e a rieseguirla, e mi dice che già esiste, quindi ho fatto come mi avevi detto su un post precedente ed ho sostituito il CREATE con ALTER, ho rieseguito la SP e continua a funzionare a correttamente.
Ho fatto errori?

Grazie mille

alx_81 Profilo | Guru

>Ho fatto errori?
per la security il discorso è delicato..
con che utente accedi al db? forse sarebbe carino fare un ruolo che può eseguire le tue sp, e poi fare un utente sql (se non puoi usare la winauth) che ha quel ruolo per cui può eseguire le stored procedure..
Ma ripeto, è un discorso delicato che andrebbe affrontato con la conoscenza su ciò che devi fare e sul tuo ambiente..

--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

eh infatti hai toccato un altro punto dolente (per me si intende) in termini di conoscenza.

Al momento sul server Accedo al db con l'autenticazione di windows, ed il db non ha neanche la password.
Anche in questo caso vorrei poter proteggere ancora di più non solo questo db, ma anche altri che sto iniziando ad utilizzare per lavori più complessi, visto che ho sempre lavorato con access e da poco mi sto avvicinando a sql server.

Magari sapresti darmi qualche link di riferimento per mettere le password ai database? O non so se ritieni più opportuno procedere in altra maniera se puoi consigliarmi.

Grazie mille
Guido

alx_81 Profilo | Guru

>Al momento sul server Accedo al db con l'autenticazione di windows, ed il db non ha neanche la password.
guarda che l'autenticazione windows passa il contesto del tuo utente, loggato sulla macchina, che ha eccome una password di protezione. Che in teoria dovresti conoscere solo tu.
Se sei sotto dominio, puoi pensare di fare un gruppo sul domain controller in cui metti anche il tuo utente (ad esempio un gruppo SQLAdmins).
A quel punto, sul database, come login aggiungi il gruppo. Questo è un metodo molto sicuro per l'accesso, più che usare un'autenticazione sql.
Ma è veramente troppo poco.. devi prima capire bene come funziona e come si configura la security. E questo è un argomento vastissimo e vario.

Comunque, andando sui BOL (Books OnLine - http://msdn.microsoft.com/en-us/library/ms130214.aspx) troverai molte risposte.
Oppure puoi anche basarti su questo whitepaper: http://www.microsoft.com/sqlserver/2008/en/us/wp-sql-2008-security.aspx (2008) o quelli su 2005: http://www.microsoft.com/sqlserver/2005/en/us/white-papers.aspx#sec

--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

zseven Profilo | Senior Member

ok, sei stato chiarissimo e gentilissimo!
Mi stavo inoltre leggendo proprio il tuo articolo sulla sql injection, e adesso è tutto molto più chiaro, sia su come mi hanno attaccato e sia su come proteggermi tra parametri e stored.

Adesso approfondirò l'argomento su come proteggere al meglio il server e i database.

Grazie mille
Guido

alx_81 Profilo | Guru

>Adesso approfondirò l'argomento su come proteggere al meglio
>il server e i database.
bravo, meglio così

>Grazie mille
di nulla!
--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5