Skip to content

Commit 8cd9293

Browse files
committed
database/sqlite: add information about the schema table
1 parent 91d5fe8 commit 8cd9293

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

database/sqlite.rst

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ From the interactive prompt given by ``sqlite3``, it is possible to run SQL stat
3030
3131
# Show the version
3232
.version
33+
SELECT SQLITE_VERSION();
3334
3435
# Quit
3536
.exit
@@ -94,3 +95,75 @@ For example:
9495
.. code-block:: sql
9596
9697
SELECT DATETIME(users.last_update_time, 'unixepoch') FROM users;
98+
99+
Schema table
100+
------------
101+
102+
According to the `documentation <https://www.sqlite.org/schematab.html>`_, every SQLite database contains a single "schema table" named ``sqlite_master`` that stores the schema for that database.
103+
104+
.. code-block:: sql
105+
106+
sqlite> .schema sqlite_master
107+
CREATE TABLE sqlite_master (
108+
type text,
109+
name text,
110+
tbl_name text,
111+
rootpage integer,
112+
sql text
113+
);
114+
115+
To understand its content in actual database, let's create a new table in an empty database.
116+
117+
.. code-block:: sql
118+
119+
DROP TABLE IF EXISTS `users`;
120+
CREATE TABLE IF NOT EXISTS `users` (
121+
`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
122+
`name` TEXT NOT NULL,
123+
`email` VARCHAR(255) UNIQUE NOT NULL,
124+
`password` VARCHAR(110) NOT NULL,
125+
`admin` TINYINT(1) NOT NULL DEFAULT '0',
126+
`created` DATETIME NOT NULL
127+
);
128+
129+
After executing these statements, the schema table contains the ``CREATE TABLE`` statement and other objects:
130+
131+
.. code-block:: text
132+
133+
sqlite> SELECT * FROM sqlite_master;
134+
table|users|users|2|CREATE TABLE `users` (
135+
`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
136+
`name` TEXT NOT NULL,
137+
`email` VARCHAR(255) UNIQUE NOT NULL,
138+
`password` VARCHAR(110) NOT NULL,
139+
`admin` TINYINT(1) NOT NULL DEFAULT '0',
140+
`created` DATETIME NOT NULL
141+
)
142+
index|sqlite_autoindex_users_1|users|3|
143+
table|sqlite_sequence|sqlite_sequence|4|CREATE TABLE sqlite_sequence(name,seq)
144+
145+
From a SQL injection vulnerability, this table can be obtained using queries such as:
146+
147+
.. code-block:: sql
148+
149+
-- Concatenate all fields and select the 1st entry (using COALESCE to support NULL values)
150+
SELECT type||';'||name||';'||tbl_name||';'||rootpage||';'||COALESCE(sql,'') FROM sqlite_master
151+
LIMIT 0,1;
152+
153+
-- Concatenate all fields of all rows
154+
SELECT GROUP_CONCAT(type||';'||name||';'||tbl_name||';'||rootpage||';'||COALESCE(sql,''),'^')
155+
FROM sqlite_master;
156+
157+
To exfiltrate the characters of such a string, functions ``HEX``, ``SUBSTR`` and ``LENGTH`` (documented in `Built-In Scalar SQL Functions <https://sqlite.org/lang_corefunc.html>`_) can be used.
158+
For example:
159+
160+
.. code-block:: sql
161+
162+
sqlite> SELECT HEX('hello');
163+
68656C6C6F
164+
sqlite> SELECT LENGTH(HEX('hello'));
165+
10
166+
sqlite> SELECT SUBSTR(HEX('hello'),1,1)='6';
167+
1
168+
sqlite> SELECT SUBSTR(HEX('hello'),1,1)>'9';
169+
0

0 commit comments

Comments
 (0)