From 9563b12f2a690a35fd2d39f72546e48f24409c01 Mon Sep 17 00:00:00 2001 From: Ivan Date: Thu, 1 Jul 2021 18:02:43 -0500 Subject: [PATCH 1/3] Local File Inclusion Vulnerability and fixes --- .../vulnerability/lfi/LFIVulnerability.java | 106 ++++++++++++++++++ .../lfi/secretFiles/passwords.txt | 6 + .../types/VulnerabilitySubType.java | 5 +- src/main/resources/i18n/messages.properties | 26 ++++- .../resources/i18n/messages_en_US.properties | 26 ++++- .../static/images/GitHub-Mark-32px.png | Bin 0 -> 1714 bytes src/main/resources/static/index.html | 8 +- .../LocalFileInclusion/LEVEL_1/LFI.css | 6 + .../LocalFileInclusion/LEVEL_1/LFI.html | 17 +++ 9 files changed, 189 insertions(+), 11 deletions(-) create mode 100644 src/main/java/org/sasanlabs/service/vulnerability/lfi/LFIVulnerability.java create mode 100644 src/main/java/org/sasanlabs/service/vulnerability/lfi/secretFiles/passwords.txt create mode 100644 src/main/resources/static/images/GitHub-Mark-32px.png create mode 100644 src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css create mode 100644 src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html diff --git a/src/main/java/org/sasanlabs/service/vulnerability/lfi/LFIVulnerability.java b/src/main/java/org/sasanlabs/service/vulnerability/lfi/LFIVulnerability.java new file mode 100644 index 00000000..5446a034 --- /dev/null +++ b/src/main/java/org/sasanlabs/service/vulnerability/lfi/LFIVulnerability.java @@ -0,0 +1,106 @@ +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.Map; +import java.util.Scanner; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.sasanlabs.internal.utility.GenericUtils; +import org.sasanlabs.internal.utility.LevelConstants; +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 getVulnerablePayloadLevelUnsecure( + @RequestParam Map 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(); + } + data = + data + + "go to LEVEL_2"; + payload.append(data); + reader.close(); + } catch (IOException e) { + LOGGER.error("Following error occurred:", e); + } + } + + return new ResponseEntity<>( + GenericUtils.wrapPayloadInGenericVulnerableAppTemplate(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 getVulnerablePayloadLevelUnsecureLevel2( + @RequestParam Map 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<>( + GenericUtils.wrapPayloadInGenericVulnerableAppTemplate(payload.toString()), + HttpStatus.OK); + } +} diff --git a/src/main/java/org/sasanlabs/service/vulnerability/lfi/secretFiles/passwords.txt b/src/main/java/org/sasanlabs/service/vulnerability/lfi/secretFiles/passwords.txt new file mode 100644 index 00000000..a6af29ce --- /dev/null +++ b/src/main/java/org/sasanlabs/service/vulnerability/lfi/secretFiles/passwords.txt @@ -0,0 +1,6 @@ +

TOP SECRET PASSWORDS

+ +

USER1:PQOAJ231

+

USER2:DKAO1020

+

USER3:CMVNP325

+ diff --git a/src/main/java/org/sasanlabs/vulnerability/types/VulnerabilitySubType.java b/src/main/java/org/sasanlabs/vulnerability/types/VulnerabilitySubType.java index 747a8f9a..c1ecb121 100644 --- a/src/main/java/org/sasanlabs/vulnerability/types/VulnerabilitySubType.java +++ b/src/main/java/org/sasanlabs/vulnerability/types/VulnerabilitySubType.java @@ -41,7 +41,10 @@ public enum VulnerabilitySubType { NULL_BYTE(VulnerabilityType.NULL_BYTE), // XXE Vulnerability - XXE(VulnerabilityType.XXE); + XXE(VulnerabilityType.XXE), + + // LFI Vulnerability + LFI(VulnerabilityType.LFI); private VulnerabilityType vulnerabilityType; diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties index c83e695b..64886581 100755 --- a/src/main/resources/i18n/messages.properties +++ b/src/main/resources/i18n/messages.properties @@ -203,9 +203,29 @@ COMMAND_INJECTION_URL_PARAM_DIRECTLY_EXECUTED_IF_SEMICOLON_SPACE_LOGICAL_AND_%26 # Local File Injection -#URL_BASED_LFI_INJECTION=Url based Local File Injection attack. -#LFI_URL_PARAM_BASED_DIRECT_INJECTION=Url Parameter \"fileName\" is directly passed to the include file. -#LFI_URL_PARAM_BASED_INJECTION_WITH_VALIDATION_ON_FILE=Url Parameter \"fileName\" is validated and passed to include file. +URL_BASED_LFI_INJECTION=LFI vulnerabilities allow an attacker to read (and sometimes execute) files on the victim machine.\ + An attacker can use Local File Inclusion (LFI) to trick the web application into exposing or running files on the web server. \ +An LFI attack may lead to information disclosure, remote code execution, or even Cross-site Scripting (XSS). \ +Typically, LFI occurs when an application uses the path to a file as input. If the application treats this input \ \ +as trusted, a local file may be used in the include statement. \ +

Important Links on LFI : \ +
    \
  1. \ + Testing for Local File Inclusion \ \ +
  2. \ + Local File Inclusion by netsparker \ +
+LFI_URL_PARAM_BASED_DIRECT_INJECTION=Url Parameter \"fileName\" is directly passed to the include file. +LFI_URL_PARAM_BASED_INJECTION_WITH_VALIDATION_ON_FILE=Url Parameter \"fileName\" is validated and passed to include file. +#### AttackVector description +LFI_URL_DIRECT_INJECTION=If the developer fails to implement sufficient filtering an attacker could exploit the local file \ +inclusion vulnerability by replacing the path with another path of a sensitive file such as a password file, allowing \ +the attacker to see its content. +LFI_URL_DIRECT_INJECTION_WITH_VALIDATION_ON_FILE=The null character is a control character with the value zero present in \ +many character sets that is being used as a reserved character to mark the end of a string. Once used, any character after \ +this special byte will be ignored. Commonly the way to inject this character would be with the URL encoded string %00 by \ +appending it to the requested path, this would ignore the file's extension being added to the input filename, \ +returning to an attacker the file information as a result of a successful exploitation. # Local File Injection with Null Byte #URL_WITH_NULL_BYTE_BASED_LFI_INJECTION=Url with Null Byte Injection based Local File Injection attack. diff --git a/src/main/resources/i18n/messages_en_US.properties b/src/main/resources/i18n/messages_en_US.properties index d1ff0875..be5bf115 100755 --- a/src/main/resources/i18n/messages_en_US.properties +++ b/src/main/resources/i18n/messages_en_US.properties @@ -203,9 +203,29 @@ COMMAND_INJECTION_URL_PARAM_DIRECTLY_EXECUTED_IF_SEMICOLON_SPACE_LOGICAL_AND_%26 # Local File Injection -#URL_BASED_LFI_INJECTION=Url based Local File Injection attack. -#LFI_URL_PARAM_BASED_DIRECT_INJECTION=Url Parameter \"fileName\" is directly passed to the include file. -#LFI_URL_PARAM_BASED_INJECTION_WITH_VALIDATION_ON_FILE=Url Parameter \"fileName\" is validated and passed to include file. +URL_BASED_LFI_INJECTION=LFI vulnerabilities allow an attacker to read (and sometimes execute) files on the victim machine.\ + An attacker can use Local File Inclusion (LFI) to trick the web application into exposing or running files on the web server. \ +An LFI attack may lead to information disclosure, remote code execution, or even Cross-site Scripting (XSS). \ +Typically, LFI occurs when an application uses the path to a file as input. If the application treats this input \ \ +as trusted, a local file may be used in the include statement. \ +

Important Links on LFI : \ +
    \
  1. \ + Testing for Local File Inclusion \ \ +
  2. \ + Local File Inclusion by netsparker \ +
+LFI_URL_PARAM_BASED_DIRECT_INJECTION=Url Parameter \"fileName\" is directly passed to the include file. +LFI_URL_PARAM_BASED_INJECTION_WITH_VALIDATION_ON_FILE=Url Parameter \"fileName\" is validated and passed to include file. +#### AttackVector description +LFI_URL_DIRECT_INJECTION=If the developer fails to implement sufficient filtering an attacker could exploit the local file \ +inclusion vulnerability by replacing the path with another path of a sensitive file such as a password file, allowing \ +the attacker to see its content. +LFI_URL_DIRECT_INJECTION_WITH_VALIDATION_ON_FILE=The null character is a control character with the value zero present in \ +many character sets that is being used as a reserved character to mark the end of a string. Once used, any character after \ +this special byte will be ignored. Commonly the way to inject this character would be with the URL encoded string %00 by \ +appending it to the requested path, this would ignore the file's extension being added to the input filename, \ +returning to an attacker the file information as a result of a successful exploitation. # Local File Injection with Null Byte #URL_WITH_NULL_BYTE_BASED_LFI_INJECTION=Url with Null Byte Injection based Local File Injection attack. diff --git a/src/main/resources/static/images/GitHub-Mark-32px.png b/src/main/resources/static/images/GitHub-Mark-32px.png new file mode 100644 index 0000000000000000000000000000000000000000..8b25551a97921681334176ee143b41510a117d86 GIT binary patch literal 1714 zcmaJ?X;2eq7*4oFu!ne{XxAht2qc?8LXr|_LPCfTpaBK7K$c{I0Ld=NLIOeuC;@2) zZ$K%a)k+m-s0>xHmKxL%0V&0TRzzznhgyqrIC$F)0{WwLXLrBvd*^wc_uSc%h%m9E z{W5z3f#4_!7RvAyFh6!S_*<8qJ%KOIm?#E|L=rJQq=gB5C6WLG5;c?r%V0>EmEH#X z5eSwPRa6WXBMs#$5H%GtW2go-in9p>zW@UYDNNWc^XOXZQ? z1QjEV00I#$3^1wQUJ8&-2UsjB-G|9y(LDhMNN3PM{APL4eYi{(m*ERcUnJa{R+-3^ z34^A6;U^v`8N*O6ji%S@sd{fJqD`XFIUJ5zgTe5^5nj414F(y!G&=H(f)Lgzv?>%+ zAsWD}2qhpH7>|TU`X&W6IxDNuO_vET7|j5oG&&VDr!)hUO8+0KR?nh!m<)a!?|%yG zqOwq!CWCcIhE{<$E|F|@g>nP6FoYr6C<8>D?ID9%&5J(4oSbR1I^byW*g@__U z4QsF&uJSEcFeleM3~ChjEQGbHOjsGDMbyAl(p=Ttv9RaVo8~I#js@@Y9C^_2U})yn zzSHU%6FxuY?d;&65MyR({^lU*3$z$ZllDb(o&<7d;A_`h2U+3~BJ2Hv`{W}KEU801#cv_B|9Cm!ynR{S`AMsSn z;7E=B;mb!wx$L;S>yGXG^6=&WlQn9$s?&L%Y1D8TI^MlKB1DqsEng$>f4=xYWBoPI z_S1p!sJ#d2?YI4kPA{k}Eby?F=f-J9zIc`YDl^pzjVm~9ebE?Hn?t0Nx+la|D0MB; z9)2xv1G>a1|A9kQ>~DV<=X3-4yC&n!m8-3K#P z{X@0zRuQsy$+N ziSCoLJU{Z$nQy4A4Y5UJ07$5FA~qL2%Q+cLaqDU?Lz3?=BC5;Nk6BbTmmceEaM>-Z zi>O&-dSE=%ex;vcvCOk{*JQ5^_4M z4lW7%l9IqY(z7pV(?I@@8=KPFO82)O{VDI18-*d-k$YmI^XiuPs_LuFw<^ZcD}yP5 c*NrbeloN*74g`U%%F6r~k%+>C^#XapzmV0H-2eap literal 0 HcmV?d00001 diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index e34b2a0a..3205fa6f 100755 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -22,7 +22,7 @@ @@ -86,8 +86,8 @@

How can Vulnerability Scanning Tools use VulnerableApp?


Following are the endpoints exposed:
    -
  1. Scanner Endpoint
  2. -
  3. SiteMap Endpoint
  4. +
  5. Scanner Endpoint
  6. +
  7. SiteMap Endpoint
Scanner Endpoint
diff --git a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css new file mode 100644 index 00000000..d28a03ff --- /dev/null +++ b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css @@ -0,0 +1,6 @@ +#LFI_level_1 { + color: black; + text-align: left; + font-size: 18px; + font-weight: normal; +} \ No newline at end of file diff --git a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html new file mode 100644 index 00000000..73b29d13 --- /dev/null +++ b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html @@ -0,0 +1,17 @@ +
+
+ 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. +

+ For practice these vulnerabilities enter to: + http://[baseUrl]:9090/VulnerableApp/LocalFileInclusion/[level] + Try to find the password file inside the secretFiles folder using the URL param: file +

+ click here to start in LEVEL 1 +
+
\ No newline at end of file From 4520651018c97e2aa5d18f40fc78b006e9caa931 Mon Sep 17 00:00:00 2001 From: Ivan Date: Sat, 3 Jul 2021 15:00:09 -0500 Subject: [PATCH 2/3] New levels and UI changed --- .../vulnerability/lfi/LFIVulnerability.java | 88 ++++++++++++++++--- src/main/resources/i18n/messages.properties | 5 ++ .../resources/i18n/messages_en_US.properties | 5 ++ .../LocalFileInclusion/LEVEL_1/LFI.css | 12 +++ .../LocalFileInclusion/LEVEL_1/LFI.html | 8 +- .../LocalFileInclusion/LEVEL_1/LFI.js | 21 +++++ 6 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.js diff --git a/src/main/java/org/sasanlabs/service/vulnerability/lfi/LFIVulnerability.java b/src/main/java/org/sasanlabs/service/vulnerability/lfi/LFIVulnerability.java index 5446a034..286d8a94 100644 --- a/src/main/java/org/sasanlabs/service/vulnerability/lfi/LFIVulnerability.java +++ b/src/main/java/org/sasanlabs/service/vulnerability/lfi/LFIVulnerability.java @@ -4,12 +4,11 @@ import java.io.File; import java.io.IOException; -import java.util.Map; -import java.util.Scanner; +import java.util.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.sasanlabs.internal.utility.GenericUtils; 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; @@ -53,9 +52,6 @@ public ResponseEntity getVulnerablePayloadLevelUnsecure( while (reader.hasNextLine()) { data = data + reader.nextLine(); } - data = - data - + "go to LEVEL_2"; payload.append(data); reader.close(); } catch (IOException e) { @@ -63,9 +59,7 @@ public ResponseEntity getVulnerablePayloadLevelUnsecure( } } - return new ResponseEntity<>( - GenericUtils.wrapPayloadInGenericVulnerableAppTemplate(payload.toString()), - HttpStatus.OK); + return new ResponseEntity(payload.toString(), HttpStatus.OK); } @AttackVector( @@ -99,8 +93,78 @@ public ResponseEntity getVulnerablePayloadLevelUnsecureLevel2( } } - return new ResponseEntity<>( - GenericUtils.wrapPayloadInGenericVulnerableAppTemplate(payload.toString()), - HttpStatus.OK); + return new ResponseEntity(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 getVulnerablePayloadLevelUnsecureLevel3( + @RequestParam Map 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(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 getVulnerablePayloadLevelUnsecureLevel4( + @RequestParam Map queryParams) { + StringBuilder payload = new StringBuilder(); + String queryParameterURL = queryParams.get(URL_PARAM_KEY); + String[] files = new String[] {"secretFiles/passwords.txt"}; + List 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(payload.toString(), HttpStatus.OK); } } diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties index 64886581..2e28425c 100755 --- a/src/main/resources/i18n/messages.properties +++ b/src/main/resources/i18n/messages.properties @@ -217,6 +217,7 @@ as trusted, a local file may be used in the include statement. \ LFI_URL_PARAM_BASED_DIRECT_INJECTION=Url Parameter \"fileName\" is directly passed to the include file. LFI_URL_PARAM_BASED_INJECTION_WITH_VALIDATION_ON_FILE=Url Parameter \"fileName\" is validated and passed to include file. +LFI_URL_PARAM_BASED_INJECTION_WITH_DOT_DOT_SLASH=Url Parameter \"fileName\" is validated and passed to include file. #### AttackVector description LFI_URL_DIRECT_INJECTION=If the developer fails to implement sufficient filtering an attacker could exploit the local file \ inclusion vulnerability by replacing the path with another path of a sensitive file such as a password file, allowing \ @@ -226,6 +227,10 @@ many character sets that is being used as a reserved character to mark the end o this special byte will be ignored. Commonly the way to inject this character would be with the URL encoded string %00 by \ appending it to the requested path, this would ignore the file's extension being added to the input filename, \ returning to an attacker the file information as a result of a successful exploitation. +LFI_URL_DIRECT_INJECTION_DOT_DOT_SLASH=The attacker can see a file content by appending the sequence: dot-dot-slash (../) \ +and the file's name in the url. +LFI_URL_DIRECT_INJECTION_WHITELISTING=A way to prevent LFI attacks is with a whitelisting: use verified and secured whitelist \ +files and ignore everything else # Local File Injection with Null Byte #URL_WITH_NULL_BYTE_BASED_LFI_INJECTION=Url with Null Byte Injection based Local File Injection attack. diff --git a/src/main/resources/i18n/messages_en_US.properties b/src/main/resources/i18n/messages_en_US.properties index be5bf115..46f1c25f 100755 --- a/src/main/resources/i18n/messages_en_US.properties +++ b/src/main/resources/i18n/messages_en_US.properties @@ -217,6 +217,7 @@ as trusted, a local file may be used in the include statement. \ LFI_URL_PARAM_BASED_DIRECT_INJECTION=Url Parameter \"fileName\" is directly passed to the include file. LFI_URL_PARAM_BASED_INJECTION_WITH_VALIDATION_ON_FILE=Url Parameter \"fileName\" is validated and passed to include file. +LFI_URL_PARAM_BASED_INJECTION_WITH_DOT_DOT_SLASH=Url Parameter \"fileName\" is validated and passed to include file. #### AttackVector description LFI_URL_DIRECT_INJECTION=If the developer fails to implement sufficient filtering an attacker could exploit the local file \ inclusion vulnerability by replacing the path with another path of a sensitive file such as a password file, allowing \ @@ -226,6 +227,10 @@ many character sets that is being used as a reserved character to mark the end o this special byte will be ignored. Commonly the way to inject this character would be with the URL encoded string %00 by \ appending it to the requested path, this would ignore the file's extension being added to the input filename, \ returning to an attacker the file information as a result of a successful exploitation. +LFI_URL_DIRECT_INJECTION_DOT_DOT_SLASH=The attacker can see a file content by appending the sequence: dot-dot-slash (../) \ +and the file's name in the url. +LFI_URL_DIRECT_INJECTION_WHITELISTING=A way to prevent LFI attacks is with a whitelisting: use verified and secured whitelist \ +files and ignore everything else # Local File Injection with Null Byte #URL_WITH_NULL_BYTE_BASED_LFI_INJECTION=Url with Null Byte Injection based Local File Injection attack. diff --git a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css index d28a03ff..de450889 100644 --- a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css +++ b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css @@ -3,4 +3,16 @@ 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; } \ No newline at end of file diff --git a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html index 73b29d13..a1ff3947 100644 --- a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html +++ b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html @@ -8,10 +8,10 @@ sanitized, allowing directory traversal characters (such as dot-dot-slash) to be injected.

- For practice these vulnerabilities enter to: - http://[baseUrl]:9090/VulnerableApp/LocalFileInclusion/[level] Try to find the password file inside the secretFiles folder using the URL param: file -

- click here to start in LEVEL 1 + +
+ +
\ No newline at end of file diff --git a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.js b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.js new file mode 100644 index 00000000..8adf6335 --- /dev/null +++ b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.js @@ -0,0 +1,21 @@ +function addingEventListenerToVerifyUrl() { + document.getElementById("verifyUrl").addEventListener("click", function () { + let url = getUrlForVulnerabilityLevel(); + const queryString = location.search; + + url = url + queryString; + + console.log(url); + + doGetAjaxCall(updateUIWithVerifyResponse, url, false); + }); +} +addingEventListenerToVerifyUrl(); + +function updateUIWithVerifyResponse(data) { + if (data) { + document.getElementById("verificationResponse").innerHTML = data; + } else { + document.getElementById("verificationResponse").innerHTML = "Try again."; + } +} From 0e67f1498610545c0f49cdb5408e8e2a3b30c605 Mon Sep 17 00:00:00 2001 From: Ivan Date: Sun, 4 Jul 2021 11:29:05 -0500 Subject: [PATCH 3/3] Input box for LFI vulnerability --- .../LocalFileInclusion/LEVEL_1/LFI.css | 4 ++++ .../LocalFileInclusion/LEVEL_1/LFI.html | 3 +++ .../LocalFileInclusion/LEVEL_1/LFI.js | 21 ++++++++++++------- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css index de450889..5f109f5e 100644 --- a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css +++ b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.css @@ -15,4 +15,8 @@ transition: 0.2s opacity; color: #FFF; font-size: 12px; +} + +#url { + width: 500px } \ No newline at end of file diff --git a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html index a1ff3947..422a0fe4 100644 --- a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html +++ b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.html @@ -10,7 +10,10 @@

Try to find the password file inside the secretFiles folder using the URL param: file +

+ please enter a URL: +
diff --git a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.js b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.js index 8adf6335..3796fec1 100644 --- a/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.js +++ b/src/main/resources/static/templates/LocalFileInclusion/LEVEL_1/LFI.js @@ -1,13 +1,9 @@ function addingEventListenerToVerifyUrl() { document.getElementById("verifyUrl").addEventListener("click", function () { - let url = getUrlForVulnerabilityLevel(); - const queryString = location.search; - - url = url + queryString; - - console.log(url); - - doGetAjaxCall(updateUIWithVerifyResponse, url, false); + let urlInput = document.getElementById("url").value; + let params = "?file=" + getParameterByName("file", urlInput); + let urlLevel = getUrlForVulnerabilityLevel() + params; + doGetAjaxCall(updateUIWithVerifyResponse, urlLevel, false); }); } addingEventListenerToVerifyUrl(); @@ -19,3 +15,12 @@ function updateUIWithVerifyResponse(data) { 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]; +}