Skip to content

Commit 9237a68

Browse files
author
GitHub Actions Deployer
committed
Sphinx build of 8cd9293
1 parent aec80e9 commit 9237a68

File tree

4 files changed

+139
-1
lines changed

4 files changed

+139
-1
lines changed

_sources/database/sqlite.rst.txt

+73
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

database/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ <h1>Databases<a class="headerlink" href="#databases" title="Permalink to this he
6363
<li class="toctree-l2"><a class="reference internal" href="sqlite.html#introduction">Introduction</a></li>
6464
<li class="toctree-l2"><a class="reference internal" href="sqlite.html#basic-commands">Basic commands</a></li>
6565
<li class="toctree-l2"><a class="reference internal" href="sqlite.html#sql-statements">SQL statements</a></li>
66+
<li class="toctree-l2"><a class="reference internal" href="sqlite.html#schema-table">Schema table</a></li>
6667
</ul>
6768
</li>
6869
</ul>

database/sqlite.html

+64
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ <h2>Basic commands<a class="headerlink" href="#basic-commands" title="Permalink
6363

6464
<span class="c1"># Show the version</span>
6565
.version
66+
SELECT SQLITE_VERSION<span class="o">()</span><span class="p">;</span>
6667

6768
<span class="c1"># Quit</span>
6869
.exit
@@ -121,6 +122,68 @@ <h2>SQL statements<a class="headerlink" href="#sql-statements" title="Permalink
121122
</pre></div>
122123
</div>
123124
</section>
125+
<section id="schema-table">
126+
<h2>Schema table<a class="headerlink" href="#schema-table" title="Permalink to this headline"></a></h2>
127+
<p>According to the <a class="reference external" href="https://www.sqlite.org/schematab.html">documentation</a>, every SQLite database contains a single “schema table” named <code class="docutils literal notranslate"><span class="pre">sqlite_master</span></code> that stores the schema for that database.</p>
128+
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="n">sqlite</span><span class="o">&gt;</span><span class="w"> </span><span class="p">.</span><span class="k">schema</span><span class="w"> </span><span class="n">sqlite_master</span><span class="w"></span>
129+
<span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">sqlite_master</span><span class="w"> </span><span class="p">(</span><span class="w"></span>
130+
<span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="nb">text</span><span class="p">,</span><span class="w"></span>
131+
<span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="nb">text</span><span class="p">,</span><span class="w"></span>
132+
<span class="w"> </span><span class="n">tbl_name</span><span class="w"> </span><span class="nb">text</span><span class="p">,</span><span class="w"></span>
133+
<span class="w"> </span><span class="n">rootpage</span><span class="w"> </span><span class="nb">integer</span><span class="p">,</span><span class="w"></span>
134+
<span class="w"> </span><span class="k">sql</span><span class="w"> </span><span class="nb">text</span><span class="w"></span>
135+
<span class="p">);</span><span class="w"></span>
136+
</pre></div>
137+
</div>
138+
<p>To understand its content in actual database, let’s create a new table in an empty database.</p>
139+
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">DROP</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">IF</span><span class="w"> </span><span class="k">EXISTS</span><span class="w"> </span><span class="o">`</span><span class="n">users</span><span class="o">`</span><span class="p">;</span><span class="w"></span>
140+
<span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">IF</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">EXISTS</span><span class="w"> </span><span class="o">`</span><span class="n">users</span><span class="o">`</span><span class="w"> </span><span class="p">(</span><span class="w"></span>
141+
<span class="w"> </span><span class="o">`</span><span class="n">uid</span><span class="o">`</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="n">AUTOINCREMENT</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w"></span>
142+
<span class="w"> </span><span class="o">`</span><span class="n">name</span><span class="o">`</span><span class="w"> </span><span class="nb">TEXT</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w"></span>
143+
<span class="w"> </span><span class="o">`</span><span class="n">email</span><span class="o">`</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span><span class="w"> </span><span class="k">UNIQUE</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w"></span>
144+
<span class="w"> </span><span class="o">`</span><span class="n">password</span><span class="o">`</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">110</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w"></span>
145+
<span class="w"> </span><span class="o">`</span><span class="k">admin</span><span class="o">`</span><span class="w"> </span><span class="n">TINYINT</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="s1">&#39;0&#39;</span><span class="p">,</span><span class="w"></span>
146+
<span class="w"> </span><span class="o">`</span><span class="n">created</span><span class="o">`</span><span class="w"> </span><span class="n">DATETIME</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="w"></span>
147+
<span class="p">);</span><span class="w"></span>
148+
</pre></div>
149+
</div>
150+
<p>After executing these statements, the schema table contains the <code class="docutils literal notranslate"><span class="pre">CREATE</span> <span class="pre">TABLE</span></code> statement and other objects:</p>
151+
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>sqlite&gt; SELECT * FROM sqlite_master;
152+
table|users|users|2|CREATE TABLE `users` (
153+
`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
154+
`name` TEXT NOT NULL,
155+
`email` VARCHAR(255) UNIQUE NOT NULL,
156+
`password` VARCHAR(110) NOT NULL,
157+
`admin` TINYINT(1) NOT NULL DEFAULT &#39;0&#39;,
158+
`created` DATETIME NOT NULL
159+
)
160+
index|sqlite_autoindex_users_1|users|3|
161+
table|sqlite_sequence|sqlite_sequence|4|CREATE TABLE sqlite_sequence(name,seq)
162+
</pre></div>
163+
</div>
164+
<p>From a SQL injection vulnerability, this table can be obtained using queries such as:</p>
165+
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="c1">-- Concatenate all fields and select the 1st entry (using COALESCE to support NULL values)</span>
166+
<span class="k">SELECT</span><span class="w"> </span><span class="k">type</span><span class="o">||</span><span class="s1">&#39;;&#39;</span><span class="o">||</span><span class="n">name</span><span class="o">||</span><span class="s1">&#39;;&#39;</span><span class="o">||</span><span class="n">tbl_name</span><span class="o">||</span><span class="s1">&#39;;&#39;</span><span class="o">||</span><span class="n">rootpage</span><span class="o">||</span><span class="s1">&#39;;&#39;</span><span class="o">||</span><span class="k">COALESCE</span><span class="p">(</span><span class="k">sql</span><span class="p">,</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">sqlite_master</span><span class="w"></span>
167+
<span class="w"> </span><span class="k">LIMIT</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
168+
169+
<span class="c1">-- Concatenate all fields of all rows</span>
170+
<span class="k">SELECT</span><span class="w"> </span><span class="n">GROUP_CONCAT</span><span class="p">(</span><span class="k">type</span><span class="o">||</span><span class="s1">&#39;;&#39;</span><span class="o">||</span><span class="n">name</span><span class="o">||</span><span class="s1">&#39;;&#39;</span><span class="o">||</span><span class="n">tbl_name</span><span class="o">||</span><span class="s1">&#39;;&#39;</span><span class="o">||</span><span class="n">rootpage</span><span class="o">||</span><span class="s1">&#39;;&#39;</span><span class="o">||</span><span class="k">COALESCE</span><span class="p">(</span><span class="k">sql</span><span class="p">,</span><span class="s1">&#39;&#39;</span><span class="p">),</span><span class="s1">&#39;^&#39;</span><span class="p">)</span><span class="w"></span>
171+
<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">sqlite_master</span><span class="p">;</span><span class="w"></span>
172+
</pre></div>
173+
</div>
174+
<p>To exfiltrate the characters of such a string, functions <code class="docutils literal notranslate"><span class="pre">HEX</span></code>, <code class="docutils literal notranslate"><span class="pre">SUBSTR</span></code> and <code class="docutils literal notranslate"><span class="pre">LENGTH</span></code> (documented in <a class="reference external" href="https://sqlite.org/lang_corefunc.html">Built-In Scalar SQL Functions</a>) can be used.
175+
For example:</p>
176+
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="n">sqlite</span><span class="o">&gt;</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">HEX</span><span class="p">(</span><span class="s1">&#39;hello&#39;</span><span class="p">);</span><span class="w"></span>
177+
<span class="mi">68656</span><span class="n">C6C6F</span><span class="w"></span>
178+
<span class="n">sqlite</span><span class="o">&gt;</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="k">LENGTH</span><span class="p">(</span><span class="n">HEX</span><span class="p">(</span><span class="s1">&#39;hello&#39;</span><span class="p">));</span><span class="w"></span>
179+
<span class="mi">10</span><span class="w"></span>
180+
<span class="n">sqlite</span><span class="o">&gt;</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">SUBSTR</span><span class="p">(</span><span class="n">HEX</span><span class="p">(</span><span class="s1">&#39;hello&#39;</span><span class="p">),</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="o">=</span><span class="s1">&#39;6&#39;</span><span class="p">;</span><span class="w"></span>
181+
<span class="mi">1</span><span class="w"></span>
182+
<span class="n">sqlite</span><span class="o">&gt;</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">SUBSTR</span><span class="p">(</span><span class="n">HEX</span><span class="p">(</span><span class="s1">&#39;hello&#39;</span><span class="p">),</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="o">&gt;</span><span class="s1">&#39;9&#39;</span><span class="p">;</span><span class="w"></span>
183+
<span class="mi">0</span><span class="w"></span>
184+
</pre></div>
185+
</div>
186+
</section>
124187
</section>
125188

126189

@@ -136,6 +199,7 @@ <h3><a href="../index.html">Table of Contents</a></h3>
136199
<li><a class="reference internal" href="#introduction">Introduction</a></li>
137200
<li><a class="reference internal" href="#basic-commands">Basic commands</a></li>
138201
<li><a class="reference internal" href="#sql-statements">SQL statements</a></li>
202+
<li><a class="reference internal" href="#schema-table">Schema table</a></li>
139203
</ul>
140204
</li>
141205
</ul>

searchindex.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)