-
-
Notifications
You must be signed in to change notification settings - Fork 421
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Local File Inclusion Vulnerability #293
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
package org.sasanlabs.service.vulnerability.lfi; | ||
|
||
import static org.sasanlabs.vulnerability.utils.Constants.NULL_BYTE_CHARACTER; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.*; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.sasanlabs.internal.utility.LevelConstants; | ||
import org.sasanlabs.internal.utility.Variant; | ||
import org.sasanlabs.internal.utility.annotations.AttackVector; | ||
import org.sasanlabs.internal.utility.annotations.VulnerableAppRequestMapping; | ||
import org.sasanlabs.internal.utility.annotations.VulnerableAppRestController; | ||
import org.sasanlabs.service.vulnerability.pathTraversal.PathTraversalVulnerability; | ||
import org.sasanlabs.vulnerability.types.VulnerabilitySubType; | ||
import org.sasanlabs.vulnerability.types.VulnerabilityType; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
|
||
@VulnerableAppRestController( | ||
descriptionLabel = "URL_BASED_LFI_INJECTION", | ||
value = "LocalFileInclusion", | ||
type = {VulnerabilityType.LFI}) | ||
public class LFIVulnerability { | ||
|
||
private static final transient Logger LOGGER = | ||
LogManager.getLogger(PathTraversalVulnerability.class); | ||
|
||
private static final String URL_PARAM_KEY = "file"; | ||
|
||
@AttackVector( | ||
vulnerabilityExposed = VulnerabilitySubType.LFI, | ||
description = "LFI_URL_DIRECT_INJECTION") | ||
@VulnerableAppRequestMapping( | ||
value = LevelConstants.LEVEL_1, | ||
descriptionLabel = "LFI_URL_PARAM_BASED_DIRECT_INJECTION", | ||
htmlTemplate = "LEVEL_1/LFI") | ||
public ResponseEntity<String> getVulnerablePayloadLevelUnsecure( | ||
@RequestParam Map<String, String> queryParams) { | ||
StringBuilder payload = new StringBuilder(); | ||
String queryParameterURL = queryParams.get(URL_PARAM_KEY); | ||
if (queryParameterURL != null) { | ||
try { | ||
File file = | ||
new File( | ||
"src/main/java/org/sasanlabs/service/vulnerability/lfi/" | ||
+ queryParameterURL); | ||
Scanner reader = new Scanner(file); | ||
String data = ""; | ||
while (reader.hasNextLine()) { | ||
data = data + reader.nextLine(); | ||
} | ||
payload.append(data); | ||
reader.close(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please close the reader in finally block or better use try with resourcr There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright! |
||
} catch (IOException e) { | ||
LOGGER.error("Following error occurred:", e); | ||
} | ||
} | ||
|
||
return new ResponseEntity<String>(payload.toString(), HttpStatus.OK); | ||
} | ||
|
||
@AttackVector( | ||
vulnerabilityExposed = VulnerabilitySubType.LFI, | ||
description = "LFI_URL_DIRECT_INJECTION_WITH_VALIDATION_ON_FILE") | ||
@VulnerableAppRequestMapping( | ||
value = LevelConstants.LEVEL_2, | ||
descriptionLabel = "LFI_URL_PARAM_BASED_INJECTION_WITH_VALIDATION_ON_FILE", | ||
htmlTemplate = "LEVEL_1/LFI") | ||
public ResponseEntity<String> getVulnerablePayloadLevelUnsecureLevel2( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please try queryparam by name injection instead of map. |
||
@RequestParam Map<String, String> queryParams) { | ||
StringBuilder payload = new StringBuilder(); | ||
String queryParameterURL = queryParams.get(URL_PARAM_KEY); | ||
if (queryParameterURL != null && queryParameterURL.contains(NULL_BYTE_CHARACTER)) { | ||
try { | ||
queryParameterURL = queryParameterURL.replace(NULL_BYTE_CHARACTER, ""); | ||
File file = | ||
new File( | ||
"src/main/java/org/" | ||
+ "sasanlabs/service/vulnerability/lfi/" | ||
+ queryParameterURL); | ||
Scanner reader = new Scanner(file); | ||
String data = ""; | ||
while (reader.hasNextLine()) { | ||
data = data + reader.nextLine(); | ||
} | ||
payload.append(data); | ||
reader.close(); | ||
} catch (IOException e) { | ||
LOGGER.error("Following error occurred:", e); | ||
} | ||
} | ||
|
||
return new ResponseEntity<String>(payload.toString(), HttpStatus.OK); | ||
} | ||
|
||
@AttackVector( | ||
vulnerabilityExposed = VulnerabilitySubType.LFI, | ||
description = "LFI_URL_DIRECT_INJECTION_DOT_DOT_SLASH") | ||
@VulnerableAppRequestMapping( | ||
value = LevelConstants.LEVEL_3, | ||
descriptionLabel = "LFI_URL_PARAM_BASED_INJECTION_WITH_DOT_DOT_SLASH", | ||
htmlTemplate = "LEVEL_1/LFI") | ||
public ResponseEntity<String> getVulnerablePayloadLevelUnsecureLevel3( | ||
@RequestParam Map<String, String> queryParams) { | ||
StringBuilder payload = new StringBuilder(); | ||
String queryParameterURL = queryParams.get(URL_PARAM_KEY); | ||
if (queryParameterURL != null && queryParameterURL.equals("../passwords.txt")) { | ||
try { | ||
queryParameterURL = queryParameterURL.replace("..", "secretFiles"); | ||
File file = | ||
new File( | ||
"src/main/java/org/" | ||
+ "sasanlabs/service/vulnerability/lfi/" | ||
+ queryParameterURL); | ||
Scanner reader = new Scanner(file); | ||
String data = ""; | ||
while (reader.hasNextLine()) { | ||
data = data + reader.nextLine(); | ||
} | ||
payload.append(data); | ||
reader.close(); | ||
} catch (IOException e) { | ||
LOGGER.error("Following error occurred:", e); | ||
} | ||
} | ||
|
||
return new ResponseEntity<String>(payload.toString(), HttpStatus.OK); | ||
} | ||
|
||
@AttackVector( | ||
vulnerabilityExposed = VulnerabilitySubType.LFI, | ||
description = "LFI_URL_DIRECT_INJECTION_WHITELISTING") | ||
@VulnerableAppRequestMapping( | ||
value = LevelConstants.LEVEL_4, | ||
variant = Variant.SECURE, | ||
descriptionLabel = "LFI_URL_PARAM_BASED_DIRECT_INJECTION", | ||
htmlTemplate = "LEVEL_1/LFI") | ||
public ResponseEntity<String> getVulnerablePayloadLevelUnsecureLevel4( | ||
@RequestParam Map<String, String> queryParams) { | ||
StringBuilder payload = new StringBuilder(); | ||
String queryParameterURL = queryParams.get(URL_PARAM_KEY); | ||
String[] files = new String[] {"secretFiles/passwords.txt"}; | ||
List<String> protectedFiles = new ArrayList<>(Arrays.asList(files)); | ||
if (queryParameterURL != null && protectedFiles.contains(queryParameterURL) == false) { | ||
try { | ||
File file = | ||
new File( | ||
"src/main/java/org/" | ||
+ "sasanlabs/service/vulnerability/lfi/" | ||
+ queryParameterURL); | ||
Scanner reader = new Scanner(file); | ||
String data = ""; | ||
while (reader.hasNextLine()) { | ||
data = data + reader.nextLine(); | ||
} | ||
payload.append(data); | ||
reader.close(); | ||
} catch (IOException e) { | ||
LOGGER.error("Following error occurred:", e); | ||
} | ||
} else { | ||
payload.append("You don't have access to this data"); | ||
} | ||
|
||
return new ResponseEntity<String>(payload.toString(), HttpStatus.OK); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<h2>TOP SECRET PASSWORDS</h2> | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we don't need a special file, use /etc/passwd and equivalent for windows. |
||
<p>USER1:PQOAJ231</p> | ||
<p>USER2:DKAO1020</p> | ||
<p>USER3:CMVNP325</p> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,7 @@ | |
<!-- TODO Add active to mode when clicked--> | ||
<div class="navbar navbar-item"> | ||
<div class="navbar-item-menu active" id="home"> | ||
<a href="/">Home</a> | ||
<a href="/VulnerableApp">Home</a> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks a lot for the fix. |
||
</div> | ||
<div class="navbar-item-menu" id="about"> | ||
<a href="#about">About Us</a> | ||
|
@@ -31,7 +31,7 @@ | |
Mode | ||
</div> | ||
<div class="navbar-item-menu"> | ||
<a href="https://github.com/SasanLabs/VulnerableApp" target="_blank"><img src="/images/GitHub-Mark-32px.png" /></a> | ||
<a href="https://github.com/SasanLabs/VulnerableApp" target="_blank"><img src="images/GitHub-Mark-32px.png" /></a> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Amazing |
||
</div> | ||
</div> | ||
</div> | ||
|
@@ -86,8 +86,8 @@ <h2>How can Vulnerability Scanning Tools use VulnerableApp?</h2> | |
<br/> | ||
<b>Following are the endpoints exposed: </b> | ||
<ol> | ||
<li><a href="/scanner">Scanner Endpoint</a></li> | ||
<li><a href="/sitemap.xml">SiteMap Endpoint</a></li> | ||
<li><a href="/VulnerableApp/scanner">Scanner Endpoint</a></li> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks a lot this fix. |
||
<li><a href="/VulnerableApp/sitemap.xml">SiteMap Endpoint</a></li> | ||
</ol> | ||
|
||
<b>Scanner Endpoint</b><br/> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#LFI_level_1 { | ||
color: black; | ||
text-align: left; | ||
font-size: 18px; | ||
font-weight: normal; | ||
} | ||
|
||
#verifyUrl { | ||
background: blueviolet; | ||
display: inline-block; | ||
padding: 4px 4px; | ||
margin: 10px; | ||
border: 1px solid transparent; | ||
border-radius: 2px; | ||
transition: 0.2s opacity; | ||
color: #FFF; | ||
font-size: 12px; | ||
} | ||
|
||
#url { | ||
width: 500px | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<div id="LFI_level_1"> | ||
<div> | ||
Local file inclusion (also known as LFI) is the process of including files, | ||
that are already locally present on the server, through the exploiting of | ||
vulnerable inclusion procedures implemented in the application. | ||
This vulnerability occurs, for example, when a page receives, as input, | ||
the path to the file that has to be included and this input is not properly | ||
sanitized, allowing directory traversal characters (such as dot-dot-slash) | ||
to be injected. | ||
<br /> <br /> | ||
Try to find the password file inside the secretFiles folder using the URL param: <i>file</i> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line sounds like a challenge, which doesn't align with our vulnerable applications mission. Consider this application as a general application which has flaws and let scanners explore and find them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I will change it. |
||
</div> | ||
<br /> <br /> | ||
<div> | ||
<b>please enter a URL:</b> | ||
<input type="text" id="url"/> | ||
<button id="verifyUrl">Verify URL</button> | ||
<div id="verificationResponse"></div> | ||
</div> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
function addingEventListenerToVerifyUrl() { | ||
document.getElementById("verifyUrl").addEventListener("click", function () { | ||
let urlInput = document.getElementById("url").value; | ||
let params = "?file=" + getParameterByName("file", urlInput); | ||
let urlLevel = getUrlForVulnerabilityLevel() + params; | ||
doGetAjaxCall(updateUIWithVerifyResponse, urlLevel, false); | ||
}); | ||
} | ||
addingEventListenerToVerifyUrl(); | ||
|
||
function updateUIWithVerifyResponse(data) { | ||
if (data) { | ||
document.getElementById("verificationResponse").innerHTML = data; | ||
} else { | ||
document.getElementById("verificationResponse").innerHTML = "Try again."; | ||
} | ||
} | ||
|
||
function getParameterByName(name, url) { | ||
name = name.replace(/[\[\]]/g, "\\$&"); | ||
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), | ||
results = regex.exec(url); | ||
if (!results) return null; | ||
if (!results[2]) return ""; | ||
return results[2]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is scanner the best way to read file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, do you have a suggestion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be buffered reader but not sure if there are any new libraries which can be more better. Please check.